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 @@...@@ -5,10 +5,12 @@
55
6const std = @import("std");6const std = @import("std");
7const builtin = @import("builtin");7const builtin = @import("builtin");
8const Value = @import("value.zig").Value;
9const Type = @import("type.zig").Type;
10const assert = std.debug.assert;8const assert = std.debug.assert;
9
11const Air = @This();10const Air = @This();
11const Value = @import("value.zig").Value;
12const Type = @import("type.zig").Type;
13const InternPool = @import("InternPool.zig");
1214
13instructions: std.MultiArrayList(Inst).Slice,15instructions: std.MultiArrayList(Inst).Slice,
14/// The meaning of this data is determined by `Inst.Tag` value.16/// The meaning of this data is determined by `Inst.Tag` value.
...@@ -837,7 +839,88 @@ pub const Inst = struct {...@@ -837,7 +839,88 @@ pub const Inst = struct {
837 /// The position of an AIR instruction within the `Air` instructions array.839 /// The position of an AIR instruction within the `Air` instructions array.
838 pub const Index = u32;840 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
842 /// All instructions have an 8-byte payload, which is contained within925 /// All instructions have an 8-byte payload, which is contained within
843 /// this union. `Tag` determines which union field is active, as well as926 /// 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 {...@@ -1066,10 +1149,13 @@ pub fn getMainBody(air: Air) []const Air.Inst.Index {
10661149
1067pub fn typeOf(air: Air, inst: Air.Inst.Ref) Type {1150pub fn typeOf(air: Air, inst: Air.Inst.Ref) Type {
1068 const ref_int = @enumToInt(inst);1151 const ref_int = @enumToInt(inst);
1069 if (ref_int < Air.Inst.Ref.typed_value_map.len) {1152 if (ref_int < InternPool.static_keys.len) {
1070 return Air.Inst.Ref.typed_value_map[ref_int].ty;1153 return .{
1154 .ip_index = InternPool.static_keys[ref_int].typeOf(),
1155 .legacy = undefined,
1156 };
1071 }1157 }
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);
1073}1159}
10741160
1075pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {1161pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
...@@ -1286,11 +1372,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -1286,11 +1372,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
12861372
1287 .call, .call_always_tail, .call_never_tail, .call_never_inline => {1373 .call, .call_always_tail, .call_never_tail, .call_never_inline => {
1288 const callee_ty = air.typeOf(datas[inst].pl_op.operand);1374 const callee_ty = air.typeOf(datas[inst].pl_op.operand);
1289 switch (callee_ty.zigTypeTag()) {1375 return callee_ty.fnReturnType();
1290 .Fn => return callee_ty.fnReturnType(),
1291 .Pointer => return callee_ty.childType().fnReturnType(),
1292 else => unreachable,
1293 }
1294 },1376 },
12951377
1296 .slice_elem_val, .ptr_elem_val, .array_elem_val => {1378 .slice_elem_val, .ptr_elem_val, .array_elem_val => {
...@@ -1328,11 +1410,11 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -1328,11 +1410,11 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
13281410
1329pub fn getRefType(air: Air, ref: Air.Inst.Ref) Type {1411pub fn getRefType(air: Air, ref: Air.Inst.Ref) Type {
1330 const ref_int = @enumToInt(ref);1412 const ref_int = @enumToInt(ref);
1331 if (ref_int < Air.Inst.Ref.typed_value_map.len) {1413 if (ref_int < ref_start_index) {
1332 var buffer: Value.ToTypeBuffer = undefined;1414 const ip_index = @intToEnum(InternPool.Index, ref_int);
1333 return Air.Inst.Ref.typed_value_map[ref_int].val.toType(&buffer);1415 return ip_index.toType();
1334 }1416 }
1335 const inst_index = ref_int - Air.Inst.Ref.typed_value_map.len;1417 const inst_index = ref_int - ref_start_index;
1336 const air_tags = air.instructions.items(.tag);1418 const air_tags = air.instructions.items(.tag);
1337 const air_datas = air.instructions.items(.data);1419 const air_datas = air.instructions.items(.data);
1338 assert(air_tags[inst_index] == .const_ty);1420 assert(air_tags[inst_index] == .const_ty);
...@@ -1367,7 +1449,7 @@ pub fn deinit(air: *Air, gpa: std.mem.Allocator) void {...@@ -1367,7 +1449,7 @@ pub fn deinit(air: *Air, gpa: std.mem.Allocator) void {
1367 air.* = undefined;1449 air.* = undefined;
1368}1450}
13691451
1370const ref_start_index: u32 = Air.Inst.Ref.typed_value_map.len;1452pub const ref_start_index: u32 = InternPool.static_len;
13711453
1372pub fn indexToRef(inst: Air.Inst.Index) Air.Inst.Ref {1454pub fn indexToRef(inst: Air.Inst.Index) Air.Inst.Ref {
1373 return @intToEnum(Air.Inst.Ref, ref_start_index + inst);1455 return @intToEnum(Air.Inst.Ref, ref_start_index + inst);
...@@ -1383,17 +1465,18 @@ pub fn refToIndex(inst: Air.Inst.Ref) ?Air.Inst.Index {...@@ -1383,17 +1465,18 @@ pub fn refToIndex(inst: Air.Inst.Ref) ?Air.Inst.Index {
1383}1465}
13841466
1385/// Returns `null` if runtime-known.1467/// 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 {
1387 const ref_int = @enumToInt(inst);1469 const ref_int = @enumToInt(inst);
1388 if (ref_int < Air.Inst.Ref.typed_value_map.len) {1470 if (ref_int < ref_start_index) {
1389 return Air.Inst.Ref.typed_value_map[ref_int].val;1471 const ip_index = @intToEnum(InternPool.Index, ref_int);
1472 return ip_index.toValue();
1390 }1473 }
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);
1392 const air_datas = air.instructions.items(.data);1475 const air_datas = air.instructions.items(.data);
1393 switch (air.instructions.items(.tag)[inst_index]) {1476 switch (air.instructions.items(.tag)[inst_index]) {
1394 .constant => return air.values[air_datas[inst_index].ty_pl.payload],1477 .constant => return air.values[air_datas[inst_index].ty_pl.payload],
1395 .const_ty => unreachable,1478 .const_ty => unreachable,
1396 else => return air.typeOfIndex(inst_index).onePossibleValue(),1479 else => return air.typeOfIndex(inst_index).onePossibleValue(mod),
1397 }1480 }
1398}1481}
13991482
src/AstGen.zig+1-5
...@@ -8530,7 +8530,7 @@ fn builtinCall(...@@ -8530,7 +8530,7 @@ fn builtinCall(
8530 return rvalue(gz, ri, result, node);8530 return rvalue(gz, ri, result, node);
8531 },8531 },
8532 .call => {8532 .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]);
8534 const callee = try expr(gz, scope, .{ .rl = .none }, params[1]);8534 const callee = try expr(gz, scope, .{ .rl = .none }, params[1]);
8535 const args = try expr(gz, scope, .{ .rl = .none }, params[2]);8535 const args = try expr(gz, scope, .{ .rl = .none }, params[2]);
8536 const result = try gz.addPlNode(.builtin_call, node, Zir.Inst.BuiltinCall{8536 const result = try gz.addPlNode(.builtin_call, node, Zir.Inst.BuiltinCall{
...@@ -10298,10 +10298,6 @@ fn rvalue(...@@ -10298,10 +10298,6 @@ fn rvalue(
10298 as_ty | @enumToInt(Zir.Inst.Ref.noreturn_type),10298 as_ty | @enumToInt(Zir.Inst.Ref.noreturn_type),
10299 as_ty | @enumToInt(Zir.Inst.Ref.null_type),10299 as_ty | @enumToInt(Zir.Inst.Ref.null_type),
10300 as_ty | @enumToInt(Zir.Inst.Ref.undefined_type),10300 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),
10305 as_ty | @enumToInt(Zir.Inst.Ref.single_const_pointer_to_comptime_int_type),10301 as_ty | @enumToInt(Zir.Inst.Ref.single_const_pointer_to_comptime_int_type),
10306 as_ty | @enumToInt(Zir.Inst.Ref.const_slice_u8_type),10302 as_ty | @enumToInt(Zir.Inst.Ref.const_slice_u8_type),
10307 as_ty | @enumToInt(Zir.Inst.Ref.enum_literal_type),10303 as_ty | @enumToInt(Zir.Inst.Ref.enum_literal_type),
src/Autodoc.zig-2
...@@ -95,8 +95,6 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -95,8 +95,6 @@ pub fn generateZirData(self: *Autodoc) !void {
95 }95 }
96 }96 }
9797
98 log.debug("Ref map size: {}", .{Ref.typed_value_map.len});
99
100 const root_src_dir = self.comp_module.main_pkg.root_src_directory;98 const root_src_dir = self.comp_module.main_pkg.root_src_directory;
101 const root_src_path = self.comp_module.main_pkg.root_src_path;99 const root_src_path = self.comp_module.main_pkg.root_src_path;
102 const joined_src_path = try root_src_dir.join(self.arena, &.{root_src_path});100 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 {...@@ -1317,7 +1317,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1317 .emit_h = emit_h,1317 .emit_h = emit_h,
1318 .error_name_list = .{},1318 .error_name_list = .{},
1319 };1319 };
1320 try module.error_name_list.append(gpa, "(no error)");1320 try module.init();
13211321
1322 break :blk module;1322 break :blk module;
1323 } else blk: {1323 } else blk: {
...@@ -2064,6 +2064,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void...@@ -2064,6 +2064,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
2064 if (!build_options.only_c and !build_options.only_core_functionality) {2064 if (!build_options.only_c and !build_options.only_core_functionality) {
2065 if (comp.emit_docs) |doc_location| {2065 if (comp.emit_docs) |doc_location| {
2066 if (comp.bin_file.options.module) |module| {2066 if (comp.bin_file.options.module) |module| {
2067 if (true) @panic("TODO: get autodoc working again in this branch");
2067 var autodoc = Autodoc.init(module, doc_location);2068 var autodoc = Autodoc.init(module, doc_location);
2068 defer autodoc.deinit();2069 defer autodoc.deinit();
2069 try autodoc.generateZirData();2070 try autodoc.generateZirData();
src/InternPool.zig+488-30
...@@ -1,11 +1,16 @@...@@ -1,11 +1,16 @@
1//! All interned objects have both a value and a type.
2
1map: std.AutoArrayHashMapUnmanaged(void, void) = .{},3map: std.AutoArrayHashMapUnmanaged(void, void) = .{},
2items: std.MultiArrayList(Item) = .{},4items: std.MultiArrayList(Item) = .{},
3extra: std.ArrayListUnmanaged(u32) = .{},5extra: std.ArrayListUnmanaged(u32) = .{},
46
5const InternPool = @This();
6const std = @import("std");7const std = @import("std");
7const Allocator = std.mem.Allocator;8const Allocator = std.mem.Allocator;
8const assert = std.debug.assert;9const assert = std.debug.assert;
10const BigIntConst = std.math.big.int.Const;
11
12const InternPool = @This();
13const DeclIndex = enum(u32) { _ };
914
10const KeyAdapter = struct {15const KeyAdapter = struct {
11 intern_pool: *const InternPool,16 intern_pool: *const InternPool,
...@@ -17,24 +22,21 @@ const KeyAdapter = struct {...@@ -17,24 +22,21 @@ const KeyAdapter = struct {
1722
18 pub fn hash(ctx: @This(), a: Key) u32 {23 pub fn hash(ctx: @This(), a: Key) u32 {
19 _ = ctx;24 _ = ctx;
20 return a.hash();25 return a.hash32();
21 }26 }
22};27};
2328
24pub const Key = union(enum) {29pub const Key = union(enum) {
25 int_type: struct {30 int_type: IntType,
26 signedness: std.builtin.Signedness,
27 bits: u16,
28 },
29 ptr_type: struct {31 ptr_type: struct {
30 elem_type: Index,32 elem_type: Index,
31 sentinel: Index,33 sentinel: Index = .none,
32 alignment: u16,34 alignment: u16 = 0,
33 size: std.builtin.Type.Pointer.Size,35 size: std.builtin.Type.Pointer.Size,
34 is_const: bool,36 is_const: bool = false,
35 is_volatile: bool,37 is_volatile: bool = false,
36 is_allowzero: bool,38 is_allowzero: bool = false,
37 address_space: std.builtin.AddressSpace,39 address_space: std.builtin.AddressSpace = .generic,
38 },40 },
39 array_type: struct {41 array_type: struct {
40 len: u64,42 len: u64,
...@@ -52,20 +54,52 @@ pub const Key = union(enum) {...@@ -52,20 +54,52 @@ pub const Key = union(enum) {
52 error_set_type: Index,54 error_set_type: Index,
53 payload_type: Index,55 payload_type: Index,
54 },56 },
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 {
58 var hasher = std.hash.Wyhash.init(0);88 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 {
59 switch (key) {94 switch (key) {
60 .int_type => |int_type| {95 .int_type => |int_type| {
61 std.hash.autoHash(&hasher, int_type);96 std.hash.autoHash(hasher, int_type);
62 },97 },
63 .array_type => |array_type| {98 .array_type => |array_type| {
64 std.hash.autoHash(&hasher, array_type);99 std.hash.autoHash(hasher, array_type);
65 },100 },
66 else => @panic("TODO"),101 else => @panic("TODO"),
67 }102 }
68 return @truncate(u32, hasher.final());
69 }103 }
70104
71 pub fn eql(a: Key, b: Key) bool {105 pub fn eql(a: Key, b: Key) bool {
...@@ -85,6 +119,34 @@ pub const Key = union(enum) {...@@ -85,6 +119,34 @@ pub const Key = union(enum) {
85 else => @panic("TODO"),119 else => @panic("TODO"),
86 }120 }
87 }121 }
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 }
88};150};
89151
90pub const Item = struct {152pub const Item = struct {
...@@ -98,11 +160,330 @@ pub const Item = struct {...@@ -98,11 +160,330 @@ pub const Item = struct {
98/// Two values which have the same type can be equality compared simply160/// Two values which have the same type can be equality compared simply
99/// by checking if their indexes are equal, provided they are both in161/// by checking if their indexes are equal, provided they are both in
100/// the same `InternPool`.162/// the same `InternPool`.
163/// When adding a tag to this enum, consider adding a corresponding entry to
164/// `primitives` in AstGen.zig.
101pub const Index = enum(u32) {165pub 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
102 none = std.math.maxInt(u32),258 none = std.math.maxInt(u32),
259
103 _,260 _,
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 },
104};482};
105483
484/// How many items in the InternPool are statically known.
485pub const static_len: u32 = static_keys.len;
486
106pub const Tag = enum(u8) {487pub const Tag = enum(u8) {
107 /// An integer type.488 /// An integer type.
108 /// data is number of bits489 /// data is number of bits
...@@ -113,9 +494,12 @@ pub const Tag = enum(u8) {...@@ -113,9 +494,12 @@ pub const Tag = enum(u8) {
113 /// An array type.494 /// An array type.
114 /// data is payload to Array.495 /// data is payload to Array.
115 type_array,496 type_array,
116 /// A type or value that can be represented with only an enum tag.497 /// A type that can be represented with only an enum tag.
117 /// data is Simple enum value498 /// data is SimpleType enum value.
118 simple,499 simple_type,
500 /// A value that can be represented with only an enum tag.
501 /// data is SimpleValue enum value.
502 simple_value,
119 /// An unsigned integer value that can be represented by u32.503 /// An unsigned integer value that can be represented by u32.
120 /// data is integer value504 /// data is integer value
121 int_u32,505 int_u32,
...@@ -137,9 +521,20 @@ pub const Tag = enum(u8) {...@@ -137,9 +521,20 @@ pub const Tag = enum(u8) {
137 /// A float value that can be represented by f128.521 /// A float value that can be represented by f128.
138 /// data is payload index to Float128.522 /// data is payload index to Float128.
139 float_f128,523 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,
140};532};
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) {
143 f16,538 f16,
144 f32,539 f32,
145 f64,540 f64,
...@@ -147,6 +542,7 @@ pub const Simple = enum(u32) {...@@ -147,6 +542,7 @@ pub const Simple = enum(u32) {
147 f128,542 f128,
148 usize,543 usize,
149 isize,544 isize,
545 c_char,
150 c_short,546 c_short,
151 c_ushort,547 c_ushort,
152 c_int,548 c_int,
...@@ -165,14 +561,36 @@ pub const Simple = enum(u32) {...@@ -165,14 +561,36 @@ pub const Simple = enum(u32) {
165 comptime_float,561 comptime_float,
166 noreturn,562 noreturn,
167 @"anyframe",563 @"anyframe",
168 null_type,564 null,
169 undefined_type,
170 enum_literal_type,
171 undefined,565 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,
173 null,587 null,
174 bool_true,588 empty_struct,
175 bool_false,589 true,
590 false,
591 @"unreachable",
592
593 generic_poison,
176};594};
177595
178pub const Array = struct {596pub const Array = struct {
...@@ -180,10 +598,44 @@ pub const Array = struct {...@@ -180,10 +598,44 @@ pub const Array = struct {
180 child: Index,598 child: Index,
181};599};
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
183pub fn deinit(ip: *InternPool, gpa: Allocator) void {634pub fn deinit(ip: *InternPool, gpa: Allocator) void {
184 ip.map.deinit(gpa);635 ip.map.deinit(gpa);
185 ip.items.deinit(gpa);636 ip.items.deinit(gpa);
186 ip.extra.deinit(gpa);637 ip.extra.deinit(gpa);
638 ip.* = undefined;
187}639}
188640
189pub fn indexToKey(ip: InternPool, index: Index) Key {641pub fn indexToKey(ip: InternPool, index: Index) Key {
...@@ -210,7 +662,8 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {...@@ -210,7 +662,8 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
210 .sentinel = .none,662 .sentinel = .none,
211 } };663 } };
212 },664 },
213 .simple => .{ .simple = @intToEnum(Simple, data) },665 .simple_type => .{ .simple_type = @intToEnum(SimpleType, data) },
666 .simple_value => .{ .simple_value = @intToEnum(SimpleValue, data) },
214667
215 else => @panic("TODO"),668 else => @panic("TODO"),
216 };669 };
...@@ -224,12 +677,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -224,12 +677,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
224 }677 }
225 switch (key) {678 switch (key) {
226 .int_type => |int_type| {679 .int_type => |int_type| {
227 const tag: Tag = switch (int_type.signedness) {680 const t: Tag = switch (int_type.signedness) {
228 .signed => .type_int_signed,681 .signed => .type_int_signed,
229 .unsigned => .type_int_unsigned,682 .unsigned => .type_int_unsigned,
230 };683 };
231 try ip.items.append(gpa, .{684 try ip.items.append(gpa, .{
232 .tag = tag,685 .tag = t,
233 .data = int_type.bits,686 .data = int_type.bits,
234 });687 });
235 },688 },
...@@ -249,6 +702,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -249,6 +702,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
249 return @intToEnum(Index, ip.items.len - 1);702 return @intToEnum(Index, ip.items.len - 1);
250}703}
251704
705pub fn tag(ip: InternPool, index: Index) Tag {
706 const tags = ip.items.items(.tag);
707 return tags[@enumToInt(index)];
708}
709
252fn addExtra(ip: *InternPool, gpa: Allocator, extra: anytype) Allocator.Error!u32 {710fn addExtra(ip: *InternPool, gpa: Allocator, extra: anytype) Allocator.Error!u32 {
253 const fields = std.meta.fields(@TypeOf(extra));711 const fields = std.meta.fields(@TypeOf(extra));
254 try ip.extra.ensureUnusedCapacity(gpa, fields.len);712 try ip.extra.ensureUnusedCapacity(gpa, fields.len);
src/Liveness.zig+5-3
...@@ -5,15 +5,17 @@...@@ -5,15 +5,17 @@
5//! Some instructions are special, such as:5//! Some instructions are special, such as:
6//! * Conditional Branches6//! * Conditional Branches
7//! * Switch Branches7//! * Switch Branches
8const Liveness = @This();
9const std = @import("std");8const std = @import("std");
10const trace = @import("tracy.zig").trace;
11const log = std.log.scoped(.liveness);9const log = std.log.scoped(.liveness);
12const assert = std.debug.assert;10const assert = std.debug.assert;
13const Allocator = std.mem.Allocator;11const Allocator = std.mem.Allocator;
14const Air = @import("Air.zig");
15const Log2Int = std.math.Log2Int;12const 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
17pub const Verify = @import("Liveness/Verify.zig");19pub const Verify = @import("Liveness/Verify.zig");
1820
19/// This array is split into sets of 4 bits per AIR instruction.21/// 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");...@@ -32,6 +32,19 @@ const build_options = @import("build_options");
32const Liveness = @import("Liveness.zig");32const Liveness = @import("Liveness.zig");
33const isUpDir = @import("introspect.zig").isUpDir;33const isUpDir = @import("introspect.zig").isUpDir;
34const clang = @import("clang.zig");34const 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
36/// General-purpose allocator. Used for both temporary and long-term storage.49/// General-purpose allocator. Used for both temporary and long-term storage.
37gpa: Allocator,50gpa: Allocator,
...@@ -83,6 +96,9 @@ embed_table: std.StringHashMapUnmanaged(*EmbedFile) = .{},...@@ -83,6 +96,9 @@ embed_table: std.StringHashMapUnmanaged(*EmbedFile) = .{},
83string_literal_table: std.HashMapUnmanaged(StringLiteralContext.Key, Decl.OptionalIndex, StringLiteralContext, std.hash_map.default_max_load_percentage) = .{},96string_literal_table: std.HashMapUnmanaged(StringLiteralContext.Key, Decl.OptionalIndex, StringLiteralContext, std.hash_map.default_max_load_percentage) = .{},
84string_literal_bytes: ArrayListUnmanaged(u8) = .{},97string_literal_bytes: ArrayListUnmanaged(u8) = .{},
8598
99/// Stores all Type and Value objects; periodically garbage collected.
100intern_pool: InternPool = .{},
101
86/// The set of all the generic function instantiations. This is used so that when a generic102/// The set of all the generic function instantiations. This is used so that when a generic
87/// function is called twice with the same comptime parameter arguments, both calls dispatch103/// function is called twice with the same comptime parameter arguments, both calls dispatch
88/// to the same function.104/// to the same function.
...@@ -807,9 +823,9 @@ pub const Decl = struct {...@@ -807,9 +823,9 @@ pub const Decl = struct {
807 return (try decl.typedValue()).val;823 return (try decl.typedValue()).val;
808 }824 }
809825
810 pub fn isFunction(decl: Decl) !bool {826 pub fn isFunction(decl: Decl, mod: *const Module) !bool {
811 const tv = try decl.typedValue();827 const tv = try decl.typedValue();
812 return tv.ty.zigTypeTag() == .Fn;828 return tv.ty.zigTypeTag(mod) == .Fn;
813 }829 }
814830
815 /// If the Decl has a value and it is a struct, return it,831 /// If the Decl has a value and it is a struct, return it,
...@@ -921,14 +937,14 @@ pub const Decl = struct {...@@ -921,14 +937,14 @@ pub const Decl = struct {
921 };937 };
922 }938 }
923939
924 pub fn getAlignment(decl: Decl, target: Target) u32 {940 pub fn getAlignment(decl: Decl, mod: *const Module) u32 {
925 assert(decl.has_tv);941 assert(decl.has_tv);
926 if (decl.@"align" != 0) {942 if (decl.@"align" != 0) {
927 // Explicit alignment.943 // Explicit alignment.
928 return decl.@"align";944 return decl.@"align";
929 } else {945 } else {
930 // Natural alignment.946 // Natural alignment.
931 return decl.ty.abiAlignment(target);947 return decl.ty.abiAlignment(mod);
932 }948 }
933 }949 }
934};950};
...@@ -1030,7 +1046,7 @@ pub const Struct = struct {...@@ -1030,7 +1046,7 @@ pub const Struct = struct {
1030 /// Returns the field alignment. If the struct is packed, returns 0.1046 /// Returns the field alignment. If the struct is packed, returns 0.
1031 pub fn alignment(1047 pub fn alignment(
1032 field: Field,1048 field: Field,
1033 target: Target,1049 mod: *const Module,
1034 layout: std.builtin.Type.ContainerLayout,1050 layout: std.builtin.Type.ContainerLayout,
1035 ) u32 {1051 ) u32 {
1036 if (field.abi_align != 0) {1052 if (field.abi_align != 0) {
...@@ -1038,24 +1054,26 @@ pub const Struct = struct {...@@ -1038,24 +1054,26 @@ pub const Struct = struct {
1038 return field.abi_align;1054 return field.abi_align;
1039 }1055 }
10401056
1057 const target = mod.getTarget();
1058
1041 switch (layout) {1059 switch (layout) {
1042 .Packed => return 0,1060 .Packed => return 0,
1043 .Auto => {1061 .Auto => {
1044 if (target.ofmt == .c) {1062 if (target.ofmt == .c) {
1045 return alignmentExtern(field, target);1063 return alignmentExtern(field, mod);
1046 } else {1064 } else {
1047 return field.ty.abiAlignment(target);1065 return field.ty.abiAlignment(mod);
1048 }1066 }
1049 },1067 },
1050 .Extern => return alignmentExtern(field, target),1068 .Extern => return alignmentExtern(field, mod),
1051 }1069 }
1052 }1070 }
10531071
1054 pub fn alignmentExtern(field: Field, target: Target) u32 {1072 pub fn alignmentExtern(field: Field, mod: *const Module) u32 {
1055 // This logic is duplicated in Type.abiAlignmentAdvanced.1073 // 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) {
1059 // The C ABI requires 128 bit integer fields of structs1077 // The C ABI requires 128 bit integer fields of structs
1060 // to be 16-bytes aligned.1078 // to be 16-bytes aligned.
1061 return @max(ty_abi_align, 16);1079 return @max(ty_abi_align, 16);
...@@ -1132,7 +1150,7 @@ pub const Struct = struct {...@@ -1132,7 +1150,7 @@ pub const Struct = struct {
1132 };1150 };
1133 }1151 }
11341152
1135 pub fn packedFieldBitOffset(s: Struct, target: Target, index: usize) u16 {1153 pub fn packedFieldBitOffset(s: Struct, mod: *const Module, index: usize) u16 {
1136 assert(s.layout == .Packed);1154 assert(s.layout == .Packed);
1137 assert(s.haveLayout());1155 assert(s.haveLayout());
1138 var bit_sum: u64 = 0;1156 var bit_sum: u64 = 0;
...@@ -1140,12 +1158,13 @@ pub const Struct = struct {...@@ -1140,12 +1158,13 @@ pub const Struct = struct {
1140 if (i == index) {1158 if (i == index) {
1141 return @intCast(u16, bit_sum);1159 return @intCast(u16, bit_sum);
1142 }1160 }
1143 bit_sum += field.ty.bitSize(target);1161 bit_sum += field.ty.bitSize(mod);
1144 }1162 }
1145 unreachable; // index out of bounds1163 unreachable; // index out of bounds
1146 }1164 }
11471165
1148 pub const RuntimeFieldIterator = struct {1166 pub const RuntimeFieldIterator = struct {
1167 module: *const Module,
1149 struct_obj: *const Struct,1168 struct_obj: *const Struct,
1150 index: u32 = 0,1169 index: u32 = 0,
11511170
...@@ -1155,6 +1174,7 @@ pub const Struct = struct {...@@ -1155,6 +1174,7 @@ pub const Struct = struct {
1155 };1174 };
11561175
1157 pub fn next(it: *RuntimeFieldIterator) ?FieldAndIndex {1176 pub fn next(it: *RuntimeFieldIterator) ?FieldAndIndex {
1177 const mod = it.module;
1158 while (true) {1178 while (true) {
1159 var i = it.index;1179 var i = it.index;
1160 it.index += 1;1180 it.index += 1;
...@@ -1167,15 +1187,18 @@ pub const Struct = struct {...@@ -1167,15 +1187,18 @@ pub const Struct = struct {
1167 }1187 }
1168 const field = it.struct_obj.fields.values()[i];1188 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)) {
1171 return FieldAndIndex{ .index = i, .field = field };1191 return FieldAndIndex{ .index = i, .field = field };
1172 }1192 }
1173 }1193 }
1174 }1194 }
1175 };1195 };
11761196
1177 pub fn runtimeFieldIterator(s: *const Struct) RuntimeFieldIterator {1197 pub fn runtimeFieldIterator(s: *const Struct, module: *const Module) RuntimeFieldIterator {
1178 return .{ .struct_obj = s };1198 return .{
1199 .struct_obj = s,
1200 .module = module,
1201 };
1179 }1202 }
1180};1203};
11811204
...@@ -1323,9 +1346,9 @@ pub const Union = struct {...@@ -1323,9 +1346,9 @@ pub const Union = struct {
1323 /// Returns the field alignment, assuming the union is not packed.1346 /// Returns the field alignment, assuming the union is not packed.
1324 /// Keep implementation in sync with `Sema.unionFieldAlignment`.1347 /// Keep implementation in sync with `Sema.unionFieldAlignment`.
1325 /// Prefer to call that function instead of this one during Sema.1348 /// 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 {
1327 if (field.abi_align == 0) {1350 if (field.abi_align == 0) {
1328 return field.ty.abiAlignment(target);1351 return field.ty.abiAlignment(mod);
1329 } else {1352 } else {
1330 return field.abi_align;1353 return field.abi_align;
1331 }1354 }
...@@ -1383,22 +1406,22 @@ pub const Union = struct {...@@ -1383,22 +1406,22 @@ pub const Union = struct {
1383 };1406 };
1384 }1407 }
13851408
1386 pub fn hasAllZeroBitFieldTypes(u: Union) bool {1409 pub fn hasAllZeroBitFieldTypes(u: Union, mod: *const Module) bool {
1387 assert(u.haveFieldTypes());1410 assert(u.haveFieldTypes());
1388 for (u.fields.values()) |field| {1411 for (u.fields.values()) |field| {
1389 if (field.ty.hasRuntimeBits()) return false;1412 if (field.ty.hasRuntimeBits(mod)) return false;
1390 }1413 }
1391 return true;1414 return true;
1392 }1415 }
13931416
1394 pub fn mostAlignedField(u: Union, target: Target) u32 {1417 pub fn mostAlignedField(u: Union, mod: *const Module) u32 {
1395 assert(u.haveFieldTypes());1418 assert(u.haveFieldTypes());
1396 var most_alignment: u32 = 0;1419 var most_alignment: u32 = 0;
1397 var most_index: usize = undefined;1420 var most_index: usize = undefined;
1398 for (u.fields.values(), 0..) |field, i| {1421 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);
1402 if (field_align > most_alignment) {1425 if (field_align > most_alignment) {
1403 most_alignment = field_align;1426 most_alignment = field_align;
1404 most_index = i;1427 most_index = i;
...@@ -1408,20 +1431,20 @@ pub const Union = struct {...@@ -1408,20 +1431,20 @@ pub const Union = struct {
1408 }1431 }
14091432
1410 /// Returns 0 if the union is represented with 0 bits at runtime.1433 /// 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 {
1412 var max_align: u32 = 0;1435 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);
1414 for (u.fields.values()) |field| {1437 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);
1418 max_align = @max(max_align, field_align);1441 max_align = @max(max_align, field_align);
1419 }1442 }
1420 return max_align;1443 return max_align;
1421 }1444 }
14221445
1423 pub fn abiSize(u: Union, target: Target, have_tag: bool) u64 {1446 pub fn abiSize(u: Union, mod: *const Module, have_tag: bool) u64 {
1424 return u.getLayout(target, have_tag).abi_size;1447 return u.getLayout(mod, have_tag).abi_size;
1425 }1448 }
14261449
1427 pub const Layout = struct {1450 pub const Layout = struct {
...@@ -1451,7 +1474,7 @@ pub const Union = struct {...@@ -1451,7 +1474,7 @@ pub const Union = struct {
1451 };1474 };
1452 }1475 }
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 {
1455 assert(u.haveLayout());1478 assert(u.haveLayout());
1456 var most_aligned_field: u32 = undefined;1479 var most_aligned_field: u32 = undefined;
1457 var most_aligned_field_size: u64 = undefined;1480 var most_aligned_field_size: u64 = undefined;
...@@ -1460,16 +1483,16 @@ pub const Union = struct {...@@ -1460,16 +1483,16 @@ pub const Union = struct {
1460 var payload_align: u32 = 0;1483 var payload_align: u32 = 0;
1461 const fields = u.fields.values();1484 const fields = u.fields.values();
1462 for (fields, 0..) |field, i| {1485 for (fields, 0..) |field, i| {
1463 if (!field.ty.hasRuntimeBitsIgnoreComptime()) continue;1486 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
14641487
1465 const field_align = a: {1488 const field_align = a: {
1466 if (field.abi_align == 0) {1489 if (field.abi_align == 0) {
1467 break :a field.ty.abiAlignment(target);1490 break :a field.ty.abiAlignment(mod);
1468 } else {1491 } else {
1469 break :a field.abi_align;1492 break :a field.abi_align;
1470 }1493 }
1471 };1494 };
1472 const field_size = field.ty.abiSize(target);1495 const field_size = field.ty.abiSize(mod);
1473 if (field_size > payload_size) {1496 if (field_size > payload_size) {
1474 payload_size = field_size;1497 payload_size = field_size;
1475 biggest_field = @intCast(u32, i);1498 biggest_field = @intCast(u32, i);
...@@ -1481,7 +1504,7 @@ pub const Union = struct {...@@ -1481,7 +1504,7 @@ pub const Union = struct {
1481 }1504 }
1482 }1505 }
1483 payload_align = @max(payload_align, 1);1506 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)) {
1485 return .{1508 return .{
1486 .abi_size = std.mem.alignForwardGeneric(u64, payload_size, payload_align),1509 .abi_size = std.mem.alignForwardGeneric(u64, payload_size, payload_align),
1487 .abi_align = payload_align,1510 .abi_align = payload_align,
...@@ -1497,8 +1520,8 @@ pub const Union = struct {...@@ -1497,8 +1520,8 @@ pub const Union = struct {
1497 }1520 }
1498 // Put the tag before or after the payload depending on which one's1521 // Put the tag before or after the payload depending on which one's
1499 // alignment is greater.1522 // alignment is greater.
1500 const tag_size = u.tag_ty.abiSize(target);1523 const tag_size = u.tag_ty.abiSize(mod);
1501 const tag_align = @max(1, u.tag_ty.abiAlignment(target));1524 const tag_align = @max(1, u.tag_ty.abiAlignment(mod));
1502 var size: u64 = 0;1525 var size: u64 = 0;
1503 var padding: u32 = undefined;1526 var padding: u32 = undefined;
1504 if (tag_align >= payload_align) {1527 if (tag_align >= payload_align) {
...@@ -2281,7 +2304,7 @@ pub const ErrorMsg = struct {...@@ -2281,7 +2304,7 @@ pub const ErrorMsg = struct {
2281 ) !*ErrorMsg {2304 ) !*ErrorMsg {
2282 const err_msg = try gpa.create(ErrorMsg);2305 const err_msg = try gpa.create(ErrorMsg);
2283 errdefer gpa.destroy(err_msg);2306 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);
2285 return err_msg;2308 return err_msg;
2286 }2309 }
22872310
...@@ -3391,6 +3414,12 @@ pub const CompileError = error{...@@ -3391,6 +3414,12 @@ pub const CompileError = error{
3391 ComptimeBreak,3414 ComptimeBreak,
3392};3415};
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
3394pub fn deinit(mod: *Module) void {3423pub fn deinit(mod: *Module) void {
3395 const gpa = mod.gpa;3424 const gpa = mod.gpa;
33963425
...@@ -3518,6 +3547,8 @@ pub fn deinit(mod: *Module) void {...@@ -3518,6 +3547,8 @@ pub fn deinit(mod: *Module) void {
35183547
3519 mod.string_literal_table.deinit(gpa);3548 mod.string_literal_table.deinit(gpa);
3520 mod.string_literal_bytes.deinit(gpa);3549 mod.string_literal_bytes.deinit(gpa);
3550
3551 mod.intern_pool.deinit(gpa);
3521}3552}
35223553
3523pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {3554pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
...@@ -4277,7 +4308,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {...@@ -4277,7 +4308,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
4277 // Update all dependents which have at least this level of dependency.4308 // Update all dependents which have at least this level of dependency.
4278 // If our type remained the same and we're a function, only update4309 // If our type remained the same and we're a function, only update
4279 // decls which depend on our body; otherwise, update all dependents.4310 // 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
4282 for (decl.dependants.keys(), decl.dependants.values()) |dep_index, dep_type| {4313 for (decl.dependants.keys(), decl.dependants.values()) |dep_index, dep_type| {
4283 if (@enumToInt(dep_type) < @enumToInt(update_level)) continue;4314 if (@enumToInt(dep_type) < @enumToInt(update_level)) continue;
...@@ -4748,8 +4779,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4748,8 +4779,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4748 decl_tv.ty.fmt(mod),4779 decl_tv.ty.fmt(mod),
4749 });4780 });
4750 }4781 }
4751 var buffer: Value.ToTypeBuffer = undefined;4782 const ty = try decl_tv.val.toType().copy(decl_arena_allocator);
4752 const ty = try decl_tv.val.toType(&buffer).copy(decl_arena_allocator);
4753 if (ty.getNamespace() == null) {4783 if (ty.getNamespace() == null) {
4754 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)});4784 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)});
4755 }4785 }
...@@ -4775,7 +4805,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4775,7 +4805,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4775 var type_changed = true;4805 var type_changed = true;
47764806
4777 if (decl.has_tv) {4807 if (decl.has_tv) {
4778 prev_type_has_bits = decl.ty.isFnOrHasRuntimeBits();4808 prev_type_has_bits = decl.ty.isFnOrHasRuntimeBits(mod);
4779 type_changed = !decl.ty.eql(decl_tv.ty, mod);4809 type_changed = !decl.ty.eql(decl_tv.ty, mod);
4780 if (decl.getFunction()) |prev_func| {4810 if (decl.getFunction()) |prev_func| {
4781 prev_is_inline = prev_func.state == .inline_only;4811 prev_is_inline = prev_func.state == .inline_only;
...@@ -5510,7 +5540,7 @@ pub fn clearDecl(...@@ -5510,7 +5540,7 @@ pub fn clearDecl(
5510 try mod.deleteDeclExports(decl_index);5540 try mod.deleteDeclExports(decl_index);
55115541
5512 if (decl.has_tv) {5542 if (decl.has_tv) {
5513 if (decl.ty.isFnOrHasRuntimeBits()) {5543 if (decl.ty.isFnOrHasRuntimeBits(mod)) {
5514 mod.comp.bin_file.freeDecl(decl_index);5544 mod.comp.bin_file.freeDecl(decl_index);
5515 }5545 }
5516 if (decl.getInnerNamespace()) |namespace| {5546 if (decl.getInnerNamespace()) |namespace| {
...@@ -5699,7 +5729,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {...@@ -5699,7 +5729,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
56995729
5700 const arg_val = if (arg_tv.val.tag() != .generic_poison)5730 const arg_val = if (arg_tv.val.tag() != .generic_poison)
5701 arg_tv.val5731 arg_tv.val
5702 else if (arg_tv.ty.onePossibleValue()) |opv|5732 else if (arg_tv.ty.onePossibleValue(mod)) |opv|
5703 opv5733 opv
5704 else5734 else
5705 break :t arg_tv.ty;5735 break :t arg_tv.ty;
...@@ -5773,7 +5803,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {...@@ -5773,7 +5803,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
5773 // If we don't get an error return trace from a caller, create our own.5803 // If we don't get an error return trace from a caller, create our own.
5774 if (func.calls_or_awaits_errorable_fn and5804 if (func.calls_or_awaits_errorable_fn and
5775 mod.comp.bin_file.options.error_return_tracing and5805 mod.comp.bin_file.options.error_return_tracing and
5776 !sema.fn_ret_ty.isError())5806 !sema.fn_ret_ty.isError(mod))
5777 {5807 {
5778 sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {5808 sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {
5779 // TODO make these unreachable instead of @panic5809 // TODO make these unreachable instead of @panic
...@@ -5995,25 +6025,11 @@ pub fn initNewAnonDecl(...@@ -5995,25 +6025,11 @@ pub fn initNewAnonDecl(
5995 // if the Decl is referenced by an instruction or another constant. Otherwise,6025 // if the Decl is referenced by an instruction or another constant. Otherwise,
5996 // the Decl will be garbage collected by the `codegen_decl` task instead of sent6026 // the Decl will be garbage collected by the `codegen_decl` task instead of sent
5997 // to the linker.6027 // to the linker.
5998 if (typed_value.ty.isFnOrHasRuntimeBits()) {6028 if (typed_value.ty.isFnOrHasRuntimeBits(mod)) {
5999 try mod.comp.anon_work_queue.writeItem(.{ .codegen_decl = new_decl_index });6029 try mod.comp.anon_work_queue.writeItem(.{ .codegen_decl = new_decl_index });
6000 }6030 }
6001}6031}
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
6017pub fn errNoteNonLazy(6033pub fn errNoteNonLazy(
6018 mod: *Module,6034 mod: *Module,
6019 src_loc: SrcLoc,6035 src_loc: SrcLoc,
...@@ -6779,3 +6795,204 @@ pub fn backendSupportsFeature(mod: Module, feature: Feature) bool {...@@ -6779,3 +6795,204 @@ pub fn backendSupportsFeature(mod: Module, feature: Feature) bool {
6779 .field_reordering => mod.comp.bin_file.options.use_llvm,6795 .field_reordering => mod.comp.bin_file.options.use_llvm,
6780 };6796 };
6781}6797}
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 {...@@ -60,13 +60,14 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
60 if (self.ranges.items.len == 0)60 if (self.ranges.items.len == 0)
61 return false;61 return false;
6262
63 const mod = self.module;
63 std.mem.sort(Range, self.ranges.items, LessThanContext{64 std.mem.sort(Range, self.ranges.items, LessThanContext{
64 .ty = ty,65 .ty = ty,
65 .module = self.module,66 .module = mod,
66 }, lessThan);67 }, lessThan);
6768
68 if (!self.ranges.items[0].first.eql(first, ty, self.module) or69 if (!self.ranges.items[0].first.eql(first, ty, mod) or
69 !self.ranges.items[self.ranges.items.len - 1].last.eql(last, ty, self.module))70 !self.ranges.items[self.ranges.items.len - 1].last.eql(last, ty, mod))
70 {71 {
71 return false;72 return false;
72 }73 }
...@@ -76,18 +77,16 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {...@@ -76,18 +77,16 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
76 var counter = try std.math.big.int.Managed.init(self.ranges.allocator);77 var counter = try std.math.big.int.Managed.init(self.ranges.allocator);
77 defer counter.deinit();78 defer counter.deinit();
7879
79 const target = self.module.getTarget();
80
81 // look for gaps80 // look for gaps
82 for (self.ranges.items[1..], 0..) |cur, i| {81 for (self.ranges.items[1..], 0..) |cur, i| {
83 // i starts counting from the second item.82 // i starts counting from the second item.
84 const prev = self.ranges.items[i];83 const prev = self.ranges.items[i];
8584
86 // prev.last + 1 == cur.first85 // prev.last + 1 == cur.first
87 try counter.copy(prev.last.toBigInt(&space, target));86 try counter.copy(prev.last.toBigInt(&space, mod));
88 try counter.addScalar(&counter, 1);87 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);
91 if (!cur_start_int.eq(counter.toConst())) {90 if (!cur_start_int.eq(counter.toConst())) {
92 return false;91 return false;
93 }92 }
src/Sema.zig+1290-1093
...@@ -114,6 +114,7 @@ const Package = @import("Package.zig");...@@ -114,6 +114,7 @@ const Package = @import("Package.zig");
114const crash_report = @import("crash_report.zig");114const crash_report = @import("crash_report.zig");
115const build_options = @import("build_options");115const build_options = @import("build_options");
116const Compilation = @import("Compilation.zig");116const Compilation = @import("Compilation.zig");
117const InternPool = @import("InternPool.zig");
117118
118pub const default_branch_quota = 1000;119pub const default_branch_quota = 1000;
119pub const default_reference_trace_len = 2;120pub const default_reference_trace_len = 2;
...@@ -1614,6 +1615,7 @@ fn analyzeBodyInner(...@@ -1614,6 +1615,7 @@ fn analyzeBodyInner(
1614 },1615 },
1615 .@"try" => blk: {1616 .@"try" => blk: {
1616 if (!block.is_comptime) break :blk try sema.zirTry(block, inst);1617 if (!block.is_comptime) break :blk try sema.zirTry(block, inst);
1618 const mod = sema.mod;
1617 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;1619 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1618 const src = inst_data.src();1620 const src = inst_data.src();
1619 const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };1621 const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
...@@ -1621,18 +1623,18 @@ fn analyzeBodyInner(...@@ -1621,18 +1623,18 @@ fn analyzeBodyInner(
1621 const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len];1623 const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len];
1622 const err_union = try sema.resolveInst(extra.data.operand);1624 const err_union = try sema.resolveInst(extra.data.operand);
1623 const err_union_ty = sema.typeOf(err_union);1625 const err_union_ty = sema.typeOf(err_union);
1624 if (err_union_ty.zigTypeTag() != .ErrorUnion) {1626 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {
1625 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{1627 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
1626 err_union_ty.fmt(sema.mod),1628 err_union_ty.fmt(sema.mod),
1627 });1629 });
1628 }1630 }
1629 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);1631 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);
1630 assert(is_non_err != .none);1632 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| {
1632 if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);1634 if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);
1633 return err;1635 return err;
1634 };1636 };
1635 if (is_non_err_tv.val.toBool()) {1637 if (is_non_err_val.toBool()) {
1636 break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false);1638 break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false);
1637 }1639 }
1638 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse1640 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
...@@ -1654,11 +1656,11 @@ fn analyzeBodyInner(...@@ -1654,11 +1656,11 @@ fn analyzeBodyInner(
1654 const err_union = try sema.analyzeLoad(block, src, operand, operand_src);1656 const err_union = try sema.analyzeLoad(block, src, operand, operand_src);
1655 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);1657 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);
1656 assert(is_non_err != .none);1658 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| {
1658 if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);1660 if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);
1659 return err;1661 return err;
1660 };1662 };
1661 if (is_non_err_tv.val.toBool()) {1663 if (is_non_err_val.toBool()) {
1662 break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);1664 break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
1663 }1665 }
1664 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse1666 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
...@@ -1721,17 +1723,12 @@ fn analyzeBodyInner(...@@ -1721,17 +1723,12 @@ fn analyzeBodyInner(
1721}1723}
17221724
1723pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {1725pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {
1724 var i: usize = @enumToInt(zir_ref);1726 const i = @enumToInt(zir_ref);
1725
1726 // First section of indexes correspond to a set number of constant values.1727 // 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.
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);
1729 return zir_ref;1730 // The last section of indexes refers to the map of ZIR => AIR.
1730 }1731 const inst = sema.inst_map.get(i - InternPool.static_len).?;
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)).?;
1735 const ty = sema.typeOf(inst);1732 const ty = sema.typeOf(inst);
1736 if (ty.tag() == .generic_poison) return error.GenericPoison;1733 if (ty.tag() == .generic_poison) return error.GenericPoison;
1737 return inst;1734 return inst;
...@@ -1766,9 +1763,8 @@ pub fn resolveConstString(...@@ -1766,9 +1763,8 @@ pub fn resolveConstString(
1766}1763}
17671764
1768pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {1765pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {
1769 assert(zir_ref != .var_args_param);
1770 const air_inst = try sema.resolveInst(zir_ref);1766 const air_inst = try sema.resolveInst(zir_ref);
1771 assert(air_inst != .var_args_param);1767 assert(air_inst != .var_args_param_type);
1772 const ty = try sema.analyzeAsType(block, src, air_inst);1768 const ty = try sema.analyzeAsType(block, src, air_inst);
1773 if (ty.tag() == .generic_poison) return error.GenericPoison;1769 if (ty.tag() == .generic_poison) return error.GenericPoison;
1774 return ty;1770 return ty;
...@@ -1783,8 +1779,7 @@ fn analyzeAsType(...@@ -1783,8 +1779,7 @@ fn analyzeAsType(
1783 const wanted_type = Type.initTag(.type);1779 const wanted_type = Type.initTag(.type);
1784 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);1780 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
1785 const val = try sema.resolveConstValue(block, src, coerced_inst, "types must be comptime-known");1781 const val = try sema.resolveConstValue(block, src, coerced_inst, "types must be comptime-known");
1786 var buffer: Value.ToTypeBuffer = undefined;1782 const ty = val.toType();
1787 const ty = val.toType(&buffer);
1788 return ty.copy(sema.arena);1783 return ty.copy(sema.arena);
1789}1784}
17901785
...@@ -1950,12 +1945,12 @@ fn resolveMaybeUndefValAllowVariablesMaybeRuntime(...@@ -1950,12 +1945,12 @@ fn resolveMaybeUndefValAllowVariablesMaybeRuntime(
1950 make_runtime: *bool,1945 make_runtime: *bool,
1951) CompileError!?Value {1946) CompileError!?Value {
1952 // First section of indexes correspond to a set number of constant values.1947 // First section of indexes correspond to a set number of constant values.
1953 var i: usize = @enumToInt(inst);1948 const int = @enumToInt(inst);
1954 if (i < Air.Inst.Ref.typed_value_map.len) {1949 if (int < InternPool.static_len) {
1955 return Air.Inst.Ref.typed_value_map[i].val;1950 return @intToEnum(InternPool.Index, int).toValue();
1956 }1951 }
1957 i -= Air.Inst.Ref.typed_value_map.len;
19581952
1953 const i = int - InternPool.static_len;
1959 const air_tags = sema.air_instructions.items(.tag);1954 const air_tags = sema.air_instructions.items(.tag);
1960 if (try sema.typeHasOnePossibleValue(sema.typeOf(inst))) |opv| {1955 if (try sema.typeHasOnePossibleValue(sema.typeOf(inst))) |opv| {
1961 if (air_tags[i] == .constant) {1956 if (air_tags[i] == .constant) {
...@@ -2010,13 +2005,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, opt...@@ -2010,13 +2005,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, opt
2010}2005}
20112006
2012fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {2007fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
2008 const mod = sema.mod;
2013 const msg = msg: {2009 const msg = msg: {
2014 const msg = try sema.errMsg(block, src, "type '{}' does not support array initialization syntax", .{2010 const msg = try sema.errMsg(block, src, "type '{}' does not support array initialization syntax", .{
2015 ty.fmt(sema.mod),2011 ty.fmt(mod),
2016 });2012 });
2017 errdefer msg.destroy(sema.gpa);2013 errdefer msg.destroy(sema.gpa);
2018 if (ty.isSlice()) {2014 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)});
2020 }2016 }
2021 break :msg msg;2017 break :msg msg;
2022 };2018 };
...@@ -2042,7 +2038,8 @@ fn failWithErrorSetCodeMissing(...@@ -2042,7 +2038,8 @@ fn failWithErrorSetCodeMissing(
2042}2038}
20432039
2044fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: Type, val: Value, vector_index: usize) CompileError {2040fn 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) {
2046 const msg = msg: {2043 const msg = msg: {
2047 const msg = try sema.errMsg(block, src, "overflow of vector type '{}' with value '{}'", .{2044 const msg = try sema.errMsg(block, src, "overflow of vector type '{}' with value '{}'", .{
2048 int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod),2045 int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod),
...@@ -2084,12 +2081,13 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError...@@ -2084,12 +2081,13 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError
2084}2081}
20852082
2086fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError {2083fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError {
2084 const mod = sema.mod;
2087 const inner_ty = if (object_ty.isSinglePointer()) object_ty.childType() else object_ty;2085 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: {
2090 var buf: Type.Payload.ElemType = undefined;2088 var buf: Type.Payload.ElemType = undefined;
2091 const child_ty = inner_ty.optionalChild(&buf);2089 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;
2093 const msg = msg: {2091 const msg = msg: {
2094 const msg = try sema.errMsg(block, src, "optional type '{}' does not support field access", .{object_ty.fmt(sema.mod)});2092 const msg = try sema.errMsg(block, src, "optional type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
2095 errdefer msg.destroy(sema.gpa);2093 errdefer msg.destroy(sema.gpa);
...@@ -2097,9 +2095,9 @@ fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, objec...@@ -2097,9 +2095,9 @@ fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, objec
2097 break :msg msg;2095 break :msg msg;
2098 };2096 };
2099 return sema.failWithOwnedErrorMsg(msg);2097 return sema.failWithOwnedErrorMsg(msg);
2100 } else if (inner_ty.zigTypeTag() == .ErrorUnion) err: {2098 } else if (inner_ty.zigTypeTag(mod) == .ErrorUnion) err: {
2101 const child_ty = inner_ty.errorUnionPayload();2099 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;
2103 const msg = msg: {2101 const msg = msg: {
2104 const msg = try sema.errMsg(block, src, "error union type '{}' does not support field access", .{object_ty.fmt(sema.mod)});2102 const msg = try sema.errMsg(block, src, "error union type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
2105 errdefer msg.destroy(sema.gpa);2103 errdefer msg.destroy(sema.gpa);
...@@ -2111,14 +2109,14 @@ fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, objec...@@ -2111,14 +2109,14 @@ fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, objec
2111 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)});2109 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
2112}2110}
21132111
2114fn typeSupportsFieldAccess(ty: Type, field_name: []const u8) bool {2112fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: []const u8) bool {
2115 switch (ty.zigTypeTag()) {2113 switch (ty.zigTypeTag(mod)) {
2116 .Array => return mem.eql(u8, field_name, "len"),2114 .Array => return mem.eql(u8, field_name, "len"),
2117 .Pointer => {2115 .Pointer => {
2118 const ptr_info = ty.ptrInfo().data;2116 const ptr_info = ty.ptrInfo().data;
2119 if (ptr_info.size == .Slice) {2117 if (ptr_info.size == .Slice) {
2120 return mem.eql(u8, field_name, "ptr") or mem.eql(u8, field_name, "len");2118 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) {
2122 return mem.eql(u8, field_name, "len");2120 return mem.eql(u8, field_name, "len");
2123 } else return false;2121 } else return false;
2124 },2122 },
...@@ -2352,10 +2350,10 @@ fn analyzeAsInt(...@@ -2352,10 +2350,10 @@ fn analyzeAsInt(
2352 dest_ty: Type,2350 dest_ty: Type,
2353 reason: []const u8,2351 reason: []const u8,
2354) !u64 {2352) !u64 {
2353 const mod = sema.mod;
2355 const coerced = try sema.coerce(block, dest_ty, air_ref, src);2354 const coerced = try sema.coerce(block, dest_ty, air_ref, src);
2356 const val = try sema.resolveConstValue(block, src, coerced, reason);2355 const val = try sema.resolveConstValue(block, src, coerced, reason);
2357 const target = sema.mod.getTarget();2356 return (try val.getUnsignedIntAdvanced(mod, sema)).?;
2358 return (try val.getUnsignedIntAdvanced(target, sema)).?;
2359}2357}
23602358
2361// Returns a compile error if the value has tag `variable`. See `resolveInstValue` for2359// Returns a compile error if the value has tag `variable`. See `resolveInstValue` for
...@@ -2926,23 +2924,23 @@ fn zirEnumDecl(...@@ -2926,23 +2924,23 @@ fn zirEnumDecl(
29262924
2927 if (tag_type_ref != .none) {2925 if (tag_type_ref != .none) {
2928 const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref);2926 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) {
2930 return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)});2928 return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)});
2931 }2929 }
2932 enum_obj.tag_ty = try ty.copy(decl_arena_allocator);2930 enum_obj.tag_ty = try ty.copy(decl_arena_allocator);
2933 enum_obj.tag_ty_inferred = false;2931 enum_obj.tag_ty_inferred = false;
2934 } else if (fields_len == 0) {2932 } 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);
2936 enum_obj.tag_ty_inferred = true;2934 enum_obj.tag_ty_inferred = true;
2937 } else {2935 } else {
2938 const bits = std.math.log2_int_ceil(usize, fields_len);2936 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);
2940 enum_obj.tag_ty_inferred = true;2938 enum_obj.tag_ty_inferred = true;
2941 }2939 }
2942 }2940 }
29432941
2944 if (small.nonexhaustive and enum_obj.tag_ty.zigTypeTag() != .ComptimeInt) {2942 if (small.nonexhaustive and enum_obj.tag_ty.zigTypeTag(mod) != .ComptimeInt) {
2945 if (fields_len > 1 and std.math.log2_int(u64, fields_len) == enum_obj.tag_ty.bitSize(sema.mod.getTarget())) {2943 if (fields_len > 1 and std.math.log2_int(u64, fields_len) == enum_obj.tag_ty.bitSize(mod)) {
2946 return sema.fail(block, src, "non-exhaustive enum specifies every value", .{});2944 return sema.fail(block, src, "non-exhaustive enum specifies every value", .{});
2947 }2945 }
2948 }2946 }
...@@ -3319,7 +3317,8 @@ fn ensureResultUsed(...@@ -3319,7 +3317,8 @@ fn ensureResultUsed(
3319 ty: Type,3317 ty: Type,
3320 src: LazySrcLoc,3318 src: LazySrcLoc,
3321) CompileError!void {3319) CompileError!void {
3322 switch (ty.zigTypeTag()) {3320 const mod = sema.mod;
3321 switch (ty.zigTypeTag(mod)) {
3323 .Void, .NoReturn => return,3322 .Void, .NoReturn => return,
3324 .ErrorSet, .ErrorUnion => {3323 .ErrorSet, .ErrorUnion => {
3325 const msg = msg: {3324 const msg = msg: {
...@@ -3347,11 +3346,12 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3347,11 +3346,12 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3347 const tracy = trace(@src());3346 const tracy = trace(@src());
3348 defer tracy.end();3347 defer tracy.end();
33493348
3349 const mod = sema.mod;
3350 const inst_data = sema.code.instructions.items(.data)[inst].un_node;3350 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
3351 const operand = try sema.resolveInst(inst_data.operand);3351 const operand = try sema.resolveInst(inst_data.operand);
3352 const src = inst_data.src();3352 const src = inst_data.src();
3353 const operand_ty = sema.typeOf(operand);3353 const operand_ty = sema.typeOf(operand);
3354 switch (operand_ty.zigTypeTag()) {3354 switch (operand_ty.zigTypeTag(mod)) {
3355 .ErrorSet, .ErrorUnion => {3355 .ErrorSet, .ErrorUnion => {
3356 const msg = msg: {3356 const msg = msg: {
3357 const msg = try sema.errMsg(block, src, "error is discarded", .{});3357 const msg = try sema.errMsg(block, src, "error is discarded", .{});
...@@ -3369,16 +3369,17 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index...@@ -3369,16 +3369,17 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index
3369 const tracy = trace(@src());3369 const tracy = trace(@src());
3370 defer tracy.end();3370 defer tracy.end();
33713371
3372 const mod = sema.mod;
3372 const inst_data = sema.code.instructions.items(.data)[inst].un_node;3373 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
3373 const src = inst_data.src();3374 const src = inst_data.src();
3374 const operand = try sema.resolveInst(inst_data.operand);3375 const operand = try sema.resolveInst(inst_data.operand);
3375 const operand_ty = sema.typeOf(operand);3376 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)
3377 operand_ty.childType()3378 operand_ty.childType()
3378 else3379 else
3379 operand_ty;3380 operand_ty;
3380 if (err_union_ty.zigTypeTag() != .ErrorUnion) return;3381 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) return;
3381 const payload_ty = err_union_ty.errorUnionPayload().zigTypeTag();3382 const payload_ty = err_union_ty.errorUnionPayload().zigTypeTag(mod);
3382 if (payload_ty != .Void and payload_ty != .NoReturn) {3383 if (payload_ty != .Void and payload_ty != .NoReturn) {
3383 const msg = msg: {3384 const msg = msg: {
3384 const msg = try sema.errMsg(block, src, "error union payload is ignored", .{});3385 const msg = try sema.errMsg(block, src, "error union payload is ignored", .{});
...@@ -3920,19 +3921,20 @@ fn zirArrayBasePtr(...@@ -3920,19 +3921,20 @@ fn zirArrayBasePtr(
3920 block: *Block,3921 block: *Block,
3921 inst: Zir.Inst.Index,3922 inst: Zir.Inst.Index,
3922) CompileError!Air.Inst.Ref {3923) CompileError!Air.Inst.Ref {
3924 const mod = sema.mod;
3923 const inst_data = sema.code.instructions.items(.data)[inst].un_node;3925 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
3924 const src = inst_data.src();3926 const src = inst_data.src();
39253927
3926 const start_ptr = try sema.resolveInst(inst_data.operand);3928 const start_ptr = try sema.resolveInst(inst_data.operand);
3927 var base_ptr = start_ptr;3929 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)) {
3929 .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true),3931 .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true),
3930 .Optional => base_ptr = try sema.analyzeOptionalPayloadPtr(block, src, base_ptr, false, true),3932 .Optional => base_ptr = try sema.analyzeOptionalPayloadPtr(block, src, base_ptr, false, true),
3931 else => break,3933 else => break,
3932 };3934 };
39333935
3934 const elem_ty = sema.typeOf(base_ptr).childType();3936 const elem_ty = sema.typeOf(base_ptr).childType();
3935 switch (elem_ty.zigTypeTag()) {3937 switch (elem_ty.zigTypeTag(mod)) {
3936 .Array, .Vector => return base_ptr,3938 .Array, .Vector => return base_ptr,
3937 .Struct => if (elem_ty.isTuple()) {3939 .Struct => if (elem_ty.isTuple()) {
3938 // TODO validate element count3940 // TODO validate element count
...@@ -3948,19 +3950,20 @@ fn zirFieldBasePtr(...@@ -3948,19 +3950,20 @@ fn zirFieldBasePtr(
3948 block: *Block,3950 block: *Block,
3949 inst: Zir.Inst.Index,3951 inst: Zir.Inst.Index,
3950) CompileError!Air.Inst.Ref {3952) CompileError!Air.Inst.Ref {
3953 const mod = sema.mod;
3951 const inst_data = sema.code.instructions.items(.data)[inst].un_node;3954 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
3952 const src = inst_data.src();3955 const src = inst_data.src();
39533956
3954 const start_ptr = try sema.resolveInst(inst_data.operand);3957 const start_ptr = try sema.resolveInst(inst_data.operand);
3955 var base_ptr = start_ptr;3958 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)) {
3957 .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true),3960 .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true),
3958 .Optional => base_ptr = try sema.analyzeOptionalPayloadPtr(block, src, base_ptr, false, true),3961 .Optional => base_ptr = try sema.analyzeOptionalPayloadPtr(block, src, base_ptr, false, true),
3959 else => break,3962 else => break,
3960 };3963 };
39613964
3962 const elem_ty = sema.typeOf(base_ptr).childType();3965 const elem_ty = sema.typeOf(base_ptr).childType();
3963 switch (elem_ty.zigTypeTag()) {3966 switch (elem_ty.zigTypeTag(mod)) {
3964 .Struct, .Union => return base_ptr,3967 .Struct, .Union => return base_ptr,
3965 else => {},3968 else => {},
3966 }3969 }
...@@ -3968,6 +3971,7 @@ fn zirFieldBasePtr(...@@ -3968,6 +3971,7 @@ fn zirFieldBasePtr(
3968}3971}
39693972
3970fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {3973fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3974 const mod = sema.mod;
3971 const gpa = sema.gpa;3975 const gpa = sema.gpa;
3972 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;3976 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
3973 const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);3977 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....@@ -3991,7 +3995,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
3991 const object_ty = sema.typeOf(object);3995 const object_ty = sema.typeOf(object);
3992 // Each arg could be an indexable, or a range, in which case the length3996 // Each arg could be an indexable, or a range, in which case the length
3993 // is passed directly as an integer.3997 // is passed directly as an integer.
3994 const is_int = switch (object_ty.zigTypeTag()) {3998 const is_int = switch (object_ty.zigTypeTag(mod)) {
3995 .Int, .ComptimeInt => true,3999 .Int, .ComptimeInt => true,
3996 else => false,4000 else => false,
3997 };4001 };
...@@ -4000,7 +4004,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4000,7 +4004,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4000 .input_index = i,4004 .input_index = i,
4001 } };4005 } };
4002 const arg_len_uncoerced = if (is_int) object else l: {4006 const arg_len_uncoerced = if (is_int) object else l: {
4003 if (!object_ty.isIndexable()) {4007 if (!object_ty.isIndexable(mod)) {
4004 // Instead of using checkIndexable we customize this error.4008 // Instead of using checkIndexable we customize this error.
4005 const msg = msg: {4009 const msg = msg: {
4006 const msg = try sema.errMsg(block, arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(sema.mod)});4010 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....@@ -4010,7 +4014,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4010 };4014 };
4011 return sema.failWithOwnedErrorMsg(msg);4015 return sema.failWithOwnedErrorMsg(msg);
4012 }4016 }
4013 if (!object_ty.indexableHasLen()) continue;4017 if (!object_ty.indexableHasLen(mod)) continue;
40144018
4015 break :l try sema.fieldVal(block, arg_src, object, "len", arg_src);4019 break :l try sema.fieldVal(block, arg_src, object, "len", arg_src);
4016 };4020 };
...@@ -4061,7 +4065,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4061,7 +4065,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4061 const object_ty = sema.typeOf(object);4065 const object_ty = sema.typeOf(object);
4062 // Each arg could be an indexable, or a range, in which case the length4066 // Each arg could be an indexable, or a range, in which case the length
4063 // is passed directly as an integer.4067 // is passed directly as an integer.
4064 switch (object_ty.zigTypeTag()) {4068 switch (object_ty.zigTypeTag(mod)) {
4065 .Int, .ComptimeInt => continue,4069 .Int, .ComptimeInt => continue,
4066 else => {},4070 else => {},
4067 }4071 }
...@@ -4096,13 +4100,14 @@ fn validateArrayInitTy(...@@ -4096,13 +4100,14 @@ fn validateArrayInitTy(
4096 block: *Block,4100 block: *Block,
4097 inst: Zir.Inst.Index,4101 inst: Zir.Inst.Index,
4098) CompileError!void {4102) CompileError!void {
4103 const mod = sema.mod;
4099 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;4104 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
4100 const src = inst_data.src();4105 const src = inst_data.src();
4101 const ty_src: LazySrcLoc = .{ .node_offset_init_ty = inst_data.src_node };4106 const ty_src: LazySrcLoc = .{ .node_offset_init_ty = inst_data.src_node };
4102 const extra = sema.code.extraData(Zir.Inst.ArrayInit, inst_data.payload_index).data;4107 const extra = sema.code.extraData(Zir.Inst.ArrayInit, inst_data.payload_index).data;
4103 const ty = try sema.resolveType(block, ty_src, extra.ty);4108 const ty = try sema.resolveType(block, ty_src, extra.ty);
41044109
4105 switch (ty.zigTypeTag()) {4110 switch (ty.zigTypeTag(mod)) {
4106 .Array => {4111 .Array => {
4107 const array_len = ty.arrayLen();4112 const array_len = ty.arrayLen();
4108 if (extra.init_count != array_len) {4113 if (extra.init_count != array_len) {
...@@ -4141,11 +4146,12 @@ fn validateStructInitTy(...@@ -4141,11 +4146,12 @@ fn validateStructInitTy(
4141 block: *Block,4146 block: *Block,
4142 inst: Zir.Inst.Index,4147 inst: Zir.Inst.Index,
4143) CompileError!void {4148) CompileError!void {
4149 const mod = sema.mod;
4144 const inst_data = sema.code.instructions.items(.data)[inst].un_node;4150 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
4145 const src = inst_data.src();4151 const src = inst_data.src();
4146 const ty = try sema.resolveType(block, src, inst_data.operand);4152 const ty = try sema.resolveType(block, src, inst_data.operand);
41474153
4148 switch (ty.zigTypeTag()) {4154 switch (ty.zigTypeTag(mod)) {
4149 .Struct, .Union => return,4155 .Struct, .Union => return,
4150 else => {},4156 else => {},
4151 }4157 }
...@@ -4160,6 +4166,7 @@ fn zirValidateStructInit(...@@ -4160,6 +4166,7 @@ fn zirValidateStructInit(
4160 const tracy = trace(@src());4166 const tracy = trace(@src());
4161 defer tracy.end();4167 defer tracy.end();
41624168
4169 const mod = sema.mod;
4163 const validate_inst = sema.code.instructions.items(.data)[inst].pl_node;4170 const validate_inst = sema.code.instructions.items(.data)[inst].pl_node;
4164 const init_src = validate_inst.src();4171 const init_src = validate_inst.src();
4165 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);4172 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);
...@@ -4168,7 +4175,7 @@ fn zirValidateStructInit(...@@ -4168,7 +4175,7 @@ fn zirValidateStructInit(
4168 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;4175 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
4169 const object_ptr = try sema.resolveInst(field_ptr_extra.lhs);4176 const object_ptr = try sema.resolveInst(field_ptr_extra.lhs);
4170 const agg_ty = sema.typeOf(object_ptr).childType();4177 const agg_ty = sema.typeOf(object_ptr).childType();
4171 switch (agg_ty.zigTypeTag()) {4178 switch (agg_ty.zigTypeTag(mod)) {
4172 .Struct => return sema.validateStructInit(4179 .Struct => return sema.validateStructInit(
4173 block,4180 block,
4174 agg_ty,4181 agg_ty,
...@@ -4589,6 +4596,7 @@ fn zirValidateArrayInit(...@@ -4589,6 +4596,7 @@ fn zirValidateArrayInit(
4589 block: *Block,4596 block: *Block,
4590 inst: Zir.Inst.Index,4597 inst: Zir.Inst.Index,
4591) CompileError!void {4598) CompileError!void {
4599 const mod = sema.mod;
4592 const validate_inst = sema.code.instructions.items(.data)[inst].pl_node;4600 const validate_inst = sema.code.instructions.items(.data)[inst].pl_node;
4593 const init_src = validate_inst.src();4601 const init_src = validate_inst.src();
4594 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);4602 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);
...@@ -4599,7 +4607,7 @@ fn zirValidateArrayInit(...@@ -4599,7 +4607,7 @@ fn zirValidateArrayInit(
4599 const array_ty = sema.typeOf(array_ptr).childType();4607 const array_ty = sema.typeOf(array_ptr).childType();
4600 const array_len = array_ty.arrayLen();4608 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)) {
4603 .Struct => {4611 .Struct => {
4604 var root_msg: ?*Module.ErrorMsg = null;4612 var root_msg: ?*Module.ErrorMsg = null;
4605 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);4613 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
...@@ -4667,7 +4675,7 @@ fn zirValidateArrayInit(...@@ -4667,7 +4675,7 @@ fn zirValidateArrayInit(
4667 // Determine whether the value stored to this pointer is comptime-known.4675 // Determine whether the value stored to this pointer is comptime-known.
46684676
4669 if (array_ty.isTuple()) {4677 if (array_ty.isTuple()) {
4670 if (array_ty.structFieldValueComptime(i)) |opv| {4678 if (array_ty.structFieldValueComptime(mod, i)) |opv| {
4671 element_vals[i] = opv;4679 element_vals[i] = opv;
4672 continue;4680 continue;
4673 }4681 }
...@@ -4770,12 +4778,13 @@ fn zirValidateArrayInit(...@@ -4770,12 +4778,13 @@ fn zirValidateArrayInit(
4770}4778}
47714779
4772fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {4780fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
4781 const mod = sema.mod;
4773 const inst_data = sema.code.instructions.items(.data)[inst].un_node;4782 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
4774 const src = inst_data.src();4783 const src = inst_data.src();
4775 const operand = try sema.resolveInst(inst_data.operand);4784 const operand = try sema.resolveInst(inst_data.operand);
4776 const operand_ty = sema.typeOf(operand);4785 const operand_ty = sema.typeOf(operand);
47774786
4778 if (operand_ty.zigTypeTag() != .Pointer) {4787 if (operand_ty.zigTypeTag(mod) != .Pointer) {
4779 return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(sema.mod)});4788 return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(sema.mod)});
4780 } else switch (operand_ty.ptrSize()) {4789 } else switch (operand_ty.ptrSize()) {
4781 .One, .C => {},4790 .One, .C => {},
...@@ -4788,7 +4797,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -4788,7 +4797,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
4788 return;4797 return;
4789 }4798 }
47904799
4791 const elem_ty = operand_ty.elemType2();4800 const elem_ty = operand_ty.elemType2(mod);
4792 if (try sema.resolveMaybeUndefVal(operand)) |val| {4801 if (try sema.resolveMaybeUndefVal(operand)) |val| {
4793 if (val.isUndef()) {4802 if (val.isUndef()) {
4794 return sema.fail(block, src, "cannot dereference undefined value", .{});4803 return sema.fail(block, src, "cannot dereference undefined value", .{});
...@@ -4818,7 +4827,8 @@ fn failWithBadMemberAccess(...@@ -4818,7 +4827,8 @@ fn failWithBadMemberAccess(
4818 field_src: LazySrcLoc,4827 field_src: LazySrcLoc,
4819 field_name: []const u8,4828 field_name: []const u8,
4820) CompileError {4829) CompileError {
4821 const kw_name = switch (agg_ty.zigTypeTag()) {4830 const mod = sema.mod;
4831 const kw_name = switch (agg_ty.zigTypeTag(mod)) {
4822 .Union => "union",4832 .Union => "union",
4823 .Struct => "struct",4833 .Struct => "struct",
4824 .Opaque => "opaque",4834 .Opaque => "opaque",
...@@ -4894,8 +4904,9 @@ fn failWithBadUnionFieldAccess(...@@ -4894,8 +4904,9 @@ fn failWithBadUnionFieldAccess(
4894}4904}
48954905
4896fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void {4906fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void {
4897 const src_loc = decl_ty.declSrcLocOrNull(sema.mod) orelse return;4907 const mod = sema.mod;
4898 const category = switch (decl_ty.zigTypeTag()) {4908 const src_loc = decl_ty.declSrcLocOrNull(mod) orelse return;
4909 const category = switch (decl_ty.zigTypeTag(mod)) {
4899 .Union => "union",4910 .Union => "union",
4900 .Struct => "struct",4911 .Struct => "struct",
4901 .Enum => "enum",4912 .Enum => "enum",
...@@ -4903,7 +4914,7 @@ fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !vo...@@ -4903,7 +4914,7 @@ fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !vo
4903 .ErrorSet => "error set",4914 .ErrorSet => "error set",
4904 else => unreachable,4915 else => unreachable,
4905 };4916 };
4906 try sema.mod.errNoteNonLazy(src_loc, parent, "{s} declared here", .{category});4917 try mod.errNoteNonLazy(src_loc, parent, "{s} declared here", .{category});
4907}4918}
49084919
4909fn zirStoreToBlockPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {4920fn 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...@@ -5028,6 +5039,7 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
5028 const tracy = trace(@src());5039 const tracy = trace(@src());
5029 defer tracy.end();5040 defer tracy.end();
50305041
5042 const mod = sema.mod;
5031 const zir_tags = sema.code.instructions.items(.tag);5043 const zir_tags = sema.code.instructions.items(.tag);
5032 const zir_datas = sema.code.instructions.items(.data);5044 const zir_datas = sema.code.instructions.items(.data);
5033 const inst_data = zir_datas[inst].pl_node;5045 const inst_data = zir_datas[inst].pl_node;
...@@ -5046,9 +5058,9 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v...@@ -5046,9 +5058,9 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
5046 // %b = store(%a, %c)5058 // %b = store(%a, %c)
5047 // Where %c is an error union or error set. In such case we need to add5059 // Where %c is an error union or error set. In such case we need to add
5048 // to the current function's inferred error set, if any.5060 // to the current function's inferred error set, if any.
5049 if (is_ret and (sema.typeOf(operand).zigTypeTag() == .ErrorUnion or5061 if (is_ret and (sema.typeOf(operand).zigTypeTag(mod) == .ErrorUnion or
5050 sema.typeOf(operand).zigTypeTag() == .ErrorSet) and5062 sema.typeOf(operand).zigTypeTag(mod) == .ErrorSet) and
5051 sema.fn_ret_ty.zigTypeTag() == .ErrorUnion)5063 sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion)
5052 {5064 {
5053 try sema.addToInferredErrorSet(operand);5065 try sema.addToInferredErrorSet(operand);
5054 }5066 }
...@@ -6270,6 +6282,7 @@ fn zirCall(...@@ -6270,6 +6282,7 @@ fn zirCall(
6270 const tracy = trace(@src());6282 const tracy = trace(@src());
6271 defer tracy.end();6283 defer tracy.end();
62726284
6285 const mod = sema.mod;
6273 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;6286 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
6274 const callee_src: LazySrcLoc = .{ .node_offset_call_func = inst_data.src_node };6287 const callee_src: LazySrcLoc = .{ .node_offset_call_func = inst_data.src_node };
6275 const call_src = inst_data.src();6288 const call_src = inst_data.src();
...@@ -6342,7 +6355,7 @@ fn zirCall(...@@ -6342,7 +6355,7 @@ fn zirCall(
63426355
6343 sema.inst_map.putAssumeCapacity(inst, inst: {6356 sema.inst_map.putAssumeCapacity(inst, inst: {
6344 if (arg_index >= fn_params_len)6357 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
6347 if (func_ty_info.param_types[arg_index].tag() == .generic_poison)6360 if (func_ty_info.param_types[arg_index].tag() == .generic_poison)
6348 break :inst Air.Inst.Ref.generic_poison_type;6361 break :inst Air.Inst.Ref.generic_poison_type;
...@@ -6352,10 +6365,10 @@ fn zirCall(...@@ -6352,10 +6365,10 @@ fn zirCall(
63526365
6353 const resolved = try sema.resolveBody(block, args_body[arg_start..arg_end], inst);6366 const resolved = try sema.resolveBody(block, args_body[arg_start..arg_end], inst);
6354 const resolved_ty = sema.typeOf(resolved);6367 const resolved_ty = sema.typeOf(resolved);
6355 if (resolved_ty.zigTypeTag() == .NoReturn) {6368 if (resolved_ty.zigTypeTag(mod) == .NoReturn) {
6356 return resolved;6369 return resolved;
6357 }6370 }
6358 if (resolved_ty.isError()) {6371 if (resolved_ty.isError(mod)) {
6359 input_is_error = true;6372 input_is_error = true;
6360 }6373 }
6361 resolved_args[arg_index] = resolved;6374 resolved_args[arg_index] = resolved;
...@@ -6380,7 +6393,7 @@ fn zirCall(...@@ -6380,7 +6393,7 @@ fn zirCall(
63806393
6381 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only6394 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only
6382 // need to clean-up our own trace if we were passed to a non-error-handling expression.6395 // 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))) {
6384 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");6397 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
6385 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);6398 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
6386 const field_index = try sema.structFieldIndex(block, stack_trace_ty, "index", call_src);6399 const field_index = try sema.structFieldIndex(block, stack_trace_ty, "index", call_src);
...@@ -6417,20 +6430,21 @@ fn checkCallArgumentCount(...@@ -6417,20 +6430,21 @@ fn checkCallArgumentCount(
6417 total_args: usize,6430 total_args: usize,
6418 member_fn: bool,6431 member_fn: bool,
6419) !Type {6432) !Type {
6433 const mod = sema.mod;
6420 const func_ty = func_ty: {6434 const func_ty = func_ty: {
6421 switch (callee_ty.zigTypeTag()) {6435 switch (callee_ty.zigTypeTag(mod)) {
6422 .Fn => break :func_ty callee_ty,6436 .Fn => break :func_ty callee_ty,
6423 .Pointer => {6437 .Pointer => {
6424 const ptr_info = callee_ty.ptrInfo().data;6438 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) {
6426 break :func_ty ptr_info.pointee_type;6440 break :func_ty ptr_info.pointee_type;
6427 }6441 }
6428 },6442 },
6429 .Optional => {6443 .Optional => {
6430 var buf: Type.Payload.ElemType = undefined;6444 var buf: Type.Payload.ElemType = undefined;
6431 const opt_child = callee_ty.optionalChild(&buf);6445 const opt_child = callee_ty.optionalChild(&buf);
6432 if (opt_child.zigTypeTag() == .Fn or (opt_child.isSinglePointer() and6446 if (opt_child.zigTypeTag(mod) == .Fn or (opt_child.isSinglePointer() and
6433 opt_child.childType().zigTypeTag() == .Fn))6447 opt_child.childType().zigTypeTag(mod) == .Fn))
6434 {6448 {
6435 const msg = msg: {6449 const msg = msg: {
6436 const msg = try sema.errMsg(block, func_src, "cannot call optional type '{}'", .{6450 const msg = try sema.errMsg(block, func_src, "cannot call optional type '{}'", .{
...@@ -6488,13 +6502,14 @@ fn callBuiltin(...@@ -6488,13 +6502,14 @@ fn callBuiltin(
6488 modifier: std.builtin.CallModifier,6502 modifier: std.builtin.CallModifier,
6489 args: []const Air.Inst.Ref,6503 args: []const Air.Inst.Ref,
6490) !void {6504) !void {
6505 const mod = sema.mod;
6491 const callee_ty = sema.typeOf(builtin_fn);6506 const callee_ty = sema.typeOf(builtin_fn);
6492 const func_ty = func_ty: {6507 const func_ty = func_ty: {
6493 switch (callee_ty.zigTypeTag()) {6508 switch (callee_ty.zigTypeTag(mod)) {
6494 .Fn => break :func_ty callee_ty,6509 .Fn => break :func_ty callee_ty,
6495 .Pointer => {6510 .Pointer => {
6496 const ptr_info = callee_ty.ptrInfo().data;6511 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) {
6498 break :func_ty ptr_info.pointee_type;6513 break :func_ty ptr_info.pointee_type;
6499 }6514 }
6500 },6515 },
...@@ -6715,7 +6730,7 @@ fn analyzeCall(...@@ -6715,7 +6730,7 @@ fn analyzeCall(
6715 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),6730 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
6716 }),6731 }),
6717 else => {6732 else => {
6718 assert(callee_ty.isPtrAtRuntime());6733 assert(callee_ty.isPtrAtRuntime(mod));
6719 return sema.fail(block, call_src, "{s} call of function pointer", .{6734 return sema.fail(block, call_src, "{s} call of function pointer", .{
6720 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),6735 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
6721 });6736 });
...@@ -6978,7 +6993,7 @@ fn analyzeCall(...@@ -6978,7 +6993,7 @@ fn analyzeCall(
6978 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);6993 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);
6979 };6994 };
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) {
6982 try sema.emitDbgInline(6997 try sema.emitDbgInline(
6983 block,6998 block,
6984 module_fn,6999 module_fn,
...@@ -7068,7 +7083,7 @@ fn analyzeCall(...@@ -7068,7 +7083,7 @@ fn analyzeCall(
7068 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);7083 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
70697084
7070 try sema.queueFullTypeResolution(func_ty_info.return_type);7085 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)) {
7072 sema.owner_func.?.calls_or_awaits_errorable_fn = true;7087 sema.owner_func.?.calls_or_awaits_errorable_fn = true;
7073 }7088 }
70747089
...@@ -7301,8 +7316,9 @@ fn analyzeGenericCallArg(...@@ -7301,8 +7316,9 @@ fn analyzeGenericCallArg(
7301 new_fn_info: Type.Payload.Function.Data,7316 new_fn_info: Type.Payload.Function.Data,
7302 runtime_i: *u32,7317 runtime_i: *u32,
7303) !void {7318) !void {
7319 const mod = sema.mod;
7304 const is_runtime = comptime_arg.val.tag() == .generic_poison and7320 const is_runtime = comptime_arg.val.tag() == .generic_poison and
7305 comptime_arg.ty.hasRuntimeBits() and7321 comptime_arg.ty.hasRuntimeBits(mod) and
7306 !(try sema.typeRequiresComptime(comptime_arg.ty));7322 !(try sema.typeRequiresComptime(comptime_arg.ty));
7307 if (is_runtime) {7323 if (is_runtime) {
7308 const param_ty = new_fn_info.param_types[runtime_i.*];7324 const param_ty = new_fn_info.param_types[runtime_i.*];
...@@ -7591,7 +7607,7 @@ fn instantiateGenericCall(...@@ -7591,7 +7607,7 @@ fn instantiateGenericCall(
75917607
7592 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);7608 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)) {
7595 sema.owner_func.?.calls_or_awaits_errorable_fn = true;7611 sema.owner_func.?.calls_or_awaits_errorable_fn = true;
7596 }7612 }
75977613
...@@ -7872,8 +7888,9 @@ fn zirIntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -7872,8 +7888,9 @@ fn zirIntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
7872 const tracy = trace(@src());7888 const tracy = trace(@src());
7873 defer tracy.end();7889 defer tracy.end();
78747890
7891 const mod = sema.mod;
7875 const int_type = sema.code.instructions.items(.data)[inst].int_type;7892 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
7878 return sema.addType(ty);7895 return sema.addType(ty);
7879}7896}
...@@ -7882,12 +7899,13 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -7882,12 +7899,13 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
7882 const tracy = trace(@src());7899 const tracy = trace(@src());
7883 defer tracy.end();7900 defer tracy.end();
78847901
7902 const mod = sema.mod;
7885 const inst_data = sema.code.instructions.items(.data)[inst].un_node;7903 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
7886 const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };7904 const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };
7887 const child_type = try sema.resolveType(block, operand_src, inst_data.operand);7905 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) {
7889 return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(sema.mod)});7907 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) {
7891 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(sema.mod)});7909 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(sema.mod)});
7892 }7910 }
7893 const opt_type = try Type.optional(sema.arena, child_type);7911 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...@@ -7896,14 +7914,15 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
7896}7914}
78977915
7898fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {7916fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
7917 const mod = sema.mod;
7899 const bin = sema.code.instructions.items(.data)[inst].bin;7918 const bin = sema.code.instructions.items(.data)[inst].bin;
7900 const indexable_ty = try sema.resolveType(block, .unneeded, bin.lhs);7919 const indexable_ty = try sema.resolveType(block, .unneeded, bin.lhs);
7901 assert(indexable_ty.isIndexable()); // validated by a previous instruction7920 assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction
7902 if (indexable_ty.zigTypeTag() == .Struct) {7921 if (indexable_ty.zigTypeTag(mod) == .Struct) {
7903 const elem_type = indexable_ty.structFieldType(@enumToInt(bin.rhs));7922 const elem_type = indexable_ty.structFieldType(@enumToInt(bin.rhs));
7904 return sema.addType(elem_type);7923 return sema.addType(elem_type);
7905 } else {7924 } else {
7906 const elem_type = indexable_ty.elemType2();7925 const elem_type = indexable_ty.elemType2(mod);
7907 return sema.addType(elem_type);7926 return sema.addType(elem_type);
7908 }7927 }
7909}7928}
...@@ -7960,9 +7979,10 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -7960,9 +7979,10 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
7960}7979}
79617980
7962fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src: LazySrcLoc) !void {7981fn 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) {
7964 return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(sema.mod)});7984 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) {
7966 return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{});7986 return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{});
7967 }7987 }
7968}7988}
...@@ -7986,6 +8006,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -7986,6 +8006,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
7986 const tracy = trace(@src());8006 const tracy = trace(@src());
7987 defer tracy.end();8007 defer tracy.end();
79888008
8009 const mod = sema.mod;
7989 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;8010 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
7990 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;8011 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
7991 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };8012 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...@@ -7993,7 +8014,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
7993 const error_set = try sema.resolveType(block, lhs_src, extra.lhs);8014 const error_set = try sema.resolveType(block, lhs_src, extra.lhs);
7994 const payload = try sema.resolveType(block, rhs_src, extra.rhs);8015 const payload = try sema.resolveType(block, rhs_src, extra.rhs);
79958016
7996 if (error_set.zigTypeTag() != .ErrorSet) {8017 if (error_set.zigTypeTag(mod) != .ErrorSet) {
7997 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{8018 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{
7998 error_set.fmt(sema.mod),8019 error_set.fmt(sema.mod),
7999 });8020 });
...@@ -8004,11 +8025,12 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8004,11 +8025,12 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8004}8025}
80058026
8006fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, payload_src: LazySrcLoc) !void {8027fn 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) {
8008 return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{8030 return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{
8009 payload_ty.fmt(sema.mod),8031 payload_ty.fmt(sema.mod),
8010 });8032 });
8011 } else if (payload_ty.zigTypeTag() == .ErrorSet) {8033 } else if (payload_ty.zigTypeTag(mod) == .ErrorSet) {
8012 return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{8034 return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{
8013 payload_ty.fmt(sema.mod),8035 payload_ty.fmt(sema.mod),
8014 });8036 });
...@@ -8089,10 +8111,10 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -8089,10 +8111,10 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
8089 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };8111 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
8090 const uncasted_operand = try sema.resolveInst(extra.operand);8112 const uncasted_operand = try sema.resolveInst(extra.operand);
8091 const operand = try sema.coerce(block, Type.err_int, uncasted_operand, operand_src);8113 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
8094 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {8116 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));
8096 if (int > sema.mod.global_error_set.count() or int == 0)8118 if (int > sema.mod.global_error_set.count() or int == 0)
8097 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});8119 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
8098 const payload = try sema.arena.create(Value.Payload.Error);8120 const payload = try sema.arena.create(Value.Payload.Error);
...@@ -8123,6 +8145,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8123,6 +8145,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8123 const tracy = trace(@src());8145 const tracy = trace(@src());
8124 defer tracy.end();8146 defer tracy.end();
81258147
8148 const mod = sema.mod;
8126 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;8149 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
8127 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;8150 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
8128 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };8151 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...@@ -8130,7 +8153,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8130 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };8153 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
8131 const lhs = try sema.resolveInst(extra.lhs);8154 const lhs = try sema.resolveInst(extra.lhs);
8132 const rhs = try sema.resolveInst(extra.rhs);8155 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) {
8134 const msg = msg: {8157 const msg = msg: {
8135 const msg = try sema.errMsg(block, lhs_src, "expected error set type, found 'bool'", .{});8158 const msg = try sema.errMsg(block, lhs_src, "expected error set type, found 'bool'", .{});
8136 errdefer msg.destroy(sema.gpa);8159 errdefer msg.destroy(sema.gpa);
...@@ -8141,9 +8164,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8141,9 +8164,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8141 }8164 }
8142 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);8165 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);
8143 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);8166 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);
8144 if (lhs_ty.zigTypeTag() != .ErrorSet)8167 if (lhs_ty.zigTypeTag(mod) != .ErrorSet)
8145 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{lhs_ty.fmt(sema.mod)});8168 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)
8147 return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(sema.mod)});8170 return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(sema.mod)});
81488171
8149 // Anything merged with anyerror is anyerror.8172 // Anything merged with anyerror is anyerror.
...@@ -8184,6 +8207,7 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8184,6 +8207,7 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8184}8207}
81858208
8186fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8209fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8210 const mod = sema.mod;
8187 const arena = sema.arena;8211 const arena = sema.arena;
8188 const inst_data = sema.code.instructions.items(.data)[inst].un_node;8212 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
8189 const src = inst_data.src();8213 const src = inst_data.src();
...@@ -8191,7 +8215,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8191,7 +8215,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
8191 const operand = try sema.resolveInst(inst_data.operand);8215 const operand = try sema.resolveInst(inst_data.operand);
8192 const operand_ty = sema.typeOf(operand);8216 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)) {
8195 .Enum => operand,8219 .Enum => operand,
8196 .Union => blk: {8220 .Union => blk: {
8197 const union_ty = try sema.resolveTypeFields(operand_ty);8221 const union_ty = try sema.resolveTypeFields(operand_ty);
...@@ -8213,8 +8237,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8213,8 +8237,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
8213 };8237 };
8214 const enum_tag_ty = sema.typeOf(enum_tag);8238 const enum_tag_ty = sema.typeOf(enum_tag);
82158239
8216 var int_tag_type_buffer: Type.Payload.Bits = undefined;8240 const int_tag_ty = try enum_tag_ty.intTagType().copy(arena);
8217 const int_tag_ty = try enum_tag_ty.intTagType(&int_tag_type_buffer).copy(arena);
82188241
8219 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {8242 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {
8220 return sema.addConstant(int_tag_ty, opv);8243 return sema.addConstant(int_tag_ty, opv);
...@@ -8231,6 +8254,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8231,6 +8254,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
8231}8254}
82328255
8233fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8256fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8257 const mod = sema.mod;
8234 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;8258 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
8235 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;8259 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
8236 const src = inst_data.src();8260 const src = inst_data.src();
...@@ -8239,15 +8263,14 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8239,15 +8263,14 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
8239 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);8263 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
8240 const operand = try sema.resolveInst(extra.rhs);8264 const operand = try sema.resolveInst(extra.rhs);
82418265
8242 if (dest_ty.zigTypeTag() != .Enum) {8266 if (dest_ty.zigTypeTag(mod) != .Enum) {
8243 return sema.fail(block, dest_ty_src, "expected enum, found '{}'", .{dest_ty.fmt(sema.mod)});8267 return sema.fail(block, dest_ty_src, "expected enum, found '{}'", .{dest_ty.fmt(sema.mod)});
8244 }8268 }
8245 _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand));8269 _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand));
82468270
8247 if (try sema.resolveMaybeUndefVal(operand)) |int_val| {8271 if (try sema.resolveMaybeUndefVal(operand)) |int_val| {
8248 if (dest_ty.isNonexhaustiveEnum()) {8272 if (dest_ty.isNonexhaustiveEnum()) {
8249 var buffer: Type.Payload.Bits = undefined;8273 const int_tag_ty = dest_ty.intTagType();
8250 const int_tag_ty = dest_ty.intTagType(&buffer);
8251 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {8274 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {
8252 return sema.addConstant(dest_ty, int_val);8275 return sema.addConstant(dest_ty, int_val);
8253 }8276 }
...@@ -8329,11 +8352,12 @@ fn analyzeOptionalPayloadPtr(...@@ -8329,11 +8352,12 @@ fn analyzeOptionalPayloadPtr(
8329 safety_check: bool,8352 safety_check: bool,
8330 initializing: bool,8353 initializing: bool,
8331) CompileError!Air.Inst.Ref {8354) CompileError!Air.Inst.Ref {
8355 const mod = sema.mod;
8332 const optional_ptr_ty = sema.typeOf(optional_ptr);8356 const optional_ptr_ty = sema.typeOf(optional_ptr);
8333 assert(optional_ptr_ty.zigTypeTag() == .Pointer);8357 assert(optional_ptr_ty.zigTypeTag(mod) == .Pointer);
83348358
8335 const opt_type = optional_ptr_ty.elemType();8359 const opt_type = optional_ptr_ty.elemType();
8336 if (opt_type.zigTypeTag() != .Optional) {8360 if (opt_type.zigTypeTag(mod) != .Optional) {
8337 return sema.fail(block, src, "expected optional type, found '{}'", .{opt_type.fmt(sema.mod)});8361 return sema.fail(block, src, "expected optional type, found '{}'", .{opt_type.fmt(sema.mod)});
8338 }8362 }
83398363
...@@ -8361,7 +8385,7 @@ fn analyzeOptionalPayloadPtr(...@@ -8361,7 +8385,7 @@ fn analyzeOptionalPayloadPtr(
8361 );8385 );
8362 }8386 }
8363 if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| {8387 if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| {
8364 if (val.isNull()) {8388 if (val.isNull(mod)) {
8365 return sema.fail(block, src, "unable to unwrap null", .{});8389 return sema.fail(block, src, "unable to unwrap null", .{});
8366 }8390 }
8367 // The same Value represents the pointer to the optional and the payload.8391 // The same Value represents the pointer to the optional and the payload.
...@@ -8397,11 +8421,12 @@ fn zirOptionalPayload(...@@ -8397,11 +8421,12 @@ fn zirOptionalPayload(
8397 const tracy = trace(@src());8421 const tracy = trace(@src());
8398 defer tracy.end();8422 defer tracy.end();
83998423
8424 const mod = sema.mod;
8400 const inst_data = sema.code.instructions.items(.data)[inst].un_node;8425 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
8401 const src = inst_data.src();8426 const src = inst_data.src();
8402 const operand = try sema.resolveInst(inst_data.operand);8427 const operand = try sema.resolveInst(inst_data.operand);
8403 const operand_ty = sema.typeOf(operand);8428 const operand_ty = sema.typeOf(operand);
8404 const result_ty = switch (operand_ty.zigTypeTag()) {8429 const result_ty = switch (operand_ty.zigTypeTag(mod)) {
8405 .Optional => try operand_ty.optionalChildAlloc(sema.arena),8430 .Optional => try operand_ty.optionalChildAlloc(sema.arena),
8406 .Pointer => t: {8431 .Pointer => t: {
8407 if (operand_ty.ptrSize() != .C) {8432 if (operand_ty.ptrSize() != .C) {
...@@ -8424,7 +8449,7 @@ fn zirOptionalPayload(...@@ -8424,7 +8449,7 @@ fn zirOptionalPayload(
8424 };8449 };
84258450
8426 if (try sema.resolveDefinedValue(block, src, operand)) |val| {8451 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
8427 if (val.isNull()) {8452 if (val.isNull(mod)) {
8428 return sema.fail(block, src, "unable to unwrap null", .{});8453 return sema.fail(block, src, "unable to unwrap null", .{});
8429 }8454 }
8430 if (val.castTag(.opt_payload)) |payload| {8455 if (val.castTag(.opt_payload)) |payload| {
...@@ -8450,12 +8475,13 @@ fn zirErrUnionPayload(...@@ -8450,12 +8475,13 @@ fn zirErrUnionPayload(
8450 const tracy = trace(@src());8475 const tracy = trace(@src());
8451 defer tracy.end();8476 defer tracy.end();
84528477
8478 const mod = sema.mod;
8453 const inst_data = sema.code.instructions.items(.data)[inst].un_node;8479 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
8454 const src = inst_data.src();8480 const src = inst_data.src();
8455 const operand = try sema.resolveInst(inst_data.operand);8481 const operand = try sema.resolveInst(inst_data.operand);
8456 const operand_src = src;8482 const operand_src = src;
8457 const err_union_ty = sema.typeOf(operand);8483 const err_union_ty = sema.typeOf(operand);
8458 if (err_union_ty.zigTypeTag() != .ErrorUnion) {8484 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {
8459 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{8485 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
8460 err_union_ty.fmt(sema.mod),8486 err_union_ty.fmt(sema.mod),
8461 });8487 });
...@@ -8468,7 +8494,7 @@ fn analyzeErrUnionPayload(...@@ -8468,7 +8494,7 @@ fn analyzeErrUnionPayload(
8468 block: *Block,8494 block: *Block,
8469 src: LazySrcLoc,8495 src: LazySrcLoc,
8470 err_union_ty: Type,8496 err_union_ty: Type,
8471 operand: Zir.Inst.Ref,8497 operand: Air.Inst.Ref,
8472 operand_src: LazySrcLoc,8498 operand_src: LazySrcLoc,
8473 safety_check: bool,8499 safety_check: bool,
8474) CompileError!Air.Inst.Ref {8500) CompileError!Air.Inst.Ref {
...@@ -8517,10 +8543,11 @@ fn analyzeErrUnionPayloadPtr(...@@ -8517,10 +8543,11 @@ fn analyzeErrUnionPayloadPtr(
8517 safety_check: bool,8543 safety_check: bool,
8518 initializing: bool,8544 initializing: bool,
8519) CompileError!Air.Inst.Ref {8545) CompileError!Air.Inst.Ref {
8546 const mod = sema.mod;
8520 const operand_ty = sema.typeOf(operand);8547 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) {
8524 return sema.fail(block, src, "expected error union type, found '{}'", .{8551 return sema.fail(block, src, "expected error union type, found '{}'", .{
8525 operand_ty.elemType().fmt(sema.mod),8552 operand_ty.elemType().fmt(sema.mod),
8526 });8553 });
...@@ -8594,8 +8621,9 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -8594,8 +8621,9 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
8594}8621}
85958622
8596fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {8623fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {
8624 const mod = sema.mod;
8597 const operand_ty = sema.typeOf(operand);8625 const operand_ty = sema.typeOf(operand);
8598 if (operand_ty.zigTypeTag() != .ErrorUnion) {8626 if (operand_ty.zigTypeTag(mod) != .ErrorUnion) {
8599 return sema.fail(block, src, "expected error union type, found '{}'", .{8627 return sema.fail(block, src, "expected error union type, found '{}'", .{
8600 operand_ty.fmt(sema.mod),8628 operand_ty.fmt(sema.mod),
8601 });8629 });
...@@ -8617,13 +8645,14 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -8617,13 +8645,14 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
8617 const tracy = trace(@src());8645 const tracy = trace(@src());
8618 defer tracy.end();8646 defer tracy.end();
86198647
8648 const mod = sema.mod;
8620 const inst_data = sema.code.instructions.items(.data)[inst].un_node;8649 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
8621 const src = inst_data.src();8650 const src = inst_data.src();
8622 const operand = try sema.resolveInst(inst_data.operand);8651 const operand = try sema.resolveInst(inst_data.operand);
8623 const operand_ty = sema.typeOf(operand);8652 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) {
8627 return sema.fail(block, src, "expected error union type, found '{}'", .{8656 return sema.fail(block, src, "expected error union type, found '{}'", .{
8628 operand_ty.elemType().fmt(sema.mod),8657 operand_ty.elemType().fmt(sema.mod),
8629 });8658 });
...@@ -8677,8 +8706,7 @@ fn zirFunc(...@@ -8677,8 +8706,7 @@ fn zirFunc(
8677 extra_index += ret_ty_body.len;8706 extra_index += ret_ty_body.len;
86788707
8679 const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, Type.type, "return type must be comptime-known");8708 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;8709 break :blk try ret_ty_val.toType().copy(sema.arena);
8681 break :blk try ret_ty_val.toType(&buffer).copy(sema.arena);
8682 },8710 },
8683 };8711 };
86848712
...@@ -8849,6 +8877,7 @@ fn funcCommon(...@@ -8849,6 +8877,7 @@ fn funcCommon(
8849 noalias_bits: u32,8877 noalias_bits: u32,
8850 is_noinline: bool,8878 is_noinline: bool,
8851) CompileError!Air.Inst.Ref {8879) CompileError!Air.Inst.Ref {
8880 const mod = sema.mod;
8852 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };8881 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };
8853 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };8882 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };
8854 const func_src = LazySrcLoc.nodeOffset(src_node_offset);8883 const func_src = LazySrcLoc.nodeOffset(src_node_offset);
...@@ -8890,31 +8919,6 @@ fn funcCommon(...@@ -8890,31 +8919,6 @@ fn funcCommon(
88908919
8891 const target = sema.mod.getTarget();8920 const target = sema.mod.getTarget();
8892 const fn_ty: Type = fn_ty: {8921 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
8918 // In the case of generic calling convention, or generic alignment, we use8922 // In the case of generic calling convention, or generic alignment, we use
8919 // default values which are only meaningful for the generic function, *not*8923 // default values which are only meaningful for the generic function, *not*
8920 // the instantiation, which can depend on comptime parameters.8924 // the instantiation, which can depend on comptime parameters.
...@@ -8985,8 +8989,8 @@ fn funcCommon(...@@ -8985,8 +8989,8 @@ fn funcCommon(
8985 });8989 });
8986 };8990 };
89878991
8988 if (!return_type.isValidReturnType()) {8992 if (!return_type.isValidReturnType(mod)) {
8989 const opaque_str = if (return_type.zigTypeTag() == .Opaque) "opaque " else "";8993 const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else "";
8990 const msg = msg: {8994 const msg = msg: {
8991 const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{8995 const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{
8992 opaque_str, return_type.fmt(sema.mod),8996 opaque_str, return_type.fmt(sema.mod),
...@@ -9201,22 +9205,23 @@ fn analyzeParameter(...@@ -9201,22 +9205,23 @@ fn analyzeParameter(
9201 has_body: bool,9205 has_body: bool,
9202 is_noalias: bool,9206 is_noalias: bool,
9203) !void {9207) !void {
9208 const mod = sema.mod;
9204 const requires_comptime = try sema.typeRequiresComptime(param.ty);9209 const requires_comptime = try sema.typeRequiresComptime(param.ty);
9205 comptime_params[i] = param.is_comptime or requires_comptime;9210 comptime_params[i] = param.is_comptime or requires_comptime;
9206 const this_generic = param.ty.tag() == .generic_poison;9211 const this_generic = param.ty.tag() == .generic_poison;
9207 is_generic.* = is_generic.* or this_generic;9212 is_generic.* = is_generic.* or this_generic;
9208 const target = sema.mod.getTarget();9213 const target = mod.getTarget();
9209 if (param.is_comptime and !Type.fnCallingConventionAllowsZigTypes(target, cc)) {9214 if (param.is_comptime and !Type.fnCallingConventionAllowsZigTypes(target, cc)) {
9210 return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)});9215 return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)});
9211 }9216 }
9212 if (this_generic and !sema.no_partial_func_ty and !Type.fnCallingConventionAllowsZigTypes(target, cc)) {9217 if (this_generic and !sema.no_partial_func_ty and !Type.fnCallingConventionAllowsZigTypes(target, cc)) {
9213 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)});9218 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)});
9214 }9219 }
9215 if (!param.ty.isValidParamType()) {9220 if (!param.ty.isValidParamType(mod)) {
9216 const opaque_str = if (param.ty.zigTypeTag() == .Opaque) "opaque " else "";9221 const opaque_str = if (param.ty.zigTypeTag(mod) == .Opaque) "opaque " else "";
9217 const msg = msg: {9222 const msg = msg: {
9218 const msg = try sema.errMsg(block, param_src, "parameter of {s}type '{}' not allowed", .{9223 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),
9220 });9225 });
9221 errdefer msg.destroy(sema.gpa);9226 errdefer msg.destroy(sema.gpa);
92229227
...@@ -9228,11 +9233,11 @@ fn analyzeParameter(...@@ -9228,11 +9233,11 @@ fn analyzeParameter(
9228 if (!this_generic and !Type.fnCallingConventionAllowsZigTypes(target, cc) and !try sema.validateExternType(param.ty, .param_ty)) {9233 if (!this_generic and !Type.fnCallingConventionAllowsZigTypes(target, cc) and !try sema.validateExternType(param.ty, .param_ty)) {
9229 const msg = msg: {9234 const msg = msg: {
9230 const msg = try sema.errMsg(block, param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{9235 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),
9232 });9237 });
9233 errdefer msg.destroy(sema.gpa);9238 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);
9236 try sema.explainWhyTypeIsNotExtern(msg, param_src.toSrcLoc(src_decl), param.ty, .param_ty);9241 try sema.explainWhyTypeIsNotExtern(msg, param_src.toSrcLoc(src_decl), param.ty, .param_ty);
92379242
9238 try sema.addDeclaredHereNote(msg, param.ty);9243 try sema.addDeclaredHereNote(msg, param.ty);
...@@ -9243,11 +9248,11 @@ fn analyzeParameter(...@@ -9243,11 +9248,11 @@ fn analyzeParameter(
9243 if (!sema.is_generic_instantiation and requires_comptime and !param.is_comptime and has_body) {9248 if (!sema.is_generic_instantiation and requires_comptime and !param.is_comptime and has_body) {
9244 const msg = msg: {9249 const msg = msg: {
9245 const msg = try sema.errMsg(block, param_src, "parameter of type '{}' must be declared comptime", .{9250 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),
9247 });9252 });
9248 errdefer msg.destroy(sema.gpa);9253 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);
9251 try sema.explainWhyTypeIsComptime(msg, param_src.toSrcLoc(src_decl), param.ty);9256 try sema.explainWhyTypeIsComptime(msg, param_src.toSrcLoc(src_decl), param.ty);
92529257
9253 try sema.addDeclaredHereNote(msg, param.ty);9258 try sema.addDeclaredHereNote(msg, param.ty);
...@@ -9256,7 +9261,7 @@ fn analyzeParameter(...@@ -9256,7 +9261,7 @@ fn analyzeParameter(
9256 return sema.failWithOwnedErrorMsg(msg);9261 return sema.failWithOwnedErrorMsg(msg);
9257 }9262 }
9258 if (!sema.is_generic_instantiation and !this_generic and is_noalias and9263 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)))
9260 {9265 {
9261 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});9266 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});
9262 }9267 }
...@@ -9472,13 +9477,14 @@ fn analyzeAs(...@@ -9472,13 +9477,14 @@ fn analyzeAs(
9472 zir_operand: Zir.Inst.Ref,9477 zir_operand: Zir.Inst.Ref,
9473 no_cast_to_comptime_int: bool,9478 no_cast_to_comptime_int: bool,
9474) CompileError!Air.Inst.Ref {9479) CompileError!Air.Inst.Ref {
9480 const mod = sema.mod;
9475 const operand = try sema.resolveInst(zir_operand);9481 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;
9477 const dest_ty = sema.resolveType(block, src, zir_dest_type) catch |err| switch (err) {9483 const dest_ty = sema.resolveType(block, src, zir_dest_type) catch |err| switch (err) {
9478 error.GenericPoison => return operand,9484 error.GenericPoison => return operand,
9479 else => |e| return e,9485 else => |e| return e,
9480 };9486 };
9481 if (dest_ty.zigTypeTag() == .NoReturn) {9487 if (dest_ty.zigTypeTag(mod) == .NoReturn) {
9482 return sema.fail(block, src, "cannot cast to noreturn", .{});9488 return sema.fail(block, src, "cannot cast to noreturn", .{});
9483 }9489 }
9484 const is_ret = if (Zir.refToIndex(zir_dest_type)) |ptr_index|9490 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...@@ -9495,11 +9501,12 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9495 const tracy = trace(@src());9501 const tracy = trace(@src());
9496 defer tracy.end();9502 defer tracy.end();
94979503
9504 const mod = sema.mod;
9498 const inst_data = sema.code.instructions.items(.data)[inst].un_node;9505 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
9499 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };9506 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
9500 const ptr = try sema.resolveInst(inst_data.operand);9507 const ptr = try sema.resolveInst(inst_data.operand);
9501 const ptr_ty = sema.typeOf(ptr);9508 const ptr_ty = sema.typeOf(ptr);
9502 if (!ptr_ty.isPtrAtRuntime()) {9509 if (!ptr_ty.isPtrAtRuntime(mod)) {
9503 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)});9510 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)});
9504 }9511 }
9505 if (try sema.resolveMaybeUndefValIntable(ptr)) |ptr_val| {9512 if (try sema.resolveMaybeUndefValIntable(ptr)) |ptr_val| {
...@@ -9586,25 +9593,25 @@ fn intCast(...@@ -9586,25 +9593,25 @@ fn intCast(
9586 operand_src: LazySrcLoc,9593 operand_src: LazySrcLoc,
9587 runtime_safety: bool,9594 runtime_safety: bool,
9588) CompileError!Air.Inst.Ref {9595) CompileError!Air.Inst.Ref {
9596 const mod = sema.mod;
9589 const operand_ty = sema.typeOf(operand);9597 const operand_ty = sema.typeOf(operand);
9590 const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, dest_ty_src);9598 const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, dest_ty_src);
9591 const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src);9599 const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src);
95929600
9593 if (try sema.isComptimeKnown(operand)) {9601 if (try sema.isComptimeKnown(operand)) {
9594 return sema.coerce(block, dest_ty, operand, operand_src);9602 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) {
9596 return sema.fail(block, operand_src, "unable to cast runtime value to 'comptime_int'", .{});9604 return sema.fail(block, operand_src, "unable to cast runtime value to 'comptime_int'", .{});
9597 }9605 }
95989606
9599 try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, dest_ty_src, operand_src);9607 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
9602 if ((try sema.typeHasOnePossibleValue(dest_ty))) |opv| {9610 if ((try sema.typeHasOnePossibleValue(dest_ty))) |opv| {
9603 // requirement: intCast(u0, input) iff input == 09611 // requirement: intCast(u0, input) iff input == 0
9604 if (runtime_safety and block.wantSafety()) {9612 if (runtime_safety and block.wantSafety()) {
9605 try sema.requireRuntimeBlock(block, src, operand_src);9613 try sema.requireRuntimeBlock(block, src, operand_src);
9606 const target = sema.mod.getTarget();9614 const wanted_info = dest_scalar_ty.intInfo(mod);
9607 const wanted_info = dest_scalar_ty.intInfo(target);
9608 const wanted_bits = wanted_info.bits;9615 const wanted_bits = wanted_info.bits;
96099616
9610 if (wanted_bits == 0) {9617 if (wanted_bits == 0) {
...@@ -9631,9 +9638,8 @@ fn intCast(...@@ -9631,9 +9638,8 @@ fn intCast(
96319638
9632 try sema.requireRuntimeBlock(block, src, operand_src);9639 try sema.requireRuntimeBlock(block, src, operand_src);
9633 if (runtime_safety and block.wantSafety()) {9640 if (runtime_safety and block.wantSafety()) {
9634 const target = sema.mod.getTarget();9641 const actual_info = operand_scalar_ty.intInfo(mod);
9635 const actual_info = operand_scalar_ty.intInfo(target);9642 const wanted_info = dest_scalar_ty.intInfo(mod);
9636 const wanted_info = dest_scalar_ty.intInfo(target);
9637 const actual_bits = actual_info.bits;9643 const actual_bits = actual_info.bits;
9638 const wanted_bits = wanted_info.bits;9644 const wanted_bits = wanted_info.bits;
9639 const actual_value_bits = actual_bits - @boolToInt(actual_info.signedness == .signed);9645 const actual_value_bits = actual_bits - @boolToInt(actual_info.signedness == .signed);
...@@ -9642,7 +9648,7 @@ fn intCast(...@@ -9642,7 +9648,7 @@ fn intCast(
9642 // range shrinkage9648 // range shrinkage
9643 // requirement: int value fits into target type9649 // requirement: int value fits into target type
9644 if (wanted_value_bits < actual_value_bits) {9650 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);
9646 const dest_max_val = if (is_vector)9652 const dest_max_val = if (is_vector)
9647 try Value.Tag.repeated.create(sema.arena, dest_max_val_scalar)9653 try Value.Tag.repeated.create(sema.arena, dest_max_val_scalar)
9648 else9654 else
...@@ -9653,7 +9659,7 @@ fn intCast(...@@ -9653,7 +9659,7 @@ fn intCast(
9653 if (actual_info.signedness == .signed) {9659 if (actual_info.signedness == .signed) {
9654 // Reinterpret the sign-bit as part of the value. This will make9660 // Reinterpret the sign-bit as part of the value. This will make
9655 // negative differences (`operand` > `dest_max`) appear too big.9661 // 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);
9657 const diff_unsigned = try block.addBitCast(unsigned_operand_ty, diff);9663 const diff_unsigned = try block.addBitCast(unsigned_operand_ty, diff);
96589664
9659 // If the destination type is signed, then we need to double its9665 // 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...@@ -9727,6 +9733,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9727 const tracy = trace(@src());9733 const tracy = trace(@src());
9728 defer tracy.end();9734 defer tracy.end();
97299735
9736 const mod = sema.mod;
9730 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;9737 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
9731 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };9738 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
9732 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };9739 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...@@ -9735,7 +9742,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9735 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);9742 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
9736 const operand = try sema.resolveInst(extra.rhs);9743 const operand = try sema.resolveInst(extra.rhs);
9737 const operand_ty = sema.typeOf(operand);9744 const operand_ty = sema.typeOf(operand);
9738 switch (dest_ty.zigTypeTag()) {9745 switch (dest_ty.zigTypeTag(mod)) {
9739 .AnyFrame,9746 .AnyFrame,
9740 .ComptimeFloat,9747 .ComptimeFloat,
9741 .ComptimeInt,9748 .ComptimeInt,
...@@ -9757,7 +9764,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9757,7 +9764,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9757 const msg = msg: {9764 const msg = msg: {
9758 const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)});9765 const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)});
9759 errdefer msg.destroy(sema.gpa);9766 errdefer msg.destroy(sema.gpa);
9760 switch (operand_ty.zigTypeTag()) {9767 switch (operand_ty.zigTypeTag(mod)) {
9761 .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToEnum to cast from '{}'", .{operand_ty.fmt(sema.mod)}),9768 .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToEnum to cast from '{}'", .{operand_ty.fmt(sema.mod)}),
9762 else => {},9769 else => {},
9763 }9770 }
...@@ -9771,7 +9778,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9771,7 +9778,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9771 const msg = msg: {9778 const msg = msg: {
9772 const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)});9779 const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)});
9773 errdefer msg.destroy(sema.gpa);9780 errdefer msg.destroy(sema.gpa);
9774 switch (operand_ty.zigTypeTag()) {9781 switch (operand_ty.zigTypeTag(mod)) {
9775 .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToPtr to cast from '{}'", .{operand_ty.fmt(sema.mod)}),9782 .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToPtr to cast from '{}'", .{operand_ty.fmt(sema.mod)}),
9776 .Pointer => try sema.errNote(block, dest_ty_src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(sema.mod)}),9783 .Pointer => try sema.errNote(block, dest_ty_src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(sema.mod)}),
9777 else => {},9784 else => {},
...@@ -9782,7 +9789,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9782,7 +9789,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9782 return sema.failWithOwnedErrorMsg(msg);9789 return sema.failWithOwnedErrorMsg(msg);
9783 },9790 },
9784 .Struct, .Union => if (dest_ty.containerLayout() == .Auto) {9791 .Struct, .Union => if (dest_ty.containerLayout() == .Auto) {
9785 const container = switch (dest_ty.zigTypeTag()) {9792 const container = switch (dest_ty.zigTypeTag(mod)) {
9786 .Struct => "struct",9793 .Struct => "struct",
9787 .Union => "union",9794 .Union => "union",
9788 else => unreachable,9795 else => unreachable,
...@@ -9799,7 +9806,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9799,7 +9806,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9799 .Vector,9806 .Vector,
9800 => {},9807 => {},
9801 }9808 }
9802 switch (operand_ty.zigTypeTag()) {9809 switch (operand_ty.zigTypeTag(mod)) {
9803 .AnyFrame,9810 .AnyFrame,
9804 .ComptimeFloat,9811 .ComptimeFloat,
9805 .ComptimeInt,9812 .ComptimeInt,
...@@ -9821,7 +9828,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9821,7 +9828,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9821 const msg = msg: {9828 const msg = msg: {
9822 const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(sema.mod)});9829 const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(sema.mod)});
9823 errdefer msg.destroy(sema.gpa);9830 errdefer msg.destroy(sema.gpa);
9824 switch (dest_ty.zigTypeTag()) {9831 switch (dest_ty.zigTypeTag(mod)) {
9825 .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @enumToInt to cast to '{}'", .{dest_ty.fmt(sema.mod)}),9832 .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @enumToInt to cast to '{}'", .{dest_ty.fmt(sema.mod)}),
9826 else => {},9833 else => {},
9827 }9834 }
...@@ -9834,7 +9841,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9834,7 +9841,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9834 const msg = msg: {9841 const msg = msg: {
9835 const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(sema.mod)});9842 const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(sema.mod)});
9836 errdefer msg.destroy(sema.gpa);9843 errdefer msg.destroy(sema.gpa);
9837 switch (dest_ty.zigTypeTag()) {9844 switch (dest_ty.zigTypeTag(mod)) {
9838 .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @ptrToInt to cast to '{}'", .{dest_ty.fmt(sema.mod)}),9845 .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @ptrToInt to cast to '{}'", .{dest_ty.fmt(sema.mod)}),
9839 .Pointer => try sema.errNote(block, operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(sema.mod)}),9846 .Pointer => try sema.errNote(block, operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(sema.mod)}),
9840 else => {},9847 else => {},
...@@ -9845,7 +9852,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9845,7 +9852,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9845 return sema.failWithOwnedErrorMsg(msg);9852 return sema.failWithOwnedErrorMsg(msg);
9846 },9853 },
9847 .Struct, .Union => if (operand_ty.containerLayout() == .Auto) {9854 .Struct, .Union => if (operand_ty.containerLayout() == .Auto) {
9848 const container = switch (operand_ty.zigTypeTag()) {9855 const container = switch (operand_ty.zigTypeTag(mod)) {
9849 .Struct => "struct",9856 .Struct => "struct",
9850 .Union => "union",9857 .Union => "union",
9851 else => unreachable,9858 else => unreachable,
...@@ -9869,6 +9876,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -9869,6 +9876,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
9869 const tracy = trace(@src());9876 const tracy = trace(@src());
9870 defer tracy.end();9877 defer tracy.end();
98719878
9879 const mod = sema.mod;
9872 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;9880 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
9873 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };9881 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
9874 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };9882 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...@@ -9878,7 +9886,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
9878 const operand = try sema.resolveInst(extra.rhs);9886 const operand = try sema.resolveInst(extra.rhs);
98799887
9880 const target = sema.mod.getTarget();9888 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)) {
9882 .ComptimeFloat => true,9890 .ComptimeFloat => true,
9883 .Float => false,9891 .Float => false,
9884 else => return sema.fail(9892 else => return sema.fail(
...@@ -9890,7 +9898,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -9890,7 +9898,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
9890 };9898 };
98919899
9892 const operand_ty = sema.typeOf(operand);9900 const operand_ty = sema.typeOf(operand);
9893 switch (operand_ty.zigTypeTag()) {9901 switch (operand_ty.zigTypeTag(mod)) {
9894 .ComptimeFloat, .Float, .ComptimeInt => {},9902 .ComptimeFloat, .Float, .ComptimeInt => {},
9895 else => return sema.fail(9903 else => return sema.fail(
9896 block,9904 block,
...@@ -9944,20 +9952,21 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9944,20 +9952,21 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9944 const tracy = trace(@src());9952 const tracy = trace(@src());
9945 defer tracy.end();9953 defer tracy.end();
99469954
9955 const mod = sema.mod;
9947 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;9956 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
9948 const src = inst_data.src();9957 const src = inst_data.src();
9949 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;9958 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
9950 const array_ptr = try sema.resolveInst(extra.lhs);9959 const array_ptr = try sema.resolveInst(extra.lhs);
9951 const elem_index = try sema.resolveInst(extra.rhs);9960 const elem_index = try sema.resolveInst(extra.rhs);
9952 const indexable_ty = sema.typeOf(array_ptr);9961 const indexable_ty = sema.typeOf(array_ptr);
9953 if (indexable_ty.zigTypeTag() != .Pointer) {9962 if (indexable_ty.zigTypeTag(mod) != .Pointer) {
9954 const capture_src: LazySrcLoc = .{ .for_capture_from_input = inst_data.src_node };9963 const capture_src: LazySrcLoc = .{ .for_capture_from_input = inst_data.src_node };
9955 const msg = msg: {9964 const msg = msg: {
9956 const msg = try sema.errMsg(block, capture_src, "pointer capture of non pointer type '{}'", .{9965 const msg = try sema.errMsg(block, capture_src, "pointer capture of non pointer type '{}'", .{
9957 indexable_ty.fmt(sema.mod),9966 indexable_ty.fmt(sema.mod),
9958 });9967 });
9959 errdefer msg.destroy(sema.gpa);9968 errdefer msg.destroy(sema.gpa);
9960 if (indexable_ty.zigTypeTag() == .Array) {9969 if (indexable_ty.zigTypeTag(mod) == .Array) {
9961 try sema.errNote(block, src, msg, "consider using '&' here", .{});9970 try sema.errNote(block, src, msg, "consider using '&' here", .{});
9962 }9971 }
9963 break :msg msg;9972 break :msg msg;
...@@ -10076,6 +10085,7 @@ fn zirSwitchCapture(...@@ -10076,6 +10085,7 @@ fn zirSwitchCapture(
10076 const tracy = trace(@src());10085 const tracy = trace(@src());
10077 defer tracy.end();10086 defer tracy.end();
1007810087
10088 const mod = sema.mod;
10079 const zir_datas = sema.code.instructions.items(.data);10089 const zir_datas = sema.code.instructions.items(.data);
10080 const capture_info = zir_datas[inst].switch_capture;10090 const capture_info = zir_datas[inst].switch_capture;
10081 const switch_info = zir_datas[capture_info.switch_inst].pl_node;10091 const switch_info = zir_datas[capture_info.switch_inst].pl_node;
...@@ -10091,7 +10101,7 @@ fn zirSwitchCapture(...@@ -10091,7 +10101,7 @@ fn zirSwitchCapture(
1009110101
10092 if (block.inline_case_capture != .none) {10102 if (block.inline_case_capture != .none) {
10093 const item_val = sema.resolveConstValue(block, .unneeded, block.inline_case_capture, undefined) catch unreachable;10103 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) {
10095 const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(item_val, sema.mod).?);10105 const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(item_val, sema.mod).?);
10096 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;10106 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;
10097 const field_ty = union_obj.fields.values()[field_index].ty;10107 const field_ty = union_obj.fields.values()[field_index].ty;
...@@ -10144,7 +10154,7 @@ fn zirSwitchCapture(...@@ -10144,7 +10154,7 @@ fn zirSwitchCapture(
10144 return operand_ptr;10154 return operand_ptr;
10145 }10155 }
1014610156
10147 switch (operand_ty.zigTypeTag()) {10157 switch (operand_ty.zigTypeTag(mod)) {
10148 .ErrorSet => if (block.switch_else_err_ty) |some| {10158 .ErrorSet => if (block.switch_else_err_ty) |some| {
10149 return sema.bitCast(block, some, operand, operand_src, null);10159 return sema.bitCast(block, some, operand, operand_src, null);
10150 } else {10160 } else {
...@@ -10162,7 +10172,7 @@ fn zirSwitchCapture(...@@ -10162,7 +10172,7 @@ fn zirSwitchCapture(
10162 switch_extra.data.getScalarProng(sema.code, switch_extra.end, capture_info.prong_index).item,10172 switch_extra.data.getScalarProng(sema.code, switch_extra.end, capture_info.prong_index).item,
10163 };10173 };
1016410174
10165 switch (operand_ty.zigTypeTag()) {10175 switch (operand_ty.zigTypeTag(mod)) {
10166 .Union => {10176 .Union => {
10167 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;10177 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;
10168 const first_item = try sema.resolveInst(items[0]);10178 const first_item = try sema.resolveInst(items[0]);
...@@ -10269,6 +10279,7 @@ fn zirSwitchCapture(...@@ -10269,6 +10279,7 @@ fn zirSwitchCapture(
10269}10279}
1027010280
10271fn zirSwitchCaptureTag(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {10281fn zirSwitchCaptureTag(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
10282 const mod = sema.mod;
10272 const zir_datas = sema.code.instructions.items(.data);10283 const zir_datas = sema.code.instructions.items(.data);
10273 const inst_data = zir_datas[inst].un_tok;10284 const inst_data = zir_datas[inst].un_tok;
10274 const src = inst_data.src();10285 const src = inst_data.src();
...@@ -10280,7 +10291,7 @@ fn zirSwitchCaptureTag(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile...@@ -10280,7 +10291,7 @@ fn zirSwitchCaptureTag(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
10280 const operand_ptr_ty = sema.typeOf(operand_ptr);10291 const operand_ptr_ty = sema.typeOf(operand_ptr);
10281 const operand_ty = if (is_ref) operand_ptr_ty.childType() else operand_ptr_ty;10292 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) {
10284 const msg = msg: {10295 const msg = msg: {
10285 const msg = try sema.errMsg(block, src, "cannot capture tag of non-union type '{}'", .{10296 const msg = try sema.errMsg(block, src, "cannot capture tag of non-union type '{}'", .{
10286 operand_ty.fmt(sema.mod),10297 operand_ty.fmt(sema.mod),
...@@ -10301,6 +10312,7 @@ fn zirSwitchCond(...@@ -10301,6 +10312,7 @@ fn zirSwitchCond(
10301 inst: Zir.Inst.Index,10312 inst: Zir.Inst.Index,
10302 is_ref: bool,10313 is_ref: bool,
10303) CompileError!Air.Inst.Ref {10314) CompileError!Air.Inst.Ref {
10315 const mod = sema.mod;
10304 const inst_data = sema.code.instructions.items(.data)[inst].un_node;10316 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
10305 const src = inst_data.src();10317 const src = inst_data.src();
10306 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = inst_data.src_node };10318 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = inst_data.src_node };
...@@ -10311,7 +10323,7 @@ fn zirSwitchCond(...@@ -10311,7 +10323,7 @@ fn zirSwitchCond(
10311 operand_ptr;10323 operand_ptr;
10312 const operand_ty = sema.typeOf(operand);10324 const operand_ty = sema.typeOf(operand);
1031310325
10314 switch (operand_ty.zigTypeTag()) {10326 switch (operand_ty.zigTypeTag(mod)) {
10315 .Type,10327 .Type,
10316 .Void,10328 .Void,
10317 .Bool,10329 .Bool,
...@@ -10371,6 +10383,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10371,6 +10383,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10371 const tracy = trace(@src());10383 const tracy = trace(@src());
10372 defer tracy.end();10384 defer tracy.end();
1037310385
10386 const mod = sema.mod;
10374 const gpa = sema.gpa;10387 const gpa = sema.gpa;
10375 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;10388 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
10376 const src = inst_data.src();10389 const src = inst_data.src();
...@@ -10415,7 +10428,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10415,7 +10428,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10415 const target_ty = sema.typeOf(raw_operand);10428 const target_ty = sema.typeOf(raw_operand);
10416 break :blk if (zir_tags[cond_index] == .switch_cond_ref) target_ty.elemType() else target_ty;10429 break :blk if (zir_tags[cond_index] == .switch_cond_ref) target_ty.elemType() else target_ty;
10417 };10430 };
10418 const union_originally = maybe_union_ty.zigTypeTag() == .Union;10431 const union_originally = maybe_union_ty.zigTypeTag(mod) == .Union;
1041910432
10420 // Duplicate checking variables later also used for `inline else`.10433 // Duplicate checking variables later also used for `inline else`.
10421 var seen_enum_fields: []?Module.SwitchProngSrc = &.{};10434 var seen_enum_fields: []?Module.SwitchProngSrc = &.{};
...@@ -10433,7 +10446,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10433,7 +10446,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10433 var empty_enum = false;10446 var empty_enum = false;
1043410447
10435 const operand_ty = sema.typeOf(operand);10448 const operand_ty = sema.typeOf(operand);
10436 const err_set = operand_ty.zigTypeTag() == .ErrorSet;10449 const err_set = operand_ty.zigTypeTag(mod) == .ErrorSet;
1043710450
10438 var else_error_ty: ?Type = null;10451 var else_error_ty: ?Type = null;
1043910452
...@@ -10459,10 +10472,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10459,10 +10472,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10459 return sema.failWithOwnedErrorMsg(msg);10472 return sema.failWithOwnedErrorMsg(msg);
10460 }10473 }
1046110474
10462 const target = sema.mod.getTarget();
10463
10464 // Validate for duplicate items, missing else prong, and invalid range.10475 // Validate for duplicate items, missing else prong, and invalid range.
10465 switch (operand_ty.zigTypeTag()) {10476 switch (operand_ty.zigTypeTag(mod)) {
10466 .Union => unreachable, // handled in zirSwitchCond10477 .Union => unreachable, // handled in zirSwitchCond
10467 .Enum => {10478 .Enum => {
10468 seen_enum_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount());10479 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...@@ -10774,12 +10785,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10774 }10785 }
1077510786
10776 check_range: {10787 check_range: {
10777 if (operand_ty.zigTypeTag() == .Int) {10788 if (operand_ty.zigTypeTag(mod) == .Int) {
10778 var arena = std.heap.ArenaAllocator.init(gpa);10789 var arena = std.heap.ArenaAllocator.init(gpa);
10779 defer arena.deinit();10790 defer arena.deinit();
1078010791
10781 const min_int = try operand_ty.minInt(arena.allocator(), target);10792 const min_int = try operand_ty.minInt(arena.allocator(), mod);
10782 const max_int = try operand_ty.maxInt(arena.allocator(), target);10793 const max_int = try operand_ty.maxInt(arena.allocator(), mod);
10783 if (try range_set.spans(min_int, max_int, operand_ty)) {10794 if (try range_set.spans(min_int, max_int, operand_ty)) {
10784 if (special_prong == .@"else") {10795 if (special_prong == .@"else") {
10785 return sema.fail(10796 return sema.fail(
...@@ -11080,7 +11091,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11080,7 +11091,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11080 if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) {11091 if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) {
11081 return Air.Inst.Ref.unreachable_value;11092 return Air.Inst.Ref.unreachable_value;
11082 }11093 }
11083 if (sema.mod.backendSupportsFeature(.is_named_enum_value) and block.wantSafety() and operand_ty.zigTypeTag() == .Enum and11094 if (sema.mod.backendSupportsFeature(.is_named_enum_value) and block.wantSafety() and operand_ty.zigTypeTag(mod) == .Enum and
11084 (!operand_ty.isNonexhaustiveEnum() or union_originally))11095 (!operand_ty.isNonexhaustiveEnum() or union_originally))
11085 {11096 {
11086 try sema.zirDbgStmt(block, cond_dbg_node_index);11097 try sema.zirDbgStmt(block, cond_dbg_node_index);
...@@ -11135,7 +11146,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11135,7 +11146,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11135 const analyze_body = if (union_originally) blk: {11146 const analyze_body = if (union_originally) blk: {
11136 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;11147 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;
11137 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);11148 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;
11139 } else true;11150 } else true;
1114011151
11141 if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) {11152 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...@@ -11242,7 +11253,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11242 const analyze_body = if (union_originally) blk: {11253 const analyze_body = if (union_originally) blk: {
11243 const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable;11254 const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable;
11244 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);11255 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;
11246 } else true;11257 } else true;
1124711258
11248 if (emit_bb) sema.emitBackwardBranch(block, .unneeded) catch |err| switch (err) {11259 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...@@ -11286,7 +11297,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11286 const item = try sema.resolveInst(item_ref);11297 const item = try sema.resolveInst(item_ref);
11287 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;11298 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;
11288 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);11299 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;
11290 } else false11301 } else false
11291 else11302 else
11292 true;11303 true;
...@@ -11409,7 +11420,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11409,7 +11420,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11409 var final_else_body: []const Air.Inst.Index = &.{};11420 var final_else_body: []const Air.Inst.Index = &.{};
11410 if (special.body.len != 0 or !is_first or case_block.wantSafety()) {11421 if (special.body.len != 0 or !is_first or case_block.wantSafety()) {
11411 var emit_bb = false;11422 var emit_bb = false;
11412 if (special.is_inline) switch (operand_ty.zigTypeTag()) {11423 if (special.is_inline) switch (operand_ty.zigTypeTag(mod)) {
11413 .Enum => {11424 .Enum => {
11414 if (operand_ty.isNonexhaustiveEnum() and !union_originally) {11425 if (operand_ty.isNonexhaustiveEnum() and !union_originally) {
11415 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{11426 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...@@ -11429,7 +11440,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1142911440
11430 const analyze_body = if (union_originally) blk: {11441 const analyze_body = if (union_originally) blk: {
11431 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);11442 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;
11433 } else true;11444 } else true;
1143411445
11435 if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src);11446 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...@@ -11551,7 +11562,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11551 case_block.inline_case_capture = .none;11562 case_block.inline_case_capture = .none;
1155211563
11553 if (sema.mod.backendSupportsFeature(.is_named_enum_value) and special.body.len != 0 and block.wantSafety() and11564 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))
11555 {11566 {
11556 try sema.zirDbgStmt(&case_block, cond_dbg_node_index);11567 try sema.zirDbgStmt(&case_block, cond_dbg_node_index);
11557 const ok = try case_block.addUnOp(.is_named_enum_value, operand);11568 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...@@ -11563,7 +11574,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11563 if (seen_field != null) continue;11574 if (seen_field != null) continue;
11564 const union_obj = maybe_union_ty.cast(Type.Payload.Union).?.data;11575 const union_obj = maybe_union_ty.cast(Type.Payload.Union).?.data;
11565 const field_ty = union_obj.fields.values()[index].ty;11576 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;
11567 } else false11578 } else false
11568 else11579 else
11569 true;11580 true;
...@@ -11629,9 +11640,9 @@ const RangeSetUnhandledIterator = struct {...@@ -11629,9 +11640,9 @@ const RangeSetUnhandledIterator = struct {
11629 first: bool = true,11640 first: bool = true,
1163011641
11631 fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator {11642 fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator {
11632 const target = sema.mod.getTarget();11643 const mod = sema.mod;
11633 const min = try ty.minInt(sema.arena, target);11644 const min = try ty.minInt(sema.arena, mod);
11634 const max = try ty.maxInt(sema.arena, target);11645 const max = try ty.maxInt(sema.arena, mod);
1163511646
11636 return RangeSetUnhandledIterator{11647 return RangeSetUnhandledIterator{
11637 .sema = sema,11648 .sema = sema,
...@@ -11931,18 +11942,19 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op...@@ -11931,18 +11942,19 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
11931}11942}
1193211943
11933fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, cond: Zir.Inst.Ref, cond_src: LazySrcLoc) !void {11944fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, cond: Zir.Inst.Ref, cond_src: LazySrcLoc) !void {
11945 const mod = sema.mod;
11934 const index = Zir.refToIndex(cond) orelse return;11946 const index = Zir.refToIndex(cond) orelse return;
11935 if (sema.code.instructions.items(.tag)[index] != .is_non_err) return;11947 if (sema.code.instructions.items(.tag)[index] != .is_non_err) return;
1193611948
11937 const err_inst_data = sema.code.instructions.items(.data)[index].un_node;11949 const err_inst_data = sema.code.instructions.items(.data)[index].un_node;
11938 const err_operand = try sema.resolveInst(err_inst_data.operand);11950 const err_operand = try sema.resolveInst(err_inst_data.operand);
11939 const operand_ty = sema.typeOf(err_operand);11951 const operand_ty = sema.typeOf(err_operand);
11940 if (operand_ty.zigTypeTag() == .ErrorSet) {11952 if (operand_ty.zigTypeTag(mod) == .ErrorSet) {
11941 try sema.maybeErrorUnwrapComptime(block, body, err_operand);11953 try sema.maybeErrorUnwrapComptime(block, body, err_operand);
11942 return;11954 return;
11943 }11955 }
11944 if (try sema.resolveDefinedValue(block, cond_src, err_operand)) |val| {11956 if (try sema.resolveDefinedValue(block, cond_src, err_operand)) |val| {
11945 if (!operand_ty.isError()) return;11957 if (!operand_ty.isError(mod)) return;
11946 if (val.getError() == null) return;11958 if (val.getError() == null) return;
11947 try sema.maybeErrorUnwrapComptime(block, body, err_operand);11959 try sema.maybeErrorUnwrapComptime(block, body, err_operand);
11948 }11960 }
...@@ -11972,6 +11984,7 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I...@@ -11972,6 +11984,7 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I
11972}11984}
1197311985
11974fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {11986fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
11987 const mod = sema.mod;
11975 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;11988 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
11976 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;11989 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
11977 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };11990 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...@@ -11995,7 +12008,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
11995 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch break :hf false;12008 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch break :hf false;
11996 break :hf field_index < ty.structFieldCount();12009 break :hf field_index < ty.structFieldCount();
11997 }12010 }
11998 break :hf switch (ty.zigTypeTag()) {12011 break :hf switch (ty.zigTypeTag(mod)) {
11999 .Struct => ty.structFields().contains(field_name),12012 .Struct => ty.structFields().contains(field_name),
12000 .Union => ty.unionFields().contains(field_name),12013 .Union => ty.unionFields().contains(field_name),
12001 .Enum => ty.enumFields().contains(field_name),12014 .Enum => ty.enumFields().contains(field_name),
...@@ -12126,6 +12139,7 @@ fn zirShl(...@@ -12126,6 +12139,7 @@ fn zirShl(
12126 const tracy = trace(@src());12139 const tracy = trace(@src());
12127 defer tracy.end();12140 defer tracy.end();
1212812141
12142 const mod = sema.mod;
12129 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;12143 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
12130 const src = inst_data.src();12144 const src = inst_data.src();
12131 sema.src = src;12145 sema.src = src;
...@@ -12136,11 +12150,10 @@ fn zirShl(...@@ -12136,11 +12150,10 @@ fn zirShl(
12136 const rhs = try sema.resolveInst(extra.rhs);12150 const rhs = try sema.resolveInst(extra.rhs);
12137 const lhs_ty = sema.typeOf(lhs);12151 const lhs_ty = sema.typeOf(lhs);
12138 const rhs_ty = sema.typeOf(rhs);12152 const rhs_ty = sema.typeOf(rhs);
12139 const target = sema.mod.getTarget();
12140 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);12153 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1214112154
12142 const scalar_ty = lhs_ty.scalarType();12155 const scalar_ty = lhs_ty.scalarType(mod);
12143 const scalar_rhs_ty = rhs_ty.scalarType();12156 const scalar_rhs_ty = rhs_ty.scalarType(mod);
1214412157
12145 // TODO coerce rhs if air_tag is not shl_sat12158 // TODO coerce rhs if air_tag is not shl_sat
12146 const rhs_is_comptime_int = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);12159 const rhs_is_comptime_int = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);
...@@ -12156,18 +12169,18 @@ fn zirShl(...@@ -12156,18 +12169,18 @@ fn zirShl(
12156 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {12169 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
12157 return lhs;12170 return lhs;
12158 }12171 }
12159 if (scalar_ty.zigTypeTag() != .ComptimeInt and air_tag != .shl_sat) {12172 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) {
12160 var bits_payload = Value.Payload.U64{12173 var bits_payload = Value.Payload.U64{
12161 .base = .{ .tag = .int_u64 },12174 .base = .{ .tag = .int_u64 },
12162 .data = scalar_ty.intInfo(target).bits,12175 .data = scalar_ty.intInfo(mod).bits,
12163 };12176 };
12164 const bit_value = Value.initPayload(&bits_payload.base);12177 const bit_value = Value.initPayload(&bits_payload.base);
12165 if (rhs_ty.zigTypeTag() == .Vector) {12178 if (rhs_ty.zigTypeTag(mod) == .Vector) {
12166 var i: usize = 0;12179 var i: usize = 0;
12167 while (i < rhs_ty.vectorLen()) : (i += 1) {12180 while (i < rhs_ty.vectorLen()) : (i += 1) {
12168 var elem_value_buf: Value.ElemValueBuffer = undefined;12181 var elem_value_buf: Value.ElemValueBuffer = undefined;
12169 const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf);12182 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)) {
12171 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{12184 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
12172 rhs_elem.fmtValue(scalar_ty, sema.mod),12185 rhs_elem.fmtValue(scalar_ty, sema.mod),
12173 i,12186 i,
...@@ -12175,26 +12188,26 @@ fn zirShl(...@@ -12175,26 +12188,26 @@ fn zirShl(
12175 });12188 });
12176 }12189 }
12177 }12190 }
12178 } else if (rhs_val.compareHetero(.gte, bit_value, target)) {12191 } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {
12179 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{12192 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
12180 rhs_val.fmtValue(scalar_ty, sema.mod),12193 rhs_val.fmtValue(scalar_ty, sema.mod),
12181 scalar_ty.fmt(sema.mod),12194 scalar_ty.fmt(sema.mod),
12182 });12195 });
12183 }12196 }
12184 }12197 }
12185 if (rhs_ty.zigTypeTag() == .Vector) {12198 if (rhs_ty.zigTypeTag(mod) == .Vector) {
12186 var i: usize = 0;12199 var i: usize = 0;
12187 while (i < rhs_ty.vectorLen()) : (i += 1) {12200 while (i < rhs_ty.vectorLen()) : (i += 1) {
12188 var elem_value_buf: Value.ElemValueBuffer = undefined;12201 var elem_value_buf: Value.ElemValueBuffer = undefined;
12189 const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf);12202 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)) {
12191 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{12204 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
12192 rhs_elem.fmtValue(scalar_ty, sema.mod),12205 rhs_elem.fmtValue(scalar_ty, sema.mod),
12193 i,12206 i,
12194 });12207 });
12195 }12208 }
12196 }12209 }
12197 } else if (rhs_val.compareHetero(.lt, Value.zero, target)) {12210 } else if (rhs_val.compareHetero(.lt, Value.zero, mod)) {
12198 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{12211 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
12199 rhs_val.fmtValue(scalar_ty, sema.mod),12212 rhs_val.fmtValue(scalar_ty, sema.mod),
12200 });12213 });
...@@ -12204,7 +12217,7 @@ fn zirShl(...@@ -12204,7 +12217,7 @@ fn zirShl(
12204 const runtime_src = if (maybe_lhs_val) |lhs_val| rs: {12217 const runtime_src = if (maybe_lhs_val) |lhs_val| rs: {
12205 if (lhs_val.isUndef()) return sema.addConstUndef(lhs_ty);12218 if (lhs_val.isUndef()) return sema.addConstUndef(lhs_ty);
12206 const rhs_val = maybe_rhs_val orelse {12219 const rhs_val = maybe_rhs_val orelse {
12207 if (scalar_ty.zigTypeTag() == .ComptimeInt) {12220 if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) {
12208 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});12221 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});
12209 }12222 }
12210 break :rs rhs_src;12223 break :rs rhs_src;
...@@ -12213,7 +12226,7 @@ fn zirShl(...@@ -12213,7 +12226,7 @@ fn zirShl(
12213 const val = switch (air_tag) {12226 const val = switch (air_tag) {
12214 .shl_exact => val: {12227 .shl_exact => val: {
12215 const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, sema.mod);12228 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) {
12217 break :val shifted.wrapped_result;12230 break :val shifted.wrapped_result;
12218 }12231 }
12219 if (shifted.overflow_bit.compareAllWithZero(.eq, sema.mod)) {12232 if (shifted.overflow_bit.compareAllWithZero(.eq, sema.mod)) {
...@@ -12222,12 +12235,12 @@ fn zirShl(...@@ -12222,12 +12235,12 @@ fn zirShl(
12222 return sema.fail(block, src, "operation caused overflow", .{});12235 return sema.fail(block, src, "operation caused overflow", .{});
12223 },12236 },
1222412237
12225 .shl_sat => if (scalar_ty.zigTypeTag() == .ComptimeInt)12238 .shl_sat => if (scalar_ty.zigTypeTag(mod) == .ComptimeInt)
12226 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, sema.mod)12239 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, sema.mod)
12227 else12240 else
12228 try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, sema.mod),12241 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)
12231 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, sema.mod)12244 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, sema.mod)
12232 else12245 else
12233 try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, sema.mod),12246 try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, sema.mod),
...@@ -12241,11 +12254,11 @@ fn zirShl(...@@ -12241,11 +12254,11 @@ fn zirShl(
12241 const new_rhs = if (air_tag == .shl_sat) rhs: {12254 const new_rhs = if (air_tag == .shl_sat) rhs: {
12242 // Limit the RHS type for saturating shl to be an integer as small as the LHS.12255 // Limit the RHS type for saturating shl to be an integer as small as the LHS.
12243 if (rhs_is_comptime_int or12256 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)
12245 {12258 {
12246 const max_int = try sema.addConstant(12259 const max_int = try sema.addConstant(
12247 lhs_ty,12260 lhs_ty,
12248 try lhs_ty.maxInt(sema.arena, target),12261 try lhs_ty.maxInt(sema.arena, mod),
12249 );12262 );
12250 const rhs_limited = try sema.analyzeMinMax(block, rhs_src, .min, &.{ rhs, max_int }, &.{ rhs_src, rhs_src });12263 const rhs_limited = try sema.analyzeMinMax(block, rhs_src, .min, &.{ rhs, max_int }, &.{ rhs_src, rhs_src });
12251 break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false);12264 break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false);
...@@ -12256,11 +12269,11 @@ fn zirShl(...@@ -12256,11 +12269,11 @@ fn zirShl(
1225612269
12257 try sema.requireRuntimeBlock(block, src, runtime_src);12270 try sema.requireRuntimeBlock(block, src, runtime_src);
12258 if (block.wantSafety()) {12271 if (block.wantSafety()) {
12259 const bit_count = scalar_ty.intInfo(target).bits;12272 const bit_count = scalar_ty.intInfo(mod).bits;
12260 if (!std.math.isPowerOfTwo(bit_count)) {12273 if (!std.math.isPowerOfTwo(bit_count)) {
12261 const bit_count_val = try Value.Tag.int_u64.create(sema.arena, bit_count);12274 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: {
12264 const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));12277 const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));
12265 const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);12278 const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);
12266 break :ok try block.addInst(.{12279 break :ok try block.addInst(.{
...@@ -12290,7 +12303,7 @@ fn zirShl(...@@ -12290,7 +12303,7 @@ fn zirShl(
12290 } },12303 } },
12291 });12304 });
12292 const ov_bit = try sema.tupleFieldValByIndex(block, src, op_ov, 1, op_ov_tuple_ty);12305 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)
12294 try block.addInst(.{12307 try block.addInst(.{
12295 .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce,12308 .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce,
12296 .data = .{ .reduce = .{12309 .data = .{ .reduce = .{
...@@ -12319,6 +12332,7 @@ fn zirShr(...@@ -12319,6 +12332,7 @@ fn zirShr(
12319 const tracy = trace(@src());12332 const tracy = trace(@src());
12320 defer tracy.end();12333 defer tracy.end();
1232112334
12335 const mod = sema.mod;
12322 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;12336 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
12323 const src = inst_data.src();12337 const src = inst_data.src();
12324 sema.src = src;12338 sema.src = src;
...@@ -12330,8 +12344,7 @@ fn zirShr(...@@ -12330,8 +12344,7 @@ fn zirShr(
12330 const lhs_ty = sema.typeOf(lhs);12344 const lhs_ty = sema.typeOf(lhs);
12331 const rhs_ty = sema.typeOf(rhs);12345 const rhs_ty = sema.typeOf(rhs);
12332 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);12346 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
12333 const target = sema.mod.getTarget();12347 const scalar_ty = lhs_ty.scalarType(mod);
12334 const scalar_ty = lhs_ty.scalarType();
1233512348
12336 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(lhs);12349 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(lhs);
12337 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);12350 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);
...@@ -12344,18 +12357,18 @@ fn zirShr(...@@ -12344,18 +12357,18 @@ fn zirShr(
12344 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {12357 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
12345 return lhs;12358 return lhs;
12346 }12359 }
12347 if (scalar_ty.zigTypeTag() != .ComptimeInt) {12360 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) {
12348 var bits_payload = Value.Payload.U64{12361 var bits_payload = Value.Payload.U64{
12349 .base = .{ .tag = .int_u64 },12362 .base = .{ .tag = .int_u64 },
12350 .data = scalar_ty.intInfo(target).bits,12363 .data = scalar_ty.intInfo(mod).bits,
12351 };12364 };
12352 const bit_value = Value.initPayload(&bits_payload.base);12365 const bit_value = Value.initPayload(&bits_payload.base);
12353 if (rhs_ty.zigTypeTag() == .Vector) {12366 if (rhs_ty.zigTypeTag(mod) == .Vector) {
12354 var i: usize = 0;12367 var i: usize = 0;
12355 while (i < rhs_ty.vectorLen()) : (i += 1) {12368 while (i < rhs_ty.vectorLen()) : (i += 1) {
12356 var elem_value_buf: Value.ElemValueBuffer = undefined;12369 var elem_value_buf: Value.ElemValueBuffer = undefined;
12357 const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf);12370 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)) {
12359 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{12372 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
12360 rhs_elem.fmtValue(scalar_ty, sema.mod),12373 rhs_elem.fmtValue(scalar_ty, sema.mod),
12361 i,12374 i,
...@@ -12363,26 +12376,26 @@ fn zirShr(...@@ -12363,26 +12376,26 @@ fn zirShr(
12363 });12376 });
12364 }12377 }
12365 }12378 }
12366 } else if (rhs_val.compareHetero(.gte, bit_value, target)) {12379 } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {
12367 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{12380 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
12368 rhs_val.fmtValue(scalar_ty, sema.mod),12381 rhs_val.fmtValue(scalar_ty, sema.mod),
12369 scalar_ty.fmt(sema.mod),12382 scalar_ty.fmt(sema.mod),
12370 });12383 });
12371 }12384 }
12372 }12385 }
12373 if (rhs_ty.zigTypeTag() == .Vector) {12386 if (rhs_ty.zigTypeTag(mod) == .Vector) {
12374 var i: usize = 0;12387 var i: usize = 0;
12375 while (i < rhs_ty.vectorLen()) : (i += 1) {12388 while (i < rhs_ty.vectorLen()) : (i += 1) {
12376 var elem_value_buf: Value.ElemValueBuffer = undefined;12389 var elem_value_buf: Value.ElemValueBuffer = undefined;
12377 const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf);12390 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)) {
12379 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{12392 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
12380 rhs_elem.fmtValue(scalar_ty, sema.mod),12393 rhs_elem.fmtValue(scalar_ty, sema.mod),
12381 i,12394 i,
12382 });12395 });
12383 }12396 }
12384 }12397 }
12385 } else if (rhs_val.compareHetero(.lt, Value.zero, target)) {12398 } else if (rhs_val.compareHetero(.lt, Value.zero, mod)) {
12386 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{12399 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
12387 rhs_val.fmtValue(scalar_ty, sema.mod),12400 rhs_val.fmtValue(scalar_ty, sema.mod),
12388 });12401 });
...@@ -12405,18 +12418,18 @@ fn zirShr(...@@ -12405,18 +12418,18 @@ fn zirShr(
12405 }12418 }
12406 } else rhs_src;12419 } 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) {
12409 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});12422 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});
12410 }12423 }
1241112424
12412 try sema.requireRuntimeBlock(block, src, runtime_src);12425 try sema.requireRuntimeBlock(block, src, runtime_src);
12413 const result = try block.addBinOp(air_tag, lhs, rhs);12426 const result = try block.addBinOp(air_tag, lhs, rhs);
12414 if (block.wantSafety()) {12427 if (block.wantSafety()) {
12415 const bit_count = scalar_ty.intInfo(target).bits;12428 const bit_count = scalar_ty.intInfo(mod).bits;
12416 if (!std.math.isPowerOfTwo(bit_count)) {12429 if (!std.math.isPowerOfTwo(bit_count)) {
12417 const bit_count_val = try Value.Tag.int_u64.create(sema.arena, bit_count);12430 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: {
12420 const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));12433 const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));
12421 const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);12434 const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);
12422 break :ok try block.addInst(.{12435 break :ok try block.addInst(.{
...@@ -12436,7 +12449,7 @@ fn zirShr(...@@ -12436,7 +12449,7 @@ fn zirShr(
12436 if (air_tag == .shr_exact) {12449 if (air_tag == .shr_exact) {
12437 const back = try block.addBinOp(.shl, result, rhs);12450 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: {
12440 const eql = try block.addCmpVector(lhs, back, .eq);12453 const eql = try block.addCmpVector(lhs, back, .eq);
12441 break :ok try block.addInst(.{12454 break :ok try block.addInst(.{
12442 .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce,12455 .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce,
...@@ -12461,6 +12474,7 @@ fn zirBitwise(...@@ -12461,6 +12474,7 @@ fn zirBitwise(
12461 const tracy = trace(@src());12474 const tracy = trace(@src());
12462 defer tracy.end();12475 defer tracy.end();
1246312476
12477 const mod = sema.mod;
12464 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;12478 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
12465 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };12479 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
12466 sema.src = src;12480 sema.src = src;
...@@ -12475,8 +12489,8 @@ fn zirBitwise(...@@ -12475,8 +12489,8 @@ fn zirBitwise(
1247512489
12476 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };12490 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
12477 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } });12491 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } });
12478 const scalar_type = resolved_type.scalarType();12492 const scalar_type = resolved_type.scalarType(mod);
12479 const scalar_tag = scalar_type.zigTypeTag();12493 const scalar_tag = scalar_type.zigTypeTag(mod);
1248012494
12481 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);12495 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
12482 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);12496 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
...@@ -12484,7 +12498,7 @@ fn zirBitwise(...@@ -12484,7 +12498,7 @@ fn zirBitwise(
12484 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;12498 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1248512499
12486 if (!is_int) {12500 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)) });
12488 }12502 }
1248912503
12490 const runtime_src = runtime: {12504 const runtime_src = runtime: {
...@@ -12515,15 +12529,16 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -12515,15 +12529,16 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
12515 const tracy = trace(@src());12529 const tracy = trace(@src());
12516 defer tracy.end();12530 defer tracy.end();
1251712531
12532 const mod = sema.mod;
12518 const inst_data = sema.code.instructions.items(.data)[inst].un_node;12533 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
12519 const src = inst_data.src();12534 const src = inst_data.src();
12520 const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };12535 const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };
1252112536
12522 const operand = try sema.resolveInst(inst_data.operand);12537 const operand = try sema.resolveInst(inst_data.operand);
12523 const operand_type = sema.typeOf(operand);12538 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) {
12527 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{12542 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{
12528 operand_type.fmt(sema.mod),12543 operand_type.fmt(sema.mod),
12529 });12544 });
...@@ -12532,7 +12547,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -12532,7 +12547,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
12532 if (try sema.resolveMaybeUndefVal(operand)) |val| {12547 if (try sema.resolveMaybeUndefVal(operand)) |val| {
12533 if (val.isUndef()) {12548 if (val.isUndef()) {
12534 return sema.addConstUndef(operand_type);12549 return sema.addConstUndef(operand_type);
12535 } else if (operand_type.zigTypeTag() == .Vector) {12550 } else if (operand_type.zigTypeTag(mod) == .Vector) {
12536 const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen());12551 const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen());
12537 var elem_val_buf: Value.ElemValueBuffer = undefined;12552 var elem_val_buf: Value.ElemValueBuffer = undefined;
12538 const elems = try sema.arena.alloc(Value, vec_len);12553 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...@@ -12728,18 +12743,19 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12728 };12743 };
1272912744
12730 const result_ty = try Type.array(sema.arena, result_len, res_sent_val, resolved_elem_ty, sema.mod);12745 const result_ty = try Type.array(sema.arena, result_len, res_sent_val, resolved_elem_ty, sema.mod);
12746 const mod = sema.mod;
12731 const ptr_addrspace = p: {12747 const ptr_addrspace = p: {
12732 if (lhs_ty.zigTypeTag() == .Pointer) break :p lhs_ty.ptrAddressSpace();12748 if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace();
12733 if (rhs_ty.zigTypeTag() == .Pointer) break :p rhs_ty.ptrAddressSpace();12749 if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace();
12734 break :p null;12750 break :p null;
12735 };12751 };
1273612752
12737 const runtime_src = if (switch (lhs_ty.zigTypeTag()) {12753 const runtime_src = if (switch (lhs_ty.zigTypeTag(mod)) {
12738 .Array, .Struct => try sema.resolveMaybeUndefVal(lhs),12754 .Array, .Struct => try sema.resolveMaybeUndefVal(lhs),
12739 .Pointer => try sema.resolveDefinedValue(block, lhs_src, lhs),12755 .Pointer => try sema.resolveDefinedValue(block, lhs_src, lhs),
12740 else => unreachable,12756 else => unreachable,
12741 }) |lhs_val| rs: {12757 }) |lhs_val| rs: {
12742 if (switch (rhs_ty.zigTypeTag()) {12758 if (switch (rhs_ty.zigTypeTag(mod)) {
12743 .Array, .Struct => try sema.resolveMaybeUndefVal(rhs),12759 .Array, .Struct => try sema.resolveMaybeUndefVal(rhs),
12744 .Pointer => try sema.resolveDefinedValue(block, rhs_src, rhs),12760 .Pointer => try sema.resolveDefinedValue(block, rhs_src, rhs),
12745 else => unreachable,12761 else => unreachable,
...@@ -12841,8 +12857,9 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12841,8 +12857,9 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12841}12857}
1284212858
12843fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, peer_ty: Type) !?Type.ArrayInfo {12859fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, peer_ty: Type) !?Type.ArrayInfo {
12860 const mod = sema.mod;
12844 const operand_ty = sema.typeOf(operand);12861 const operand_ty = sema.typeOf(operand);
12845 switch (operand_ty.zigTypeTag()) {12862 switch (operand_ty.zigTypeTag(mod)) {
12846 .Array => return operand_ty.arrayInfo(),12863 .Array => return operand_ty.arrayInfo(),
12847 .Pointer => {12864 .Pointer => {
12848 const ptr_info = operand_ty.ptrInfo().data;12865 const ptr_info = operand_ty.ptrInfo().data;
...@@ -12859,7 +12876,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins...@@ -12859,7 +12876,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
12859 };12876 };
12860 },12877 },
12861 .One => {12878 .One => {
12862 if (ptr_info.pointee_type.zigTypeTag() == .Array) {12879 if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {
12863 return ptr_info.pointee_type.arrayInfo();12880 return ptr_info.pointee_type.arrayInfo();
12864 }12881 }
12865 },12882 },
...@@ -12867,10 +12884,10 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins...@@ -12867,10 +12884,10 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
12867 }12884 }
12868 },12885 },
12869 .Struct => {12886 .Struct => {
12870 if (operand_ty.isTuple() and peer_ty.isIndexable()) {12887 if (operand_ty.isTuple() and peer_ty.isIndexable(mod)) {
12871 assert(!peer_ty.isTuple());12888 assert(!peer_ty.isTuple());
12872 return .{12889 return .{
12873 .elem_type = peer_ty.elemType2(),12890 .elem_type = peer_ty.elemType2(mod),
12874 .sentinel = null,12891 .sentinel = null,
12875 .len = operand_ty.arrayLen(),12892 .len = operand_ty.arrayLen(),
12876 };12893 };
...@@ -12970,11 +12987,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12970,11 +12987,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12970 }12987 }
1297112988
12972 // Analyze the lhs first, to catch the case that someone tried to do exponentiation12989 // Analyze the lhs first, to catch the case that someone tried to do exponentiation
12990 const mod = sema.mod;
12973 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse {12991 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse {
12974 const msg = msg: {12992 const msg = msg: {
12975 const msg = try sema.errMsg(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(sema.mod)});12993 const msg = try sema.errMsg(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(sema.mod)});
12976 errdefer msg.destroy(sema.gpa);12994 errdefer msg.destroy(sema.gpa);
12977 switch (lhs_ty.zigTypeTag()) {12995 switch (lhs_ty.zigTypeTag(mod)) {
12978 .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => {12996 .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => {
12979 try sema.errNote(block, operator_src, msg, "this operator multiplies arrays; use std.math.pow for exponentiation", .{});12997 try sema.errNote(block, operator_src, msg, "this operator multiplies arrays; use std.math.pow for exponentiation", .{});
12980 },12998 },
...@@ -12994,7 +13012,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12994,7 +13012,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1299413012
12995 const result_ty = try Type.array(sema.arena, result_len, lhs_info.sentinel, lhs_info.elem_type, sema.mod);13013 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;
12998 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);13016 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);
1299913017
13000 if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| {13018 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...@@ -13082,6 +13100,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13082}13100}
1308313101
13084fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13102fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13103 const mod = sema.mod;
13085 const inst_data = sema.code.instructions.items(.data)[inst].un_node;13104 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
13086 const src = inst_data.src();13105 const src = inst_data.src();
13087 const lhs_src = src;13106 const lhs_src = src;
...@@ -13089,9 +13108,9 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13089,9 +13108,9 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1308913108
13090 const rhs = try sema.resolveInst(inst_data.operand);13109 const rhs = try sema.resolveInst(inst_data.operand);
13091 const rhs_ty = sema.typeOf(rhs);13110 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)) {
13095 .Int, .ComptimeInt, .Float, .ComptimeFloat => false,13114 .Int, .ComptimeInt, .Float, .ComptimeFloat => false,
13096 else => true,13115 else => true,
13097 }) {13116 }) {
...@@ -13108,7 +13127,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13108,7 +13127,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13108 return block.addUnOp(if (block.float_mode == .Optimized) .neg_optimized else .neg, rhs);13127 return block.addUnOp(if (block.float_mode == .Optimized) .neg_optimized else .neg, rhs);
13109 }13128 }
1311013129
13111 const lhs = if (rhs_ty.zigTypeTag() == .Vector)13130 const lhs = if (rhs_ty.zigTypeTag(mod) == .Vector)
13112 try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero))13131 try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero))
13113 else13132 else
13114 try sema.resolveInst(.zero);13133 try sema.resolveInst(.zero);
...@@ -13117,6 +13136,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13117,6 +13136,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13117}13136}
1311813137
13119fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13138fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13139 const mod = sema.mod;
13120 const inst_data = sema.code.instructions.items(.data)[inst].un_node;13140 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
13121 const src = inst_data.src();13141 const src = inst_data.src();
13122 const lhs_src = src;13142 const lhs_src = src;
...@@ -13124,14 +13144,14 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -13124,14 +13144,14 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1312413144
13125 const rhs = try sema.resolveInst(inst_data.operand);13145 const rhs = try sema.resolveInst(inst_data.operand);
13126 const rhs_ty = sema.typeOf(rhs);13146 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)) {
13130 .Int, .ComptimeInt, .Float, .ComptimeFloat => {},13150 .Int, .ComptimeInt, .Float, .ComptimeFloat => {},
13131 else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(sema.mod)}),13151 else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(sema.mod)}),
13132 }13152 }
1313313153
13134 const lhs = if (rhs_ty.zigTypeTag() == .Vector)13154 const lhs = if (rhs_ty.zigTypeTag(mod) == .Vector)
13135 try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero))13155 try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero))
13136 else13156 else
13137 try sema.resolveInst(.zero);13157 try sema.resolveInst(.zero);
...@@ -13161,6 +13181,7 @@ fn zirArithmetic(...@@ -13161,6 +13181,7 @@ fn zirArithmetic(
13161}13181}
1316213182
13163fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13183fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13184 const mod = sema.mod;
13164 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;13185 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
13165 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };13186 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
13166 sema.src = src;13187 sema.src = src;
...@@ -13171,8 +13192,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -13171,8 +13192,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13171 const rhs = try sema.resolveInst(extra.rhs);13192 const rhs = try sema.resolveInst(extra.rhs);
13172 const lhs_ty = sema.typeOf(lhs);13193 const lhs_ty = sema.typeOf(lhs);
13173 const rhs_ty = sema.typeOf(rhs);13194 const rhs_ty = sema.typeOf(rhs);
13174 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();13195 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
13175 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();13196 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
13176 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);13197 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
13177 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);13198 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...@@ -13181,25 +13202,24 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13181 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },13202 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
13182 });13203 });
1318313204
13184 const is_vector = resolved_type.zigTypeTag() == .Vector;13205 const is_vector = resolved_type.zigTypeTag(mod) == .Vector;
1318513206
13186 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);13207 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
13187 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);13208 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1318813209
13189 const lhs_scalar_ty = lhs_ty.scalarType();13210 const lhs_scalar_ty = lhs_ty.scalarType(mod);
13190 const rhs_scalar_ty = rhs_ty.scalarType();13211 const rhs_scalar_ty = rhs_ty.scalarType(mod);
13191 const scalar_tag = resolved_type.scalarType().zigTypeTag();13212 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1319213213
13193 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;13214 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1319413215
13195 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div);13216 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div);
1319613217
13197 const mod = sema.mod;
13198 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);13218 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
13199 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);13219 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
1320013220
13201 if ((lhs_ty.zigTypeTag() == .ComptimeFloat and rhs_ty.zigTypeTag() == .ComptimeInt) or13221 if ((lhs_ty.zigTypeTag(mod) == .ComptimeFloat and rhs_ty.zigTypeTag(mod) == .ComptimeInt) or
13202 (lhs_ty.zigTypeTag() == .ComptimeInt and rhs_ty.zigTypeTag() == .ComptimeFloat))13222 (lhs_ty.zigTypeTag(mod) == .ComptimeInt and rhs_ty.zigTypeTag(mod) == .ComptimeFloat))
13203 {13223 {
13204 // If it makes a difference whether we coerce to ints or floats before doing the division, error.13224 // If it makes a difference whether we coerce to ints or floats before doing the division, error.
13205 // If lhs % rhs is 0, it doesn't matter.13225 // 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...@@ -13268,7 +13288,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13268 const runtime_src = rs: {13288 const runtime_src = rs: {
13269 if (maybe_lhs_val) |lhs_val| {13289 if (maybe_lhs_val) |lhs_val| {
13270 if (lhs_val.isUndef()) {13290 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)) {
13272 if (maybe_rhs_val) |rhs_val| {13292 if (maybe_rhs_val) |rhs_val| {
13273 if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) {13293 if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) {
13274 return sema.addConstUndef(resolved_type);13294 return sema.addConstUndef(resolved_type);
...@@ -13309,7 +13329,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -13309,7 +13329,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13309 }13329 }
1331013330
13311 const air_tag = if (is_int) blk: {13331 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)) {
13313 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()) });13333 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()) });
13314 }13334 }
13315 break :blk Air.Inst.Tag.div_trunc;13335 break :blk Air.Inst.Tag.div_trunc;
...@@ -13321,6 +13341,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -13321,6 +13341,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13321}13341}
1332213342
13323fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13343fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13344 const mod = sema.mod;
13324 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;13345 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
13325 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };13346 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
13326 sema.src = src;13347 sema.src = src;
...@@ -13331,8 +13352,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13331,8 +13352,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13331 const rhs = try sema.resolveInst(extra.rhs);13352 const rhs = try sema.resolveInst(extra.rhs);
13332 const lhs_ty = sema.typeOf(lhs);13353 const lhs_ty = sema.typeOf(lhs);
13333 const rhs_ty = sema.typeOf(rhs);13354 const rhs_ty = sema.typeOf(rhs);
13334 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();13355 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
13335 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();13356 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
13336 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);13357 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
13337 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);13358 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);
1333813359
...@@ -13341,19 +13362,18 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13341,19 +13362,18 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13341 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },13362 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
13342 });13363 });
1334313364
13344 const is_vector = resolved_type.zigTypeTag() == .Vector;13365 const is_vector = resolved_type.zigTypeTag(mod) == .Vector;
1334513366
13346 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);13367 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
13347 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);13368 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1334813369
13349 const lhs_scalar_ty = lhs_ty.scalarType();13370 const lhs_scalar_ty = lhs_ty.scalarType(mod);
13350 const scalar_tag = resolved_type.scalarType().zigTypeTag();13371 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1335113372
13352 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;13373 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1335313374
13354 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_exact);13375 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_exact);
1335513376
13356 const mod = sema.mod;
13357 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);13377 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
13358 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);13378 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...@@ -13437,7 +13457,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13437 const ok = if (!is_int) ok: {13457 const ok = if (!is_int) ok: {
13438 const floored = try block.addUnOp(.floor, result);13458 const floored = try block.addUnOp(.floor, result);
1343913459
13440 if (resolved_type.zigTypeTag() == .Vector) {13460 if (resolved_type.zigTypeTag(mod) == .Vector) {
13441 const eql = try block.addCmpVector(result, floored, .eq);13461 const eql = try block.addCmpVector(result, floored, .eq);
13442 break :ok try block.addInst(.{13462 break :ok try block.addInst(.{
13443 .tag = switch (block.float_mode) {13463 .tag = switch (block.float_mode) {
...@@ -13459,7 +13479,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13459,7 +13479,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13459 } else ok: {13479 } else ok: {
13460 const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs);13480 const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs);
1346113481
13462 if (resolved_type.zigTypeTag() == .Vector) {13482 if (resolved_type.zigTypeTag(mod) == .Vector) {
13463 const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero);13483 const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero);
13464 const zero = try sema.addConstant(resolved_type, zero_val);13484 const zero = try sema.addConstant(resolved_type, zero_val);
13465 const eql = try block.addCmpVector(remainder, zero, .eq);13485 const eql = try block.addCmpVector(remainder, zero, .eq);
...@@ -13484,6 +13504,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13484,6 +13504,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13484}13504}
1348513505
13486fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13506fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13507 const mod = sema.mod;
13487 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;13508 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
13488 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };13509 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
13489 sema.src = src;13510 sema.src = src;
...@@ -13494,8 +13515,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13494,8 +13515,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13494 const rhs = try sema.resolveInst(extra.rhs);13515 const rhs = try sema.resolveInst(extra.rhs);
13495 const lhs_ty = sema.typeOf(lhs);13516 const lhs_ty = sema.typeOf(lhs);
13496 const rhs_ty = sema.typeOf(rhs);13517 const rhs_ty = sema.typeOf(rhs);
13497 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();13518 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
13498 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();13519 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
13499 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);13520 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
13500 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);13521 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);
1350113522
...@@ -13504,20 +13525,19 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13504,20 +13525,19 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13504 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },13525 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
13505 });13526 });
1350613527
13507 const is_vector = resolved_type.zigTypeTag() == .Vector;13528 const is_vector = resolved_type.zigTypeTag(mod) == .Vector;
1350813529
13509 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);13530 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
13510 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);13531 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1351113532
13512 const lhs_scalar_ty = lhs_ty.scalarType();13533 const lhs_scalar_ty = lhs_ty.scalarType(mod);
13513 const rhs_scalar_ty = rhs_ty.scalarType();13534 const rhs_scalar_ty = rhs_ty.scalarType(mod);
13514 const scalar_tag = resolved_type.scalarType().zigTypeTag();13535 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1351513536
13516 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;13537 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1351713538
13518 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_floor);13539 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_floor);
1351913540
13520 const mod = sema.mod;
13521 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);13541 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
13522 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);13542 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...@@ -13562,7 +13582,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13562 }13582 }
13563 if (maybe_lhs_val) |lhs_val| {13583 if (maybe_lhs_val) |lhs_val| {
13564 if (lhs_val.isUndef()) {13584 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)) {
13566 if (maybe_rhs_val) |rhs_val| {13586 if (maybe_rhs_val) |rhs_val| {
13567 if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) {13587 if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) {
13568 return sema.addConstUndef(resolved_type);13588 return sema.addConstUndef(resolved_type);
...@@ -13600,6 +13620,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13600,6 +13620,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13600}13620}
1360113621
13602fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13622fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13623 const mod = sema.mod;
13603 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;13624 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
13604 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };13625 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
13605 sema.src = src;13626 sema.src = src;
...@@ -13610,8 +13631,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13610,8 +13631,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13610 const rhs = try sema.resolveInst(extra.rhs);13631 const rhs = try sema.resolveInst(extra.rhs);
13611 const lhs_ty = sema.typeOf(lhs);13632 const lhs_ty = sema.typeOf(lhs);
13612 const rhs_ty = sema.typeOf(rhs);13633 const rhs_ty = sema.typeOf(rhs);
13613 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();13634 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
13614 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();13635 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
13615 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);13636 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
13616 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);13637 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);
1361713638
...@@ -13620,20 +13641,19 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13620,20 +13641,19 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13620 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },13641 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
13621 });13642 });
1362213643
13623 const is_vector = resolved_type.zigTypeTag() == .Vector;13644 const is_vector = resolved_type.zigTypeTag(mod) == .Vector;
1362413645
13625 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);13646 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
13626 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);13647 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1362713648
13628 const lhs_scalar_ty = lhs_ty.scalarType();13649 const lhs_scalar_ty = lhs_ty.scalarType(mod);
13629 const rhs_scalar_ty = rhs_ty.scalarType();13650 const rhs_scalar_ty = rhs_ty.scalarType(mod);
13630 const scalar_tag = resolved_type.scalarType().zigTypeTag();13651 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1363113652
13632 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;13653 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1363313654
13634 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_trunc);13655 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_trunc);
1363513656
13636 const mod = sema.mod;
13637 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);13657 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
13638 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);13658 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...@@ -13677,7 +13697,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13677 }13697 }
13678 if (maybe_lhs_val) |lhs_val| {13698 if (maybe_lhs_val) |lhs_val| {
13679 if (lhs_val.isUndef()) {13699 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)) {
13681 if (maybe_rhs_val) |rhs_val| {13701 if (maybe_rhs_val) |rhs_val| {
13682 if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) {13702 if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) {
13683 return sema.addConstUndef(resolved_type);13703 return sema.addConstUndef(resolved_type);
...@@ -13727,22 +13747,20 @@ fn addDivIntOverflowSafety(...@@ -13727,22 +13747,20 @@ fn addDivIntOverflowSafety(
13727 casted_rhs: Air.Inst.Ref,13747 casted_rhs: Air.Inst.Ref,
13728 is_int: bool,13748 is_int: bool,
13729) CompileError!void {13749) CompileError!void {
13750 const mod = sema.mod;
13730 if (!is_int) return;13751 if (!is_int) return;
1373113752
13732 // If the LHS is unsigned, it cannot cause overflow.13753 // If the LHS is unsigned, it cannot cause overflow.
13733 if (!lhs_scalar_ty.isSignedInt()) return;13754 if (!lhs_scalar_ty.isSignedInt(mod)) return;
13734
13735 const mod = sema.mod;
13736 const target = mod.getTarget();
1373713755
13738 // If the LHS is widened to a larger integer type, no overflow is possible.13756 // 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) {
13740 return;13758 return;
13741 }13759 }
1374213760
13743 const min_int = try resolved_type.minInt(sema.arena, target);13761 const min_int = try resolved_type.minInt(sema.arena, mod);
13744 const neg_one_scalar = try Value.Tag.int_i64.create(sema.arena, -1);13762 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)
13746 try Value.Tag.repeated.create(sema.arena, neg_one_scalar)13764 try Value.Tag.repeated.create(sema.arena, neg_one_scalar)
13747 else13765 else
13748 neg_one_scalar;13766 neg_one_scalar;
...@@ -13759,7 +13777,7 @@ fn addDivIntOverflowSafety(...@@ -13759,7 +13777,7 @@ fn addDivIntOverflowSafety(
13759 }13777 }
1376013778
13761 var ok: Air.Inst.Ref = .none;13779 var ok: Air.Inst.Ref = .none;
13762 if (resolved_type.zigTypeTag() == .Vector) {13780 if (resolved_type.zigTypeTag(mod) == .Vector) {
13763 if (maybe_lhs_val == null) {13781 if (maybe_lhs_val == null) {
13764 const min_int_ref = try sema.addConstant(resolved_type, min_int);13782 const min_int_ref = try sema.addConstant(resolved_type, min_int);
13765 ok = try block.addCmpVector(casted_lhs, min_int_ref, .neq);13783 ok = try block.addCmpVector(casted_lhs, min_int_ref, .neq);
...@@ -13815,7 +13833,8 @@ fn addDivByZeroSafety(...@@ -13815,7 +13833,8 @@ fn addDivByZeroSafety(
13815 // emitted above.13833 // emitted above.
13816 if (maybe_rhs_val != null) return;13834 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: {
13819 const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero);13838 const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero);
13820 const zero = try sema.addConstant(resolved_type, zero_val);13839 const zero = try sema.addConstant(resolved_type, zero_val);
13821 const ok = try block.addCmpVector(casted_rhs, zero, .neq);13840 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...@@ -13842,6 +13861,7 @@ fn airTag(block: *Block, is_int: bool, normal: Air.Inst.Tag, optimized: Air.Inst
13842}13861}
1384313862
13844fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13863fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13864 const mod = sema.mod;
13845 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;13865 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
13846 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };13866 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
13847 sema.src = src;13867 sema.src = src;
...@@ -13852,8 +13872,8 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13852,8 +13872,8 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13852 const rhs = try sema.resolveInst(extra.rhs);13872 const rhs = try sema.resolveInst(extra.rhs);
13853 const lhs_ty = sema.typeOf(lhs);13873 const lhs_ty = sema.typeOf(lhs);
13854 const rhs_ty = sema.typeOf(rhs);13874 const rhs_ty = sema.typeOf(rhs);
13855 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();13875 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
13856 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();13876 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
13857 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);13877 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
13858 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);13878 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);
1385913879
...@@ -13862,20 +13882,19 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13862,20 +13882,19 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13862 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },13882 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
13863 });13883 });
1386413884
13865 const is_vector = resolved_type.zigTypeTag() == .Vector;13885 const is_vector = resolved_type.zigTypeTag(mod) == .Vector;
1386613886
13867 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);13887 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
13868 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);13888 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1386913889
13870 const lhs_scalar_ty = lhs_ty.scalarType();13890 const lhs_scalar_ty = lhs_ty.scalarType(mod);
13871 const rhs_scalar_ty = rhs_ty.scalarType();13891 const rhs_scalar_ty = rhs_ty.scalarType(mod);
13872 const scalar_tag = resolved_type.scalarType().zigTypeTag();13892 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1387313893
13874 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;13894 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1387513895
13876 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .mod_rem);13896 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .mod_rem);
1387713897
13878 const mod = sema.mod;
13879 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);13898 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
13880 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);13899 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....@@ -13904,7 +13923,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13904 } else Value.zero;13923 } else Value.zero;
13905 return sema.addConstant(resolved_type, zero_val);13924 return sema.addConstant(resolved_type, zero_val);
13906 }13925 }
13907 } else if (lhs_scalar_ty.isSignedInt()) {13926 } else if (lhs_scalar_ty.isSignedInt(mod)) {
13908 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);13927 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
13909 }13928 }
13910 if (maybe_rhs_val) |rhs_val| {13929 if (maybe_rhs_val) |rhs_val| {
...@@ -13929,7 +13948,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13929,7 +13948,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13929 return sema.addConstant(resolved_type, rem_result);13948 return sema.addConstant(resolved_type, rem_result);
13930 }13949 }
13931 break :rs lhs_src;13950 break :rs lhs_src;
13932 } else if (rhs_scalar_ty.isSignedInt()) {13951 } else if (rhs_scalar_ty.isSignedInt(mod)) {
13933 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);13952 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);
13934 } else {13953 } else {
13935 break :rs rhs_src;13954 break :rs rhs_src;
...@@ -13978,7 +13997,8 @@ fn intRem(...@@ -13978,7 +13997,8 @@ fn intRem(
13978 lhs: Value,13997 lhs: Value,
13979 rhs: Value,13998 rhs: Value,
13980) CompileError!Value {13999) CompileError!Value {
13981 if (ty.zigTypeTag() == .Vector) {14000 const mod = sema.mod;
14001 if (ty.zigTypeTag(mod) == .Vector) {
13982 const result_data = try sema.arena.alloc(Value, ty.vectorLen());14002 const result_data = try sema.arena.alloc(Value, ty.vectorLen());
13983 for (result_data, 0..) |*scalar, i| {14003 for (result_data, 0..) |*scalar, i| {
13984 var lhs_buf: Value.ElemValueBuffer = undefined;14004 var lhs_buf: Value.ElemValueBuffer = undefined;
...@@ -13997,13 +14017,13 @@ fn intRemScalar(...@@ -13997,13 +14017,13 @@ fn intRemScalar(
13997 lhs: Value,14017 lhs: Value,
13998 rhs: Value,14018 rhs: Value,
13999) CompileError!Value {14019) CompileError!Value {
14000 const target = sema.mod.getTarget();14020 const mod = sema.mod;
14001 // TODO is this a performance issue? maybe we should try the operation without14021 // TODO is this a performance issue? maybe we should try the operation without
14002 // resorting to BigInt first.14022 // resorting to BigInt first.
14003 var lhs_space: Value.BigIntSpace = undefined;14023 var lhs_space: Value.BigIntSpace = undefined;
14004 var rhs_space: Value.BigIntSpace = undefined;14024 var rhs_space: Value.BigIntSpace = undefined;
14005 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema);14025 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
14006 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema);14026 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
14007 const limbs_q = try sema.arena.alloc(14027 const limbs_q = try sema.arena.alloc(
14008 math.big.Limb,14028 math.big.Limb,
14009 lhs_bigint.limbs.len,14029 lhs_bigint.limbs.len,
...@@ -14025,6 +14045,7 @@ fn intRemScalar(...@@ -14025,6 +14045,7 @@ fn intRemScalar(
14025}14045}
1402614046
14027fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {14047fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14048 const mod = sema.mod;
14028 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;14049 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
14029 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };14050 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
14030 sema.src = src;14051 sema.src = src;
...@@ -14035,8 +14056,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -14035,8 +14056,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14035 const rhs = try sema.resolveInst(extra.rhs);14056 const rhs = try sema.resolveInst(extra.rhs);
14036 const lhs_ty = sema.typeOf(lhs);14057 const lhs_ty = sema.typeOf(lhs);
14037 const rhs_ty = sema.typeOf(rhs);14058 const rhs_ty = sema.typeOf(rhs);
14038 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();14059 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
14039 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();14060 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
14040 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);14061 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
14041 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);14062 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...@@ -14048,13 +14069,12 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14048 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);14069 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
14049 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);14070 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
14053 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;14074 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1405414075
14055 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .mod);14076 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .mod);
1405614077
14057 const mod = sema.mod;
14058 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);14078 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
14059 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);14079 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...@@ -14127,6 +14147,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14127}14147}
1412814148
14129fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {14149fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14150 const mod = sema.mod;
14130 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;14151 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
14131 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };14152 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
14132 sema.src = src;14153 sema.src = src;
...@@ -14137,8 +14158,8 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -14137,8 +14158,8 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14137 const rhs = try sema.resolveInst(extra.rhs);14158 const rhs = try sema.resolveInst(extra.rhs);
14138 const lhs_ty = sema.typeOf(lhs);14159 const lhs_ty = sema.typeOf(lhs);
14139 const rhs_ty = sema.typeOf(rhs);14160 const rhs_ty = sema.typeOf(rhs);
14140 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();14161 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
14141 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();14162 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
14142 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);14163 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
14143 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);14164 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...@@ -14150,13 +14171,12 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14150 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);14171 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
14151 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);14172 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
14155 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;14176 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1415614177
14157 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .rem);14178 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .rem);
1415814179
14159 const mod = sema.mod;
14160 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);14180 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
14161 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);14181 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
1416214182
...@@ -14268,7 +14288,7 @@ fn zirOverflowArithmetic(...@@ -14268,7 +14288,7 @@ fn zirOverflowArithmetic(
14268 const lhs = try sema.coerce(block, dest_ty, uncasted_lhs, lhs_src);14288 const lhs = try sema.coerce(block, dest_ty, uncasted_lhs, lhs_src);
14269 const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src);14289 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) {
14272 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(mod)});14292 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(mod)});
14273 }14293 }
1427414294
...@@ -14434,12 +14454,14 @@ fn zirOverflowArithmetic(...@@ -14434,12 +14454,14 @@ fn zirOverflowArithmetic(
14434}14454}
1443514455
14436fn maybeRepeated(sema: *Sema, ty: Type, val: Value) !Value {14456fn 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;
14438 return Value.Tag.repeated.create(sema.arena, val);14459 return Value.Tag.repeated.create(sema.arena, val);
14439}14460}
1444014461
14441fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {14462fn 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
14444 const types = try sema.arena.alloc(Type, 2);14466 const types = try sema.arena.alloc(Type, 2);
14445 const values = try sema.arena.alloc(Value, 2);14467 const values = try sema.arena.alloc(Value, 2);
...@@ -14468,10 +14490,11 @@ fn analyzeArithmetic(...@@ -14468,10 +14490,11 @@ fn analyzeArithmetic(
14468 rhs_src: LazySrcLoc,14490 rhs_src: LazySrcLoc,
14469 want_safety: bool,14491 want_safety: bool,
14470) CompileError!Air.Inst.Ref {14492) CompileError!Air.Inst.Ref {
14493 const mod = sema.mod;
14471 const lhs_ty = sema.typeOf(lhs);14494 const lhs_ty = sema.typeOf(lhs);
14472 const rhs_ty = sema.typeOf(rhs);14495 const rhs_ty = sema.typeOf(rhs);
14473 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();14496 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
14474 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();14497 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
14475 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);14498 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1447614499
14477 if (lhs_zig_ty_tag == .Pointer) switch (lhs_ty.ptrSize()) {14500 if (lhs_zig_ty_tag == .Pointer) switch (lhs_ty.ptrSize()) {
...@@ -14491,18 +14514,17 @@ fn analyzeArithmetic(...@@ -14491,18 +14514,17 @@ fn analyzeArithmetic(
14491 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },14514 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
14492 });14515 });
1449314516
14494 const is_vector = resolved_type.zigTypeTag() == .Vector;14517 const is_vector = resolved_type.zigTypeTag(mod) == .Vector;
1449514518
14496 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);14519 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
14497 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);14520 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
14501 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;14524 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1450214525
14503 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, zir_tag);14526 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, zir_tag);
1450414527
14505 const mod = sema.mod;
14506 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);14528 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
14507 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);14529 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
14508 const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: {14530 const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: {
...@@ -14910,7 +14932,7 @@ fn analyzeArithmetic(...@@ -14910,7 +14932,7 @@ fn analyzeArithmetic(
14910 } },14932 } },
14911 });14933 });
14912 const ov_bit = try sema.tupleFieldValByIndex(block, src, op_ov, 1, op_ov_tuple_ty);14934 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)
14914 try block.addInst(.{14936 try block.addInst(.{
14915 .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce,14937 .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce,
14916 .data = .{ .reduce = .{14938 .data = .{ .reduce = .{
...@@ -14944,12 +14966,12 @@ fn analyzePtrArithmetic(...@@ -14944,12 +14966,12 @@ fn analyzePtrArithmetic(
14944 // TODO if the operand is comptime-known to be negative, or is a negative int,14966 // TODO if the operand is comptime-known to be negative, or is a negative int,
14945 // coerce to isize instead of usize.14967 // coerce to isize instead of usize.
14946 const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src);14968 const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src);
14947 const target = sema.mod.getTarget();14969 const mod = sema.mod;
14948 const opt_ptr_val = try sema.resolveMaybeUndefVal(ptr);14970 const opt_ptr_val = try sema.resolveMaybeUndefVal(ptr);
14949 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);14971 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);
14950 const ptr_ty = sema.typeOf(ptr);14972 const ptr_ty = sema.typeOf(ptr);
14951 const ptr_info = ptr_ty.ptrInfo().data;14973 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)
14953 ptr_info.pointee_type.childType()14975 ptr_info.pointee_type.childType()
14954 else14976 else
14955 ptr_info.pointee_type;14977 ptr_info.pointee_type;
...@@ -14963,9 +14985,9 @@ fn analyzePtrArithmetic(...@@ -14963,9 +14985,9 @@ fn analyzePtrArithmetic(
14963 }14985 }
14964 // If the addend is not a comptime-known value we can still count on14986 // If the addend is not a comptime-known value we can still count on
14965 // it being a multiple of the type size.14987 // it being a multiple of the type size.
14966 const elem_size = elem_ty.abiSize(target);14988 const elem_size = elem_ty.abiSize(mod);
14967 const addend = if (opt_off_val) |off_val| a: {14989 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));
14969 break :a elem_size * off_int;14991 break :a elem_size * off_int;
14970 } else elem_size;14992 } else elem_size;
1497114993
...@@ -14991,10 +15013,10 @@ fn analyzePtrArithmetic(...@@ -14991,10 +15013,10 @@ fn analyzePtrArithmetic(
14991 if (opt_off_val) |offset_val| {15013 if (opt_off_val) |offset_val| {
14992 if (ptr_val.isUndef()) return sema.addConstUndef(new_ptr_ty);15014 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));
14995 if (offset_int == 0) return ptr;15017 if (offset_int == 0) return ptr;
14996 if (try ptr_val.getUnsignedIntAdvanced(target, sema)) |addr| {15018 if (try ptr_val.getUnsignedIntAdvanced(mod, sema)) |addr| {
14997 const elem_size = elem_ty.abiSize(target);15019 const elem_size = elem_ty.abiSize(mod);
14998 const new_addr = switch (air_tag) {15020 const new_addr = switch (air_tag) {
14999 .ptr_add => addr + elem_size * offset_int,15021 .ptr_add => addr + elem_size * offset_int,
15000 .ptr_sub => addr - elem_size * offset_int,15022 .ptr_sub => addr - elem_size * offset_int,
...@@ -15116,6 +15138,7 @@ fn zirAsm(...@@ -15116,6 +15138,7 @@ fn zirAsm(
1511615138
15117 const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);15139 const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);
15118 const inputs = try sema.arena.alloc(ConstraintName, inputs_len);15140 const inputs = try sema.arena.alloc(ConstraintName, inputs_len);
15141 const mod = sema.mod;
1511915142
15120 for (args, 0..) |*arg, arg_i| {15143 for (args, 0..) |*arg, arg_i| {
15121 const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);15144 const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);
...@@ -15123,7 +15146,7 @@ fn zirAsm(...@@ -15123,7 +15146,7 @@ fn zirAsm(
1512315146
15124 const uncasted_arg = try sema.resolveInst(input.data.operand);15147 const uncasted_arg = try sema.resolveInst(input.data.operand);
15125 const uncasted_arg_ty = sema.typeOf(uncasted_arg);15148 const uncasted_arg_ty = sema.typeOf(uncasted_arg);
15126 switch (uncasted_arg_ty.zigTypeTag()) {15149 switch (uncasted_arg_ty.zigTypeTag(mod)) {
15127 .ComptimeInt => arg.* = try sema.coerce(block, Type.initTag(.usize), uncasted_arg, src),15150 .ComptimeInt => arg.* = try sema.coerce(block, Type.initTag(.usize), uncasted_arg, src),
15128 .ComptimeFloat => arg.* = try sema.coerce(block, Type.initTag(.f64), uncasted_arg, src),15151 .ComptimeFloat => arg.* = try sema.coerce(block, Type.initTag(.f64), uncasted_arg, src),
15129 else => {15152 else => {
...@@ -15205,6 +15228,7 @@ fn zirCmpEq(...@@ -15205,6 +15228,7 @@ fn zirCmpEq(
15205 const tracy = trace(@src());15228 const tracy = trace(@src());
15206 defer tracy.end();15229 defer tracy.end();
1520715230
15231 const mod = sema.mod;
15208 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;15232 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
15209 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;15233 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
15210 const src: LazySrcLoc = inst_data.src();15234 const src: LazySrcLoc = inst_data.src();
...@@ -15215,8 +15239,8 @@ fn zirCmpEq(...@@ -15215,8 +15239,8 @@ fn zirCmpEq(
1521515239
15216 const lhs_ty = sema.typeOf(lhs);15240 const lhs_ty = sema.typeOf(lhs);
15217 const rhs_ty = sema.typeOf(rhs);15241 const rhs_ty = sema.typeOf(rhs);
15218 const lhs_ty_tag = lhs_ty.zigTypeTag();15242 const lhs_ty_tag = lhs_ty.zigTypeTag(mod);
15219 const rhs_ty_tag = rhs_ty.zigTypeTag();15243 const rhs_ty_tag = rhs_ty.zigTypeTag(mod);
15220 if (lhs_ty_tag == .Null and rhs_ty_tag == .Null) {15244 if (lhs_ty_tag == .Null and rhs_ty_tag == .Null) {
15221 // null == null, null != null15245 // null == null, null != null
15222 if (op == .eq) {15246 if (op == .eq) {
...@@ -15295,6 +15319,7 @@ fn analyzeCmpUnionTag(...@@ -15295,6 +15319,7 @@ fn analyzeCmpUnionTag(
15295 tag_src: LazySrcLoc,15319 tag_src: LazySrcLoc,
15296 op: std.math.CompareOperator,15320 op: std.math.CompareOperator,
15297) CompileError!Air.Inst.Ref {15321) CompileError!Air.Inst.Ref {
15322 const mod = sema.mod;
15298 const union_ty = try sema.resolveTypeFields(sema.typeOf(un));15323 const union_ty = try sema.resolveTypeFields(sema.typeOf(un));
15299 const union_tag_ty = union_ty.unionTagType() orelse {15324 const union_tag_ty = union_ty.unionTagType() orelse {
15300 const msg = msg: {15325 const msg = msg: {
...@@ -15313,7 +15338,7 @@ fn analyzeCmpUnionTag(...@@ -15313,7 +15338,7 @@ fn analyzeCmpUnionTag(
15313 if (try sema.resolveMaybeUndefVal(coerced_tag)) |enum_val| {15338 if (try sema.resolveMaybeUndefVal(coerced_tag)) |enum_val| {
15314 if (enum_val.isUndef()) return sema.addConstUndef(Type.bool);15339 if (enum_val.isUndef()) return sema.addConstUndef(Type.bool);
15315 const field_ty = union_ty.unionFieldType(enum_val, sema.mod);15340 const field_ty = union_ty.unionFieldType(enum_val, sema.mod);
15316 if (field_ty.zigTypeTag() == .NoReturn) {15341 if (field_ty.zigTypeTag(mod) == .NoReturn) {
15317 return Air.Inst.Ref.bool_false;15342 return Air.Inst.Ref.bool_false;
15318 }15343 }
15319 }15344 }
...@@ -15352,32 +15377,33 @@ fn analyzeCmp(...@@ -15352,32 +15377,33 @@ fn analyzeCmp(
15352 rhs_src: LazySrcLoc,15377 rhs_src: LazySrcLoc,
15353 is_equality_cmp: bool,15378 is_equality_cmp: bool,
15354) CompileError!Air.Inst.Ref {15379) CompileError!Air.Inst.Ref {
15380 const mod = sema.mod;
15355 const lhs_ty = sema.typeOf(lhs);15381 const lhs_ty = sema.typeOf(lhs);
15356 const rhs_ty = sema.typeOf(rhs);15382 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) {
15358 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);15384 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
15359 }15385 }
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) {
15362 return sema.cmpVector(block, src, lhs, rhs, op, lhs_src, rhs_src);15388 return sema.cmpVector(block, src, lhs, rhs, op, lhs_src, rhs_src);
15363 }15389 }
15364 if (lhs_ty.isNumeric() and rhs_ty.isNumeric()) {15390 if (lhs_ty.isNumeric(mod) and rhs_ty.isNumeric(mod)) {
15365 // This operation allows any combination of integer and float types, regardless of the15391 // This operation allows any combination of integer and float types, regardless of the
15366 // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for15392 // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for
15367 // numeric types.15393 // numeric types.
15368 return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src);15394 return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src);
15369 }15395 }
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) {
15371 const casted_lhs = try sema.analyzeErrUnionCode(block, lhs_src, lhs);15397 const casted_lhs = try sema.analyzeErrUnionCode(block, lhs_src, lhs);
15372 return sema.cmpSelf(block, src, casted_lhs, rhs, op, lhs_src, rhs_src);15398 return sema.cmpSelf(block, src, casted_lhs, rhs, op, lhs_src, rhs_src);
15373 }15399 }
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) {
15375 const casted_rhs = try sema.analyzeErrUnionCode(block, rhs_src, rhs);15401 const casted_rhs = try sema.analyzeErrUnionCode(block, rhs_src, rhs);
15376 return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src);15402 return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src);
15377 }15403 }
15378 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };15404 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
15379 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } });15405 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)) {
15381 return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{15407 return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{
15382 compareOperatorName(op), resolved_type.fmt(sema.mod),15408 compareOperatorName(op), resolved_type.fmt(sema.mod),
15383 });15409 });
...@@ -15408,6 +15434,7 @@ fn cmpSelf(...@@ -15408,6 +15434,7 @@ fn cmpSelf(
15408 lhs_src: LazySrcLoc,15434 lhs_src: LazySrcLoc,
15409 rhs_src: LazySrcLoc,15435 rhs_src: LazySrcLoc,
15410) CompileError!Air.Inst.Ref {15436) CompileError!Air.Inst.Ref {
15437 const mod = sema.mod;
15411 const resolved_type = sema.typeOf(casted_lhs);15438 const resolved_type = sema.typeOf(casted_lhs);
15412 const runtime_src: LazySrcLoc = src: {15439 const runtime_src: LazySrcLoc = src: {
15413 if (try sema.resolveMaybeUndefVal(casted_lhs)) |lhs_val| {15440 if (try sema.resolveMaybeUndefVal(casted_lhs)) |lhs_val| {
...@@ -15415,7 +15442,7 @@ fn cmpSelf(...@@ -15415,7 +15442,7 @@ fn cmpSelf(
15415 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {15442 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {
15416 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);15443 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);
1541715444
15418 if (resolved_type.zigTypeTag() == .Vector) {15445 if (resolved_type.zigTypeTag(mod) == .Vector) {
15419 const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.bool);15446 const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.bool);
15420 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_type);15447 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_type);
15421 return sema.addConstant(result_ty, cmp_val);15448 return sema.addConstant(result_ty, cmp_val);
...@@ -15427,7 +15454,7 @@ fn cmpSelf(...@@ -15427,7 +15454,7 @@ fn cmpSelf(
15427 return Air.Inst.Ref.bool_false;15454 return Air.Inst.Ref.bool_false;
15428 }15455 }
15429 } else {15456 } else {
15430 if (resolved_type.zigTypeTag() == .Bool) {15457 if (resolved_type.zigTypeTag(mod) == .Bool) {
15431 // We can lower bool eq/neq more efficiently.15458 // We can lower bool eq/neq more efficiently.
15432 return sema.runtimeBoolCmp(block, src, op, casted_rhs, lhs_val.toBool(), rhs_src);15459 return sema.runtimeBoolCmp(block, src, op, casted_rhs, lhs_val.toBool(), rhs_src);
15433 }15460 }
...@@ -15436,7 +15463,7 @@ fn cmpSelf(...@@ -15436,7 +15463,7 @@ fn cmpSelf(
15436 } else {15463 } else {
15437 // For bools, we still check the other operand, because we can lower15464 // For bools, we still check the other operand, because we can lower
15438 // bool eq/neq more efficiently.15465 // bool eq/neq more efficiently.
15439 if (resolved_type.zigTypeTag() == .Bool) {15466 if (resolved_type.zigTypeTag(mod) == .Bool) {
15440 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {15467 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {
15441 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);15468 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);
15442 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src);15469 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src);
...@@ -15446,7 +15473,7 @@ fn cmpSelf(...@@ -15446,7 +15473,7 @@ fn cmpSelf(
15446 }15473 }
15447 };15474 };
15448 try sema.requireRuntimeBlock(block, src, runtime_src);15475 try sema.requireRuntimeBlock(block, src, runtime_src);
15449 if (resolved_type.zigTypeTag() == .Vector) {15476 if (resolved_type.zigTypeTag(mod) == .Vector) {
15450 return block.addCmpVector(casted_lhs, casted_rhs, op);15477 return block.addCmpVector(casted_lhs, casted_rhs, op);
15451 }15478 }
15452 const tag = Air.Inst.Tag.fromCmpOp(op, block.float_mode == .Optimized);15479 const tag = Air.Inst.Tag.fromCmpOp(op, block.float_mode == .Optimized);
...@@ -15475,10 +15502,11 @@ fn runtimeBoolCmp(...@@ -15475,10 +15502,11 @@ fn runtimeBoolCmp(
15475}15502}
1547615503
15477fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15504fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15505 const mod = sema.mod;
15478 const inst_data = sema.code.instructions.items(.data)[inst].un_node;15506 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
15479 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };15507 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
15480 const ty = try sema.resolveType(block, operand_src, inst_data.operand);15508 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
15481 switch (ty.zigTypeTag()) {15509 switch (ty.zigTypeTag(mod)) {
15482 .Fn,15510 .Fn,
15483 .NoReturn,15511 .NoReturn,
15484 .Undefined,15512 .Undefined,
...@@ -15509,8 +15537,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15509,8 +15537,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15509 .AnyFrame,15537 .AnyFrame,
15510 => {},15538 => {},
15511 }15539 }
15512 const target = sema.mod.getTarget();15540 const val = try ty.lazyAbiSize(mod, sema.arena);
15513 const val = try ty.lazyAbiSize(target, sema.arena);
15514 if (val.tag() == .lazy_size) {15541 if (val.tag() == .lazy_size) {
15515 try sema.queueFullTypeResolution(ty);15542 try sema.queueFullTypeResolution(ty);
15516 }15543 }
...@@ -15518,10 +15545,11 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15518,10 +15545,11 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15518}15545}
1551915546
15520fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15547fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15548 const mod = sema.mod;
15521 const inst_data = sema.code.instructions.items(.data)[inst].un_node;15549 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
15522 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };15550 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
15523 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);15551 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
15524 switch (operand_ty.zigTypeTag()) {15552 switch (operand_ty.zigTypeTag(mod)) {
15525 .Fn,15553 .Fn,
15526 .NoReturn,15554 .NoReturn,
15527 .Undefined,15555 .Undefined,
...@@ -15552,8 +15580,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -15552,8 +15580,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
15552 .AnyFrame,15580 .AnyFrame,
15553 => {},15581 => {},
15554 }15582 }
15555 const target = sema.mod.getTarget();15583 const bit_size = try operand_ty.bitSizeAdvanced(mod, sema);
15556 const bit_size = try operand_ty.bitSizeAdvanced(target, sema);
15557 return sema.addIntUnsigned(Type.comptime_int, bit_size);15584 return sema.addIntUnsigned(Type.comptime_int, bit_size);
15558}15585}
1555915586
...@@ -15765,13 +15792,13 @@ fn zirBuiltinSrc(...@@ -15765,13 +15792,13 @@ fn zirBuiltinSrc(
15765}15792}
1576615793
15767fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15794fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15795 const mod = sema.mod;
15768 const inst_data = sema.code.instructions.items(.data)[inst].un_node;15796 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
15769 const src = inst_data.src();15797 const src = inst_data.src();
15770 const ty = try sema.resolveType(block, src, inst_data.operand);15798 const ty = try sema.resolveType(block, src, inst_data.operand);
15771 const type_info_ty = try sema.getBuiltinType("Type");15799 const type_info_ty = try sema.getBuiltinType("Type");
15772 const target = sema.mod.getTarget();
1577315800
15774 switch (ty.zigTypeTag()) {15801 switch (ty.zigTypeTag(mod)) {
15775 .Type => return sema.addConstant(15802 .Type => return sema.addConstant(
15776 type_info_ty,15803 type_info_ty,
15777 try Value.Tag.@"union".create(sema.arena, .{15804 try Value.Tag.@"union".create(sema.arena, .{
...@@ -15881,8 +15908,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15881,8 +15908,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15881 try sema.mod.declareDeclDependency(sema.owner_decl_index, fn_info_decl_index);15908 try sema.mod.declareDeclDependency(sema.owner_decl_index, fn_info_decl_index);
15882 try sema.ensureDeclAnalyzed(fn_info_decl_index);15909 try sema.ensureDeclAnalyzed(fn_info_decl_index);
15883 const fn_info_decl = sema.mod.declPtr(fn_info_decl_index);15910 const fn_info_decl = sema.mod.declPtr(fn_info_decl_index);
15884 var fn_ty_buffer: Value.ToTypeBuffer = undefined;15911 const fn_ty = fn_info_decl.val.toType();
15885 const fn_ty = fn_info_decl.val.toType(&fn_ty_buffer);
15886 const param_info_decl_index = (try sema.namespaceLookup(15912 const param_info_decl_index = (try sema.namespaceLookup(
15887 block,15913 block,
15888 src,15914 src,
...@@ -15892,8 +15918,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15892,8 +15918,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15892 try sema.mod.declareDeclDependency(sema.owner_decl_index, param_info_decl_index);15918 try sema.mod.declareDeclDependency(sema.owner_decl_index, param_info_decl_index);
15893 try sema.ensureDeclAnalyzed(param_info_decl_index);15919 try sema.ensureDeclAnalyzed(param_info_decl_index);
15894 const param_info_decl = sema.mod.declPtr(param_info_decl_index);15920 const param_info_decl = sema.mod.declPtr(param_info_decl_index);
15895 var param_buffer: Value.ToTypeBuffer = undefined;15921 const param_ty = param_info_decl.val.toType();
15896 const param_ty = param_info_decl.val.toType(&param_buffer);
15897 const new_decl = try params_anon_decl.finish(15922 const new_decl = try params_anon_decl.finish(
15898 try Type.Tag.array.create(params_anon_decl.arena(), .{15923 try Type.Tag.array.create(params_anon_decl.arena(), .{
15899 .len = param_vals.len,15924 .len = param_vals.len,
...@@ -15924,7 +15949,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15924,7 +15949,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15924 // calling_convention: CallingConvention,15949 // calling_convention: CallingConvention,
15925 try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.cc)),15950 try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.cc)),
15926 // alignment: comptime_int,15951 // 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)),
15928 // is_generic: bool,15953 // is_generic: bool,
15929 Value.makeBool(info.is_generic),15954 Value.makeBool(info.is_generic),
15930 // is_var_args: bool,15955 // is_var_args: bool,
...@@ -15944,7 +15969,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15944,7 +15969,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15944 );15969 );
15945 },15970 },
15946 .Int => {15971 .Int => {
15947 const info = ty.intInfo(target);15972 const info = ty.intInfo(mod);
15948 const field_values = try sema.arena.alloc(Value, 2);15973 const field_values = try sema.arena.alloc(Value, 2);
15949 // signedness: Signedness,15974 // signedness: Signedness,
15950 field_values[0] = try Value.Tag.enum_field_index.create(15975 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...@@ -15965,7 +15990,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15965 .Float => {15990 .Float => {
15966 const field_values = try sema.arena.alloc(Value, 1);15991 const field_values = try sema.arena.alloc(Value, 1);
15967 // bits: comptime_int,15992 // 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
15970 return sema.addConstant(15995 return sema.addConstant(
15971 type_info_ty,15996 type_info_ty,
...@@ -15980,7 +16005,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15980,7 +16005,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15980 const alignment = if (info.@"align" != 0)16005 const alignment = if (info.@"align" != 0)
15981 try Value.Tag.int_u64.create(sema.arena, info.@"align")16006 try Value.Tag.int_u64.create(sema.arena, info.@"align")
15982 else16007 else
15983 try info.pointee_type.lazyAbiAlignment(target, sema.arena);16008 try info.pointee_type.lazyAbiAlignment(mod, sema.arena);
1598416009
15985 const field_values = try sema.arena.create([8]Value);16010 const field_values = try sema.arena.create([8]Value);
15986 field_values.* = .{16011 field_values.* = .{
...@@ -16072,8 +16097,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16072,8 +16097,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16072 try sema.mod.declareDeclDependency(sema.owner_decl_index, set_field_ty_decl_index);16097 try sema.mod.declareDeclDependency(sema.owner_decl_index, set_field_ty_decl_index);
16073 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);16098 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);
16074 const set_field_ty_decl = sema.mod.declPtr(set_field_ty_decl_index);16099 const set_field_ty_decl = sema.mod.declPtr(set_field_ty_decl_index);
16075 var buffer: Value.ToTypeBuffer = undefined;16100 break :t try set_field_ty_decl.val.toType().copy(fields_anon_decl.arena());
16076 break :t try set_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
16077 };16101 };
1607816102
16079 try sema.queueFullTypeResolution(try error_field_ty.copy(sema.arena));16103 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...@@ -16164,8 +16188,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16164 },16188 },
16165 .Enum => {16189 .Enum => {
16166 // TODO: look into memoizing this result.16190 // TODO: look into memoizing this result.
16167 var int_tag_type_buffer: Type.Payload.Bits = undefined;16191 const int_tag_ty = try ty.intTagType().copy(sema.arena);
16168 const int_tag_ty = try ty.intTagType(&int_tag_type_buffer).copy(sema.arena);
1616916192
16170 const is_exhaustive = Value.makeBool(!ty.isNonexhaustiveEnum());16193 const is_exhaustive = Value.makeBool(!ty.isNonexhaustiveEnum());
1617116194
...@@ -16182,8 +16205,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16182,8 +16205,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16182 try sema.mod.declareDeclDependency(sema.owner_decl_index, enum_field_ty_decl_index);16205 try sema.mod.declareDeclDependency(sema.owner_decl_index, enum_field_ty_decl_index);
16183 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);16206 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);
16184 const enum_field_ty_decl = sema.mod.declPtr(enum_field_ty_decl_index);16207 const enum_field_ty_decl = sema.mod.declPtr(enum_field_ty_decl_index);
16185 var buffer: Value.ToTypeBuffer = undefined;16208 break :t try enum_field_ty_decl.val.toType().copy(fields_anon_decl.arena());
16186 break :t try enum_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
16187 };16209 };
1618816210
16189 const enum_fields = ty.enumFields();16211 const enum_fields = ty.enumFields();
...@@ -16275,8 +16297,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16275,8 +16297,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16275 try sema.mod.declareDeclDependency(sema.owner_decl_index, union_field_ty_decl_index);16297 try sema.mod.declareDeclDependency(sema.owner_decl_index, union_field_ty_decl_index);
16276 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);16298 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);
16277 const union_field_ty_decl = sema.mod.declPtr(union_field_ty_decl_index);16299 const union_field_ty_decl = sema.mod.declPtr(union_field_ty_decl_index);
16278 var buffer: Value.ToTypeBuffer = undefined;16300 break :t try union_field_ty_decl.val.toType().copy(fields_anon_decl.arena());
16279 break :t try union_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
16280 };16301 };
1628116302
16282 const union_ty = try sema.resolveTypeFields(ty);16303 const union_ty = try sema.resolveTypeFields(ty);
...@@ -16383,8 +16404,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16383,8 +16404,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16383 try sema.mod.declareDeclDependency(sema.owner_decl_index, struct_field_ty_decl_index);16404 try sema.mod.declareDeclDependency(sema.owner_decl_index, struct_field_ty_decl_index);
16384 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);16405 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);
16385 const struct_field_ty_decl = sema.mod.declPtr(struct_field_ty_decl_index);16406 const struct_field_ty_decl = sema.mod.declPtr(struct_field_ty_decl_index);
16386 var buffer: Value.ToTypeBuffer = undefined;16407 break :t try struct_field_ty_decl.val.toType().copy(fields_anon_decl.arena());
16387 break :t try struct_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
16388 };16408 };
16389 const struct_ty = try sema.resolveTypeFields(ty);16409 const struct_ty = try sema.resolveTypeFields(ty);
16390 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout16410 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...@@ -16430,7 +16450,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16430 // is_comptime: bool,16450 // is_comptime: bool,
16431 Value.makeBool(is_comptime),16451 Value.makeBool(is_comptime),
16432 // alignment: comptime_int,16452 // alignment: comptime_int,
16433 try field_ty.lazyAbiAlignment(target, fields_anon_decl.arena()),16453 try field_ty.lazyAbiAlignment(mod, fields_anon_decl.arena()),
16434 };16454 };
16435 struct_field_val.* = try Value.Tag.aggregate.create(fields_anon_decl.arena(), struct_field_fields);16455 struct_field_val.* = try Value.Tag.aggregate.create(fields_anon_decl.arena(), struct_field_fields);
16436 }16456 }
...@@ -16463,7 +16483,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16463,7 +16483,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16463 else16483 else
16464 field.default_val;16484 field.default_val;
16465 const default_val_ptr = try sema.optRefValue(block, field.ty, opt_default_val);16485 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
16468 struct_field_fields.* = .{16488 struct_field_fields.* = .{
16469 // name: []const u8,16489 // name: []const u8,
...@@ -16506,7 +16526,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16506,7 +16526,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16506 if (layout == .Packed) {16526 if (layout == .Packed) {
16507 const struct_obj = struct_ty.castTag(.@"struct").?.data;16527 const struct_obj = struct_ty.castTag(.@"struct").?.data;
16508 assert(struct_obj.haveLayout());16528 assert(struct_obj.haveLayout());
16509 assert(struct_obj.backing_int_ty.isInt());16529 assert(struct_obj.backing_int_ty.isInt(mod));
16510 const backing_int_ty_val = try Value.Tag.ty.create(sema.arena, struct_obj.backing_int_ty);16530 const backing_int_ty_val = try Value.Tag.ty.create(sema.arena, struct_obj.backing_int_ty);
16511 break :blk try Value.Tag.opt_payload.create(sema.arena, backing_int_ty_val);16531 break :blk try Value.Tag.opt_payload.create(sema.arena, backing_int_ty_val);
16512 } else {16532 } else {
...@@ -16584,8 +16604,7 @@ fn typeInfoDecls(...@@ -16584,8 +16604,7 @@ fn typeInfoDecls(
16584 try sema.mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);16604 try sema.mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);
16585 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);16605 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);
16586 const declaration_ty_decl = sema.mod.declPtr(declaration_ty_decl_index);16606 const declaration_ty_decl = sema.mod.declPtr(declaration_ty_decl_index);
16587 var buffer: Value.ToTypeBuffer = undefined;16607 break :t try declaration_ty_decl.val.toType().copy(decls_anon_decl.arena());
16588 break :t try declaration_ty_decl.val.toType(&buffer).copy(decls_anon_decl.arena());
16589 };16608 };
16590 try sema.queueFullTypeResolution(try declaration_ty.copy(sema.arena));16609 try sema.queueFullTypeResolution(try declaration_ty.copy(sema.arena));
1659116610
...@@ -16632,8 +16651,7 @@ fn typeInfoNamespaceDecls(...@@ -16632,8 +16651,7 @@ fn typeInfoNamespaceDecls(
16632 if (decl.kind == .@"usingnamespace") {16651 if (decl.kind == .@"usingnamespace") {
16633 if (decl.analysis == .in_progress) continue;16652 if (decl.analysis == .in_progress) continue;
16634 try sema.mod.ensureDeclAnalyzed(decl_index);16653 try sema.mod.ensureDeclAnalyzed(decl_index);
16635 var buf: Value.ToTypeBuffer = undefined;16654 const new_ns = decl.val.toType().getNamespace().?;
16636 const new_ns = decl.val.toType(&buf).getNamespace().?;
16637 try sema.typeInfoNamespaceDecls(block, decls_anon_decl, new_ns, decl_vals, seen_namespaces);16655 try sema.typeInfoNamespaceDecls(block, decls_anon_decl, new_ns, decl_vals, seen_namespaces);
16638 continue;16656 continue;
16639 }16657 }
...@@ -16709,10 +16727,11 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -16709,10 +16727,11 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
16709}16727}
1671016728
16711fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type {16729fn 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)) {
16713 .ComptimeInt => return Type.comptime_int,16732 .ComptimeInt => return Type.comptime_int,
16714 .Int => {16733 .Int => {
16715 const bits = operand.bitSize(sema.mod.getTarget());16734 const bits = operand.bitSize(mod);
16716 const count = if (bits == 0)16735 const count = if (bits == 0)
16717 016736 0
16718 else blk: {16737 else blk: {
...@@ -16723,10 +16742,10 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi...@@ -16723,10 +16742,10 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
16723 }16742 }
16724 break :blk count;16743 break :blk count;
16725 };16744 };
16726 return Module.makeIntType(sema.arena, .unsigned, count);16745 return mod.intType(.unsigned, count);
16727 },16746 },
16728 .Vector => {16747 .Vector => {
16729 const elem_ty = operand.elemType2();16748 const elem_ty = operand.elemType2(mod);
16730 const log2_elem_ty = try sema.log2IntType(block, elem_ty, src);16749 const log2_elem_ty = try sema.log2IntType(block, elem_ty, src);
16731 return Type.Tag.vector.create(sema.arena, .{16750 return Type.Tag.vector.create(sema.arena, .{
16732 .len = operand.vectorLen(),16751 .len = operand.vectorLen(),
...@@ -16920,9 +16939,10 @@ fn finishCondBr(...@@ -16920,9 +16939,10 @@ fn finishCondBr(
16920}16939}
1692116940
16922fn checkNullableType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {16941fn checkNullableType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
16923 switch (ty.zigTypeTag()) {16942 const mod = sema.mod;
16943 switch (ty.zigTypeTag(mod)) {
16924 .Optional, .Null, .Undefined => return,16944 .Optional, .Null, .Undefined => return,
16925 .Pointer => if (ty.isPtrLikeOptional()) return,16945 .Pointer => if (ty.isPtrLikeOptional(mod)) return,
16926 else => {},16946 else => {},
16927 }16947 }
16928 return sema.failWithExpectedOptionalType(block, src, ty);16948 return sema.failWithExpectedOptionalType(block, src, ty);
...@@ -16951,10 +16971,11 @@ fn zirIsNonNullPtr(...@@ -16951,10 +16971,11 @@ fn zirIsNonNullPtr(
16951 const tracy = trace(@src());16971 const tracy = trace(@src());
16952 defer tracy.end();16972 defer tracy.end();
1695316973
16974 const mod = sema.mod;
16954 const inst_data = sema.code.instructions.items(.data)[inst].un_node;16975 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
16955 const src = inst_data.src();16976 const src = inst_data.src();
16956 const ptr = try sema.resolveInst(inst_data.operand);16977 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));
16958 if ((try sema.resolveMaybeUndefVal(ptr)) == null) {16979 if ((try sema.resolveMaybeUndefVal(ptr)) == null) {
16959 return block.addUnOp(.is_non_null_ptr, ptr);16980 return block.addUnOp(.is_non_null_ptr, ptr);
16960 }16981 }
...@@ -16963,7 +16984,8 @@ fn zirIsNonNullPtr(...@@ -16963,7 +16984,8 @@ fn zirIsNonNullPtr(
16963}16984}
1696416985
16965fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {16986fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
16966 switch (ty.zigTypeTag()) {16987 const mod = sema.mod;
16988 switch (ty.zigTypeTag(mod)) {
16967 .ErrorSet, .ErrorUnion, .Undefined => return,16989 .ErrorSet, .ErrorUnion, .Undefined => return,
16968 else => return sema.fail(block, src, "expected error union type, found '{}'", .{16990 else => return sema.fail(block, src, "expected error union type, found '{}'", .{
16969 ty.fmt(sema.mod),16991 ty.fmt(sema.mod),
...@@ -16986,10 +17008,11 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -16986,10 +17008,11 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
16986 const tracy = trace(@src());17008 const tracy = trace(@src());
16987 defer tracy.end();17009 defer tracy.end();
1698817010
17011 const mod = sema.mod;
16989 const inst_data = sema.code.instructions.items(.data)[inst].un_node;17012 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
16990 const src = inst_data.src();17013 const src = inst_data.src();
16991 const ptr = try sema.resolveInst(inst_data.operand);17014 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));
16993 const loaded = try sema.analyzeLoad(block, src, ptr, src);17016 const loaded = try sema.analyzeLoad(block, src, ptr, src);
16994 return sema.analyzeIsNonErr(block, src, loaded);17017 return sema.analyzeIsNonErr(block, src, loaded);
16995}17018}
...@@ -17012,6 +17035,7 @@ fn zirCondbr(...@@ -17012,6 +17035,7 @@ fn zirCondbr(
17012 const tracy = trace(@src());17035 const tracy = trace(@src());
17013 defer tracy.end();17036 defer tracy.end();
1701417037
17038 const mod = sema.mod;
17015 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;17039 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
17016 const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };17040 const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
17017 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);17041 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
...@@ -17052,7 +17076,7 @@ fn zirCondbr(...@@ -17052,7 +17076,7 @@ fn zirCondbr(
17052 const err_inst_data = sema.code.instructions.items(.data)[index].un_node;17076 const err_inst_data = sema.code.instructions.items(.data)[index].un_node;
17053 const err_operand = try sema.resolveInst(err_inst_data.operand);17077 const err_operand = try sema.resolveInst(err_inst_data.operand);
17054 const operand_ty = sema.typeOf(err_operand);17078 const operand_ty = sema.typeOf(err_operand);
17055 assert(operand_ty.zigTypeTag() == .ErrorUnion);17079 assert(operand_ty.zigTypeTag(mod) == .ErrorUnion);
17056 const result_ty = operand_ty.errorUnionSet();17080 const result_ty = operand_ty.errorUnionSet();
17057 break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand);17081 break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand);
17058 };17082 };
...@@ -17079,7 +17103,7 @@ fn zirCondbr(...@@ -17079,7 +17103,7 @@ fn zirCondbr(
17079 return always_noreturn;17103 return always_noreturn;
17080}17104}
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 {
17083 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;17107 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
17084 const src = inst_data.src();17108 const src = inst_data.src();
17085 const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };17109 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!...@@ -17087,7 +17111,8 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
17087 const body = sema.code.extra[extra.end..][0..extra.data.body_len];17111 const body = sema.code.extra[extra.end..][0..extra.data.body_len];
17088 const err_union = try sema.resolveInst(extra.data.operand);17112 const err_union = try sema.resolveInst(extra.data.operand);
17089 const err_union_ty = sema.typeOf(err_union);17113 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) {
17091 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{17116 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{
17092 err_union_ty.fmt(sema.mod),17117 err_union_ty.fmt(sema.mod),
17093 });17118 });
...@@ -17124,7 +17149,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -17124,7 +17149,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
17124 return try_inst;17149 return try_inst;
17125}17150}
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 {
17128 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;17153 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
17129 const src = inst_data.src();17154 const src = inst_data.src();
17130 const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };17155 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...@@ -17133,7 +17158,8 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
17133 const operand = try sema.resolveInst(extra.data.operand);17158 const operand = try sema.resolveInst(extra.data.operand);
17134 const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src);17159 const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src);
17135 const err_union_ty = sema.typeOf(err_union);17160 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) {
17137 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{17163 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{
17138 err_union_ty.fmt(sema.mod),17164 err_union_ty.fmt(sema.mod),
17139 });17165 });
...@@ -17275,16 +17301,17 @@ fn zirRetImplicit(...@@ -17275,16 +17301,17 @@ fn zirRetImplicit(
17275 const tracy = trace(@src());17301 const tracy = trace(@src());
17276 defer tracy.end();17302 defer tracy.end();
1727717303
17304 const mod = sema.mod;
17278 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;17305 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
17279 const operand = try sema.resolveInst(inst_data.operand);17306 const operand = try sema.resolveInst(inst_data.operand);
1728017307
17281 const r_brace_src = inst_data.src();17308 const r_brace_src = inst_data.src();
17282 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };17309 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);
17284 if (base_tag == .NoReturn) {17311 if (base_tag == .NoReturn) {
17285 const msg = msg: {17312 const msg = msg: {
17286 const msg = try sema.errMsg(block, ret_ty_src, "function declared '{}' implicitly returns", .{17313 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),
17288 });17315 });
17289 errdefer msg.destroy(sema.gpa);17316 errdefer msg.destroy(sema.gpa);
17290 try sema.errNote(block, r_brace_src, msg, "control flow reaches end of body here", .{});17317 try sema.errNote(block, r_brace_src, msg, "control flow reaches end of body here", .{});
...@@ -17294,7 +17321,7 @@ fn zirRetImplicit(...@@ -17294,7 +17321,7 @@ fn zirRetImplicit(
17294 } else if (base_tag != .Void) {17321 } else if (base_tag != .Void) {
17295 const msg = msg: {17322 const msg = msg: {
17296 const msg = try sema.errMsg(block, ret_ty_src, "function with non-void return type '{}' implicitly returns", .{17323 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),
17298 });17325 });
17299 errdefer msg.destroy(sema.gpa);17326 errdefer msg.destroy(sema.gpa);
17300 try sema.errNote(block, r_brace_src, msg, "control flow reaches end of body here", .{});17327 try sema.errNote(block, r_brace_src, msg, "control flow reaches end of body here", .{});
...@@ -17397,17 +17424,19 @@ fn retWithErrTracing(...@@ -17397,17 +17424,19 @@ fn retWithErrTracing(
17397}17424}
1739817425
17399fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {17426fn 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() and17430 return fn_ret_ty.isError(mod) and
17403 sema.mod.comp.bin_file.options.error_return_tracing;17431 mod.comp.bin_file.options.error_return_tracing;
17404}17432}
1740517433
17406fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {17434fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
17435 const mod = sema.mod;
17407 const inst_data = sema.code.instructions.items(.data)[inst].save_err_ret_index;17436 const inst_data = sema.code.instructions.items(.data)[inst].save_err_ret_index;
1740817437
17409 if (!sema.mod.backendSupportsFeature(.error_return_trace)) return;17438 if (!mod.backendSupportsFeature(.error_return_trace)) return;
17410 if (!sema.mod.comp.bin_file.options.error_return_tracing) return;17439 if (!mod.comp.bin_file.options.error_return_tracing) return;
1741117440
17412 // This is only relevant at runtime.17441 // This is only relevant at runtime.
17413 if (block.is_comptime or block.is_typeof) return;17442 if (block.is_comptime or block.is_typeof) return;
...@@ -17415,7 +17444,7 @@ fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -17415,7 +17444,7 @@ fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
17415 const save_index = inst_data.operand == .none or b: {17444 const save_index = inst_data.operand == .none or b: {
17416 const operand = try sema.resolveInst(inst_data.operand);17445 const operand = try sema.resolveInst(inst_data.operand);
17417 const operand_ty = sema.typeOf(operand);17446 const operand_ty = sema.typeOf(operand);
17418 break :b operand_ty.isError();17447 break :b operand_ty.isError(mod);
17419 };17448 };
1742017449
17421 if (save_index)17450 if (save_index)
...@@ -17467,11 +17496,12 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index)...@@ -17467,11 +17496,12 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index)
17467}17496}
1746817497
17469fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {17498fn 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
17472 if (sema.fn_ret_ty.errorUnionSet().castTag(.error_set_inferred)) |payload| {17502 if (sema.fn_ret_ty.errorUnionSet().castTag(.error_set_inferred)) |payload| {
17473 const op_ty = sema.typeOf(uncasted_operand);17503 const op_ty = sema.typeOf(uncasted_operand);
17474 switch (op_ty.zigTypeTag()) {17504 switch (op_ty.zigTypeTag(mod)) {
17475 .ErrorSet => {17505 .ErrorSet => {
17476 try payload.data.addErrorSet(sema.gpa, op_ty);17506 try payload.data.addErrorSet(sema.gpa, op_ty);
17477 },17507 },
...@@ -17492,7 +17522,8 @@ fn analyzeRet(...@@ -17492,7 +17522,8 @@ fn analyzeRet(
17492 // Special case for returning an error to an inferred error set; we need to17522 // Special case for returning an error to an inferred error set; we need to
17493 // add the error tag to the inferred error set of the in-scope function, so17523 // add the error tag to the inferred error set of the in-scope function, so
17494 // that the coercion below works correctly.17524 // 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) {
17496 try sema.addToInferredErrorSet(uncasted_operand);17527 try sema.addToInferredErrorSet(uncasted_operand);
17497 }17528 }
17498 const operand = sema.coerceExtra(block, sema.fn_ret_ty, uncasted_operand, src, .{ .is_ret = true }) catch |err| switch (err) {17529 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...@@ -17540,6 +17571,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17540 const tracy = trace(@src());17571 const tracy = trace(@src());
17541 defer tracy.end();17572 defer tracy.end();
1754217573
17574 const mod = sema.mod;
17543 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;17575 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;
17544 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);17576 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);
17545 const elem_ty_src: LazySrcLoc = .{ .node_offset_ptr_elem = extra.data.src_node };17577 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...@@ -17582,7 +17614,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17582 break :blk 0;17614 break :blk 0;
17583 }17615 }
17584 }17616 }
17585 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(target, sema)).?);17617 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?);
17586 try sema.validateAlign(block, align_src, abi_align);17618 try sema.validateAlign(block, align_src, abi_align);
17587 break :blk abi_align;17619 break :blk abi_align;
17588 } else 0;17620 } else 0;
...@@ -17591,7 +17623,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -17591,7 +17623,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17591 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);17623 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
17592 extra_i += 1;17624 extra_i += 1;
17593 break :blk try sema.analyzeAddressSpace(block, addrspace_src, ref, .pointer);17625 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
17596 const bit_offset = if (inst_data.flags.has_bit_range) blk: {17628 const bit_offset = if (inst_data.flags.has_bit_range) blk: {
17597 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);17629 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...@@ -17611,9 +17643,9 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17611 return sema.fail(block, bitoffset_src, "bit offset starts after end of host integer", .{});17643 return sema.fail(block, bitoffset_src, "bit offset starts after end of host integer", .{});
17612 }17644 }
1761317645
17614 if (elem_ty.zigTypeTag() == .NoReturn) {17646 if (elem_ty.zigTypeTag(mod) == .NoReturn) {
17615 return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{});17647 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) {
17617 if (inst_data.size != .One) {17649 if (inst_data.size != .One) {
17618 return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{});17650 return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{});
17619 }17651 }
...@@ -17623,7 +17655,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -17623,7 +17655,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17623 {17655 {
17624 return sema.fail(block, align_src, "function pointer alignment disagrees with function alignment", .{});17656 return sema.fail(block, align_src, "function pointer alignment disagrees with function alignment", .{});
17625 }17657 }
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) {
17627 return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{});17659 return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{});
17628 } else if (inst_data.size == .C) {17660 } else if (inst_data.size == .C) {
17629 if (!try sema.validateExternType(elem_ty, .other)) {17661 if (!try sema.validateExternType(elem_ty, .other)) {
...@@ -17639,7 +17671,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -17639,7 +17671,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17639 };17671 };
17640 return sema.failWithOwnedErrorMsg(msg);17672 return sema.failWithOwnedErrorMsg(msg);
17641 }17673 }
17642 if (elem_ty.zigTypeTag() == .Opaque) {17674 if (elem_ty.zigTypeTag(mod) == .Opaque) {
17643 return sema.fail(block, elem_ty_src, "C pointers cannot point to opaque types", .{});17675 return sema.fail(block, elem_ty_src, "C pointers cannot point to opaque types", .{});
17644 }17676 }
17645 }17677 }
...@@ -17666,8 +17698,9 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -17666,8 +17698,9 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
17666 const inst_data = sema.code.instructions.items(.data)[inst].un_node;17698 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
17667 const src = inst_data.src();17699 const src = inst_data.src();
17668 const obj_ty = try sema.resolveType(block, src, inst_data.operand);17700 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)) {
17671 .Struct => return sema.structInitEmpty(block, obj_ty, src, src),17704 .Struct => return sema.structInitEmpty(block, obj_ty, src, src),
17672 .Array, .Vector => return sema.arrayInitEmpty(block, src, obj_ty),17705 .Array, .Vector => return sema.arrayInitEmpty(block, src, obj_ty),
17673 .Void => return sema.addConstant(obj_ty, Value.void),17706 .Void => return sema.addConstant(obj_ty, Value.void),
...@@ -17696,9 +17729,10 @@ fn structInitEmpty(...@@ -17696,9 +17729,10 @@ fn structInitEmpty(
17696}17729}
1769717730
17698fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref {17731fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref {
17732 const mod = sema.mod;
17699 const arr_len = obj_ty.arrayLen();17733 const arr_len = obj_ty.arrayLen();
17700 if (arr_len != 0) {17734 if (arr_len != 0) {
17701 if (obj_ty.zigTypeTag() == .Array) {17735 if (obj_ty.zigTypeTag(mod) == .Array) {
17702 return sema.fail(block, src, "expected {d} array elements; found 0", .{arr_len});17736 return sema.fail(block, src, "expected {d} array elements; found 0", .{arr_len});
17703 } else {17737 } else {
17704 return sema.fail(block, src, "expected {d} vector elements; found 0", .{arr_len});17738 return sema.fail(block, src, "expected {d} vector elements; found 0", .{arr_len});
...@@ -17766,13 +17800,14 @@ fn zirStructInit(...@@ -17766,13 +17800,14 @@ fn zirStructInit(
17766 const extra = sema.code.extraData(Zir.Inst.StructInit, inst_data.payload_index);17800 const extra = sema.code.extraData(Zir.Inst.StructInit, inst_data.payload_index);
17767 const src = inst_data.src();17801 const src = inst_data.src();
1776817802
17803 const mod = sema.mod;
17769 const first_item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end).data;17804 const first_item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end).data;
17770 const first_field_type_data = zir_datas[first_item.field_type].pl_node;17805 const first_field_type_data = zir_datas[first_item.field_type].pl_node;
17771 const first_field_type_extra = sema.code.extraData(Zir.Inst.FieldType, first_field_type_data.payload_index).data;17806 const first_field_type_extra = sema.code.extraData(Zir.Inst.FieldType, first_field_type_data.payload_index).data;
17772 const resolved_ty = try sema.resolveType(block, src, first_field_type_extra.container_type);17807 const resolved_ty = try sema.resolveType(block, src, first_field_type_extra.container_type);
17773 try sema.resolveTypeLayout(resolved_ty);17808 try sema.resolveTypeLayout(resolved_ty);
1777417809
17775 if (resolved_ty.zigTypeTag() == .Struct) {17810 if (resolved_ty.zigTypeTag(mod) == .Struct) {
17776 // This logic must be synchronized with that in `zirStructInitEmpty`.17811 // This logic must be synchronized with that in `zirStructInitEmpty`.
1777717812
17778 // Maps field index to field_type index of where it was already initialized.17813 // Maps field index to field_type index of where it was already initialized.
...@@ -17815,7 +17850,7 @@ fn zirStructInit(...@@ -17815,7 +17850,7 @@ fn zirStructInit(
17815 }17850 }
17816 found_fields[field_index] = item.data.field_type;17851 found_fields[field_index] = item.data.field_type;
17817 field_inits[field_index] = try sema.resolveInst(item.data.init);17852 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| {
17819 const init_val = (try sema.resolveMaybeUndefVal(field_inits[field_index])) orelse {17854 const init_val = (try sema.resolveMaybeUndefVal(field_inits[field_index])) orelse {
17820 return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime-known");17855 return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime-known");
17821 };17856 };
...@@ -17827,7 +17862,7 @@ fn zirStructInit(...@@ -17827,7 +17862,7 @@ fn zirStructInit(
17827 }17862 }
1782817863
17829 return sema.finishStructInit(block, src, src, field_inits, resolved_ty, is_ref);17864 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) {
17831 if (extra.data.fields_len != 1) {17866 if (extra.data.fields_len != 1) {
17832 return sema.fail(block, src, "union initialization expects exactly one field", .{});17867 return sema.fail(block, src, "union initialization expects exactly one field", .{});
17833 }17868 }
...@@ -18014,6 +18049,7 @@ fn zirStructInitAnon(...@@ -18014,6 +18049,7 @@ fn zirStructInitAnon(
18014 inst: Zir.Inst.Index,18049 inst: Zir.Inst.Index,
18015 is_ref: bool,18050 is_ref: bool,
18016) CompileError!Air.Inst.Ref {18051) CompileError!Air.Inst.Ref {
18052 const mod = sema.mod;
18017 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;18053 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
18018 const src = inst_data.src();18054 const src = inst_data.src();
18019 const extra = sema.code.extraData(Zir.Inst.StructInitAnon, inst_data.payload_index);18055 const extra = sema.code.extraData(Zir.Inst.StructInitAnon, inst_data.payload_index);
...@@ -18050,7 +18086,7 @@ fn zirStructInitAnon(...@@ -18050,7 +18086,7 @@ fn zirStructInitAnon(
1805018086
18051 const init = try sema.resolveInst(item.data.init);18087 const init = try sema.resolveInst(item.data.init);
18052 field_ty.* = sema.typeOf(init);18088 field_ty.* = sema.typeOf(init);
18053 if (types[i].zigTypeTag() == .Opaque) {18089 if (types[i].zigTypeTag(mod) == .Opaque) {
18054 const msg = msg: {18090 const msg = msg: {
18055 const decl = sema.mod.declPtr(block.src_decl);18091 const decl = sema.mod.declPtr(block.src_decl);
18056 const field_src = Module.initSrc(src.node_offset.x, sema.gpa, decl, i);18092 const field_src = Module.initSrc(src.node_offset.x, sema.gpa, decl, i);
...@@ -18148,15 +18184,16 @@ fn zirArrayInit(...@@ -18148,15 +18184,16 @@ fn zirArrayInit(
1814818184
18149 const array_ty = try sema.resolveType(block, src, args[0]);18185 const array_ty = try sema.resolveType(block, src, args[0]);
18150 const sentinel_val = array_ty.sentinel();18186 const sentinel_val = array_ty.sentinel();
18187 const mod = sema.mod;
1815118188
18152 const resolved_args = try gpa.alloc(Air.Inst.Ref, args.len - 1 + @boolToInt(sentinel_val != null));18189 const resolved_args = try gpa.alloc(Air.Inst.Ref, args.len - 1 + @boolToInt(sentinel_val != null));
18153 defer gpa.free(resolved_args);18190 defer gpa.free(resolved_args);
18154 for (args[1..], 0..) |arg, i| {18191 for (args[1..], 0..) |arg, i| {
18155 const resolved_arg = try sema.resolveInst(arg);18192 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)
18157 array_ty.structFieldType(i)18194 array_ty.structFieldType(i)
18158 else18195 else
18159 array_ty.elemType2();18196 array_ty.elemType2(mod);
18160 resolved_args[i] = sema.coerce(block, elem_ty, resolved_arg, .unneeded) catch |err| switch (err) {18197 resolved_args[i] = sema.coerce(block, elem_ty, resolved_arg, .unneeded) catch |err| switch (err) {
18161 error.NeededSourceLocation => {18198 error.NeededSourceLocation => {
18162 const decl = sema.mod.declPtr(block.src_decl);18199 const decl = sema.mod.declPtr(block.src_decl);
...@@ -18169,7 +18206,7 @@ fn zirArrayInit(...@@ -18169,7 +18206,7 @@ fn zirArrayInit(
18169 }18206 }
1817018207
18171 if (sentinel_val) |some| {18208 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);
18173 }18210 }
1817418211
18175 const opt_runtime_index: ?u32 = for (resolved_args, 0..) |arg, i| {18212 const opt_runtime_index: ?u32 = for (resolved_args, 0..) |arg, i| {
...@@ -18227,7 +18264,7 @@ fn zirArrayInit(...@@ -18227,7 +18264,7 @@ fn zirArrayInit(
18227 const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{18264 const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
18228 .mutable = true,18265 .mutable = true,
18229 .@"addrspace" = target_util.defaultAddressSpace(target, .local),18266 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
18230 .pointee_type = array_ty.elemType2(),18267 .pointee_type = array_ty.elemType2(mod),
18231 });18268 });
18232 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);18269 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
1823318270
...@@ -18252,6 +18289,7 @@ fn zirArrayInitAnon(...@@ -18252,6 +18289,7 @@ fn zirArrayInitAnon(
18252 const src = inst_data.src();18289 const src = inst_data.src();
18253 const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);18290 const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
18254 const operands = sema.code.refSlice(extra.end, extra.data.operands_len);18291 const operands = sema.code.refSlice(extra.end, extra.data.operands_len);
18292 const mod = sema.mod;
1825518293
18256 const types = try sema.arena.alloc(Type, operands.len);18294 const types = try sema.arena.alloc(Type, operands.len);
18257 const values = try sema.arena.alloc(Value, operands.len);18295 const values = try sema.arena.alloc(Value, operands.len);
...@@ -18262,7 +18300,7 @@ fn zirArrayInitAnon(...@@ -18262,7 +18300,7 @@ fn zirArrayInitAnon(
18262 const operand_src = src; // TODO better source location18300 const operand_src = src; // TODO better source location
18263 const elem = try sema.resolveInst(operand);18301 const elem = try sema.resolveInst(operand);
18264 types[i] = sema.typeOf(elem);18302 types[i] = sema.typeOf(elem);
18265 if (types[i].zigTypeTag() == .Opaque) {18303 if (types[i].zigTypeTag(mod) == .Opaque) {
18266 const msg = msg: {18304 const msg = msg: {
18267 const msg = try sema.errMsg(block, operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});18305 const msg = try sema.errMsg(block, operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
18268 errdefer msg.destroy(sema.gpa);18306 errdefer msg.destroy(sema.gpa);
...@@ -18379,11 +18417,12 @@ fn fieldType(...@@ -18379,11 +18417,12 @@ fn fieldType(
18379 field_src: LazySrcLoc,18417 field_src: LazySrcLoc,
18380 ty_src: LazySrcLoc,18418 ty_src: LazySrcLoc,
18381) CompileError!Air.Inst.Ref {18419) CompileError!Air.Inst.Ref {
18420 const mod = sema.mod;
18382 var cur_ty = aggregate_ty;18421 var cur_ty = aggregate_ty;
18383 while (true) {18422 while (true) {
18384 const resolved_ty = try sema.resolveTypeFields(cur_ty);18423 const resolved_ty = try sema.resolveTypeFields(cur_ty);
18385 cur_ty = resolved_ty;18424 cur_ty = resolved_ty;
18386 switch (cur_ty.zigTypeTag()) {18425 switch (cur_ty.zigTypeTag(mod)) {
18387 .Struct => {18426 .Struct => {
18388 if (cur_ty.isAnonStruct()) {18427 if (cur_ty.isAnonStruct()) {
18389 const field_index = try sema.anonStructFieldIndex(block, cur_ty, field_name, field_src);18428 const field_index = try sema.anonStructFieldIndex(block, cur_ty, field_name, field_src);
...@@ -18449,14 +18488,14 @@ fn zirFrame(...@@ -18449,14 +18488,14 @@ fn zirFrame(
18449}18488}
1845018489
18451fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {18490fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
18491 const mod = sema.mod;
18452 const inst_data = sema.code.instructions.items(.data)[inst].un_node;18492 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
18453 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };18493 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
18454 const ty = try sema.resolveType(block, operand_src, inst_data.operand);18494 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
18455 if (ty.isNoReturn()) {18495 if (ty.isNoReturn()) {
18456 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)});18496 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)});
18457 }18497 }
18458 const target = sema.mod.getTarget();18498 const val = try ty.lazyAbiAlignment(mod, sema.arena);
18459 const val = try ty.lazyAbiAlignment(target, sema.arena);
18460 if (val.tag() == .lazy_align) {18499 if (val.tag() == .lazy_align) {
18461 try sema.queueFullTypeResolution(ty);18500 try sema.queueFullTypeResolution(ty);
18462 }18501 }
...@@ -18499,16 +18538,17 @@ fn zirUnaryMath(...@@ -18499,16 +18538,17 @@ fn zirUnaryMath(
18499 const tracy = trace(@src());18538 const tracy = trace(@src());
18500 defer tracy.end();18539 defer tracy.end();
1850118540
18541 const mod = sema.mod;
18502 const inst_data = sema.code.instructions.items(.data)[inst].un_node;18542 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
18503 const operand = try sema.resolveInst(inst_data.operand);18543 const operand = try sema.resolveInst(inst_data.operand);
18504 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };18544 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
18505 const operand_ty = sema.typeOf(operand);18545 const operand_ty = sema.typeOf(operand);
1850618546
18507 switch (operand_ty.zigTypeTag()) {18547 switch (operand_ty.zigTypeTag(mod)) {
18508 .ComptimeFloat, .Float => {},18548 .ComptimeFloat, .Float => {},
18509 .Vector => {18549 .Vector => {
18510 const scalar_ty = operand_ty.scalarType();18550 const scalar_ty = operand_ty.scalarType(mod);
18511 switch (scalar_ty.zigTypeTag()) {18551 switch (scalar_ty.zigTypeTag(mod)) {
18512 .ComptimeFloat, .Float => {},18552 .ComptimeFloat, .Float => {},
18513 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty.fmt(sema.mod)}),18553 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty.fmt(sema.mod)}),
18514 }18554 }
...@@ -18516,9 +18556,9 @@ fn zirUnaryMath(...@@ -18516,9 +18556,9 @@ fn zirUnaryMath(
18516 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty.fmt(sema.mod)}),18556 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty.fmt(sema.mod)}),
18517 }18557 }
1851818558
18519 switch (operand_ty.zigTypeTag()) {18559 switch (operand_ty.zigTypeTag(mod)) {
18520 .Vector => {18560 .Vector => {
18521 const scalar_ty = operand_ty.scalarType();18561 const scalar_ty = operand_ty.scalarType(mod);
18522 const vec_len = operand_ty.vectorLen();18562 const vec_len = operand_ty.vectorLen();
18523 const result_ty = try Type.vector(sema.arena, vec_len, scalar_ty);18563 const result_ty = try Type.vector(sema.arena, vec_len, scalar_ty);
18524 if (try sema.resolveMaybeUndefVal(operand)) |val| {18564 if (try sema.resolveMaybeUndefVal(operand)) |val| {
...@@ -18564,7 +18604,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18564,7 +18604,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18564 const mod = sema.mod;18604 const mod = sema.mod;
1856518605
18566 try sema.resolveTypeLayout(operand_ty);18606 try sema.resolveTypeLayout(operand_ty);
18567 const enum_ty = switch (operand_ty.zigTypeTag()) {18607 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {
18568 .EnumLiteral => {18608 .EnumLiteral => {
18569 const val = try sema.resolveConstValue(block, .unneeded, operand, "");18609 const val = try sema.resolveConstValue(block, .unneeded, operand, "");
18570 const bytes = val.castTag(.enum_literal).?.data;18610 const bytes = val.castTag(.enum_literal).?.data;
...@@ -18654,11 +18694,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18654,11 +18694,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18654 const bits_val = struct_val[1];18694 const bits_val = struct_val[1];
1865518695
18656 const signedness = signedness_val.toEnum(std.builtin.Signedness);18696 const signedness = signedness_val.toEnum(std.builtin.Signedness);
18657 const bits = @intCast(u16, bits_val.toUnsignedInt(target));18697 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
18658 const ty = switch (signedness) {18698 const ty = try mod.intType(signedness, bits);
18659 .signed => try Type.Tag.int_signed.create(sema.arena, bits),
18660 .unsigned => try Type.Tag.int_unsigned.create(sema.arena, bits),
18661 };
18662 return sema.addType(ty);18699 return sema.addType(ty);
18663 },18700 },
18664 .Vector => {18701 .Vector => {
...@@ -18667,9 +18704,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18667,9 +18704,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18667 const len_val = struct_val[0];18704 const len_val = struct_val[0];
18668 const child_val = struct_val[1];18705 const child_val = struct_val[1];
1866918706
18670 const len = len_val.toUnsignedInt(target);18707 const len = len_val.toUnsignedInt(mod);
18671 var buffer: Value.ToTypeBuffer = undefined;18708 const child_ty = child_val.toType();
18672 const child_ty = child_val.toType(&buffer);
1867318709
18674 try sema.checkVectorElemType(block, src, child_ty);18710 try sema.checkVectorElemType(block, src, child_ty);
1867518711
...@@ -18682,7 +18718,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18682,7 +18718,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18682 // bits: comptime_int,18718 // bits: comptime_int,
18683 const bits_val = struct_val[0];18719 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));
18686 const ty = switch (bits) {18722 const ty = switch (bits) {
18687 16 => Type.f16,18723 16 => Type.f16,
18688 32 => Type.f32,18724 32 => Type.f32,
...@@ -18708,10 +18744,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18708,10 +18744,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18708 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {18744 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
18709 return sema.fail(block, src, "alignment must fit in 'u32'", .{});18745 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
18710 }18746 }
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;18749 const unresolved_elem_ty = child_val.toType();
18714 const unresolved_elem_ty = child_val.toType(&buffer);
18715 const elem_ty = if (abi_align == 0)18750 const elem_ty = if (abi_align == 0)
18716 unresolved_elem_ty18751 unresolved_elem_ty
18717 else t: {18752 else t: {
...@@ -18723,7 +18758,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18723,7 +18758,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18723 const ptr_size = size_val.toEnum(std.builtin.Type.Pointer.Size);18758 const ptr_size = size_val.toEnum(std.builtin.Type.Pointer.Size);
1872418759
18725 var actual_sentinel: ?Value = null;18760 var actual_sentinel: ?Value = null;
18726 if (!sentinel_val.isNull()) {18761 if (!sentinel_val.isNull(mod)) {
18727 if (ptr_size == .One or ptr_size == .C) {18762 if (ptr_size == .One or ptr_size == .C) {
18728 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});18763 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
18729 }18764 }
...@@ -18735,9 +18770,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18735,9 +18770,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18735 actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;18770 actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
18736 }18771 }
1873718772
18738 if (elem_ty.zigTypeTag() == .NoReturn) {18773 if (elem_ty.zigTypeTag(mod) == .NoReturn) {
18739 return sema.fail(block, src, "pointer to noreturn not allowed", .{});18774 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) {
18741 if (ptr_size != .One) {18776 if (ptr_size != .One) {
18742 return sema.fail(block, src, "function pointers must be single pointers", .{});18777 return sema.fail(block, src, "function pointers must be single pointers", .{});
18743 }18778 }
...@@ -18747,7 +18782,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18747,7 +18782,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18747 {18782 {
18748 return sema.fail(block, src, "function pointer alignment disagrees with function alignment", .{});18783 return sema.fail(block, src, "function pointer alignment disagrees with function alignment", .{});
18749 }18784 }
18750 } else if (ptr_size == .Many and elem_ty.zigTypeTag() == .Opaque) {18785 } else if (ptr_size == .Many and elem_ty.zigTypeTag(mod) == .Opaque) {
18751 return sema.fail(block, src, "unknown-length pointer to opaque not allowed", .{});18786 return sema.fail(block, src, "unknown-length pointer to opaque not allowed", .{});
18752 } else if (ptr_size == .C) {18787 } else if (ptr_size == .C) {
18753 if (!try sema.validateExternType(elem_ty, .other)) {18788 if (!try sema.validateExternType(elem_ty, .other)) {
...@@ -18763,7 +18798,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18763,7 +18798,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18763 };18798 };
18764 return sema.failWithOwnedErrorMsg(msg);18799 return sema.failWithOwnedErrorMsg(msg);
18765 }18800 }
18766 if (elem_ty.zigTypeTag() == .Opaque) {18801 if (elem_ty.zigTypeTag(mod) == .Opaque) {
18767 return sema.fail(block, src, "C pointers cannot point to opaque types", .{});18802 return sema.fail(block, src, "C pointers cannot point to opaque types", .{});
18768 }18803 }
18769 }18804 }
...@@ -18790,9 +18825,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18790,9 +18825,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18790 // sentinel: ?*const anyopaque,18825 // sentinel: ?*const anyopaque,
18791 const sentinel_val = struct_val[2];18826 const sentinel_val = struct_val[2];
1879218827
18793 const len = len_val.toUnsignedInt(target);18828 const len = len_val.toUnsignedInt(mod);
18794 var buffer: Value.ToTypeBuffer = undefined;18829 const child_ty = try child_val.toType().copy(sema.arena);
18795 const child_ty = try child_val.toType(&buffer).copy(sema.arena);
18796 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {18830 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {
18797 const ptr_ty = try Type.ptr(sema.arena, mod, .{18831 const ptr_ty = try Type.ptr(sema.arena, mod, .{
18798 .@"addrspace" = .generic,18832 .@"addrspace" = .generic,
...@@ -18810,8 +18844,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18810,8 +18844,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18810 // child: type,18844 // child: type,
18811 const child_val = struct_val[0];18845 const child_val = struct_val[0];
1881218846
18813 var buffer: Value.ToTypeBuffer = undefined;18847 const child_ty = try child_val.toType().copy(sema.arena);
18814 const child_ty = try child_val.toType(&buffer).copy(sema.arena);
1881518848
18816 const ty = try Type.optional(sema.arena, child_ty);18849 const ty = try Type.optional(sema.arena, child_ty);
18817 return sema.addType(ty);18850 return sema.addType(ty);
...@@ -18824,11 +18857,10 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18824,11 +18857,10 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18824 // payload: type,18857 // payload: type,
18825 const payload_val = struct_val[1];18858 const payload_val = struct_val[1];
1882618859
18827 var buffer: Value.ToTypeBuffer = undefined;18860 const error_set_ty = try error_set_val.toType().copy(sema.arena);
18828 const error_set_ty = try error_set_val.toType(&buffer).copy(sema.arena);18861 const payload_ty = try payload_val.toType().copy(sema.arena);
18829 const payload_ty = try payload_val.toType(&buffer).copy(sema.arena);
1883018862
18831 if (error_set_ty.zigTypeTag() != .ErrorSet) {18863 if (error_set_ty.zigTypeTag(mod) != .ErrorSet) {
18832 return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{});18864 return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{});
18833 }18865 }
1883418866
...@@ -18839,11 +18871,11 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18839,11 +18871,11 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18839 return sema.addType(ty);18871 return sema.addType(ty);
18840 },18872 },
18841 .ErrorSet => {18873 .ErrorSet => {
18842 const payload_val = union_val.val.optionalValue() orelse18874 const payload_val = union_val.val.optionalValue(mod) orelse
18843 return sema.addType(Type.initTag(.anyerror));18875 return sema.addType(Type.initTag(.anyerror));
18844 const slice_val = payload_val.castTag(.slice).?.data;18876 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));
18847 var names: Module.ErrorSet.NameMap = .{};18879 var names: Module.ErrorSet.NameMap = .{};
18848 try names.ensureUnusedCapacity(sema.arena, len);18880 try names.ensureUnusedCapacity(sema.arena, len);
18849 var i: usize = 0;18881 var i: usize = 0;
...@@ -18890,7 +18922,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18890,7 +18922,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18890 return sema.fail(block, src, "reified structs must have no decls", .{});18922 return sema.fail(block, src, "reified structs must have no decls", .{});
18891 }18923 }
1889218924
18893 if (layout != .Packed and !backing_int_val.isNull()) {18925 if (layout != .Packed and !backing_int_val.isNull(mod)) {
18894 return sema.fail(block, src, "non-packed struct does not support backing integer type", .{});18926 return sema.fail(block, src, "non-packed struct does not support backing integer type", .{});
18895 }18927 }
1889618928
...@@ -18954,10 +18986,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18954,10 +18986,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18954 };18986 };
1895518987
18956 // Enum tag type18988 // Enum tag type
18957 var buffer: Value.ToTypeBuffer = undefined;18989 const int_tag_ty = try tag_type_val.toType().copy(new_decl_arena_allocator);
18958 const int_tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator);
1895918990
18960 if (int_tag_ty.zigTypeTag() != .Int) {18991 if (int_tag_ty.zigTypeTag(mod) != .Int) {
18961 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});18992 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
18962 }18993 }
18963 enum_obj.tag_ty = int_tag_ty;18994 enum_obj.tag_ty = int_tag_ty;
...@@ -19090,7 +19121,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19090,7 +19121,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19090 const new_decl_arena_allocator = new_decl_arena.allocator();19121 const new_decl_arena_allocator = new_decl_arena.allocator();
1909119122
19092 const union_obj = try new_decl_arena_allocator.create(Module.Union);19123 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))
19094 Type.Tag.union_tagged19125 Type.Tag.union_tagged
19095 else if (layout != .Auto)19126 else if (layout != .Auto)
19096 Type.Tag.@"union"19127 Type.Tag.@"union"
...@@ -19130,11 +19161,10 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19130,11 +19161,10 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19130 var tag_ty_field_names: ?Module.EnumFull.NameMap = null;19161 var tag_ty_field_names: ?Module.EnumFull.NameMap = null;
19131 var enum_field_names: ?*Module.EnumNumbered.NameMap = null;19162 var enum_field_names: ?*Module.EnumNumbered.NameMap = null;
19132 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));19163 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));
19133 if (tag_type_val.optionalValue()) |payload_val| {19164 if (tag_type_val.optionalValue(mod)) |payload_val| {
19134 var buffer: Value.ToTypeBuffer = undefined;19165 union_obj.tag_ty = try payload_val.toType().copy(new_decl_arena_allocator);
19135 union_obj.tag_ty = try payload_val.toType(&buffer).copy(new_decl_arena_allocator);
1913619166
19137 if (union_obj.tag_ty.zigTypeTag() != .Enum) {19167 if (union_obj.tag_ty.zigTypeTag(mod) != .Enum) {
19138 return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{});19168 return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{});
19139 }19169 }
19140 tag_ty_field_names = try union_obj.tag_ty.enumFields().clone(sema.arena);19170 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...@@ -19187,14 +19217,13 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19187 return sema.fail(block, src, "duplicate union field {s}", .{field_name});19217 return sema.fail(block, src, "duplicate union field {s}", .{field_name});
19188 }19218 }
1918919219
19190 var buffer: Value.ToTypeBuffer = undefined;19220 const field_ty = try type_val.toType().copy(new_decl_arena_allocator);
19191 const field_ty = try type_val.toType(&buffer).copy(new_decl_arena_allocator);
19192 gop.value_ptr.* = .{19221 gop.value_ptr.* = .{
19193 .ty = field_ty,19222 .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)).?),
19195 };19224 };
1919619225
19197 if (field_ty.zigTypeTag() == .Opaque) {19226 if (field_ty.zigTypeTag(mod) == .Opaque) {
19198 const msg = msg: {19227 const msg = msg: {
19199 const msg = try sema.errMsg(block, src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});19228 const msg = try sema.errMsg(block, src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
19200 errdefer msg.destroy(sema.gpa);19229 errdefer msg.destroy(sema.gpa);
...@@ -19216,7 +19245,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19216,7 +19245,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19216 break :msg msg;19245 break :msg msg;
19217 };19246 };
19218 return sema.failWithOwnedErrorMsg(msg);19247 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))) {
19220 const msg = msg: {19249 const msg = msg: {
19221 const msg = try sema.errMsg(block, src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});19250 const msg = try sema.errMsg(block, src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
19222 errdefer msg.destroy(sema.gpa);19251 errdefer msg.destroy(sema.gpa);
...@@ -19280,20 +19309,18 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19280,20 +19309,18 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19280 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {19309 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
19281 return sema.fail(block, src, "alignment must fit in 'u32'", .{});19310 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
19282 }19311 }
19283 const alignment = @intCast(u29, alignment_val.toUnsignedInt(target));19312 const alignment = @intCast(u29, alignment_val.toUnsignedInt(mod));
19284 if (alignment == target_util.defaultFunctionAlignment(target)) {19313 if (alignment == target_util.defaultFunctionAlignment(target)) {
19285 break :alignment 0;19314 break :alignment 0;
19286 } else {19315 } else {
19287 break :alignment alignment;19316 break :alignment alignment;
19288 }19317 }
19289 };19318 };
19290 const return_type = return_type_val.optionalValue() orelse19319 const return_type = return_type_val.optionalValue(mod) orelse
19291 return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{});19320 return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{});
1929219321
19293 var buf: Value.ToTypeBuffer = undefined;
19294
19295 const args_slice_val = args_val.castTag(.slice).?.data;19322 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
19298 const param_types = try sema.arena.alloc(Type, args_len);19325 const param_types = try sema.arena.alloc(Type, args_len);
19299 const comptime_params = try sema.arena.alloc(bool, args_len);19326 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...@@ -19316,12 +19343,12 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19316 return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{});19343 return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{});
19317 }19344 }
1931819345
19319 const param_type_val = param_type_opt_val.optionalValue() orelse19346 const param_type_val = param_type_opt_val.optionalValue(mod) orelse
19320 return sema.fail(block, src, "Type.Fn.Param.arg_type must be non-null for @Type", .{});19347 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
19323 if (arg_is_noalias) {19350 if (arg_is_noalias) {
19324 if (!param_type.isPtrAtRuntime()) {19351 if (!param_type.isPtrAtRuntime(mod)) {
19325 return sema.fail(block, src, "non-pointer parameter declared noalias", .{});19352 return sema.fail(block, src, "non-pointer parameter declared noalias", .{});
19326 }19353 }
19327 noalias_bits |= @as(u32, 1) << (std.math.cast(u5, i) orelse19354 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...@@ -19336,7 +19363,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19336 .param_types = param_types,19363 .param_types = param_types,
19337 .comptime_params = comptime_params.ptr,19364 .comptime_params = comptime_params.ptr,
19338 .noalias_bits = noalias_bits,19365 .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),
19340 .alignment = alignment,19367 .alignment = alignment,
19341 .cc = cc,19368 .cc = cc,
19342 .is_var_args = is_var_args,19369 .is_var_args = is_var_args,
...@@ -19396,8 +19423,6 @@ fn reifyStruct(...@@ -19396,8 +19423,6 @@ fn reifyStruct(
19396 },19423 },
19397 };19424 };
1939819425
19399 const target = mod.getTarget();
19400
19401 // Fields19426 // Fields
19402 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));19427 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));
19403 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);19428 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
...@@ -19420,7 +19445,7 @@ fn reifyStruct(...@@ -19420,7 +19445,7 @@ fn reifyStruct(
19420 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {19445 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
19421 return sema.fail(block, src, "alignment must fit in 'u32'", .{});19446 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
19422 }19447 }
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
19425 if (layout == .Packed) {19450 if (layout == .Packed) {
19426 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});19451 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(...@@ -19461,7 +19486,7 @@ fn reifyStruct(
19461 return sema.fail(block, src, "duplicate struct field {s}", .{field_name});19486 return sema.fail(block, src, "duplicate struct field {s}", .{field_name});
19462 }19487 }
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: {
19465 const payload_val = if (opt_val.pointerDecl()) |opt_decl|19490 const payload_val = if (opt_val.pointerDecl()) |opt_decl|
19466 mod.declPtr(opt_decl).val19491 mod.declPtr(opt_decl).val
19467 else19492 else
...@@ -19472,8 +19497,7 @@ fn reifyStruct(...@@ -19472,8 +19497,7 @@ fn reifyStruct(
19472 return sema.fail(block, src, "comptime field without default initialization value", .{});19497 return sema.fail(block, src, "comptime field without default initialization value", .{});
19473 }19498 }
1947419499
19475 var buffer: Value.ToTypeBuffer = undefined;19500 const field_ty = try type_val.toType().copy(new_decl_arena_allocator);
19476 const field_ty = try type_val.toType(&buffer).copy(new_decl_arena_allocator);
19477 gop.value_ptr.* = .{19501 gop.value_ptr.* = .{
19478 .ty = field_ty,19502 .ty = field_ty,
19479 .abi_align = abi_align,19503 .abi_align = abi_align,
...@@ -19482,7 +19506,7 @@ fn reifyStruct(...@@ -19482,7 +19506,7 @@ fn reifyStruct(
19482 .offset = undefined,19506 .offset = undefined,
19483 };19507 };
1948419508
19485 if (field_ty.zigTypeTag() == .Opaque) {19509 if (field_ty.zigTypeTag(mod) == .Opaque) {
19486 const msg = msg: {19510 const msg = msg: {
19487 const msg = try sema.errMsg(block, src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});19511 const msg = try sema.errMsg(block, src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
19488 errdefer msg.destroy(sema.gpa);19512 errdefer msg.destroy(sema.gpa);
...@@ -19492,7 +19516,7 @@ fn reifyStruct(...@@ -19492,7 +19516,7 @@ fn reifyStruct(
19492 };19516 };
19493 return sema.failWithOwnedErrorMsg(msg);19517 return sema.failWithOwnedErrorMsg(msg);
19494 }19518 }
19495 if (field_ty.zigTypeTag() == .NoReturn) {19519 if (field_ty.zigTypeTag(mod) == .NoReturn) {
19496 const msg = msg: {19520 const msg = msg: {
19497 const msg = try sema.errMsg(block, src, "struct fields cannot be 'noreturn'", .{});19521 const msg = try sema.errMsg(block, src, "struct fields cannot be 'noreturn'", .{});
19498 errdefer msg.destroy(sema.gpa);19522 errdefer msg.destroy(sema.gpa);
...@@ -19514,7 +19538,7 @@ fn reifyStruct(...@@ -19514,7 +19538,7 @@ fn reifyStruct(
19514 break :msg msg;19538 break :msg msg;
19515 };19539 };
19516 return sema.failWithOwnedErrorMsg(msg);19540 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))) {
19518 const msg = msg: {19542 const msg = msg: {
19519 const msg = try sema.errMsg(block, src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});19543 const msg = try sema.errMsg(block, src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
19520 errdefer msg.destroy(sema.gpa);19544 errdefer msg.destroy(sema.gpa);
...@@ -19545,20 +19569,15 @@ fn reifyStruct(...@@ -19545,20 +19569,15 @@ fn reifyStruct(
1954519569
19546 var fields_bit_sum: u64 = 0;19570 var fields_bit_sum: u64 = 0;
19547 for (struct_obj.fields.values()) |field| {19571 for (struct_obj.fields.values()) |field| {
19548 fields_bit_sum += field.ty.bitSize(target);19572 fields_bit_sum += field.ty.bitSize(mod);
19549 }19573 }
1955019574
19551 if (backing_int_val.optionalValue()) |payload| {19575 if (backing_int_val.optionalValue(mod)) |payload| {
19552 var buf: Value.ToTypeBuffer = undefined;19576 const backing_int_ty = payload.toType();
19553 const backing_int_ty = payload.toType(&buf);
19554 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);19577 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);
19555 struct_obj.backing_int_ty = try backing_int_ty.copy(new_decl_arena_allocator);19578 struct_obj.backing_int_ty = try backing_int_ty.copy(new_decl_arena_allocator);
19556 } else {19579 } else {
19557 var buf: Type.Payload.Bits = .{19580 struct_obj.backing_int_ty = try mod.intType(.unsigned, @intCast(u16, fields_bit_sum));
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);
19562 }19581 }
1956319582
19564 struct_obj.status = .have_layout;19583 struct_obj.status = .have_layout;
...@@ -19569,6 +19588,7 @@ fn reifyStruct(...@@ -19569,6 +19588,7 @@ fn reifyStruct(
19569}19588}
1957019589
19571fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {19590fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
19591 const mod = sema.mod;
19572 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;19592 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
19573 const src = LazySrcLoc.nodeOffset(extra.node);19593 const src = LazySrcLoc.nodeOffset(extra.node);
19574 const addrspace_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };19594 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...@@ -19594,7 +19614,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
1959419614
19595 ptr_info.@"addrspace" = dest_addrspace;19615 ptr_info.@"addrspace" = dest_addrspace;
19596 const dest_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);19616 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)
19598 try Type.optional(sema.arena, dest_ptr_ty)19618 try Type.optional(sema.arena, dest_ptr_ty)
19599 else19619 else
19600 dest_ptr_ty;19620 dest_ptr_ty;
...@@ -19716,6 +19736,7 @@ fn zirFrameSize(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -19716,6 +19736,7 @@ fn zirFrameSize(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
19716}19736}
1971719737
19718fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19738fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
19739 const mod = sema.mod;
19719 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;19740 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
19720 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;19741 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
19721 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };19742 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!...@@ -19730,12 +19751,12 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
19730 if (try sema.resolveMaybeUndefVal(operand)) |val| {19751 if (try sema.resolveMaybeUndefVal(operand)) |val| {
19731 const result_val = try sema.floatToInt(block, operand_src, val, operand_ty, dest_ty);19752 const result_val = try sema.floatToInt(block, operand_src, val, operand_ty, dest_ty);
19732 return sema.addConstant(dest_ty, result_val);19753 return sema.addConstant(dest_ty, result_val);
19733 } else if (dest_ty.zigTypeTag() == .ComptimeInt) {19754 } else if (dest_ty.zigTypeTag(mod) == .ComptimeInt) {
19734 return sema.failWithNeededComptime(block, operand_src, "value being casted to 'comptime_int' must be comptime-known");19755 return sema.failWithNeededComptime(block, operand_src, "value being casted to 'comptime_int' must be comptime-known");
19735 }19756 }
1973619757
19737 try sema.requireRuntimeBlock(block, inst_data.src(), operand_src);19758 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) {
19739 if (block.wantSafety()) {19760 if (block.wantSafety()) {
19740 const ok = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_eq_optimized else .cmp_eq, operand, try sema.addConstant(operand_ty, Value.zero));19761 const ok = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_eq_optimized else .cmp_eq, operand, try sema.addConstant(operand_ty, Value.zero));
19741 try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds);19762 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!...@@ -19755,6 +19776,7 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
19755}19776}
1975619777
19757fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19778fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
19779 const mod = sema.mod;
19758 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;19780 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
19759 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;19781 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
19760 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };19782 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!...@@ -19769,7 +19791,7 @@ fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
19769 if (try sema.resolveMaybeUndefVal(operand)) |val| {19791 if (try sema.resolveMaybeUndefVal(operand)) |val| {
19770 const result_val = try val.intToFloatAdvanced(sema.arena, operand_ty, dest_ty, sema.mod, sema);19792 const result_val = try val.intToFloatAdvanced(sema.arena, operand_ty, dest_ty, sema.mod, sema);
19771 return sema.addConstant(dest_ty, result_val);19793 return sema.addConstant(dest_ty, result_val);
19772 } else if (dest_ty.zigTypeTag() == .ComptimeFloat) {19794 } else if (dest_ty.zigTypeTag(mod) == .ComptimeFloat) {
19773 return sema.failWithNeededComptime(block, operand_src, "value being casted to 'comptime_float' must be comptime-known");19795 return sema.failWithNeededComptime(block, operand_src, "value being casted to 'comptime_float' must be comptime-known");
19774 }19796 }
1977519797
...@@ -19778,6 +19800,7 @@ fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -19778,6 +19800,7 @@ fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
19778}19800}
1977919801
19780fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19802fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
19803 const mod = sema.mod;
19781 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;19804 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
19782 const src = inst_data.src();19805 const src = inst_data.src();
1978319806
...@@ -19790,9 +19813,8 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19790,9 +19813,8 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19790 const type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };19813 const type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
19791 const ptr_ty = try sema.resolveType(block, src, extra.lhs);19814 const ptr_ty = try sema.resolveType(block, src, extra.lhs);
19792 try sema.checkPtrType(block, type_src, ptr_ty);19815 try sema.checkPtrType(block, type_src, ptr_ty);
19793 const elem_ty = ptr_ty.elemType2();19816 const elem_ty = ptr_ty.elemType2(mod);
19794 const target = sema.mod.getTarget();19817 const ptr_align = try ptr_ty.ptrAlignmentAdvanced(mod, sema);
19795 const ptr_align = try ptr_ty.ptrAlignmentAdvanced(target, sema);
1979619818
19797 if (ptr_ty.isSlice()) {19819 if (ptr_ty.isSlice()) {
19798 const msg = msg: {19820 const msg = msg: {
...@@ -19805,8 +19827,8 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19805,8 +19827,8 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19805 }19827 }
1980619828
19807 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {19829 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {
19808 const addr = val.toUnsignedInt(target);19830 const addr = val.toUnsignedInt(mod);
19809 if (!ptr_ty.isAllowzeroPtr() and addr == 0)19831 if (!ptr_ty.isAllowzeroPtr(mod) and addr == 0)
19810 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(sema.mod)});19832 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(sema.mod)});
19811 if (addr != 0 and ptr_align != 0 and addr % ptr_align != 0)19833 if (addr != 0 and ptr_align != 0 and addr % ptr_align != 0)
19812 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(sema.mod)});19834 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...@@ -19820,8 +19842,8 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19820 }19842 }
1982119843
19822 try sema.requireRuntimeBlock(block, src, operand_src);19844 try sema.requireRuntimeBlock(block, src, operand_src);
19823 if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag() == .Fn)) {19845 if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) {
19824 if (!ptr_ty.isAllowzeroPtr()) {19846 if (!ptr_ty.isAllowzeroPtr(mod)) {
19825 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);19847 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);
19826 try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);19848 try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);
19827 }19849 }
...@@ -19926,6 +19948,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -19926,6 +19948,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
19926}19948}
1992719949
19928fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19950fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
19951 const mod = sema.mod;
19929 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;19952 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
19930 const src = inst_data.src();19953 const src = inst_data.src();
19931 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };19954 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...@@ -19934,7 +19957,6 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19934 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);19957 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
19935 const operand = try sema.resolveInst(extra.rhs);19958 const operand = try sema.resolveInst(extra.rhs);
19936 const operand_ty = sema.typeOf(operand);19959 const operand_ty = sema.typeOf(operand);
19937 const target = sema.mod.getTarget();
1993819960
19939 try sema.checkPtrType(block, dest_ty_src, dest_ty);19961 try sema.checkPtrType(block, dest_ty_src, dest_ty);
19940 try sema.checkPtrOperand(block, operand_src, operand_ty);19962 try sema.checkPtrOperand(block, operand_src, operand_ty);
...@@ -19982,18 +20004,18 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19982,18 +20004,18 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19982 else20004 else
19983 operand;20005 operand;
1998420006
19985 const dest_elem_ty = dest_ty.elemType2();20007 const dest_elem_ty = dest_ty.elemType2(mod);
19986 try sema.resolveTypeLayout(dest_elem_ty);20008 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);
19990 try sema.resolveTypeLayout(operand_elem_ty);20012 try sema.resolveTypeLayout(operand_elem_ty);
19991 const operand_align = operand_ty.ptrAlignment(target);20013 const operand_align = operand_ty.ptrAlignment(mod);
1999220014
19993 // If the destination is less aligned than the source, preserve the source alignment20015 // If the destination is less aligned than the source, preserve the source alignment
19994 const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {20016 const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {
19995 // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result20017 // 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) {
19997 var buf: Type.Payload.ElemType = undefined;20019 var buf: Type.Payload.ElemType = undefined;
19998 var dest_ptr_info = dest_ty.optionalChild(&buf).ptrInfo().data;20020 var dest_ptr_info = dest_ty.optionalChild(&buf).ptrInfo().data;
19999 dest_ptr_info.@"align" = operand_align;20021 dest_ptr_info.@"align" = operand_align;
...@@ -20006,8 +20028,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -20006,8 +20028,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
20006 };20028 };
2000720029
20008 if (dest_is_slice) {20030 if (dest_is_slice) {
20009 const operand_elem_size = operand_elem_ty.abiSize(target);20031 const operand_elem_size = operand_elem_ty.abiSize(mod);
20010 const dest_elem_size = dest_elem_ty.abiSize(target);20032 const dest_elem_size = dest_elem_ty.abiSize(mod);
20011 if (operand_elem_size != dest_elem_size) {20033 if (operand_elem_size != dest_elem_size) {
20012 return sema.fail(block, dest_ty_src, "TODO: implement @ptrCast between slices changing the length", .{});20034 return sema.fail(block, dest_ty_src, "TODO: implement @ptrCast between slices changing the length", .{});
20013 }20035 }
...@@ -20032,21 +20054,21 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -20032,21 +20054,21 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
20032 }20054 }
2003320055
20034 if (try sema.resolveMaybeUndefVal(ptr)) |operand_val| {20056 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()) {
20036 return sema.failWithUseOfUndef(block, operand_src);20058 return sema.failWithUseOfUndef(block, operand_src);
20037 }20059 }
20038 if (!dest_ty.ptrAllowsZero() and operand_val.isNull()) {20060 if (!dest_ty.ptrAllowsZero(mod) and operand_val.isNull(mod)) {
20039 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)});20061 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)});
20040 }20062 }
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) {
20042 return sema.addConstant(dest_ty, try Value.Tag.opt_payload.create(sema.arena, operand_val));20064 return sema.addConstant(dest_ty, try Value.Tag.opt_payload.create(sema.arena, operand_val));
20043 }20065 }
20044 return sema.addConstant(aligned_dest_ty, operand_val);20066 return sema.addConstant(aligned_dest_ty, operand_val);
20045 }20067 }
2004620068
20047 try sema.requireRuntimeBlock(block, src, null);20069 try sema.requireRuntimeBlock(block, src, null);
20048 if (block.wantSafety() and operand_ty.ptrAllowsZero() and !dest_ty.ptrAllowsZero() and20070 if (block.wantSafety() and operand_ty.ptrAllowsZero(mod) and !dest_ty.ptrAllowsZero(mod) and
20049 (try sema.typeHasRuntimeBits(dest_ty.elemType2()) or dest_ty.elemType2().zigTypeTag() == .Fn))20071 (try sema.typeHasRuntimeBits(dest_ty.elemType2(mod)) or dest_ty.elemType2(mod).zigTypeTag(mod) == .Fn))
20050 {20072 {
20051 const ptr_int = try block.addUnOp(.ptrtoint, ptr);20073 const ptr_int = try block.addUnOp(.ptrtoint, ptr);
20052 const is_non_zero = try block.addBinOp(.cmp_neq, ptr_int, .zero_usize);20074 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...@@ -20102,6 +20124,7 @@ fn zirVolatileCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
20102}20124}
2010320125
20104fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {20126fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20127 const mod = sema.mod;
20105 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;20128 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
20106 const src = inst_data.src();20129 const src = inst_data.src();
20107 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };20130 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...@@ -20112,7 +20135,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20112 const dest_is_comptime_int = try sema.checkIntType(block, dest_ty_src, dest_scalar_ty);20135 const dest_is_comptime_int = try sema.checkIntType(block, dest_ty_src, dest_scalar_ty);
20113 const operand_ty = sema.typeOf(operand);20136 const operand_ty = sema.typeOf(operand);
20114 const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src);20137 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;
20116 const dest_ty = if (is_vector)20139 const dest_ty = if (is_vector)
20117 try Type.vector(sema.arena, operand_ty.vectorLen(), dest_scalar_ty)20140 try Type.vector(sema.arena, operand_ty.vectorLen(), dest_scalar_ty)
20118 else20141 else
...@@ -20122,15 +20145,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -20122,15 +20145,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20122 return sema.coerce(block, dest_ty, operand, operand_src);20145 return sema.coerce(block, dest_ty, operand, operand_src);
20123 }20146 }
2012420147
20125 const target = sema.mod.getTarget();20148 const dest_info = dest_scalar_ty.intInfo(mod);
20126 const dest_info = dest_scalar_ty.intInfo(target);
2012720149
20128 if (try sema.typeHasOnePossibleValue(dest_ty)) |val| {20150 if (try sema.typeHasOnePossibleValue(dest_ty)) |val| {
20129 return sema.addConstant(dest_ty, val);20151 return sema.addConstant(dest_ty, val);
20130 }20152 }
2013120153
20132 if (operand_scalar_ty.zigTypeTag() != .ComptimeInt) {20154 if (operand_scalar_ty.zigTypeTag(mod) != .ComptimeInt) {
20133 const operand_info = operand_ty.intInfo(target);20155 const operand_info = operand_ty.intInfo(mod);
20134 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {20156 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
20135 return sema.addConstant(operand_ty, val);20157 return sema.addConstant(operand_ty, val);
20136 }20158 }
...@@ -20186,6 +20208,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -20186,6 +20208,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20186}20208}
2018720209
20188fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {20210fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20211 const mod = sema.mod;
20189 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;20212 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
20190 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;20213 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
20191 const align_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };20214 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...@@ -20199,12 +20222,12 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
20199 var ptr_info = ptr_ty.ptrInfo().data;20222 var ptr_info = ptr_ty.ptrInfo().data;
20200 ptr_info.@"align" = dest_align;20223 ptr_info.@"align" = dest_align;
20201 var dest_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);20224 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) {
20203 dest_ty = try Type.Tag.optional.create(sema.arena, dest_ty);20226 dest_ty = try Type.Tag.optional.create(sema.arena, dest_ty);
20204 }20227 }
2020520228
20206 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |val| {20229 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| {
20208 if (addr % dest_align != 0) {20231 if (addr % dest_align != 0) {
20209 return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align });20232 return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align });
20210 }20233 }
...@@ -20247,23 +20270,23 @@ fn zirBitCount(...@@ -20247,23 +20270,23 @@ fn zirBitCount(
20247 block: *Block,20270 block: *Block,
20248 inst: Zir.Inst.Index,20271 inst: Zir.Inst.Index,
20249 air_tag: Air.Inst.Tag,20272 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,
20251) CompileError!Air.Inst.Ref {20274) CompileError!Air.Inst.Ref {
20275 const mod = sema.mod;
20252 const inst_data = sema.code.instructions.items(.data)[inst].un_node;20276 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
20253 const src = inst_data.src();20277 const src = inst_data.src();
20254 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };20278 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
20255 const operand = try sema.resolveInst(inst_data.operand);20279 const operand = try sema.resolveInst(inst_data.operand);
20256 const operand_ty = sema.typeOf(operand);20280 const operand_ty = sema.typeOf(operand);
20257 _ = try sema.checkIntOrVector(block, operand, operand_src);20281 _ = try sema.checkIntOrVector(block, operand, operand_src);
20258 const target = sema.mod.getTarget();20282 const bits = operand_ty.intInfo(mod).bits;
20259 const bits = operand_ty.intInfo(target).bits;
2026020283
20261 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {20284 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
20262 return sema.addConstant(operand_ty, val);20285 return sema.addConstant(operand_ty, val);
20263 }20286 }
2026420287
20265 const result_scalar_ty = try Type.smallestUnsignedInt(sema.arena, bits);20288 const result_scalar_ty = try mod.smallestUnsignedInt(bits);
20266 switch (operand_ty.zigTypeTag()) {20289 switch (operand_ty.zigTypeTag(mod)) {
20267 .Vector => {20290 .Vector => {
20268 const vec_len = operand_ty.vectorLen();20291 const vec_len = operand_ty.vectorLen();
20269 const result_ty = try Type.vector(sema.arena, vec_len, result_scalar_ty);20292 const result_ty = try Type.vector(sema.arena, vec_len, result_scalar_ty);
...@@ -20272,10 +20295,10 @@ fn zirBitCount(...@@ -20272,10 +20295,10 @@ fn zirBitCount(
2027220295
20273 var elem_buf: Value.ElemValueBuffer = undefined;20296 var elem_buf: Value.ElemValueBuffer = undefined;
20274 const elems = try sema.arena.alloc(Value, vec_len);20297 const elems = try sema.arena.alloc(Value, vec_len);
20275 const scalar_ty = operand_ty.scalarType();20298 const scalar_ty = operand_ty.scalarType(mod);
20276 for (elems, 0..) |*elem, i| {20299 for (elems, 0..) |*elem, i| {
20277 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);20300 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);
20279 elem.* = try Value.Tag.int_u64.create(sema.arena, count);20302 elem.* = try Value.Tag.int_u64.create(sema.arena, count);
20280 }20303 }
20281 return sema.addConstant(20304 return sema.addConstant(
...@@ -20291,7 +20314,7 @@ fn zirBitCount(...@@ -20291,7 +20314,7 @@ fn zirBitCount(
20291 if (try sema.resolveMaybeUndefVal(operand)) |val| {20314 if (try sema.resolveMaybeUndefVal(operand)) |val| {
20292 if (val.isUndef()) return sema.addConstUndef(result_scalar_ty);20315 if (val.isUndef()) return sema.addConstUndef(result_scalar_ty);
20293 try sema.resolveLazyValue(val);20316 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));
20295 } else {20318 } else {
20296 try sema.requireRuntimeBlock(block, src, operand_src);20319 try sema.requireRuntimeBlock(block, src, operand_src);
20297 return block.addTyOp(air_tag, result_scalar_ty, operand);20320 return block.addTyOp(air_tag, result_scalar_ty, operand);
...@@ -20302,14 +20325,14 @@ fn zirBitCount(...@@ -20302,14 +20325,14 @@ fn zirBitCount(
20302}20325}
2030320326
20304fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {20327fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20328 const mod = sema.mod;
20305 const inst_data = sema.code.instructions.items(.data)[inst].un_node;20329 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
20306 const src = inst_data.src();20330 const src = inst_data.src();
20307 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };20331 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
20308 const operand = try sema.resolveInst(inst_data.operand);20332 const operand = try sema.resolveInst(inst_data.operand);
20309 const operand_ty = sema.typeOf(operand);20333 const operand_ty = sema.typeOf(operand);
20310 const scalar_ty = try sema.checkIntOrVector(block, operand, operand_src);20334 const scalar_ty = try sema.checkIntOrVector(block, operand, operand_src);
20311 const target = sema.mod.getTarget();20335 const bits = scalar_ty.intInfo(mod).bits;
20312 const bits = scalar_ty.intInfo(target).bits;
20313 if (bits % 8 != 0) {20336 if (bits % 8 != 0) {
20314 return sema.fail(20337 return sema.fail(
20315 block,20338 block,
...@@ -20323,11 +20346,11 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -20323,11 +20346,11 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20323 return sema.addConstant(operand_ty, val);20346 return sema.addConstant(operand_ty, val);
20324 }20347 }
2032520348
20326 switch (operand_ty.zigTypeTag()) {20349 switch (operand_ty.zigTypeTag(mod)) {
20327 .Int => {20350 .Int => {
20328 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {20351 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {
20329 if (val.isUndef()) return sema.addConstUndef(operand_ty);20352 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);
20331 return sema.addConstant(operand_ty, result_val);20354 return sema.addConstant(operand_ty, result_val);
20332 } else operand_src;20355 } else operand_src;
2033320356
...@@ -20344,7 +20367,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -20344,7 +20367,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20344 const elems = try sema.arena.alloc(Value, vec_len);20367 const elems = try sema.arena.alloc(Value, vec_len);
20345 for (elems, 0..) |*elem, i| {20368 for (elems, 0..) |*elem, i| {
20346 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);20369 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);
20348 }20371 }
20349 return sema.addConstant(20372 return sema.addConstant(
20350 operand_ty,20373 operand_ty,
...@@ -20371,12 +20394,12 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -20371,12 +20394,12 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
20371 return sema.addConstant(operand_ty, val);20394 return sema.addConstant(operand_ty, val);
20372 }20395 }
2037320396
20374 const target = sema.mod.getTarget();20397 const mod = sema.mod;
20375 switch (operand_ty.zigTypeTag()) {20398 switch (operand_ty.zigTypeTag(mod)) {
20376 .Int => {20399 .Int => {
20377 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {20400 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {
20378 if (val.isUndef()) return sema.addConstUndef(operand_ty);20401 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);
20380 return sema.addConstant(operand_ty, result_val);20403 return sema.addConstant(operand_ty, result_val);
20381 } else operand_src;20404 } else operand_src;
2038220405
...@@ -20393,7 +20416,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -20393,7 +20416,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
20393 const elems = try sema.arena.alloc(Value, vec_len);20416 const elems = try sema.arena.alloc(Value, vec_len);
20394 for (elems, 0..) |*elem, i| {20417 for (elems, 0..) |*elem, i| {
20395 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);20418 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);
20397 }20420 }
20398 return sema.addConstant(20421 return sema.addConstant(
20399 operand_ty,20422 operand_ty,
...@@ -20429,10 +20452,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -20429,10 +20452,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
2042920452
20430 const ty = try sema.resolveType(block, lhs_src, extra.lhs);20453 const ty = try sema.resolveType(block, lhs_src, extra.lhs);
20431 const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs, "name of field must be comptime-known");20454 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;
20434 try sema.resolveTypeLayout(ty);20457 try sema.resolveTypeLayout(ty);
20435 switch (ty.zigTypeTag()) {20458 switch (ty.zigTypeTag(mod)) {
20436 .Struct => {},20459 .Struct => {},
20437 else => {20460 else => {
20438 const msg = msg: {20461 const msg = msg: {
...@@ -20464,15 +20487,16 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -20464,15 +20487,16 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
20464 if (i == field_index) {20487 if (i == field_index) {
20465 return bit_sum;20488 return bit_sum;
20466 }20489 }
20467 bit_sum += field.ty.bitSize(target);20490 bit_sum += field.ty.bitSize(mod);
20468 } else unreachable;20491 } else unreachable;
20469 },20492 },
20470 else => return ty.structFieldOffset(field_index, target) * 8,20493 else => return ty.structFieldOffset(field_index, mod) * 8,
20471 }20494 }
20472}20495}
2047320496
20474fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {20497fn 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)) {
20476 .Struct, .Enum, .Union, .Opaque => return,20500 .Struct, .Enum, .Union, .Opaque => return,
20477 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(sema.mod)}),20501 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(sema.mod)}),
20478 }20502 }
...@@ -20480,7 +20504,8 @@ fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Com...@@ -20480,7 +20504,8 @@ fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Com
2048020504
20481/// Returns `true` if the type was a comptime_int.20505/// Returns `true` if the type was a comptime_int.
20482fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {20506fn 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)) {
20484 .ComptimeInt => return true,20509 .ComptimeInt => return true,
20485 .Int => return false,20510 .Int => return false,
20486 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(sema.mod)}),20511 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(sema.mod)}),
...@@ -20493,7 +20518,8 @@ fn checkInvalidPtrArithmetic(...@@ -20493,7 +20518,8 @@ fn checkInvalidPtrArithmetic(
20493 src: LazySrcLoc,20518 src: LazySrcLoc,
20494 ty: Type,20519 ty: Type,
20495) CompileError!void {20520) CompileError!void {
20496 switch (try ty.zigTypeTagOrPoison()) {20521 const mod = sema.mod;
20522 switch (try ty.zigTypeTagOrPoison(mod)) {
20497 .Pointer => switch (ty.ptrSize()) {20523 .Pointer => switch (ty.ptrSize()) {
20498 .One, .Slice => return,20524 .One, .Slice => return,
20499 .Many, .C => return sema.fail(20525 .Many, .C => return sema.fail(
...@@ -20532,7 +20558,8 @@ fn checkPtrOperand(...@@ -20532,7 +20558,8 @@ fn checkPtrOperand(
20532 ty_src: LazySrcLoc,20558 ty_src: LazySrcLoc,
20533 ty: Type,20559 ty: Type,
20534) CompileError!void {20560) CompileError!void {
20535 switch (ty.zigTypeTag()) {20561 const mod = sema.mod;
20562 switch (ty.zigTypeTag(mod)) {
20536 .Pointer => return,20563 .Pointer => return,
20537 .Fn => {20564 .Fn => {
20538 const msg = msg: {20565 const msg = msg: {
...@@ -20550,7 +20577,7 @@ fn checkPtrOperand(...@@ -20550,7 +20577,7 @@ fn checkPtrOperand(
20550 };20577 };
20551 return sema.failWithOwnedErrorMsg(msg);20578 return sema.failWithOwnedErrorMsg(msg);
20552 },20579 },
20553 .Optional => if (ty.isPtrLikeOptional()) return,20580 .Optional => if (ty.isPtrLikeOptional(mod)) return,
20554 else => {},20581 else => {},
20555 }20582 }
20556 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(sema.mod)});20583 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(sema.mod)});
...@@ -20562,7 +20589,8 @@ fn checkPtrType(...@@ -20562,7 +20589,8 @@ fn checkPtrType(
20562 ty_src: LazySrcLoc,20589 ty_src: LazySrcLoc,
20563 ty: Type,20590 ty: Type,
20564) CompileError!void {20591) CompileError!void {
20565 switch (ty.zigTypeTag()) {20592 const mod = sema.mod;
20593 switch (ty.zigTypeTag(mod)) {
20566 .Pointer => return,20594 .Pointer => return,
20567 .Fn => {20595 .Fn => {
20568 const msg = msg: {20596 const msg = msg: {
...@@ -20580,7 +20608,7 @@ fn checkPtrType(...@@ -20580,7 +20608,7 @@ fn checkPtrType(
20580 };20608 };
20581 return sema.failWithOwnedErrorMsg(msg);20609 return sema.failWithOwnedErrorMsg(msg);
20582 },20610 },
20583 .Optional => if (ty.isPtrLikeOptional()) return,20611 .Optional => if (ty.isPtrLikeOptional(mod)) return,
20584 else => {},20612 else => {},
20585 }20613 }
20586 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(sema.mod)});20614 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(sema.mod)});
...@@ -20592,9 +20620,10 @@ fn checkVectorElemType(...@@ -20592,9 +20620,10 @@ fn checkVectorElemType(
20592 ty_src: LazySrcLoc,20620 ty_src: LazySrcLoc,
20593 ty: Type,20621 ty: Type,
20594) CompileError!void {20622) CompileError!void {
20595 switch (ty.zigTypeTag()) {20623 const mod = sema.mod;
20624 switch (ty.zigTypeTag(mod)) {
20596 .Int, .Float, .Bool => return,20625 .Int, .Float, .Bool => return,
20597 else => if (ty.isPtrAtRuntime()) return,20626 else => if (ty.isPtrAtRuntime(mod)) return,
20598 }20627 }
20599 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(sema.mod)});20628 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(sema.mod)});
20600}20629}
...@@ -20605,7 +20634,8 @@ fn checkFloatType(...@@ -20605,7 +20634,8 @@ fn checkFloatType(
20605 ty_src: LazySrcLoc,20634 ty_src: LazySrcLoc,
20606 ty: Type,20635 ty: Type,
20607) CompileError!void {20636) CompileError!void {
20608 switch (ty.zigTypeTag()) {20637 const mod = sema.mod;
20638 switch (ty.zigTypeTag(mod)) {
20609 .ComptimeInt, .ComptimeFloat, .Float => {},20639 .ComptimeInt, .ComptimeFloat, .Float => {},
20610 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(sema.mod)}),20640 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(sema.mod)}),
20611 }20641 }
...@@ -20617,9 +20647,10 @@ fn checkNumericType(...@@ -20617,9 +20647,10 @@ fn checkNumericType(
20617 ty_src: LazySrcLoc,20647 ty_src: LazySrcLoc,
20618 ty: Type,20648 ty: Type,
20619) CompileError!void {20649) CompileError!void {
20620 switch (ty.zigTypeTag()) {20650 const mod = sema.mod;
20651 switch (ty.zigTypeTag(mod)) {
20621 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},20652 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
20622 .Vector => switch (ty.childType().zigTypeTag()) {20653 .Vector => switch (ty.childType().zigTypeTag(mod)) {
20623 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},20654 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
20624 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),20655 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),
20625 },20656 },
...@@ -20637,9 +20668,9 @@ fn checkAtomicPtrOperand(...@@ -20637,9 +20668,9 @@ fn checkAtomicPtrOperand(
20637 ptr_src: LazySrcLoc,20668 ptr_src: LazySrcLoc,
20638 ptr_const: bool,20669 ptr_const: bool,
20639) CompileError!Air.Inst.Ref {20670) CompileError!Air.Inst.Ref {
20640 const target = sema.mod.getTarget();20671 const mod = sema.mod;
20641 var diag: target_util.AtomicPtrAlignmentDiagnostics = .{};20672 var diag: Module.AtomicPtrAlignmentDiagnostics = .{};
20642 const alignment = target_util.atomicPtrAlignment(target, elem_ty, &diag) catch |err| switch (err) {20673 const alignment = mod.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) {
20643 error.FloatTooBig => return sema.fail(20674 error.FloatTooBig => return sema.fail(
20644 block,20675 block,
20645 elem_ty_src,20676 elem_ty_src,
...@@ -20668,7 +20699,7 @@ fn checkAtomicPtrOperand(...@@ -20668,7 +20699,7 @@ fn checkAtomicPtrOperand(
20668 };20699 };
2066920700
20670 const ptr_ty = sema.typeOf(ptr);20701 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)) {
20672 .Pointer => ptr_ty.ptrInfo().data,20703 .Pointer => ptr_ty.ptrInfo().data,
20673 else => {20704 else => {
20674 const wanted_ptr_ty = try Type.ptr(sema.arena, sema.mod, wanted_ptr_data);20705 const wanted_ptr_ty = try Type.ptr(sema.arena, sema.mod, wanted_ptr_data);
...@@ -20735,12 +20766,13 @@ fn checkIntOrVector(...@@ -20735,12 +20766,13 @@ fn checkIntOrVector(
20735 operand: Air.Inst.Ref,20766 operand: Air.Inst.Ref,
20736 operand_src: LazySrcLoc,20767 operand_src: LazySrcLoc,
20737) CompileError!Type {20768) CompileError!Type {
20769 const mod = sema.mod;
20738 const operand_ty = sema.typeOf(operand);20770 const operand_ty = sema.typeOf(operand);
20739 switch (try operand_ty.zigTypeTagOrPoison()) {20771 switch (try operand_ty.zigTypeTagOrPoison(mod)) {
20740 .Int => return operand_ty,20772 .Int => return operand_ty,
20741 .Vector => {20773 .Vector => {
20742 const elem_ty = operand_ty.childType();20774 const elem_ty = operand_ty.childType();
20743 switch (try elem_ty.zigTypeTagOrPoison()) {20775 switch (try elem_ty.zigTypeTagOrPoison(mod)) {
20744 .Int => return elem_ty,20776 .Int => return elem_ty,
20745 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{20777 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
20746 elem_ty.fmt(sema.mod),20778 elem_ty.fmt(sema.mod),
...@@ -20759,11 +20791,12 @@ fn checkIntOrVectorAllowComptime(...@@ -20759,11 +20791,12 @@ fn checkIntOrVectorAllowComptime(
20759 operand_ty: Type,20791 operand_ty: Type,
20760 operand_src: LazySrcLoc,20792 operand_src: LazySrcLoc,
20761) CompileError!Type {20793) CompileError!Type {
20762 switch (try operand_ty.zigTypeTagOrPoison()) {20794 const mod = sema.mod;
20795 switch (try operand_ty.zigTypeTagOrPoison(mod)) {
20763 .Int, .ComptimeInt => return operand_ty,20796 .Int, .ComptimeInt => return operand_ty,
20764 .Vector => {20797 .Vector => {
20765 const elem_ty = operand_ty.childType();20798 const elem_ty = operand_ty.childType();
20766 switch (try elem_ty.zigTypeTagOrPoison()) {20799 switch (try elem_ty.zigTypeTagOrPoison(mod)) {
20767 .Int, .ComptimeInt => return elem_ty,20800 .Int, .ComptimeInt => return elem_ty,
20768 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{20801 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
20769 elem_ty.fmt(sema.mod),20802 elem_ty.fmt(sema.mod),
...@@ -20777,7 +20810,8 @@ fn checkIntOrVectorAllowComptime(...@@ -20777,7 +20810,8 @@ fn checkIntOrVectorAllowComptime(
20777}20810}
2077820811
20779fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {20812fn 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)) {
20781 .ErrorSet => return,20815 .ErrorSet => return,
20782 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty.fmt(sema.mod)}),20816 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty.fmt(sema.mod)}),
20783 }20817 }
...@@ -20805,11 +20839,12 @@ fn checkSimdBinOp(...@@ -20805,11 +20839,12 @@ fn checkSimdBinOp(
20805 lhs_src: LazySrcLoc,20839 lhs_src: LazySrcLoc,
20806 rhs_src: LazySrcLoc,20840 rhs_src: LazySrcLoc,
20807) CompileError!SimdBinOp {20841) CompileError!SimdBinOp {
20842 const mod = sema.mod;
20808 const lhs_ty = sema.typeOf(uncasted_lhs);20843 const lhs_ty = sema.typeOf(uncasted_lhs);
20809 const rhs_ty = sema.typeOf(uncasted_rhs);20844 const rhs_ty = sema.typeOf(uncasted_rhs);
2081020845
20811 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);20846 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;
20813 const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{20848 const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{
20814 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },20849 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
20815 });20850 });
...@@ -20823,7 +20858,7 @@ fn checkSimdBinOp(...@@ -20823,7 +20858,7 @@ fn checkSimdBinOp(
20823 .lhs_val = try sema.resolveMaybeUndefVal(lhs),20858 .lhs_val = try sema.resolveMaybeUndefVal(lhs),
20824 .rhs_val = try sema.resolveMaybeUndefVal(rhs),20859 .rhs_val = try sema.resolveMaybeUndefVal(rhs),
20825 .result_ty = result_ty,20860 .result_ty = result_ty,
20826 .scalar_ty = result_ty.scalarType(),20861 .scalar_ty = result_ty.scalarType(mod),
20827 };20862 };
20828}20863}
2082920864
...@@ -20836,8 +20871,9 @@ fn checkVectorizableBinaryOperands(...@@ -20836,8 +20871,9 @@ fn checkVectorizableBinaryOperands(
20836 lhs_src: LazySrcLoc,20871 lhs_src: LazySrcLoc,
20837 rhs_src: LazySrcLoc,20872 rhs_src: LazySrcLoc,
20838) CompileError!void {20873) CompileError!void {
20839 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();20874 const mod = sema.mod;
20840 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();20875 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
20876 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
20841 if (lhs_zig_ty_tag != .Vector and rhs_zig_ty_tag != .Vector) return;20877 if (lhs_zig_ty_tag != .Vector and rhs_zig_ty_tag != .Vector) return;
2084220878
20843 const lhs_is_vector = switch (lhs_zig_ty_tag) {20879 const lhs_is_vector = switch (lhs_zig_ty_tag) {
...@@ -20892,6 +20928,7 @@ fn resolveExportOptions(...@@ -20892,6 +20928,7 @@ fn resolveExportOptions(
20892 src: LazySrcLoc,20928 src: LazySrcLoc,
20893 zir_ref: Zir.Inst.Ref,20929 zir_ref: Zir.Inst.Ref,
20894) CompileError!std.builtin.ExportOptions {20930) CompileError!std.builtin.ExportOptions {
20931 const mod = sema.mod;
20895 const export_options_ty = try sema.getBuiltinType("ExportOptions");20932 const export_options_ty = try sema.getBuiltinType("ExportOptions");
20896 const air_ref = try sema.resolveInst(zir_ref);20933 const air_ref = try sema.resolveInst(zir_ref);
20897 const options = try sema.coerce(block, export_options_ty, air_ref, src);20934 const options = try sema.coerce(block, export_options_ty, air_ref, src);
...@@ -20904,7 +20941,7 @@ fn resolveExportOptions(...@@ -20904,7 +20941,7 @@ fn resolveExportOptions(
20904 const name_operand = try sema.fieldVal(block, src, options, "name", name_src);20941 const name_operand = try sema.fieldVal(block, src, options, "name", name_src);
20905 const name_val = try sema.resolveConstValue(block, name_src, name_operand, "name of exported value must be comptime-known");20942 const name_val = try sema.resolveConstValue(block, name_src, name_operand, "name of exported value must be comptime-known");
20906 const name_ty = Type.initTag(.const_slice_u8);20943 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
20909 const linkage_operand = try sema.fieldVal(block, src, options, "linkage", linkage_src);20946 const linkage_operand = try sema.fieldVal(block, src, options, "linkage", linkage_src);
20910 const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_operand, "linkage of exported value must be comptime-known");20947 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(...@@ -20913,8 +20950,8 @@ fn resolveExportOptions(
20913 const section_operand = try sema.fieldVal(block, src, options, "section", section_src);20950 const section_operand = try sema.fieldVal(block, src, options, "section", section_src);
20914 const section_opt_val = try sema.resolveConstValue(block, section_src, section_operand, "linksection of exported value must be comptime-known");20951 const section_opt_val = try sema.resolveConstValue(block, section_src, section_operand, "linksection of exported value must be comptime-known");
20915 const section_ty = Type.initTag(.const_slice_u8);20952 const section_ty = Type.initTag(.const_slice_u8);
20916 const section = if (section_opt_val.optionalValue()) |section_val|20953 const section = if (section_opt_val.optionalValue(mod)) |section_val|
20917 try section_val.toAllocatedBytes(section_ty, sema.arena, sema.mod)20954 try section_val.toAllocatedBytes(section_ty, sema.arena, mod)
20918 else20955 else
20919 null;20956 null;
2092020957
...@@ -20979,6 +21016,7 @@ fn zirCmpxchg(...@@ -20979,6 +21016,7 @@ fn zirCmpxchg(
20979 block: *Block,21016 block: *Block,
20980 extended: Zir.Inst.Extended.InstData,21017 extended: Zir.Inst.Extended.InstData,
20981) CompileError!Air.Inst.Ref {21018) CompileError!Air.Inst.Ref {
21019 const mod = sema.mod;
20982 const extra = sema.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;21020 const extra = sema.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;
20983 const air_tag: Air.Inst.Tag = switch (extended.small) {21021 const air_tag: Air.Inst.Tag = switch (extended.small) {
20984 0 => .cmpxchg_weak,21022 0 => .cmpxchg_weak,
...@@ -20996,7 +21034,7 @@ fn zirCmpxchg(...@@ -20996,7 +21034,7 @@ fn zirCmpxchg(
20996 // zig fmt: on21034 // zig fmt: on
20997 const expected_value = try sema.resolveInst(extra.expected_value);21035 const expected_value = try sema.resolveInst(extra.expected_value);
20998 const elem_ty = sema.typeOf(expected_value);21036 const elem_ty = sema.typeOf(expected_value);
20999 if (elem_ty.zigTypeTag() == .Float) {21037 if (elem_ty.zigTypeTag(mod) == .Float) {
21000 return sema.fail(21038 return sema.fail(
21001 block,21039 block,
21002 elem_ty_src,21040 elem_ty_src,
...@@ -21102,26 +21140,26 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -21102,26 +21140,26 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
21102 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp", "@reduce operation must be comptime-known");21140 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp", "@reduce operation must be comptime-known");
21103 const operand = try sema.resolveInst(extra.rhs);21141 const operand = try sema.resolveInst(extra.rhs);
21104 const operand_ty = sema.typeOf(operand);21142 const operand_ty = sema.typeOf(operand);
21105 const target = sema.mod.getTarget();21143 const mod = sema.mod;
2110621144
21107 if (operand_ty.zigTypeTag() != .Vector) {21145 if (operand_ty.zigTypeTag(mod) != .Vector) {
21108 return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(sema.mod)});21146 return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(mod)});
21109 }21147 }
2111021148
21111 const scalar_ty = operand_ty.childType();21149 const scalar_ty = operand_ty.childType();
2111221150
21113 // Type-check depending on operation.21151 // Type-check depending on operation.
21114 switch (operation) {21152 switch (operation) {
21115 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag()) {21153 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag(mod)) {
21116 .Int, .Bool => {},21154 .Int, .Bool => {},
21117 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found '{}'", .{21155 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),
21119 }),21157 }),
21120 },21158 },
21121 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag()) {21159 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) {
21122 .Int, .Float => {},21160 .Int, .Float => {},
21123 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found '{}'", .{21161 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),
21125 }),21163 }),
21126 },21164 },
21127 }21165 }
...@@ -21136,19 +21174,19 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -21136,19 +21174,19 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
21136 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {21174 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
21137 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);21175 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);
21140 var elem_buf: Value.ElemValueBuffer = undefined;21178 var elem_buf: Value.ElemValueBuffer = undefined;
21141 var i: u32 = 1;21179 var i: u32 = 1;
21142 while (i < vec_len) : (i += 1) {21180 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);
21144 switch (operation) {21182 switch (operation) {
21145 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, sema.mod),21183 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, mod),
21146 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, sema.mod),21184 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, mod),
21147 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, sema.mod),21185 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, mod),
21148 .Min => accum = accum.numberMin(elem_val, target),21186 .Min => accum = accum.numberMin(elem_val, mod),
21149 .Max => accum = accum.numberMax(elem_val, target),21187 .Max => accum = accum.numberMax(elem_val, mod),
21150 .Add => accum = try sema.numberAddWrapScalar(accum, elem_val, scalar_ty),21188 .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),
21152 }21190 }
21153 }21191 }
21154 return sema.addConstant(scalar_ty, accum);21192 return sema.addConstant(scalar_ty, accum);
...@@ -21165,6 +21203,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -21165,6 +21203,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
21165}21203}
2116621204
21167fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {21205fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
21206 const mod = sema.mod;
21168 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;21207 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
21169 const extra = sema.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data;21208 const extra = sema.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data;
21170 const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };21209 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...@@ -21177,7 +21216,7 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21177 var mask = try sema.resolveInst(extra.mask);21216 var mask = try sema.resolveInst(extra.mask);
21178 var mask_ty = sema.typeOf(mask);21217 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)) {
21181 .Array, .Vector => sema.typeOf(mask).arrayLen(),21220 .Array, .Vector => sema.typeOf(mask).arrayLen(),
21182 else => return sema.fail(block, mask_src, "expected vector or array, found '{}'", .{sema.typeOf(mask).fmt(sema.mod)}),21221 else => return sema.fail(block, mask_src, "expected vector or array, found '{}'", .{sema.typeOf(mask).fmt(sema.mod)}),
21183 };21222 };
...@@ -21200,6 +21239,7 @@ fn analyzeShuffle(...@@ -21200,6 +21239,7 @@ fn analyzeShuffle(
21200 mask: Value,21239 mask: Value,
21201 mask_len: u32,21240 mask_len: u32,
21202) CompileError!Air.Inst.Ref {21241) CompileError!Air.Inst.Ref {
21242 const mod = sema.mod;
21203 const a_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = src_node };21243 const a_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = src_node };
21204 const b_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = src_node };21244 const b_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = src_node };
21205 const mask_src: LazySrcLoc = .{ .node_offset_builtin_call_arg3 = src_node };21245 const mask_src: LazySrcLoc = .{ .node_offset_builtin_call_arg3 = src_node };
...@@ -21211,7 +21251,7 @@ fn analyzeShuffle(...@@ -21211,7 +21251,7 @@ fn analyzeShuffle(
21211 .elem_type = elem_ty,21251 .elem_type = elem_ty,
21212 });21252 });
2121321253
21214 var maybe_a_len = switch (sema.typeOf(a).zigTypeTag()) {21254 var maybe_a_len = switch (sema.typeOf(a).zigTypeTag(mod)) {
21215 .Array, .Vector => sema.typeOf(a).arrayLen(),21255 .Array, .Vector => sema.typeOf(a).arrayLen(),
21216 .Undefined => null,21256 .Undefined => null,
21217 else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{21257 else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{
...@@ -21219,7 +21259,7 @@ fn analyzeShuffle(...@@ -21219,7 +21259,7 @@ fn analyzeShuffle(
21219 sema.typeOf(a).fmt(sema.mod),21259 sema.typeOf(a).fmt(sema.mod),
21220 }),21260 }),
21221 };21261 };
21222 var maybe_b_len = switch (sema.typeOf(b).zigTypeTag()) {21262 var maybe_b_len = switch (sema.typeOf(b).zigTypeTag(mod)) {
21223 .Array, .Vector => sema.typeOf(b).arrayLen(),21263 .Array, .Vector => sema.typeOf(b).arrayLen(),
21224 .Undefined => null,21264 .Undefined => null,
21225 else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{21265 else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{
...@@ -21255,7 +21295,7 @@ fn analyzeShuffle(...@@ -21255,7 +21295,7 @@ fn analyzeShuffle(
21255 var buf: Value.ElemValueBuffer = undefined;21295 var buf: Value.ElemValueBuffer = undefined;
21256 const elem = mask.elemValueBuffer(sema.mod, i, &buf);21296 const elem = mask.elemValueBuffer(sema.mod, i, &buf);
21257 if (elem.isUndef()) continue;21297 if (elem.isUndef()) continue;
21258 const int = elem.toSignedInt(sema.mod.getTarget());21298 const int = elem.toSignedInt(mod);
21259 var unsigned: u32 = undefined;21299 var unsigned: u32 = undefined;
21260 var chosen: u32 = undefined;21300 var chosen: u32 = undefined;
21261 if (int >= 0) {21301 if (int >= 0) {
...@@ -21297,7 +21337,7 @@ fn analyzeShuffle(...@@ -21297,7 +21337,7 @@ fn analyzeShuffle(
21297 values[i] = Value.undef;21337 values[i] = Value.undef;
21298 continue;21338 continue;
21299 }21339 }
21300 const int = mask_elem_val.toSignedInt(sema.mod.getTarget());21340 const int = mask_elem_val.toSignedInt(mod);
21301 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int);21341 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int);
21302 if (int >= 0) {21342 if (int >= 0) {
21303 values[i] = try a_val.elemValue(sema.mod, sema.arena, unsigned);21343 values[i] = try a_val.elemValue(sema.mod, sema.arena, unsigned);
...@@ -21356,6 +21396,7 @@ fn analyzeShuffle(...@@ -21356,6 +21396,7 @@ fn analyzeShuffle(
21356}21396}
2135721397
21358fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {21398fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
21399 const mod = sema.mod;
21359 const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data;21400 const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data;
2136021401
21361 const src = LazySrcLoc.nodeOffset(extra.node);21402 const src = LazySrcLoc.nodeOffset(extra.node);
...@@ -21369,7 +21410,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -21369,7 +21410,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
21369 const pred_uncoerced = try sema.resolveInst(extra.pred);21410 const pred_uncoerced = try sema.resolveInst(extra.pred);
21370 const pred_ty = sema.typeOf(pred_uncoerced);21411 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)) {
21373 .Vector, .Array => pred_ty.arrayLen(),21414 .Vector, .Array => pred_ty.arrayLen(),
21374 else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(sema.mod)}),21415 else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(sema.mod)}),
21375 };21416 };
...@@ -21489,6 +21530,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -21489,6 +21530,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
21489}21530}
2149021531
21491fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {21532fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
21533 const mod = sema.mod;
21492 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;21534 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
21493 const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data;21535 const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data;
21494 const src = inst_data.src();21536 const src = inst_data.src();
...@@ -21505,7 +21547,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -21505,7 +21547,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
21505 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);21547 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);
21506 const op = try sema.resolveAtomicRmwOp(block, op_src, extra.operation);21548 const op = try sema.resolveAtomicRmwOp(block, op_src, extra.operation);
2150721549
21508 switch (elem_ty.zigTypeTag()) {21550 switch (elem_ty.zigTypeTag(mod)) {
21509 .Enum => if (op != .Xchg) {21551 .Enum => if (op != .Xchg) {
21510 return sema.fail(block, op_src, "@atomicRmw with enum only allowed with .Xchg", .{});21552 return sema.fail(block, op_src, "@atomicRmw with enum only allowed with .Xchg", .{});
21511 },21553 },
...@@ -21536,7 +21578,6 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -21536,7 +21578,6 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
21536 break :rs operand_src;21578 break :rs operand_src;
21537 };21579 };
21538 if (ptr_val.isComptimeMutablePtr()) {21580 if (ptr_val.isComptimeMutablePtr()) {
21539 const target = sema.mod.getTarget();
21540 const ptr_ty = sema.typeOf(ptr);21581 const ptr_ty = sema.typeOf(ptr);
21541 const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src;21582 const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src;
21542 const new_val = switch (op) {21583 const new_val = switch (op) {
...@@ -21544,12 +21585,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -21544,12 +21585,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
21544 .Xchg => operand_val,21585 .Xchg => operand_val,
21545 .Add => try sema.numberAddWrapScalar(stored_val, operand_val, elem_ty),21586 .Add => try sema.numberAddWrapScalar(stored_val, operand_val, elem_ty),
21546 .Sub => try sema.numberSubWrapScalar(stored_val, operand_val, elem_ty),21587 .Sub => try sema.numberSubWrapScalar(stored_val, operand_val, elem_ty),
21547 .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, sema.mod),21588 .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, mod),
21548 .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, sema.mod),21589 .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, mod),
21549 .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, sema.mod),21590 .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, mod),
21550 .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, sema.mod),21591 .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, mod),
21551 .Max => stored_val.numberMax (operand_val, target),21592 .Max => stored_val.numberMax (operand_val, mod),
21552 .Min => stored_val.numberMin (operand_val, target),21593 .Min => stored_val.numberMin (operand_val, mod),
21553 // zig fmt: on21594 // zig fmt: on
21554 };21595 };
21555 try sema.storePtrVal(block, src, ptr_val, new_val, elem_ty);21596 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....@@ -21623,8 +21664,9 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
21623 const maybe_mulend1 = try sema.resolveMaybeUndefVal(mulend1);21664 const maybe_mulend1 = try sema.resolveMaybeUndefVal(mulend1);
21624 const maybe_mulend2 = try sema.resolveMaybeUndefVal(mulend2);21665 const maybe_mulend2 = try sema.resolveMaybeUndefVal(mulend2);
21625 const maybe_addend = try sema.resolveMaybeUndefVal(addend);21666 const maybe_addend = try sema.resolveMaybeUndefVal(addend);
21667 const mod = sema.mod;
2162621668
21627 switch (ty.zigTypeTag()) {21669 switch (ty.zigTypeTag(mod)) {
21628 .ComptimeFloat, .Float, .Vector => {},21670 .ComptimeFloat, .Float, .Vector => {},
21629 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(sema.mod)}),21671 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(sema.mod)}),
21630 }21672 }
...@@ -21743,7 +21785,6 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -21743,7 +21785,6 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2174321785
21744 const callee_ty = sema.typeOf(func);21786 const callee_ty = sema.typeOf(func);
21745 const func_ty = try sema.checkCallArgumentCount(block, func, func_src, callee_ty, resolved_args.len, false);21787 const func_ty = try sema.checkCallArgumentCount(block, func, func_src, callee_ty, resolved_args.len, false);
21746
21747 const ensure_result_used = extra.flags.ensure_result_used;21788 const ensure_result_used = extra.flags.ensure_result_used;
21748 return sema.analyzeCall(block, func, func_ty, func_src, call_src, modifier, ensure_result_used, resolved_args, null, null);21789 return sema.analyzeCall(block, func, func_ty, func_src, call_src, modifier, ensure_result_used, resolved_args, null, null);
21749}21790}
...@@ -21760,13 +21801,14 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -21760,13 +21801,14 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
21760 const field_name = try sema.resolveConstString(block, name_src, extra.field_name, "field name must be comptime-known");21801 const field_name = try sema.resolveConstString(block, name_src, extra.field_name, "field name must be comptime-known");
21761 const field_ptr = try sema.resolveInst(extra.field_ptr);21802 const field_ptr = try sema.resolveInst(extra.field_ptr);
21762 const field_ptr_ty = sema.typeOf(field_ptr);21803 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) {
21765 return sema.fail(block, ty_src, "expected struct or union type, found '{}'", .{parent_ty.fmt(sema.mod)});21807 return sema.fail(block, ty_src, "expected struct or union type, found '{}'", .{parent_ty.fmt(sema.mod)});
21766 }21808 }
21767 try sema.resolveTypeLayout(parent_ty);21809 try sema.resolveTypeLayout(parent_ty);
2176821810
21769 const field_index = switch (parent_ty.zigTypeTag()) {21811 const field_index = switch (parent_ty.zigTypeTag(mod)) {
21770 .Struct => blk: {21812 .Struct => blk: {
21771 if (parent_ty.isTuple()) {21813 if (parent_ty.isTuple()) {
21772 if (mem.eql(u8, field_name, "len")) {21814 if (mem.eql(u8, field_name, "len")) {
...@@ -21781,7 +21823,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -21781,7 +21823,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
21781 else => unreachable,21823 else => unreachable,
21782 };21824 };
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)) {
21785 return sema.fail(block, src, "cannot get @fieldParentPtr of a comptime field", .{});21827 return sema.fail(block, src, "cannot get @fieldParentPtr of a comptime field", .{});
21786 }21828 }
2178721829
...@@ -21913,15 +21955,14 @@ fn analyzeMinMax(...@@ -21913,15 +21955,14 @@ fn analyzeMinMax(
21913) CompileError!Air.Inst.Ref {21955) CompileError!Air.Inst.Ref {
21914 assert(operands.len == operand_srcs.len);21956 assert(operands.len == operand_srcs.len);
21915 assert(operands.len > 0);21957 assert(operands.len > 0);
21958 const mod = sema.mod;
2191621959
21917 if (operands.len == 1) return operands[0];21960 if (operands.len == 1) return operands[0];
2191821961
21919 const mod = sema.mod;
21920 const target = mod.getTarget();
21921 const opFunc = switch (air_tag) {21962 const opFunc = switch (air_tag) {
21922 .min => Value.numberMin,21963 .min => Value.numberMin,
21923 .max => Value.numberMax,21964 .max => Value.numberMax,
21924 else => unreachable,21965 else => @compileError("unreachable"),
21925 };21966 };
2192621967
21927 // First, find all comptime-known arguments, and get their min/max21968 // First, find all comptime-known arguments, and get their min/max
...@@ -21949,7 +21990,7 @@ fn analyzeMinMax(...@@ -21949,7 +21990,7 @@ fn analyzeMinMax(
21949 try sema.resolveLazyValue(operand_val);21990 try sema.resolveLazyValue(operand_val);
2195021991
21951 const vec_len = simd_op.len orelse {21992 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);
21953 cur_minmax = try sema.addConstant(simd_op.result_ty, result_val);21994 cur_minmax = try sema.addConstant(simd_op.result_ty, result_val);
21954 continue;21995 continue;
21955 };21996 };
...@@ -21959,7 +22000,7 @@ fn analyzeMinMax(...@@ -21959,7 +22000,7 @@ fn analyzeMinMax(
21959 for (elems, 0..) |*elem, i| {22000 for (elems, 0..) |*elem, i| {
21960 const lhs_elem_val = cur_val.elemValueBuffer(mod, i, &lhs_buf);22001 const lhs_elem_val = cur_val.elemValueBuffer(mod, i, &lhs_buf);
21961 const rhs_elem_val = operand_val.elemValueBuffer(mod, i, &rhs_buf);22002 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);
21963 }22004 }
21964 cur_minmax = try sema.addConstant(22005 cur_minmax = try sema.addConstant(
21965 simd_op.result_ty,22006 simd_op.result_ty,
...@@ -21984,7 +22025,7 @@ fn analyzeMinMax(...@@ -21984,7 +22025,7 @@ fn analyzeMinMax(
21984 break :refined orig_ty;22025 break :refined orig_ty;
21985 }22026 }
2198622027
21987 const refined_ty = if (orig_ty.zigTypeTag() == .Vector) blk: {22028 const refined_ty = if (orig_ty.zigTypeTag(mod) == .Vector) blk: {
21988 const elem_ty = orig_ty.childType();22029 const elem_ty = orig_ty.childType();
21989 const len = orig_ty.vectorLen();22030 const len = orig_ty.vectorLen();
2199022031
...@@ -21996,16 +22037,16 @@ fn analyzeMinMax(...@@ -21996,16 +22037,16 @@ fn analyzeMinMax(
21996 for (1..len) |idx| {22037 for (1..len) |idx| {
21997 const elem_val = try val.elemValue(mod, sema.arena, idx);22038 const elem_val = try val.elemValue(mod, sema.arena, idx);
21998 if (elem_val.isUndef()) break :blk orig_ty; // can't refine undef22039 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;22040 if (Value.order(elem_val, cur_min, mod).compare(.lt)) cur_min = elem_val;
22000 if (Value.order(elem_val, cur_max, target).compare(.gt)) cur_max = elem_val;22041 if (Value.order(elem_val, cur_max, mod).compare(.gt)) cur_max = elem_val;
22001 }22042 }
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);
22004 break :blk try Type.vector(sema.arena, len, refined_elem_ty);22045 break :blk try Type.vector(sema.arena, len, refined_elem_ty);
22005 } else blk: {22046 } else blk: {
22006 if (orig_ty.isAnyFloat()) break :blk orig_ty; // can't refine floats22047 if (orig_ty.isAnyFloat()) break :blk orig_ty; // can't refine floats
22007 if (val.isUndef()) break :blk orig_ty; // can't refine undef22048 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);
22009 };22050 };
2201022051
22011 // Apply the refined type to the current value - this isn't strictly necessary in the22052 // Apply the refined type to the current value - this isn't strictly necessary in the
...@@ -22061,7 +22102,7 @@ fn analyzeMinMax(...@@ -22061,7 +22102,7 @@ fn analyzeMinMax(
22061 // Finally, refine the type based on the comptime-known bound.22102 // Finally, refine the type based on the comptime-known bound.
22062 if (known_undef) break :refine; // can't refine undef22103 if (known_undef) break :refine; // can't refine undef
22063 const unrefined_ty = sema.typeOf(cur_minmax.?);22104 const unrefined_ty = sema.typeOf(cur_minmax.?);
22064 const is_vector = unrefined_ty.zigTypeTag() == .Vector;22105 const is_vector = unrefined_ty.zigTypeTag(mod) == .Vector;
22065 const comptime_elem_ty = if (is_vector) comptime_ty.childType() else comptime_ty;22106 const comptime_elem_ty = if (is_vector) comptime_ty.childType() else comptime_ty;
22066 const unrefined_elem_ty = if (is_vector) unrefined_ty.childType() else unrefined_ty;22107 const unrefined_elem_ty = if (is_vector) unrefined_ty.childType() else unrefined_ty;
2206722108
...@@ -22069,18 +22110,18 @@ fn analyzeMinMax(...@@ -22069,18 +22110,18 @@ fn analyzeMinMax(
2206922110
22070 // Compute the final bounds based on the runtime type and the comptime-known bound type22111 // Compute the final bounds based on the runtime type and the comptime-known bound type
22071 const min_val = switch (air_tag) {22112 const min_val = switch (air_tag) {
22072 .min => try unrefined_elem_ty.minInt(sema.arena, target),22113 .min => try unrefined_elem_ty.minInt(sema.arena, mod),
22073 .max => try comptime_elem_ty.minInt(sema.arena, target), // @max(ct, rt) >= ct22114 .max => try comptime_elem_ty.minInt(sema.arena, mod), // @max(ct, rt) >= ct
22074 else => unreachable,22115 else => unreachable,
22075 };22116 };
22076 const max_val = switch (air_tag) {22117 const max_val = switch (air_tag) {
22077 .min => try comptime_elem_ty.maxInt(sema.arena, target), // @min(ct, rt) <= ct22118 .min => try comptime_elem_ty.maxInt(sema.arena, mod), // @min(ct, rt) <= ct
22078 .max => try unrefined_elem_ty.maxInt(sema.arena, target),22119 .max => try unrefined_elem_ty.maxInt(sema.arena, mod),
22079 else => unreachable,22120 else => unreachable,
22080 };22121 };
2208122122
22082 // Find the smallest type which can contain these bounds22123 // 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
22085 const final_ty = if (is_vector)22126 const final_ty = if (is_vector)
22086 try Type.vector(sema.arena, unrefined_ty.vectorLen(), final_elem_ty)22127 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...@@ -22132,6 +22173,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
22132 const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr);22173 const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr);
22133 const src_len = try indexablePtrLenOrNone(sema, block, src_src, src_ptr);22174 const src_len = try indexablePtrLenOrNone(sema, block, src_src, src_ptr);
22134 const target = sema.mod.getTarget();22175 const target = sema.mod.getTarget();
22176 const mod = sema.mod;
2213522177
22136 if (dest_ty.isConstPtr()) {22178 if (dest_ty.isConstPtr()) {
22137 return sema.fail(block, dest_src, "cannot memcpy to constant pointer", .{});22179 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...@@ -22196,7 +22238,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
22196 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: {22238 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: {
22197 if (!dest_ptr_val.isComptimeMutablePtr()) break :rs dest_src;22239 if (!dest_ptr_val.isComptimeMutablePtr()) break :rs dest_src;
22198 if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| {22240 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)).?;
22200 const len = try sema.usizeCast(block, dest_src, len_u64);22242 const len = try sema.usizeCast(block, dest_src, len_u64);
22201 for (0..len) |i| {22243 for (0..len) |i| {
22202 const elem_index = try sema.addIntUnsigned(Type.usize, i);22244 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...@@ -22239,12 +22281,12 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
22239 // lowering. The AIR instruction requires pointers with element types of22281 // lowering. The AIR instruction requires pointers with element types of
22240 // equal ABI size.22282 // 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) {
22243 return sema.fail(block, src, "TODO: lower @memcpy to a for loop because the source or destination iterable is a tuple", .{});22285 return sema.fail(block, src, "TODO: lower @memcpy to a for loop because the source or destination iterable is a tuple", .{});
22244 }22286 }
2224522287
22246 const dest_elem_ty = dest_ty.elemType2();22288 const dest_elem_ty = dest_ty.elemType2(mod);
22247 const src_elem_ty = src_ty.elemType2();22289 const src_elem_ty = src_ty.elemType2(mod);
22248 if (.ok != try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, true, target, dest_src, src_src)) {22290 if (.ok != try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, true, target, dest_src, src_src)) {
22249 return sema.fail(block, src, "TODO: lower @memcpy to a for loop because the element types have different ABI sizes", .{});22291 return sema.fail(block, src, "TODO: lower @memcpy to a for loop because the element types have different ABI sizes", .{});
22250 }22292 }
...@@ -22255,7 +22297,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -22255,7 +22297,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
22255 var new_dest_ptr = dest_ptr;22297 var new_dest_ptr = dest_ptr;
22256 var new_src_ptr = src_ptr;22298 var new_src_ptr = src_ptr;
22257 if (len_val) |val| {22299 if (len_val) |val| {
22258 const len = val.toUnsignedInt(target);22300 const len = val.toUnsignedInt(mod);
22259 if (len == 0) {22301 if (len == 0) {
22260 // This AIR instruction guarantees length > 0 if it is comptime-known.22302 // This AIR instruction guarantees length > 0 if it is comptime-known.
22261 return;22303 return;
...@@ -22320,6 +22362,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -22320,6 +22362,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
22320}22362}
2232122363
22322fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {22364fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
22365 const mod = sema.mod;
22323 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;22366 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
22324 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;22367 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
22325 const src = inst_data.src();22368 const src = inst_data.src();
...@@ -22334,14 +22377,13 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -22334,14 +22377,13 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
22334 return sema.fail(block, dest_src, "cannot memset constant pointer", .{});22377 return sema.fail(block, dest_src, "cannot memset constant pointer", .{});
22335 }22378 }
2233622379
22337 const dest_elem_ty = dest_ptr_ty.elemType2();22380 const dest_elem_ty = dest_ptr_ty.elemType2(mod);
22338 const target = sema.mod.getTarget();
2233922381
22340 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |ptr_val| rs: {22382 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |ptr_val| rs: {
22341 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, "len", dest_src);22383 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, "len", dest_src);
22342 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse22384 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse
22343 break :rs dest_src;22385 break :rs dest_src;
22344 const len_u64 = (try len_val.getUnsignedIntAdvanced(target, sema)).?;22386 const len_u64 = (try len_val.getUnsignedIntAdvanced(mod, sema)).?;
22345 const len = try sema.usizeCast(block, dest_src, len_u64);22387 const len = try sema.usizeCast(block, dest_src, len_u64);
22346 if (len == 0) {22388 if (len == 0) {
22347 // This AIR instruction guarantees length > 0 if it is comptime-known.22389 // 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...@@ -22499,9 +22541,10 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22499 const tracy = trace(@src());22541 const tracy = trace(@src());
22500 defer tracy.end();22542 defer tracy.end();
2250122543
22544 const mod = sema.mod;
22502 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;22545 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
22503 const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);22546 const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
22504 const target = sema.mod.getTarget();22547 const target = mod.getTarget();
2250522548
22506 const align_src: LazySrcLoc = .{ .node_offset_fn_type_align = inst_data.src_node };22549 const align_src: LazySrcLoc = .{ .node_offset_fn_type_align = inst_data.src_node };
22507 const addrspace_src: LazySrcLoc = .{ .node_offset_fn_type_addrspace = inst_data.src_node };22550 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...@@ -22535,7 +22578,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22535 if (val.tag() == .generic_poison) {22578 if (val.tag() == .generic_poison) {
22536 break :blk null;22579 break :blk null;
22537 }22580 }
22538 const alignment = @intCast(u32, val.toUnsignedInt(target));22581 const alignment = @intCast(u32, val.toUnsignedInt(mod));
22539 try sema.validateAlign(block, align_src, alignment);22582 try sema.validateAlign(block, align_src, alignment);
22540 if (alignment == target_util.defaultFunctionAlignment(target)) {22583 if (alignment == target_util.defaultFunctionAlignment(target)) {
22541 break :blk 0;22584 break :blk 0;
...@@ -22551,7 +22594,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -22551,7 +22594,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22551 },22594 },
22552 else => |e| return e,22595 else => |e| return e,
22553 };22596 };
22554 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(target));22597 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(mod));
22555 try sema.validateAlign(block, align_src, alignment);22598 try sema.validateAlign(block, align_src, alignment);
22556 if (alignment == target_util.defaultFunctionAlignment(target)) {22599 if (alignment == target_util.defaultFunctionAlignment(target)) {
22557 break :blk 0;22600 break :blk 0;
...@@ -22642,8 +22685,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -22642,8 +22685,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22642 extra_index += body.len;22685 extra_index += body.len;
2264322686
22644 const val = try sema.resolveGenericBody(block, ret_src, body, inst, Type.type, "return type must be comptime-known");22687 const val = try sema.resolveGenericBody(block, ret_src, body, inst, Type.type, "return type must be comptime-known");
22645 var buffer: Value.ToTypeBuffer = undefined;22688 const ty = try val.toType().copy(sema.arena);
22646 const ty = try val.toType(&buffer).copy(sema.arena);
22647 break :blk ty;22689 break :blk ty;
22648 } else if (extra.data.bits.has_ret_ty_ref) blk: {22690 } else if (extra.data.bits.has_ret_ty_ref) blk: {
22649 const ret_ty_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);22691 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...@@ -22654,8 +22696,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22654 },22696 },
22655 else => |e| return e,22697 else => |e| return e,
22656 };22698 };
22657 var buffer: Value.ToTypeBuffer = undefined;22699 const ty = try ret_ty_tv.val.toType().copy(sema.arena);
22658 const ty = try ret_ty_tv.val.toType(&buffer).copy(sema.arena);
22659 break :blk ty;22700 break :blk ty;
22660 } else Type.void;22701 } else Type.void;
2266122702
...@@ -22727,13 +22768,14 @@ fn zirCDefine(...@@ -22727,13 +22768,14 @@ fn zirCDefine(
22727 block: *Block,22768 block: *Block,
22728 extended: Zir.Inst.Extended.InstData,22769 extended: Zir.Inst.Extended.InstData,
22729) CompileError!Air.Inst.Ref {22770) CompileError!Air.Inst.Ref {
22771 const mod = sema.mod;
22730 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;22772 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
22731 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };22773 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
22732 const val_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };22774 const val_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
2273322775
22734 const name = try sema.resolveConstString(block, name_src, extra.lhs, "name of macro being undefined must be comptime-known");22776 const name = try sema.resolveConstString(block, name_src, extra.lhs, "name of macro being undefined must be comptime-known");
22735 const rhs = try sema.resolveInst(extra.rhs);22777 const rhs = try sema.resolveInst(extra.rhs);
22736 if (sema.typeOf(rhs).zigTypeTag() != .Void) {22778 if (sema.typeOf(rhs).zigTypeTag(mod) != .Void) {
22737 const value = try sema.resolveConstString(block, val_src, extra.rhs, "value of macro being undefined must be comptime-known");22779 const value = try sema.resolveConstString(block, val_src, extra.rhs, "value of macro being undefined must be comptime-known");
22738 try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value });22780 try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value });
22739 } else {22781 } else {
...@@ -22799,9 +22841,9 @@ fn resolvePrefetchOptions(...@@ -22799,9 +22841,9 @@ fn resolvePrefetchOptions(
22799 src: LazySrcLoc,22841 src: LazySrcLoc,
22800 zir_ref: Zir.Inst.Ref,22842 zir_ref: Zir.Inst.Ref,
22801) CompileError!std.builtin.PrefetchOptions {22843) CompileError!std.builtin.PrefetchOptions {
22844 const mod = sema.mod;
22802 const options_ty = try sema.getBuiltinType("PrefetchOptions");22845 const options_ty = try sema.getBuiltinType("PrefetchOptions");
22803 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);22846 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
22804 const target = sema.mod.getTarget();
2280522847
22806 const rw_src = sema.maybeOptionsSrc(block, src, "rw");22848 const rw_src = sema.maybeOptionsSrc(block, src, "rw");
22807 const locality_src = sema.maybeOptionsSrc(block, src, "locality");22849 const locality_src = sema.maybeOptionsSrc(block, src, "locality");
...@@ -22818,7 +22860,7 @@ fn resolvePrefetchOptions(...@@ -22818,7 +22860,7 @@ fn resolvePrefetchOptions(
2281822860
22819 return std.builtin.PrefetchOptions{22861 return std.builtin.PrefetchOptions{
22820 .rw = rw_val.toEnum(std.builtin.PrefetchOptions.Rw),22862 .rw = rw_val.toEnum(std.builtin.PrefetchOptions.Rw),
22821 .locality = @intCast(u2, locality_val.toUnsignedInt(target)),22863 .locality = @intCast(u2, locality_val.toUnsignedInt(mod)),
22822 .cache = cache_val.toEnum(std.builtin.PrefetchOptions.Cache),22864 .cache = cache_val.toEnum(std.builtin.PrefetchOptions.Cache),
22823 };22865 };
22824}22866}
...@@ -22887,7 +22929,7 @@ fn resolveExternOptions(...@@ -22887,7 +22929,7 @@ fn resolveExternOptions(
22887 const is_thread_local = try sema.fieldVal(block, src, options, "is_thread_local", thread_local_src);22929 const is_thread_local = try sema.fieldVal(block, src, options, "is_thread_local", thread_local_src);
22888 const is_thread_local_val = try sema.resolveConstValue(block, thread_local_src, is_thread_local, "threadlocality of the extern symbol must be comptime-known");22930 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: {
22891 const payload = library_name_val.castTag(.opt_payload).?.data;22933 const payload = library_name_val.castTag(.opt_payload).?.data;
22892 const library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, mod);22934 const library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, mod);
22893 if (library_name.len == 0) {22935 if (library_name.len == 0) {
...@@ -22917,17 +22959,17 @@ fn zirBuiltinExtern(...@@ -22917,17 +22959,17 @@ fn zirBuiltinExtern(
22917 block: *Block,22959 block: *Block,
22918 extended: Zir.Inst.Extended.InstData,22960 extended: Zir.Inst.Extended.InstData,
22919) CompileError!Air.Inst.Ref {22961) CompileError!Air.Inst.Ref {
22962 const mod = sema.mod;
22920 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;22963 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
22921 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };22964 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
22922 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };22965 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
2292322966
22924 var ty = try sema.resolveType(block, ty_src, extra.lhs);22967 var ty = try sema.resolveType(block, ty_src, extra.lhs);
22925 if (!ty.isPtrAtRuntime()) {22968 if (!ty.isPtrAtRuntime(mod)) {
22926 return sema.fail(block, ty_src, "expected (optional) pointer", .{});22969 return sema.fail(block, ty_src, "expected (optional) pointer", .{});
22927 }22970 }
22928 if (!try sema.validateExternType(ty.childType(), .other)) {22971 if (!try sema.validateExternType(ty.childType(), .other)) {
22929 const msg = msg: {22972 const msg = msg: {
22930 const mod = sema.mod;
22931 const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});22973 const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});
22932 errdefer msg.destroy(sema.gpa);22974 errdefer msg.destroy(sema.gpa);
22933 const src_decl = sema.mod.declPtr(block.src_decl);22975 const src_decl = sema.mod.declPtr(block.src_decl);
...@@ -22945,7 +22987,7 @@ fn zirBuiltinExtern(...@@ -22945,7 +22987,7 @@ fn zirBuiltinExtern(
22945 else => |e| return e,22987 else => |e| return e,
22946 };22988 };
2294722989
22948 if (options.linkage == .Weak and !ty.ptrAllowsZero()) {22990 if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) {
22949 ty = try Type.optional(sema.arena, ty);22991 ty = try Type.optional(sema.arena, ty);
22950 }22992 }
2295122993
...@@ -23087,7 +23129,7 @@ fn validateVarType(...@@ -23087,7 +23129,7 @@ fn validateVarType(
2308723129
23088 const src_decl = mod.declPtr(block.src_decl);23130 const src_decl = mod.declPtr(block.src_decl);
23089 try sema.explainWhyTypeIsComptime(msg, src.toSrcLoc(src_decl), var_ty);23131 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) {
23091 try sema.errNote(block, src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{});23133 try sema.errNote(block, src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{});
23092 }23134 }
2309323135
...@@ -23101,8 +23143,9 @@ fn validateRunTimeType(...@@ -23101,8 +23143,9 @@ fn validateRunTimeType(
23101 var_ty: Type,23143 var_ty: Type,
23102 is_extern: bool,23144 is_extern: bool,
23103) CompileError!bool {23145) CompileError!bool {
23146 const mod = sema.mod;
23104 var ty = var_ty;23147 var ty = var_ty;
23105 while (true) switch (ty.zigTypeTag()) {23148 while (true) switch (ty.zigTypeTag(mod)) {
23106 .Bool,23149 .Bool,
23107 .Int,23150 .Int,
23108 .Float,23151 .Float,
...@@ -23126,9 +23169,9 @@ fn validateRunTimeType(...@@ -23126,9 +23169,9 @@ fn validateRunTimeType(
2312623169
23127 .Pointer => {23170 .Pointer => {
23128 const elem_ty = ty.childType();23171 const elem_ty = ty.childType();
23129 switch (elem_ty.zigTypeTag()) {23172 switch (elem_ty.zigTypeTag(mod)) {
23130 .Opaque => return true,23173 .Opaque => return true,
23131 .Fn => return elem_ty.isFnOrHasRuntimeBits(),23174 .Fn => return elem_ty.isFnOrHasRuntimeBits(mod),
23132 else => ty = elem_ty,23175 else => ty = elem_ty,
23133 }23176 }
23134 },23177 },
...@@ -23174,7 +23217,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -23174,7 +23217,7 @@ fn explainWhyTypeIsComptimeInner(
23174 type_set: *TypeSet,23217 type_set: *TypeSet,
23175) CompileError!void {23218) CompileError!void {
23176 const mod = sema.mod;23219 const mod = sema.mod;
23177 switch (ty.zigTypeTag()) {23220 switch (ty.zigTypeTag(mod)) {
23178 .Bool,23221 .Bool,
23179 .Int,23222 .Int,
23180 .Float,23223 .Float,
...@@ -23211,8 +23254,8 @@ fn explainWhyTypeIsComptimeInner(...@@ -23211,8 +23254,8 @@ fn explainWhyTypeIsComptimeInner(
23211 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.elemType(), type_set);23254 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.elemType(), type_set);
23212 },23255 },
23213 .Pointer => {23256 .Pointer => {
23214 const elem_ty = ty.elemType2();23257 const elem_ty = ty.elemType2(mod);
23215 if (elem_ty.zigTypeTag() == .Fn) {23258 if (elem_ty.zigTypeTag(mod) == .Fn) {
23216 const fn_info = elem_ty.fnInfo();23259 const fn_info = elem_ty.fnInfo();
23217 if (fn_info.is_generic) {23260 if (fn_info.is_generic) {
23218 try mod.errNoteNonLazy(src_loc, msg, "function is generic", .{});23261 try mod.errNoteNonLazy(src_loc, msg, "function is generic", .{});
...@@ -23221,7 +23264,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -23221,7 +23264,7 @@ fn explainWhyTypeIsComptimeInner(
23221 .Inline => try mod.errNoteNonLazy(src_loc, msg, "function has inline calling convention", .{}),23264 .Inline => try mod.errNoteNonLazy(src_loc, msg, "function has inline calling convention", .{}),
23222 else => {},23265 else => {},
23223 }23266 }
23224 if (fn_info.return_type.comptimeOnly()) {23267 if (fn_info.return_type.comptimeOnly(mod)) {
23225 try mod.errNoteNonLazy(src_loc, msg, "function has a comptime-only return type", .{});23268 try mod.errNoteNonLazy(src_loc, msg, "function has a comptime-only return type", .{});
23226 }23269 }
23227 return;23270 return;
...@@ -23295,7 +23338,8 @@ fn validateExternType(...@@ -23295,7 +23338,8 @@ fn validateExternType(
23295 ty: Type,23338 ty: Type,
23296 position: ExternPosition,23339 position: ExternPosition,
23297) !bool {23340) !bool {
23298 switch (ty.zigTypeTag()) {23341 const mod = sema.mod;
23342 switch (ty.zigTypeTag(mod)) {
23299 .Type,23343 .Type,
23300 .ComptimeFloat,23344 .ComptimeFloat,
23301 .ComptimeInt,23345 .ComptimeInt,
...@@ -23314,7 +23358,7 @@ fn validateExternType(...@@ -23314,7 +23358,7 @@ fn validateExternType(
23314 .AnyFrame,23358 .AnyFrame,
23315 => return true,23359 => return true,
23316 .Pointer => return !(ty.isSlice() or try sema.typeRequiresComptime(ty)),23360 .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) {
23318 8, 16, 32, 64, 128 => return true,23362 8, 16, 32, 64, 128 => return true,
23319 else => return false,23363 else => return false,
23320 },23364 },
...@@ -23329,14 +23373,12 @@ fn validateExternType(...@@ -23329,14 +23373,12 @@ fn validateExternType(
23329 return !Type.fnCallingConventionAllowsZigTypes(target, ty.fnCallingConvention());23373 return !Type.fnCallingConventionAllowsZigTypes(target, ty.fnCallingConvention());
23330 },23374 },
23331 .Enum => {23375 .Enum => {
23332 var buf: Type.Payload.Bits = undefined;23376 return sema.validateExternType(ty.intTagType(), position);
23333 return sema.validateExternType(ty.intTagType(&buf), position);
23334 },23377 },
23335 .Struct, .Union => switch (ty.containerLayout()) {23378 .Struct, .Union => switch (ty.containerLayout()) {
23336 .Extern => return true,23379 .Extern => return true,
23337 .Packed => {23380 .Packed => {
23338 const target = sema.mod.getTarget();23381 const bit_size = try ty.bitSizeAdvanced(mod, sema);
23339 const bit_size = try ty.bitSizeAdvanced(target, sema);
23340 switch (bit_size) {23382 switch (bit_size) {
23341 8, 16, 32, 64, 128 => return true,23383 8, 16, 32, 64, 128 => return true,
23342 else => return false,23384 else => return false,
...@@ -23346,10 +23388,10 @@ fn validateExternType(...@@ -23346,10 +23388,10 @@ fn validateExternType(
23346 },23388 },
23347 .Array => {23389 .Array => {
23348 if (position == .ret_ty or position == .param_ty) return false;23390 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);
23350 },23392 },
23351 .Vector => return sema.validateExternType(ty.elemType2(), .element),23393 .Vector => return sema.validateExternType(ty.elemType2(mod), .element),
23352 .Optional => return ty.isPtrLikeOptional(),23394 .Optional => return ty.isPtrLikeOptional(mod),
23353 }23395 }
23354}23396}
2335523397
...@@ -23361,7 +23403,7 @@ fn explainWhyTypeIsNotExtern(...@@ -23361,7 +23403,7 @@ fn explainWhyTypeIsNotExtern(
23361 position: ExternPosition,23403 position: ExternPosition,
23362) CompileError!void {23404) CompileError!void {
23363 const mod = sema.mod;23405 const mod = sema.mod;
23364 switch (ty.zigTypeTag()) {23406 switch (ty.zigTypeTag(mod)) {
23365 .Opaque,23407 .Opaque,
23366 .Bool,23408 .Bool,
23367 .Float,23409 .Float,
...@@ -23390,7 +23432,7 @@ fn explainWhyTypeIsNotExtern(...@@ -23390,7 +23432,7 @@ fn explainWhyTypeIsNotExtern(
23390 },23432 },
23391 .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),23433 .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),
23392 .NoReturn => try mod.errNoteNonLazy(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),23434 .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)) {
23394 try mod.errNoteNonLazy(src_loc, msg, "only integers with power of two bits are extern compatible", .{});23436 try mod.errNoteNonLazy(src_loc, msg, "only integers with power of two bits are extern compatible", .{});
23395 } else {23437 } else {
23396 try mod.errNoteNonLazy(src_loc, msg, "only integers with 8, 16, 32, 64 and 128 bits are extern compatible", .{});23438 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(...@@ -23409,8 +23451,7 @@ fn explainWhyTypeIsNotExtern(
23409 }23451 }
23410 },23452 },
23411 .Enum => {23453 .Enum => {
23412 var buf: Type.Payload.Bits = undefined;23454 const tag_ty = ty.intTagType();
23413 const tag_ty = ty.intTagType(&buf);
23414 try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});23455 try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});
23415 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);23456 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);
23416 },23457 },
...@@ -23422,17 +23463,17 @@ fn explainWhyTypeIsNotExtern(...@@ -23422,17 +23463,17 @@ fn explainWhyTypeIsNotExtern(
23422 } else if (position == .param_ty) {23463 } else if (position == .param_ty) {
23423 return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{});23464 return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{});
23424 }23465 }
23425 try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(), .element);23466 try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(mod), .element);
23426 },23467 },
23427 .Vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(), .element),23468 .Vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(mod), .element),
23428 .Optional => try mod.errNoteNonLazy(src_loc, msg, "only pointer like optionals are extern compatible", .{}),23469 .Optional => try mod.errNoteNonLazy(src_loc, msg, "only pointer like optionals are extern compatible", .{}),
23429 }23470 }
23430}23471}
2343123472
23432/// Returns true if `ty` is allowed in packed types.23473/// Returns true if `ty` is allowed in packed types.
23433/// Does *NOT* require `ty` to be resolved in any way.23474/// Does *NOT* require `ty` to be resolved in any way.
23434fn validatePackedType(ty: Type) bool {23475fn validatePackedType(ty: Type, mod: *const Module) bool {
23435 switch (ty.zigTypeTag()) {23476 switch (ty.zigTypeTag(mod)) {
23436 .Type,23477 .Type,
23437 .ComptimeFloat,23478 .ComptimeFloat,
23438 .ComptimeInt,23479 .ComptimeInt,
...@@ -23448,7 +23489,7 @@ fn validatePackedType(ty: Type) bool {...@@ -23448,7 +23489,7 @@ fn validatePackedType(ty: Type) bool {
23448 .Fn,23489 .Fn,
23449 .Array,23490 .Array,
23450 => return false,23491 => return false,
23451 .Optional => return ty.isPtrLikeOptional(),23492 .Optional => return ty.isPtrLikeOptional(mod),
23452 .Void,23493 .Void,
23453 .Bool,23494 .Bool,
23454 .Float,23495 .Float,
...@@ -23468,7 +23509,7 @@ fn explainWhyTypeIsNotPacked(...@@ -23468,7 +23509,7 @@ fn explainWhyTypeIsNotPacked(
23468 ty: Type,23509 ty: Type,
23469) CompileError!void {23510) CompileError!void {
23470 const mod = sema.mod;23511 const mod = sema.mod;
23471 switch (ty.zigTypeTag()) {23512 switch (ty.zigTypeTag(mod)) {
23472 .Void,23513 .Void,
23473 .Bool,23514 .Bool,
23474 .Float,23515 .Float,
...@@ -23731,6 +23772,7 @@ fn panicSentinelMismatch(...@@ -23731,6 +23772,7 @@ fn panicSentinelMismatch(
23731 sentinel_index: Air.Inst.Ref,23772 sentinel_index: Air.Inst.Ref,
23732) !void {23773) !void {
23733 assert(!parent_block.is_comptime);23774 assert(!parent_block.is_comptime);
23775 const mod = sema.mod;
23734 const expected_sentinel_val = maybe_sentinel orelse return;23776 const expected_sentinel_val = maybe_sentinel orelse return;
23735 const expected_sentinel = try sema.addConstant(sentinel_ty, expected_sentinel_val);23777 const expected_sentinel = try sema.addConstant(sentinel_ty, expected_sentinel_val);
2373623778
...@@ -23743,7 +23785,7 @@ fn panicSentinelMismatch(...@@ -23743,7 +23785,7 @@ fn panicSentinelMismatch(
23743 break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr);23785 break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr);
23744 };23786 };
2374523787
23746 const ok = if (sentinel_ty.zigTypeTag() == .Vector) ok: {23788 const ok = if (sentinel_ty.zigTypeTag(mod) == .Vector) ok: {
23747 const eql =23789 const eql =
23748 try parent_block.addCmpVector(expected_sentinel, actual_sentinel, .eq);23790 try parent_block.addCmpVector(expected_sentinel, actual_sentinel, .eq);
23749 break :ok try parent_block.addInst(.{23791 break :ok try parent_block.addInst(.{
...@@ -23753,7 +23795,7 @@ fn panicSentinelMismatch(...@@ -23753,7 +23795,7 @@ fn panicSentinelMismatch(
23753 .operation = .And,23795 .operation = .And,
23754 } },23796 } },
23755 });23797 });
23756 } else if (sentinel_ty.isSelfComparable(true))23798 } else if (sentinel_ty.isSelfComparable(mod, true))
23757 try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel)23799 try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel)
23758 else {23800 else {
23759 const panic_fn = try sema.getBuiltin("checkNonScalarSentinel");23801 const panic_fn = try sema.getBuiltin("checkNonScalarSentinel");
...@@ -23848,6 +23890,7 @@ fn fieldVal(...@@ -23848,6 +23890,7 @@ fn fieldVal(
23848 // When editing this function, note that there is corresponding logic to be edited23890 // When editing this function, note that there is corresponding logic to be edited
23849 // in `fieldPtr`. This function takes a value and returns a value.23891 // in `fieldPtr`. This function takes a value and returns a value.
2385023892
23893 const mod = sema.mod;
23851 const arena = sema.arena;23894 const arena = sema.arena;
23852 const object_src = src; // TODO better source location23895 const object_src = src; // TODO better source location
23853 const object_ty = sema.typeOf(object);23896 const object_ty = sema.typeOf(object);
...@@ -23862,7 +23905,7 @@ fn fieldVal(...@@ -23862,7 +23905,7 @@ fn fieldVal(
23862 else23905 else
23863 object_ty;23906 object_ty;
2386423907
23865 switch (inner_ty.zigTypeTag()) {23908 switch (inner_ty.zigTypeTag(mod)) {
23866 .Array => {23909 .Array => {
23867 if (mem.eql(u8, field_name, "len")) {23910 if (mem.eql(u8, field_name, "len")) {
23868 return sema.addConstant(23911 return sema.addConstant(
...@@ -23926,10 +23969,9 @@ fn fieldVal(...@@ -23926,10 +23969,9 @@ fn fieldVal(
23926 object;23969 object;
2392723970
23928 const val = (try sema.resolveDefinedValue(block, object_src, dereffed_type)).?;23971 const val = (try sema.resolveDefinedValue(block, object_src, dereffed_type)).?;
23929 var to_type_buffer: Value.ToTypeBuffer = undefined;23972 const child_type = val.toType();
23930 const child_type = val.toType(&to_type_buffer);
2393123973
23932 switch (try child_type.zigTypeTagOrPoison()) {23974 switch (try child_type.zigTypeTagOrPoison(mod)) {
23933 .ErrorSet => {23975 .ErrorSet => {
23934 const name: []const u8 = if (child_type.castTag(.error_set)) |payload| blk: {23976 const name: []const u8 = if (child_type.castTag(.error_set)) |payload| blk: {
23935 if (payload.data.names.getEntry(field_name)) |entry| {23977 if (payload.data.names.getEntry(field_name)) |entry| {
...@@ -23997,7 +24039,7 @@ fn fieldVal(...@@ -23997,7 +24039,7 @@ fn fieldVal(
23997 const msg = try sema.errMsg(block, src, "type '{}' has no members", .{child_type.fmt(sema.mod)});24039 const msg = try sema.errMsg(block, src, "type '{}' has no members", .{child_type.fmt(sema.mod)});
23998 errdefer msg.destroy(sema.gpa);24040 errdefer msg.destroy(sema.gpa);
23999 if (child_type.isSlice()) try sema.errNote(block, src, msg, "slice values have 'len' and 'ptr' members", .{});24041 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", .{});
24001 break :msg msg;24043 break :msg msg;
24002 };24044 };
24003 return sema.failWithOwnedErrorMsg(msg);24045 return sema.failWithOwnedErrorMsg(msg);
...@@ -24035,9 +24077,10 @@ fn fieldPtr(...@@ -24035,9 +24077,10 @@ fn fieldPtr(
24035 // When editing this function, note that there is corresponding logic to be edited24077 // When editing this function, note that there is corresponding logic to be edited
24036 // in `fieldVal`. This function takes a pointer and returns a pointer.24078 // in `fieldVal`. This function takes a pointer and returns a pointer.
2403724079
24080 const mod = sema.mod;
24038 const object_ptr_src = src; // TODO better source location24081 const object_ptr_src = src; // TODO better source location
24039 const object_ptr_ty = sema.typeOf(object_ptr);24082 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)) {
24041 .Pointer => object_ptr_ty.elemType(),24084 .Pointer => object_ptr_ty.elemType(),
24042 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(sema.mod)}),24085 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(sema.mod)}),
24043 };24086 };
...@@ -24052,7 +24095,7 @@ fn fieldPtr(...@@ -24052,7 +24095,7 @@ fn fieldPtr(
24052 else24095 else
24053 object_ty;24096 object_ty;
2405424097
24055 switch (inner_ty.zigTypeTag()) {24098 switch (inner_ty.zigTypeTag(mod)) {
24056 .Array => {24099 .Array => {
24057 if (mem.eql(u8, field_name, "len")) {24100 if (mem.eql(u8, field_name, "len")) {
24058 var anon_decl = try block.startAnonDecl();24101 var anon_decl = try block.startAnonDecl();
...@@ -24142,10 +24185,9 @@ fn fieldPtr(...@@ -24142,10 +24185,9 @@ fn fieldPtr(
24142 result;24185 result;
2414324186
24144 const val = (sema.resolveDefinedValue(block, src, inner) catch unreachable).?;24187 const val = (sema.resolveDefinedValue(block, src, inner) catch unreachable).?;
24145 var to_type_buffer: Value.ToTypeBuffer = undefined;24188 const child_type = val.toType();
24146 const child_type = val.toType(&to_type_buffer);
2414724189
24148 switch (child_type.zigTypeTag()) {24190 switch (child_type.zigTypeTag(mod)) {
24149 .ErrorSet => {24191 .ErrorSet => {
24150 // TODO resolve inferred error sets24192 // TODO resolve inferred error sets
24151 const name: []const u8 = if (child_type.castTag(.error_set)) |payload| blk: {24193 const name: []const u8 = if (child_type.castTag(.error_set)) |payload| blk: {
...@@ -24258,15 +24300,16 @@ fn fieldCallBind(...@@ -24258,15 +24300,16 @@ fn fieldCallBind(
24258 // When editing this function, note that there is corresponding logic to be edited24300 // When editing this function, note that there is corresponding logic to be edited
24259 // in `fieldVal`. This function takes a pointer and returns a pointer.24301 // in `fieldVal`. This function takes a pointer and returns a pointer.
2426024302
24303 const mod = sema.mod;
24261 const raw_ptr_src = src; // TODO better source location24304 const raw_ptr_src = src; // TODO better source location
24262 const raw_ptr_ty = sema.typeOf(raw_ptr);24305 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))
24264 raw_ptr_ty.childType()24307 raw_ptr_ty.childType()
24265 else24308 else
24266 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(sema.mod)});24309 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(sema.mod)});
2426724310
24268 // Optionally dereference a second pointer to get the concrete type.24311 // 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;
24270 const concrete_ty = if (is_double_ptr) inner_ty.childType() else inner_ty;24313 const concrete_ty = if (is_double_ptr) inner_ty.childType() else inner_ty;
24271 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;24314 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;
24272 const object_ptr = if (is_double_ptr)24315 const object_ptr = if (is_double_ptr)
...@@ -24275,7 +24318,7 @@ fn fieldCallBind(...@@ -24275,7 +24318,7 @@ fn fieldCallBind(
24275 raw_ptr;24318 raw_ptr;
2427624319
24277 find_field: {24320 find_field: {
24278 switch (concrete_ty.zigTypeTag()) {24321 switch (concrete_ty.zigTypeTag(mod)) {
24279 .Struct => {24322 .Struct => {
24280 const struct_ty = try sema.resolveTypeFields(concrete_ty);24323 const struct_ty = try sema.resolveTypeFields(concrete_ty);
24281 if (struct_ty.castTag(.@"struct")) |struct_obj| {24324 if (struct_ty.castTag(.@"struct")) |struct_obj| {
...@@ -24321,21 +24364,21 @@ fn fieldCallBind(...@@ -24321,21 +24364,21 @@ fn fieldCallBind(
24321 }24364 }
2432224365
24323 // If we get here, we need to look for a decl in the struct type instead.24366 // 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)) {
24325 .Struct, .Opaque, .Union, .Enum => found_decl: {24368 .Struct, .Opaque, .Union, .Enum => found_decl: {
24326 if (concrete_ty.getNamespace()) |namespace| {24369 if (concrete_ty.getNamespace()) |namespace| {
24327 if (try sema.namespaceLookup(block, src, namespace, field_name)) |decl_idx| {24370 if (try sema.namespaceLookup(block, src, namespace, field_name)) |decl_idx| {
24328 try sema.addReferencedBy(block, src, decl_idx);24371 try sema.addReferencedBy(block, src, decl_idx);
24329 const decl_val = try sema.analyzeDeclVal(block, src, decl_idx);24372 const decl_val = try sema.analyzeDeclVal(block, src, decl_idx);
24330 const decl_type = sema.typeOf(decl_val);24373 const decl_type = sema.typeOf(decl_val);
24331 if (decl_type.zigTypeTag() == .Fn and24374 if (decl_type.zigTypeTag(mod) == .Fn and
24332 decl_type.fnParamLen() >= 1)24375 decl_type.fnParamLen() >= 1)
24333 {24376 {
24334 const first_param_type = decl_type.fnParamType(0);24377 const first_param_type = decl_type.fnParamType(0);
24335 const first_param_tag = first_param_type.tag();24378 const first_param_tag = first_param_type.tag();
24336 // zig fmt: off24379 // zig fmt: off
24337 if (first_param_tag == .generic_poison or (24380 if (first_param_tag == .generic_poison or (
24338 first_param_type.zigTypeTag() == .Pointer and24381 first_param_type.zigTypeTag(mod) == .Pointer and
24339 (first_param_type.ptrSize() == .One or24382 (first_param_type.ptrSize() == .One or
24340 first_param_type.ptrSize() == .C) and24383 first_param_type.ptrSize() == .C) and
24341 first_param_type.childType().eql(concrete_ty, sema.mod)))24384 first_param_type.childType().eql(concrete_ty, sema.mod)))
...@@ -24356,7 +24399,7 @@ fn fieldCallBind(...@@ -24356,7 +24399,7 @@ fn fieldCallBind(
24356 .func_inst = decl_val,24399 .func_inst = decl_val,
24357 .arg0_inst = deref,24400 .arg0_inst = deref,
24358 } };24401 } };
24359 } else if (first_param_type.zigTypeTag() == .Optional) {24402 } else if (first_param_type.zigTypeTag(mod) == .Optional) {
24360 var opt_buf: Type.Payload.ElemType = undefined;24403 var opt_buf: Type.Payload.ElemType = undefined;
24361 const child = first_param_type.optionalChild(&opt_buf);24404 const child = first_param_type.optionalChild(&opt_buf);
24362 if (child.eql(concrete_ty, sema.mod)) {24405 if (child.eql(concrete_ty, sema.mod)) {
...@@ -24365,7 +24408,7 @@ fn fieldCallBind(...@@ -24365,7 +24408,7 @@ fn fieldCallBind(
24365 .func_inst = decl_val,24408 .func_inst = decl_val,
24366 .arg0_inst = deref,24409 .arg0_inst = deref,
24367 } };24410 } };
24368 } else if (child.zigTypeTag() == .Pointer and24411 } else if (child.zigTypeTag(mod) == .Pointer and
24369 child.ptrSize() == .One and24412 child.ptrSize() == .One and
24370 child.childType().eql(concrete_ty, sema.mod))24413 child.childType().eql(concrete_ty, sema.mod))
24371 {24414 {
...@@ -24374,7 +24417,7 @@ fn fieldCallBind(...@@ -24374,7 +24417,7 @@ fn fieldCallBind(
24374 .arg0_inst = object_ptr,24417 .arg0_inst = object_ptr,
24375 } };24418 } };
24376 }24419 }
24377 } else if (first_param_type.zigTypeTag() == .ErrorUnion and24420 } else if (first_param_type.zigTypeTag(mod) == .ErrorUnion and
24378 first_param_type.errorUnionPayload().eql(concrete_ty, sema.mod))24421 first_param_type.errorUnionPayload().eql(concrete_ty, sema.mod))
24379 {24422 {
24380 const deref = try sema.analyzeLoad(block, src, object_ptr, src);24423 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
...@@ -24421,9 +24464,10 @@ fn finishFieldCallBind(...@@ -24421,9 +24464,10 @@ fn finishFieldCallBind(
24421 .@"addrspace" = ptr_ty.ptrAddressSpace(),24464 .@"addrspace" = ptr_ty.ptrAddressSpace(),
24422 });24465 });
2442324466
24467 const mod = sema.mod;
24424 const container_ty = ptr_ty.childType();24468 const container_ty = ptr_ty.childType();
24425 if (container_ty.zigTypeTag() == .Struct) {24469 if (container_ty.zigTypeTag(mod) == .Struct) {
24426 if (container_ty.structFieldValueComptime(field_index)) |default_val| {24470 if (container_ty.structFieldValueComptime(mod, field_index)) |default_val| {
24427 return .{ .direct = try sema.addConstant(field_ty, default_val) };24471 return .{ .direct = try sema.addConstant(field_ty, default_val) };
24428 }24472 }
24429 }24473 }
...@@ -24504,7 +24548,8 @@ fn structFieldPtr(...@@ -24504,7 +24548,8 @@ fn structFieldPtr(
24504 unresolved_struct_ty: Type,24548 unresolved_struct_ty: Type,
24505 initializing: bool,24549 initializing: bool,
24506) CompileError!Air.Inst.Ref {24550) 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
24509 const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty);24554 const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty);
24510 try sema.resolveStructLayout(struct_ty);24555 try sema.resolveStructLayout(struct_ty);
...@@ -24544,6 +24589,7 @@ fn structFieldPtrByIndex(...@@ -24544,6 +24589,7 @@ fn structFieldPtrByIndex(
24544 return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index, initializing);24589 return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index, initializing);
24545 }24590 }
2454624591
24592 const mod = sema.mod;
24547 const struct_obj = struct_ty.castTag(.@"struct").?.data;24593 const struct_obj = struct_ty.castTag(.@"struct").?.data;
24548 const field = struct_obj.fields.values()[field_index];24594 const field = struct_obj.fields.values()[field_index];
24549 const struct_ptr_ty = sema.typeOf(struct_ptr);24595 const struct_ptr_ty = sema.typeOf(struct_ptr);
...@@ -24568,7 +24614,7 @@ fn structFieldPtrByIndex(...@@ -24568,7 +24614,7 @@ fn structFieldPtrByIndex(
24568 if (i == field_index) {24614 if (i == field_index) {
24569 ptr_ty_data.bit_offset = running_bits;24615 ptr_ty_data.bit_offset = running_bits;
24570 }24616 }
24571 running_bits += @intCast(u16, f.ty.bitSize(target));24617 running_bits += @intCast(u16, f.ty.bitSize(mod));
24572 }24618 }
24573 ptr_ty_data.host_size = (running_bits + 7) / 8;24619 ptr_ty_data.host_size = (running_bits + 7) / 8;
2457424620
...@@ -24582,7 +24628,7 @@ fn structFieldPtrByIndex(...@@ -24582,7 +24628,7 @@ fn structFieldPtrByIndex(
24582 const parent_align = if (struct_ptr_ty_info.@"align" != 0)24628 const parent_align = if (struct_ptr_ty_info.@"align" != 0)
24583 struct_ptr_ty_info.@"align"24629 struct_ptr_ty_info.@"align"
24584 else24630 else
24585 struct_ptr_ty_info.pointee_type.abiAlignment(target);24631 struct_ptr_ty_info.pointee_type.abiAlignment(mod);
24586 ptr_ty_data.@"align" = parent_align;24632 ptr_ty_data.@"align" = parent_align;
2458724633
24588 // If the field happens to be byte-aligned, simplify the pointer type.24634 // If the field happens to be byte-aligned, simplify the pointer type.
...@@ -24596,8 +24642,8 @@ fn structFieldPtrByIndex(...@@ -24596,8 +24642,8 @@ fn structFieldPtrByIndex(
24596 if (parent_align != 0 and ptr_ty_data.bit_offset % 8 == 0 and24642 if (parent_align != 0 and ptr_ty_data.bit_offset % 8 == 0 and
24597 target.cpu.arch.endian() == .Little)24643 target.cpu.arch.endian() == .Little)
24598 {24644 {
24599 const elem_size_bytes = ptr_ty_data.pointee_type.abiSize(target);24645 const elem_size_bytes = ptr_ty_data.pointee_type.abiSize(mod);
24600 const elem_size_bits = ptr_ty_data.pointee_type.bitSize(target);24646 const elem_size_bits = ptr_ty_data.pointee_type.bitSize(mod);
24601 if (elem_size_bytes * 8 == elem_size_bits) {24647 if (elem_size_bytes * 8 == elem_size_bits) {
24602 const byte_offset = ptr_ty_data.bit_offset / 8;24648 const byte_offset = ptr_ty_data.bit_offset / 8;
24603 const new_align = @as(u32, 1) << @intCast(u5, @ctz(byte_offset | parent_align));24649 const new_align = @as(u32, 1) << @intCast(u5, @ctz(byte_offset | parent_align));
...@@ -24644,7 +24690,8 @@ fn structFieldVal(...@@ -24644,7 +24690,8 @@ fn structFieldVal(
24644 field_name_src: LazySrcLoc,24690 field_name_src: LazySrcLoc,
24645 unresolved_struct_ty: Type,24691 unresolved_struct_ty: Type,
24646) CompileError!Air.Inst.Ref {24692) 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
24649 const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty);24696 const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty);
24650 switch (struct_ty.tag()) {24697 switch (struct_ty.tag()) {
...@@ -24728,9 +24775,10 @@ fn tupleFieldValByIndex(...@@ -24728,9 +24775,10 @@ fn tupleFieldValByIndex(
24728 field_index: u32,24775 field_index: u32,
24729 tuple_ty: Type,24776 tuple_ty: Type,
24730) CompileError!Air.Inst.Ref {24777) CompileError!Air.Inst.Ref {
24778 const mod = sema.mod;
24731 const field_ty = tuple_ty.structFieldType(field_index);24779 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| {
24734 return sema.addConstant(field_ty, default_value);24782 return sema.addConstant(field_ty, default_value);
24735 }24783 }
2473624784
...@@ -24743,7 +24791,7 @@ fn tupleFieldValByIndex(...@@ -24743,7 +24791,7 @@ fn tupleFieldValByIndex(
24743 return sema.addConstant(field_ty, field_values[field_index]);24791 return sema.addConstant(field_ty, field_values[field_index]);
24744 }24792 }
2474524793
24746 if (tuple_ty.structFieldValueComptime(field_index)) |default_val| {24794 if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
24747 return sema.addConstant(field_ty, default_val);24795 return sema.addConstant(field_ty, default_val);
24748 }24796 }
2474924797
...@@ -24762,7 +24810,9 @@ fn unionFieldPtr(...@@ -24762,7 +24810,9 @@ fn unionFieldPtr(
24762 initializing: bool,24810 initializing: bool,
24763) CompileError!Air.Inst.Ref {24811) CompileError!Air.Inst.Ref {
24764 const arena = sema.arena;24812 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
24767 const union_ptr_ty = sema.typeOf(union_ptr);24817 const union_ptr_ty = sema.typeOf(union_ptr);
24768 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);24818 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);
...@@ -24777,7 +24827,7 @@ fn unionFieldPtr(...@@ -24777,7 +24827,7 @@ fn unionFieldPtr(
24777 });24827 });
24778 const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name).?);24828 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) {
24781 const msg = msg: {24831 const msg = msg: {
24782 const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});24832 const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});
24783 errdefer msg.destroy(sema.gpa);24833 errdefer msg.destroy(sema.gpa);
...@@ -24839,7 +24889,7 @@ fn unionFieldPtr(...@@ -24839,7 +24889,7 @@ fn unionFieldPtr(
24839 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_val);24889 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_val);
24840 try sema.panicInactiveUnionField(block, active_tag, wanted_tag);24890 try sema.panicInactiveUnionField(block, active_tag, wanted_tag);
24841 }24891 }
24842 if (field.ty.zigTypeTag() == .NoReturn) {24892 if (field.ty.zigTypeTag(mod) == .NoReturn) {
24843 _ = try block.addNoOp(.unreach);24893 _ = try block.addNoOp(.unreach);
24844 return Air.Inst.Ref.unreachable_value;24894 return Air.Inst.Ref.unreachable_value;
24845 }24895 }
...@@ -24855,7 +24905,8 @@ fn unionFieldVal(...@@ -24855,7 +24905,8 @@ fn unionFieldVal(
24855 field_name_src: LazySrcLoc,24905 field_name_src: LazySrcLoc,
24856 unresolved_union_ty: Type,24906 unresolved_union_ty: Type,
24857) CompileError!Air.Inst.Ref {24907) 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
24860 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);24911 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);
24861 const union_obj = union_ty.cast(Type.Payload.Union).?.data;24912 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
...@@ -24911,7 +24962,7 @@ fn unionFieldVal(...@@ -24911,7 +24962,7 @@ fn unionFieldVal(
24911 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval);24962 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval);
24912 try sema.panicInactiveUnionField(block, active_tag, wanted_tag);24963 try sema.panicInactiveUnionField(block, active_tag, wanted_tag);
24913 }24964 }
24914 if (field.ty.zigTypeTag() == .NoReturn) {24965 if (field.ty.zigTypeTag(mod) == .NoReturn) {
24915 _ = try block.addNoOp(.unreach);24966 _ = try block.addNoOp(.unreach);
24916 return Air.Inst.Ref.unreachable_value;24967 return Air.Inst.Ref.unreachable_value;
24917 }24968 }
...@@ -24928,22 +24979,22 @@ fn elemPtr(...@@ -24928,22 +24979,22 @@ fn elemPtr(
24928 init: bool,24979 init: bool,
24929 oob_safety: bool,24980 oob_safety: bool,
24930) CompileError!Air.Inst.Ref {24981) CompileError!Air.Inst.Ref {
24982 const mod = sema.mod;
24931 const indexable_ptr_src = src; // TODO better source location24983 const indexable_ptr_src = src; // TODO better source location
24932 const indexable_ptr_ty = sema.typeOf(indexable_ptr);24984 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)) {
24936 .Pointer => indexable_ptr_ty.elemType(),24987 .Pointer => indexable_ptr_ty.elemType(),
24937 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(sema.mod)}),24988 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(sema.mod)}),
24938 };24989 };
24939 try checkIndexable(sema, block, src, indexable_ty);24990 try checkIndexable(sema, block, src, indexable_ty);
2494024991
24941 switch (indexable_ty.zigTypeTag()) {24992 switch (indexable_ty.zigTypeTag(mod)) {
24942 .Array, .Vector => return sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init, oob_safety),24993 .Array, .Vector => return sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init, oob_safety),
24943 .Struct => {24994 .Struct => {
24944 // Tuple field access.24995 // Tuple field access.
24945 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index, "tuple field access index must be comptime-known");24996 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));
24947 return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);24998 return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);
24948 },24999 },
24949 else => {25000 else => {
...@@ -24966,7 +25017,7 @@ fn elemPtrOneLayerOnly(...@@ -24966,7 +25017,7 @@ fn elemPtrOneLayerOnly(
24966) CompileError!Air.Inst.Ref {25017) CompileError!Air.Inst.Ref {
24967 const indexable_src = src; // TODO better source location25018 const indexable_src = src; // TODO better source location
24968 const indexable_ty = sema.typeOf(indexable);25019 const indexable_ty = sema.typeOf(indexable);
24969 const target = sema.mod.getTarget();25020 const mod = sema.mod;
2497025021
24971 try checkIndexable(sema, block, src, indexable_ty);25022 try checkIndexable(sema, block, src, indexable_ty);
2497225023
...@@ -24978,7 +25029,7 @@ fn elemPtrOneLayerOnly(...@@ -24978,7 +25029,7 @@ fn elemPtrOneLayerOnly(
24978 const runtime_src = rs: {25029 const runtime_src = rs: {
24979 const ptr_val = maybe_ptr_val orelse break :rs indexable_src;25030 const ptr_val = maybe_ptr_val orelse break :rs indexable_src;
24980 const index_val = maybe_index_val orelse break :rs elem_index_src;25031 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));
24982 const elem_ptr = try ptr_val.elemPtr(indexable_ty, sema.arena, index, sema.mod);25033 const elem_ptr = try ptr_val.elemPtr(indexable_ty, sema.arena, index, sema.mod);
24983 const result_ty = try sema.elemPtrType(indexable_ty, index);25034 const result_ty = try sema.elemPtrType(indexable_ty, index);
24984 return sema.addConstant(result_ty, elem_ptr);25035 return sema.addConstant(result_ty, elem_ptr);
...@@ -24989,7 +25040,7 @@ fn elemPtrOneLayerOnly(...@@ -24989,7 +25040,7 @@ fn elemPtrOneLayerOnly(
24989 return block.addPtrElemPtr(indexable, elem_index, result_ty);25040 return block.addPtrElemPtr(indexable, elem_index, result_ty);
24990 },25041 },
24991 .One => {25042 .One => {
24992 assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by checkIndexable25043 assert(indexable_ty.childType().zigTypeTag(mod) == .Array); // Guaranteed by checkIndexable
24993 return sema.elemPtrArray(block, src, indexable_src, indexable, elem_index_src, elem_index, init, oob_safety);25044 return sema.elemPtrArray(block, src, indexable_src, indexable, elem_index_src, elem_index, init, oob_safety);
24994 },25045 },
24995 }25046 }
...@@ -25006,7 +25057,7 @@ fn elemVal(...@@ -25006,7 +25057,7 @@ fn elemVal(
25006) CompileError!Air.Inst.Ref {25057) CompileError!Air.Inst.Ref {
25007 const indexable_src = src; // TODO better source location25058 const indexable_src = src; // TODO better source location
25008 const indexable_ty = sema.typeOf(indexable);25059 const indexable_ty = sema.typeOf(indexable);
25009 const target = sema.mod.getTarget();25060 const mod = sema.mod;
2501025061
25011 try checkIndexable(sema, block, src, indexable_ty);25062 try checkIndexable(sema, block, src, indexable_ty);
2501225063
...@@ -25014,7 +25065,7 @@ fn elemVal(...@@ -25014,7 +25065,7 @@ fn elemVal(
25014 // index is a scalar or vector instead of unconditionally casting to usize.25065 // index is a scalar or vector instead of unconditionally casting to usize.
25015 const elem_index = try sema.coerce(block, Type.usize, elem_index_uncasted, elem_index_src);25066 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)) {
25018 .Pointer => switch (indexable_ty.ptrSize()) {25069 .Pointer => switch (indexable_ty.ptrSize()) {
25019 .Slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),25070 .Slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
25020 .Many, .C => {25071 .Many, .C => {
...@@ -25024,10 +25075,10 @@ fn elemVal(...@@ -25024,10 +25075,10 @@ fn elemVal(
25024 const runtime_src = rs: {25075 const runtime_src = rs: {
25025 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;25076 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;
25026 const index_val = maybe_index_val orelse break :rs elem_index_src;25077 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));
25028 const elem_ptr_val = try indexable_val.elemPtr(indexable_ty, sema.arena, index, sema.mod);25079 const elem_ptr_val = try indexable_val.elemPtr(indexable_ty, sema.arena, index, sema.mod);
25029 if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, indexable_ty)) |elem_val| {25080 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);
25031 }25082 }
25032 break :rs indexable_src;25083 break :rs indexable_src;
25033 };25084 };
...@@ -25036,7 +25087,7 @@ fn elemVal(...@@ -25036,7 +25087,7 @@ fn elemVal(
25036 return block.addBinOp(.ptr_elem_val, indexable, elem_index);25087 return block.addBinOp(.ptr_elem_val, indexable, elem_index);
25037 },25088 },
25038 .One => {25089 .One => {
25039 assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by checkIndexable25090 assert(indexable_ty.childType().zigTypeTag(mod) == .Array); // Guaranteed by checkIndexable
25040 const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false, oob_safety);25091 const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false, oob_safety);
25041 return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src);25092 return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src);
25042 },25093 },
...@@ -25049,7 +25100,7 @@ fn elemVal(...@@ -25049,7 +25100,7 @@ fn elemVal(
25049 .Struct => {25100 .Struct => {
25050 // Tuple field access.25101 // Tuple field access.
25051 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index, "tuple field access index must be comptime-known");25102 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));
25053 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);25104 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);
25054 },25105 },
25055 else => unreachable,25106 else => unreachable,
...@@ -25093,6 +25144,7 @@ fn tupleFieldPtr(...@@ -25093,6 +25144,7 @@ fn tupleFieldPtr(
25093 field_index: u32,25144 field_index: u32,
25094 init: bool,25145 init: bool,
25095) CompileError!Air.Inst.Ref {25146) CompileError!Air.Inst.Ref {
25147 const mod = sema.mod;
25096 const tuple_ptr_ty = sema.typeOf(tuple_ptr);25148 const tuple_ptr_ty = sema.typeOf(tuple_ptr);
25097 const tuple_ty = tuple_ptr_ty.childType();25149 const tuple_ty = tuple_ptr_ty.childType();
25098 _ = try sema.resolveTypeFields(tuple_ty);25150 _ = try sema.resolveTypeFields(tuple_ty);
...@@ -25116,7 +25168,7 @@ fn tupleFieldPtr(...@@ -25116,7 +25168,7 @@ fn tupleFieldPtr(
25116 .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(),25168 .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(),
25117 });25169 });
2511825170
25119 if (tuple_ty.structFieldValueComptime(field_index)) |default_val| {25171 if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
25120 const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{25172 const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{
25121 .field_ty = field_ty,25173 .field_ty = field_ty,
25122 .field_val = default_val,25174 .field_val = default_val,
...@@ -25151,6 +25203,7 @@ fn tupleField(...@@ -25151,6 +25203,7 @@ fn tupleField(
25151 field_index_src: LazySrcLoc,25203 field_index_src: LazySrcLoc,
25152 field_index: u32,25204 field_index: u32,
25153) CompileError!Air.Inst.Ref {25205) CompileError!Air.Inst.Ref {
25206 const mod = sema.mod;
25154 const tuple_ty = try sema.resolveTypeFields(sema.typeOf(tuple));25207 const tuple_ty = try sema.resolveTypeFields(sema.typeOf(tuple));
25155 const field_count = tuple_ty.structFieldCount();25208 const field_count = tuple_ty.structFieldCount();
2515625209
...@@ -25166,13 +25219,13 @@ fn tupleField(...@@ -25166,13 +25219,13 @@ fn tupleField(
2516625219
25167 const field_ty = tuple_ty.structFieldType(field_index);25220 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| {
25170 return sema.addConstant(field_ty, default_value); // comptime field25223 return sema.addConstant(field_ty, default_value); // comptime field
25171 }25224 }
2517225225
25173 if (try sema.resolveMaybeUndefVal(tuple)) |tuple_val| {25226 if (try sema.resolveMaybeUndefVal(tuple)) |tuple_val| {
25174 if (tuple_val.isUndef()) return sema.addConstUndef(field_ty);25227 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));
25176 }25229 }
2517725230
25178 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);25231 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);
...@@ -25191,6 +25244,7 @@ fn elemValArray(...@@ -25191,6 +25244,7 @@ fn elemValArray(
25191 elem_index: Air.Inst.Ref,25244 elem_index: Air.Inst.Ref,
25192 oob_safety: bool,25245 oob_safety: bool,
25193) CompileError!Air.Inst.Ref {25246) CompileError!Air.Inst.Ref {
25247 const mod = sema.mod;
25194 const array_ty = sema.typeOf(array);25248 const array_ty = sema.typeOf(array);
25195 const array_sent = array_ty.sentinel();25249 const array_sent = array_ty.sentinel();
25196 const array_len = array_ty.arrayLen();25250 const array_len = array_ty.arrayLen();
...@@ -25204,10 +25258,9 @@ fn elemValArray(...@@ -25204,10 +25258,9 @@ fn elemValArray(
25204 const maybe_undef_array_val = try sema.resolveMaybeUndefVal(array);25258 const maybe_undef_array_val = try sema.resolveMaybeUndefVal(array);
25205 // index must be defined since it can access out of bounds25259 // index must be defined since it can access out of bounds
25206 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);25260 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
25207 const target = sema.mod.getTarget();
2520825261
25209 if (maybe_index_val) |index_val| {25262 if (maybe_index_val) |index_val| {
25210 const index = @intCast(usize, index_val.toUnsignedInt(target));25263 const index = @intCast(usize, index_val.toUnsignedInt(mod));
25211 if (array_sent) |s| {25264 if (array_sent) |s| {
25212 if (index == array_len) {25265 if (index == array_len) {
25213 return sema.addConstant(elem_ty, s);25266 return sema.addConstant(elem_ty, s);
...@@ -25223,7 +25276,7 @@ fn elemValArray(...@@ -25223,7 +25276,7 @@ fn elemValArray(
25223 return sema.addConstUndef(elem_ty);25276 return sema.addConstUndef(elem_ty);
25224 }25277 }
25225 if (maybe_index_val) |index_val| {25278 if (maybe_index_val) |index_val| {
25226 const index = @intCast(usize, index_val.toUnsignedInt(target));25279 const index = @intCast(usize, index_val.toUnsignedInt(mod));
25227 const elem_val = try array_val.elemValue(sema.mod, sema.arena, index);25280 const elem_val = try array_val.elemValue(sema.mod, sema.arena, index);
25228 return sema.addConstant(elem_ty, elem_val);25281 return sema.addConstant(elem_ty, elem_val);
25229 }25282 }
...@@ -25255,7 +25308,7 @@ fn elemPtrArray(...@@ -25255,7 +25308,7 @@ fn elemPtrArray(
25255 init: bool,25308 init: bool,
25256 oob_safety: bool,25309 oob_safety: bool,
25257) CompileError!Air.Inst.Ref {25310) CompileError!Air.Inst.Ref {
25258 const target = sema.mod.getTarget();25311 const mod = sema.mod;
25259 const array_ptr_ty = sema.typeOf(array_ptr);25312 const array_ptr_ty = sema.typeOf(array_ptr);
25260 const array_ty = array_ptr_ty.childType();25313 const array_ty = array_ptr_ty.childType();
25261 const array_sent = array_ty.sentinel() != null;25314 const array_sent = array_ty.sentinel() != null;
...@@ -25269,7 +25322,7 @@ fn elemPtrArray(...@@ -25269,7 +25322,7 @@ fn elemPtrArray(
25269 const maybe_undef_array_ptr_val = try sema.resolveMaybeUndefVal(array_ptr);25322 const maybe_undef_array_ptr_val = try sema.resolveMaybeUndefVal(array_ptr);
25270 // The index must not be undefined since it can be out of bounds.25323 // The index must not be undefined since it can be out of bounds.
25271 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {25324 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));
25273 if (index >= array_len_s) {25326 if (index >= array_len_s) {
25274 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";25327 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
25275 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });25328 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(...@@ -25290,7 +25343,7 @@ fn elemPtrArray(
25290 }25343 }
2529125344
25292 if (!init) {25345 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);
25294 }25347 }
2529525348
25296 const runtime_src = if (maybe_undef_array_ptr_val != null) elem_index_src else array_ptr_src;25349 const runtime_src = if (maybe_undef_array_ptr_val != null) elem_index_src else array_ptr_src;
...@@ -25316,16 +25369,16 @@ fn elemValSlice(...@@ -25316,16 +25369,16 @@ fn elemValSlice(
25316 elem_index: Air.Inst.Ref,25369 elem_index: Air.Inst.Ref,
25317 oob_safety: bool,25370 oob_safety: bool,
25318) CompileError!Air.Inst.Ref {25371) CompileError!Air.Inst.Ref {
25372 const mod = sema.mod;
25319 const slice_ty = sema.typeOf(slice);25373 const slice_ty = sema.typeOf(slice);
25320 const slice_sent = slice_ty.sentinel() != null;25374 const slice_sent = slice_ty.sentinel() != null;
25321 const elem_ty = slice_ty.elemType2();25375 const elem_ty = slice_ty.elemType2(mod);
25322 var runtime_src = slice_src;25376 var runtime_src = slice_src;
2532325377
25324 // slice must be defined since it can dereferenced as null25378 // slice must be defined since it can dereferenced as null
25325 const maybe_slice_val = try sema.resolveDefinedValue(block, slice_src, slice);25379 const maybe_slice_val = try sema.resolveDefinedValue(block, slice_src, slice);
25326 // index must be defined since it can index out of bounds25380 // index must be defined since it can index out of bounds
25327 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);25381 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
25328 const target = sema.mod.getTarget();
2532925382
25330 if (maybe_slice_val) |slice_val| {25383 if (maybe_slice_val) |slice_val| {
25331 runtime_src = elem_index_src;25384 runtime_src = elem_index_src;
...@@ -25335,7 +25388,7 @@ fn elemValSlice(...@@ -25335,7 +25388,7 @@ fn elemValSlice(
25335 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});25388 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
25336 }25389 }
25337 if (maybe_index_val) |index_val| {25390 if (maybe_index_val) |index_val| {
25338 const index = @intCast(usize, index_val.toUnsignedInt(target));25391 const index = @intCast(usize, index_val.toUnsignedInt(mod));
25339 if (index >= slice_len_s) {25392 if (index >= slice_len_s) {
25340 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";25393 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
25341 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });25394 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(...@@ -25373,14 +25426,14 @@ fn elemPtrSlice(
25373 elem_index: Air.Inst.Ref,25426 elem_index: Air.Inst.Ref,
25374 oob_safety: bool,25427 oob_safety: bool,
25375) CompileError!Air.Inst.Ref {25428) CompileError!Air.Inst.Ref {
25376 const target = sema.mod.getTarget();25429 const mod = sema.mod;
25377 const slice_ty = sema.typeOf(slice);25430 const slice_ty = sema.typeOf(slice);
25378 const slice_sent = slice_ty.sentinel() != null;25431 const slice_sent = slice_ty.sentinel() != null;
2537925432
25380 const maybe_undef_slice_val = try sema.resolveMaybeUndefVal(slice);25433 const maybe_undef_slice_val = try sema.resolveMaybeUndefVal(slice);
25381 // The index must not be undefined since it can be out of bounds.25434 // The index must not be undefined since it can be out of bounds.
25382 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {25435 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));
25384 break :o index;25437 break :o index;
25385 } else null;25438 } else null;
2538625439
...@@ -25484,6 +25537,7 @@ fn coerceExtra(...@@ -25484,6 +25537,7 @@ fn coerceExtra(
25484 const dest_ty_src = inst_src; // TODO better source location25537 const dest_ty_src = inst_src; // TODO better source location
25485 const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);25538 const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);
25486 const inst_ty = try sema.resolveTypeFields(sema.typeOf(inst));25539 const inst_ty = try sema.resolveTypeFields(sema.typeOf(inst));
25540 const mod = sema.mod;
25487 const target = sema.mod.getTarget();25541 const target = sema.mod.getTarget();
25488 // If the types are the same, we can return the operand.25542 // If the types are the same, we can return the operand.
25489 if (dest_ty.eql(inst_ty, sema.mod))25543 if (dest_ty.eql(inst_ty, sema.mod))
...@@ -25502,9 +25556,9 @@ fn coerceExtra(...@@ -25502,9 +25556,9 @@ fn coerceExtra(
25502 return block.addBitCast(dest_ty, inst);25556 return block.addBitCast(dest_ty, inst);
25503 }25557 }
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)) {
25508 .Optional => optional: {25562 .Optional => optional: {
25509 // undefined sets the optional bit also to undefined.25563 // undefined sets the optional bit also to undefined.
25510 if (is_undef) {25564 if (is_undef) {
...@@ -25512,18 +25566,18 @@ fn coerceExtra(...@@ -25512,18 +25566,18 @@ fn coerceExtra(
25512 }25566 }
2551325567
25514 // null to ?T25568 // null to ?T
25515 if (inst_ty.zigTypeTag() == .Null) {25569 if (inst_ty.zigTypeTag(mod) == .Null) {
25516 return sema.addConstant(dest_ty, Value.null);25570 return sema.addConstant(dest_ty, Value.null);
25517 }25571 }
2551825572
25519 // cast from ?*T and ?[*]T to ?*anyopaque25573 // cast from ?*T and ?[*]T to ?*anyopaque
25520 // but don't do it if the source type is a double pointer25574 // but don't do it if the source type is a double pointer
25521 if (dest_ty.isPtrLikeOptional() and dest_ty.elemType2().tag() == .anyopaque and25575 if (dest_ty.isPtrLikeOptional(mod) and dest_ty.elemType2(mod).tag() == .anyopaque and
25522 inst_ty.isPtrAtRuntime())25576 inst_ty.isPtrAtRuntime(mod))
25523 anyopaque_check: {25577 anyopaque_check: {
25524 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional;25578 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional;
25525 const elem_ty = inst_ty.elemType2();25579 const elem_ty = inst_ty.elemType2(mod);
25526 if (elem_ty.zigTypeTag() == .Pointer or elem_ty.isPtrLikeOptional()) {25580 if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) {
25527 in_memory_result = .{ .double_ptr_to_anyopaque = .{25581 in_memory_result = .{ .double_ptr_to_anyopaque = .{
25528 .actual = inst_ty,25582 .actual = inst_ty,
25529 .wanted = dest_ty,25583 .wanted = dest_ty,
...@@ -25532,7 +25586,7 @@ fn coerceExtra(...@@ -25532,7 +25586,7 @@ fn coerceExtra(
25532 }25586 }
25533 // Let the logic below handle wrapping the optional now that25587 // Let the logic below handle wrapping the optional now that
25534 // it has been checked to correctly coerce.25588 // it has been checked to correctly coerce.
25535 if (!inst_ty.isPtrLikeOptional()) break :anyopaque_check;25589 if (!inst_ty.isPtrLikeOptional(mod)) break :anyopaque_check;
25536 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);25590 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
25537 }25591 }
2553825592
...@@ -25554,7 +25608,7 @@ fn coerceExtra(...@@ -25554,7 +25608,7 @@ fn coerceExtra(
25554 const dest_info = dest_ty.ptrInfo().data;25608 const dest_info = dest_ty.ptrInfo().data;
2555525609
25556 // Function body to function pointer.25610 // Function body to function pointer.
25557 if (inst_ty.zigTypeTag() == .Fn) {25611 if (inst_ty.zigTypeTag(mod) == .Fn) {
25558 const fn_val = try sema.resolveConstValue(block, .unneeded, inst, "");25612 const fn_val = try sema.resolveConstValue(block, .unneeded, inst, "");
25559 const fn_decl = fn_val.pointerDecl().?;25613 const fn_decl = fn_val.pointerDecl().?;
25560 const inst_as_ptr = try sema.analyzeDeclRef(fn_decl);25614 const inst_as_ptr = try sema.analyzeDeclRef(fn_decl);
...@@ -25568,7 +25622,7 @@ fn coerceExtra(...@@ -25568,7 +25622,7 @@ fn coerceExtra(
25568 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;25622 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
25569 const ptr_elem_ty = inst_ty.childType();25623 const ptr_elem_ty = inst_ty.childType();
25570 const array_ty = dest_info.pointee_type;25624 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;
25572 const array_elem_ty = array_ty.childType();25626 const array_elem_ty = array_ty.childType();
25573 if (array_ty.arrayLen() != 1) break :single_item;25627 if (array_ty.arrayLen() != 1) break :single_item;
25574 const dest_is_mut = dest_info.mutable;25628 const dest_is_mut = dest_info.mutable;
...@@ -25584,7 +25638,7 @@ fn coerceExtra(...@@ -25584,7 +25638,7 @@ fn coerceExtra(
25584 if (!inst_ty.isSinglePointer()) break :src_array_ptr;25638 if (!inst_ty.isSinglePointer()) break :src_array_ptr;
25585 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;25639 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
25586 const array_ty = inst_ty.childType();25640 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;
25588 const array_elem_type = array_ty.childType();25642 const array_elem_type = array_ty.childType();
25589 const dest_is_mut = dest_info.mutable;25643 const dest_is_mut = dest_info.mutable;
2559025644
...@@ -25656,10 +25710,10 @@ fn coerceExtra(...@@ -25656,10 +25710,10 @@ fn coerceExtra(
2565625710
25657 // cast from *T and [*]T to *anyopaque25711 // cast from *T and [*]T to *anyopaque
25658 // but don't do it if the source type is a double pointer25712 // 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: {
25660 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;25714 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
25661 const elem_ty = inst_ty.elemType2();25715 const elem_ty = inst_ty.elemType2(mod);
25662 if (elem_ty.zigTypeTag() == .Pointer or elem_ty.isPtrLikeOptional()) {25716 if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) {
25663 in_memory_result = .{ .double_ptr_to_anyopaque = .{25717 in_memory_result = .{ .double_ptr_to_anyopaque = .{
25664 .actual = inst_ty,25718 .actual = inst_ty,
25665 .wanted = dest_ty,25719 .wanted = dest_ty,
...@@ -25679,7 +25733,7 @@ fn coerceExtra(...@@ -25679,7 +25733,7 @@ fn coerceExtra(
2567925733
25680 switch (dest_info.size) {25734 switch (dest_info.size) {
25681 // coercion to C pointer25735 // coercion to C pointer
25682 .C => switch (inst_ty.zigTypeTag()) {25736 .C => switch (inst_ty.zigTypeTag(mod)) {
25683 .Null => {25737 .Null => {
25684 return sema.addConstant(dest_ty, Value.null);25738 return sema.addConstant(dest_ty, Value.null);
25685 },25739 },
...@@ -25691,7 +25745,7 @@ fn coerceExtra(...@@ -25691,7 +25745,7 @@ fn coerceExtra(
25691 return try sema.coerceCompatiblePtrs(block, dest_ty, addr, inst_src);25745 return try sema.coerceCompatiblePtrs(block, dest_ty, addr, inst_src);
25692 },25746 },
25693 .Int => {25747 .Int => {
25694 const ptr_size_ty = switch (inst_ty.intInfo(target).signedness) {25748 const ptr_size_ty = switch (inst_ty.intInfo(mod).signedness) {
25695 .signed => Type.isize,25749 .signed => Type.isize,
25696 .unsigned => Type.usize,25750 .unsigned => Type.usize,
25697 };25751 };
...@@ -25733,7 +25787,7 @@ fn coerceExtra(...@@ -25733,7 +25787,7 @@ fn coerceExtra(
25733 },25787 },
25734 else => {},25788 else => {},
25735 },25789 },
25736 .One => switch (dest_info.pointee_type.zigTypeTag()) {25790 .One => switch (dest_info.pointee_type.zigTypeTag(mod)) {
25737 .Union => {25791 .Union => {
25738 // pointer to anonymous struct to pointer to union25792 // pointer to anonymous struct to pointer to union
25739 if (inst_ty.isSinglePointer() and25793 if (inst_ty.isSinglePointer() and
...@@ -25767,7 +25821,7 @@ fn coerceExtra(...@@ -25767,7 +25821,7 @@ fn coerceExtra(
25767 else => {},25821 else => {},
25768 },25822 },
25769 .Slice => to_slice: {25823 .Slice => to_slice: {
25770 if (inst_ty.zigTypeTag() == .Array) {25824 if (inst_ty.zigTypeTag(mod) == .Array) {
25771 return sema.fail(25825 return sema.fail(
25772 block,25826 block,
25773 inst_src,25827 inst_src,
...@@ -25789,7 +25843,7 @@ fn coerceExtra(...@@ -25789,7 +25843,7 @@ fn coerceExtra(
25789 .ptr = if (dest_info.@"align" != 0)25843 .ptr = if (dest_info.@"align" != 0)
25790 try Value.Tag.int_u64.create(sema.arena, dest_info.@"align")25844 try Value.Tag.int_u64.create(sema.arena, dest_info.@"align")
25791 else25845 else
25792 try dest_info.pointee_type.lazyAbiAlignment(target, sema.arena),25846 try dest_info.pointee_type.lazyAbiAlignment(mod, sema.arena),
25793 .len = Value.zero,25847 .len = Value.zero,
25794 });25848 });
25795 return sema.addConstant(dest_ty, slice_val);25849 return sema.addConstant(dest_ty, slice_val);
...@@ -25834,13 +25888,13 @@ fn coerceExtra(...@@ -25834,13 +25888,13 @@ fn coerceExtra(
25834 },25888 },
25835 }25889 }
25836 },25890 },
25837 .Int, .ComptimeInt => switch (inst_ty.zigTypeTag()) {25891 .Int, .ComptimeInt => switch (inst_ty.zigTypeTag(mod)) {
25838 .Float, .ComptimeFloat => float: {25892 .Float, .ComptimeFloat => float: {
25839 if (is_undef) {25893 if (is_undef) {
25840 return sema.addConstUndef(dest_ty);25894 return sema.addConstUndef(dest_ty);
25841 }25895 }
25842 const val = (try sema.resolveMaybeUndefVal(inst)) orelse {25896 const val = (try sema.resolveMaybeUndefVal(inst)) orelse {
25843 if (dest_ty.zigTypeTag() == .ComptimeInt) {25897 if (dest_ty.zigTypeTag(mod) == .ComptimeInt) {
25844 if (!opts.report_err) return error.NotCoercible;25898 if (!opts.report_err) return error.NotCoercible;
25845 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_int' must be comptime-known");25899 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_int' must be comptime-known");
25846 }25900 }
...@@ -25870,15 +25924,15 @@ fn coerceExtra(...@@ -25870,15 +25924,15 @@ fn coerceExtra(
25870 }25924 }
25871 return try sema.addConstant(dest_ty, val);25925 return try sema.addConstant(dest_ty, val);
25872 }25926 }
25873 if (dest_ty.zigTypeTag() == .ComptimeInt) {25927 if (dest_ty.zigTypeTag(mod) == .ComptimeInt) {
25874 if (!opts.report_err) return error.NotCoercible;25928 if (!opts.report_err) return error.NotCoercible;
25875 if (opts.no_cast_to_comptime_int) return inst;25929 if (opts.no_cast_to_comptime_int) return inst;
25876 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_int' must be comptime-known");25930 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_int' must be comptime-known");
25877 }25931 }
2587825932
25879 // integer widening25933 // integer widening
25880 const dst_info = dest_ty.intInfo(target);25934 const dst_info = dest_ty.intInfo(mod);
25881 const src_info = inst_ty.intInfo(target);25935 const src_info = inst_ty.intInfo(mod);
25882 if ((src_info.signedness == dst_info.signedness and dst_info.bits >= src_info.bits) or25936 if ((src_info.signedness == dst_info.signedness and dst_info.bits >= src_info.bits) or
25883 // small enough unsigned ints can get casted to large enough signed ints25937 // small enough unsigned ints can get casted to large enough signed ints
25884 (dst_info.signedness == .signed and dst_info.bits > src_info.bits))25938 (dst_info.signedness == .signed and dst_info.bits > src_info.bits))
...@@ -25892,7 +25946,7 @@ fn coerceExtra(...@@ -25892,7 +25946,7 @@ fn coerceExtra(
25892 },25946 },
25893 else => {},25947 else => {},
25894 },25948 },
25895 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) {25949 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(mod)) {
25896 .ComptimeFloat => {25950 .ComptimeFloat => {
25897 const val = try sema.resolveConstValue(block, .unneeded, inst, "");25951 const val = try sema.resolveConstValue(block, .unneeded, inst, "");
25898 const result_val = try val.floatCast(sema.arena, dest_ty, target);25952 const result_val = try val.floatCast(sema.arena, dest_ty, target);
...@@ -25913,7 +25967,7 @@ fn coerceExtra(...@@ -25913,7 +25967,7 @@ fn coerceExtra(
25913 );25967 );
25914 }25968 }
25915 return try sema.addConstant(dest_ty, result_val);25969 return try sema.addConstant(dest_ty, result_val);
25916 } else if (dest_ty.zigTypeTag() == .ComptimeFloat) {25970 } else if (dest_ty.zigTypeTag(mod) == .ComptimeFloat) {
25917 if (!opts.report_err) return error.NotCoercible;25971 if (!opts.report_err) return error.NotCoercible;
25918 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime-known");25972 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime-known");
25919 }25973 }
...@@ -25931,7 +25985,7 @@ fn coerceExtra(...@@ -25931,7 +25985,7 @@ fn coerceExtra(
25931 return sema.addConstUndef(dest_ty);25985 return sema.addConstUndef(dest_ty);
25932 }25986 }
25933 const val = (try sema.resolveMaybeUndefVal(inst)) orelse {25987 const val = (try sema.resolveMaybeUndefVal(inst)) orelse {
25934 if (dest_ty.zigTypeTag() == .ComptimeFloat) {25988 if (dest_ty.zigTypeTag(mod) == .ComptimeFloat) {
25935 if (!opts.report_err) return error.NotCoercible;25989 if (!opts.report_err) return error.NotCoercible;
25936 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime-known");25990 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime-known");
25937 }25991 }
...@@ -25955,7 +26009,7 @@ fn coerceExtra(...@@ -25955,7 +26009,7 @@ fn coerceExtra(
25955 },26009 },
25956 else => {},26010 else => {},
25957 },26011 },
25958 .Enum => switch (inst_ty.zigTypeTag()) {26012 .Enum => switch (inst_ty.zigTypeTag(mod)) {
25959 .EnumLiteral => {26013 .EnumLiteral => {
25960 // enum literal to enum26014 // enum literal to enum
25961 const val = try sema.resolveConstValue(block, .unneeded, inst, "");26015 const val = try sema.resolveConstValue(block, .unneeded, inst, "");
...@@ -25991,7 +26045,7 @@ fn coerceExtra(...@@ -25991,7 +26045,7 @@ fn coerceExtra(
25991 },26045 },
25992 else => {},26046 else => {},
25993 },26047 },
25994 .ErrorUnion => switch (inst_ty.zigTypeTag()) {26048 .ErrorUnion => switch (inst_ty.zigTypeTag(mod)) {
25995 .ErrorUnion => eu: {26049 .ErrorUnion => eu: {
25996 if (maybe_inst_val) |inst_val| {26050 if (maybe_inst_val) |inst_val| {
25997 switch (inst_val.tag()) {26051 switch (inst_val.tag()) {
...@@ -26031,7 +26085,7 @@ fn coerceExtra(...@@ -26031,7 +26085,7 @@ fn coerceExtra(
26031 };26085 };
26032 },26086 },
26033 },26087 },
26034 .Union => switch (inst_ty.zigTypeTag()) {26088 .Union => switch (inst_ty.zigTypeTag(mod)) {
26035 .Enum, .EnumLiteral => return sema.coerceEnumToUnion(block, dest_ty, dest_ty_src, inst, inst_src),26089 .Enum, .EnumLiteral => return sema.coerceEnumToUnion(block, dest_ty, dest_ty_src, inst, inst_src),
26036 .Struct => {26090 .Struct => {
26037 if (inst_ty.isAnonStruct()) {26091 if (inst_ty.isAnonStruct()) {
...@@ -26043,7 +26097,7 @@ fn coerceExtra(...@@ -26043,7 +26097,7 @@ fn coerceExtra(
26043 },26097 },
26044 else => {},26098 else => {},
26045 },26099 },
26046 .Array => switch (inst_ty.zigTypeTag()) {26100 .Array => switch (inst_ty.zigTypeTag(mod)) {
26047 .Vector => return sema.coerceArrayLike(block, dest_ty, dest_ty_src, inst, inst_src),26101 .Vector => return sema.coerceArrayLike(block, dest_ty, dest_ty_src, inst, inst_src),
26048 .Struct => {26102 .Struct => {
26049 if (inst == .empty_struct) {26103 if (inst == .empty_struct) {
...@@ -26058,7 +26112,7 @@ fn coerceExtra(...@@ -26058,7 +26112,7 @@ fn coerceExtra(
26058 },26112 },
26059 else => {},26113 else => {},
26060 },26114 },
26061 .Vector => switch (inst_ty.zigTypeTag()) {26115 .Vector => switch (inst_ty.zigTypeTag(mod)) {
26062 .Array, .Vector => return sema.coerceArrayLike(block, dest_ty, dest_ty_src, inst, inst_src),26116 .Array, .Vector => return sema.coerceArrayLike(block, dest_ty, dest_ty_src, inst, inst_src),
26063 .Struct => {26117 .Struct => {
26064 if (inst_ty.isTuple()) {26118 if (inst_ty.isTuple()) {
...@@ -26093,7 +26147,7 @@ fn coerceExtra(...@@ -26093,7 +26147,7 @@ fn coerceExtra(
2609326147
26094 if (!opts.report_err) return error.NotCoercible;26148 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) {
26097 const msg = msg: {26151 const msg = msg: {
26098 const msg = try sema.errMsg(block, inst_src, "function declared 'noreturn' returns", .{});26152 const msg = try sema.errMsg(block, inst_src, "function declared 'noreturn' returns", .{});
26099 errdefer msg.destroy(sema.gpa);26153 errdefer msg.destroy(sema.gpa);
...@@ -26111,7 +26165,7 @@ fn coerceExtra(...@@ -26111,7 +26165,7 @@ fn coerceExtra(
26111 errdefer msg.destroy(sema.gpa);26165 errdefer msg.destroy(sema.gpa);
2611226166
26113 // E!T to T26167 // E!T to T
26114 if (inst_ty.zigTypeTag() == .ErrorUnion and26168 if (inst_ty.zigTypeTag(mod) == .ErrorUnion and
26115 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)26169 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)
26116 {26170 {
26117 try sema.errNote(block, inst_src, msg, "cannot convert error union to payload type", .{});26171 try sema.errNote(block, inst_src, msg, "cannot convert error union to payload type", .{});
...@@ -26120,7 +26174,7 @@ fn coerceExtra(...@@ -26120,7 +26174,7 @@ fn coerceExtra(
2612026174
26121 // ?T to T26175 // ?T to T
26122 var buf: Type.Payload.ElemType = undefined;26176 var buf: Type.Payload.ElemType = undefined;
26123 if (inst_ty.zigTypeTag() == .Optional and26177 if (inst_ty.zigTypeTag(mod) == .Optional and
26124 (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(&buf), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)26178 (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(&buf), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)
26125 {26179 {
26126 try sema.errNote(block, inst_src, msg, "cannot convert optional to payload type", .{});26180 try sema.errNote(block, inst_src, msg, "cannot convert optional to payload type", .{});
...@@ -26133,7 +26187,7 @@ fn coerceExtra(...@@ -26133,7 +26187,7 @@ fn coerceExtra(
26133 if (opts.is_ret and sema.mod.test_functions.get(sema.func.?.owner_decl) == null) {26187 if (opts.is_ret and sema.mod.test_functions.get(sema.func.?.owner_decl) == null) {
26134 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };26188 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
26135 const src_decl = sema.mod.declPtr(sema.func.?.owner_decl);26189 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)) {
26137 try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl), msg, "function cannot return an error", .{});26191 try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl), msg, "function cannot return an error", .{});
26138 } else {26192 } else {
26139 try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl), msg, "function return type declared here", .{});26193 try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl), msg, "function return type declared here", .{});
...@@ -26264,6 +26318,7 @@ const InMemoryCoercionResult = union(enum) {...@@ -26264,6 +26318,7 @@ const InMemoryCoercionResult = union(enum) {
26264 }26318 }
2626526319
26266 fn report(res: *const InMemoryCoercionResult, sema: *Sema, block: *Block, src: LazySrcLoc, msg: *Module.ErrorMsg) !void {26320 fn report(res: *const InMemoryCoercionResult, sema: *Sema, block: *Block, src: LazySrcLoc, msg: *Module.ErrorMsg) !void {
26321 const mod = sema.mod;
26267 var cur = res;26322 var cur = res;
26268 while (true) switch (cur.*) {26323 while (true) switch (cur.*) {
26269 .ok => unreachable,26324 .ok => unreachable,
...@@ -26445,8 +26500,8 @@ const InMemoryCoercionResult = union(enum) {...@@ -26445,8 +26500,8 @@ const InMemoryCoercionResult = union(enum) {
26445 break;26500 break;
26446 },26501 },
26447 .ptr_allowzero => |pair| {26502 .ptr_allowzero => |pair| {
26448 const wanted_allow_zero = pair.wanted.ptrAllowsZero();26503 const wanted_allow_zero = pair.wanted.ptrAllowsZero(mod);
26449 const actual_allow_zero = pair.actual.ptrAllowsZero();26504 const actual_allow_zero = pair.actual.ptrAllowsZero(mod);
26450 if (actual_allow_zero and !wanted_allow_zero) {26505 if (actual_allow_zero and !wanted_allow_zero) {
26451 try sema.errNote(block, src, msg, "'{}' could have null values which are illegal in type '{}'", .{26506 try sema.errNote(block, src, msg, "'{}' could have null values which are illegal in type '{}'", .{
26452 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),26507 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
...@@ -26522,13 +26577,15 @@ fn coerceInMemoryAllowed(...@@ -26522,13 +26577,15 @@ fn coerceInMemoryAllowed(
26522 dest_src: LazySrcLoc,26577 dest_src: LazySrcLoc,
26523 src_src: LazySrcLoc,26578 src_src: LazySrcLoc,
26524) CompileError!InMemoryCoercionResult {26579) 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))
26526 return .ok;26583 return .ok;
2652726584
26528 // Differently-named integers with the same number of bits.26585 // Differently-named integers with the same number of bits.
26529 if (dest_ty.zigTypeTag() == .Int and src_ty.zigTypeTag() == .Int) {26586 if (dest_ty.zigTypeTag(mod) == .Int and src_ty.zigTypeTag(mod) == .Int) {
26530 const dest_info = dest_ty.intInfo(target);26587 const dest_info = dest_ty.intInfo(mod);
26531 const src_info = src_ty.intInfo(target);26588 const src_info = src_ty.intInfo(mod);
2653226589
26533 if (dest_info.signedness == src_info.signedness and26590 if (dest_info.signedness == src_info.signedness and
26534 dest_info.bits == src_info.bits)26591 dest_info.bits == src_info.bits)
...@@ -26551,7 +26608,7 @@ fn coerceInMemoryAllowed(...@@ -26551,7 +26608,7 @@ fn coerceInMemoryAllowed(
26551 }26608 }
2655226609
26553 // Differently-named floats with the same number of bits.26610 // 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) {
26555 const dest_bits = dest_ty.floatBits(target);26612 const dest_bits = dest_ty.floatBits(target);
26556 const src_bits = src_ty.floatBits(target);26613 const src_bits = src_ty.floatBits(target);
26557 if (dest_bits == src_bits) {26614 if (dest_bits == src_bits) {
...@@ -26575,8 +26632,8 @@ fn coerceInMemoryAllowed(...@@ -26575,8 +26632,8 @@ fn coerceInMemoryAllowed(
26575 return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_ty, src_ty, dest_is_mut, target, dest_src, src_src);26632 return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_ty, src_ty, dest_is_mut, target, dest_src, src_src);
26576 }26633 }
2657726634
26578 const dest_tag = dest_ty.zigTypeTag();26635 const dest_tag = dest_ty.zigTypeTag(mod);
26579 const src_tag = src_ty.zigTypeTag();26636 const src_tag = src_ty.zigTypeTag(mod);
2658026637
26581 // Functions26638 // Functions
26582 if (dest_tag == .Fn and src_tag == .Fn) {26639 if (dest_tag == .Fn and src_tag == .Fn) {
...@@ -26624,7 +26681,7 @@ fn coerceInMemoryAllowed(...@@ -26624,7 +26681,7 @@ fn coerceInMemoryAllowed(
26624 }26681 }
26625 const ok_sent = dest_info.sentinel == null or26682 const ok_sent = dest_info.sentinel == null or
26626 (src_info.sentinel != null and26683 (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));
26628 if (!ok_sent) {26685 if (!ok_sent) {
26629 return InMemoryCoercionResult{ .array_sentinel = .{26686 return InMemoryCoercionResult{ .array_sentinel = .{
26630 .actual = src_info.sentinel orelse Value.initTag(.unreachable_value),26687 .actual = src_info.sentinel orelse Value.initTag(.unreachable_value),
...@@ -26646,8 +26703,8 @@ fn coerceInMemoryAllowed(...@@ -26646,8 +26703,8 @@ fn coerceInMemoryAllowed(
26646 } };26703 } };
26647 }26704 }
2664826705
26649 const dest_elem_ty = dest_ty.scalarType();26706 const dest_elem_ty = dest_ty.scalarType(mod);
26650 const src_elem_ty = src_ty.scalarType();26707 const src_elem_ty = src_ty.scalarType(mod);
26651 const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src);26708 const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src);
26652 if (child != .ok) {26709 if (child != .ok) {
26653 return InMemoryCoercionResult{ .vector_elem = .{26710 return InMemoryCoercionResult{ .vector_elem = .{
...@@ -26923,6 +26980,7 @@ fn coerceInMemoryAllowedPtrs(...@@ -26923,6 +26980,7 @@ fn coerceInMemoryAllowedPtrs(
26923 dest_src: LazySrcLoc,26980 dest_src: LazySrcLoc,
26924 src_src: LazySrcLoc,26981 src_src: LazySrcLoc,
26925) !InMemoryCoercionResult {26982) !InMemoryCoercionResult {
26983 const mod = sema.mod;
26926 const dest_info = dest_ptr_ty.ptrInfo().data;26984 const dest_info = dest_ptr_ty.ptrInfo().data;
26927 const src_info = src_ptr_ty.ptrInfo().data;26985 const src_info = src_ptr_ty.ptrInfo().data;
2692826986
...@@ -26964,8 +27022,8 @@ fn coerceInMemoryAllowedPtrs(...@@ -26964,8 +27022,8 @@ fn coerceInMemoryAllowedPtrs(
26964 } };27022 } };
26965 }27023 }
2696627024
26967 const dest_allow_zero = dest_ty.ptrAllowsZero();27025 const dest_allow_zero = dest_ty.ptrAllowsZero(mod);
26968 const src_allow_zero = src_ty.ptrAllowsZero();27026 const src_allow_zero = src_ty.ptrAllowsZero(mod);
2696927027
26970 const ok_allows_zero = (dest_allow_zero and27028 const ok_allows_zero = (dest_allow_zero and
26971 (src_allow_zero or !dest_is_mut)) or27029 (src_allow_zero or !dest_is_mut)) or
...@@ -27013,12 +27071,12 @@ fn coerceInMemoryAllowedPtrs(...@@ -27013,12 +27071,12 @@ fn coerceInMemoryAllowedPtrs(
27013 const src_align = if (src_info.@"align" != 0)27071 const src_align = if (src_info.@"align" != 0)
27014 src_info.@"align"27072 src_info.@"align"
27015 else27073 else
27016 src_info.pointee_type.abiAlignment(target);27074 src_info.pointee_type.abiAlignment(mod);
2701727075
27018 const dest_align = if (dest_info.@"align" != 0)27076 const dest_align = if (dest_info.@"align" != 0)
27019 dest_info.@"align"27077 dest_info.@"align"
27020 else27078 else
27021 dest_info.pointee_type.abiAlignment(target);27079 dest_info.pointee_type.abiAlignment(mod);
2702227080
27023 if (dest_align > src_align) {27081 if (dest_align > src_align) {
27024 return InMemoryCoercionResult{ .ptr_alignment = .{27082 return InMemoryCoercionResult{ .ptr_alignment = .{
...@@ -27041,8 +27099,9 @@ fn coerceVarArgParam(...@@ -27041,8 +27099,9 @@ fn coerceVarArgParam(
27041) !Air.Inst.Ref {27099) !Air.Inst.Ref {
27042 if (block.is_typeof) return inst;27100 if (block.is_typeof) return inst;
2704327101
27102 const mod = sema.mod;
27044 const uncasted_ty = sema.typeOf(inst);27103 const uncasted_ty = sema.typeOf(inst);
27045 const coerced = switch (uncasted_ty.zigTypeTag()) {27104 const coerced = switch (uncasted_ty.zigTypeTag(mod)) {
27046 // TODO consider casting to c_int/f64 if they fit27105 // TODO consider casting to c_int/f64 if they fit
27047 .ComptimeInt, .ComptimeFloat => return sema.fail(27106 .ComptimeInt, .ComptimeFloat => return sema.fail(
27048 block,27107 block,
...@@ -27124,7 +27183,8 @@ fn storePtr2(...@@ -27124,7 +27183,8 @@ fn storePtr2(
27124 // this code does not handle tuple-to-struct coercion which requires dealing with missing27183 // this code does not handle tuple-to-struct coercion which requires dealing with missing
27125 // fields.27184 // fields.
27126 const operand_ty = sema.typeOf(uncasted_operand);27185 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) {
27128 const field_count = operand_ty.structFieldCount();27188 const field_count = operand_ty.structFieldCount();
27129 var i: u32 = 0;27189 var i: u32 = 0;
27130 while (i < field_count) : (i += 1) {27190 while (i < field_count) : (i += 1) {
...@@ -27225,7 +27285,8 @@ fn storePtr2(...@@ -27225,7 +27285,8 @@ fn storePtr2(
27225/// lengths match.27285/// lengths match.
27226fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {27286fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
27227 const array_ty = sema.typeOf(ptr).childType();27287 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;
27229 var ptr_inst = Air.refToIndex(ptr) orelse return null;27290 var ptr_inst = Air.refToIndex(ptr) orelse return null;
27230 const air_datas = sema.air_instructions.items(.data);27291 const air_datas = sema.air_instructions.items(.data);
27231 const air_tags = sema.air_instructions.items(.tag);27292 const air_tags = sema.air_instructions.items(.tag);
...@@ -27237,7 +27298,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {...@@ -27237,7 +27298,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
27237 .pointer => prev_ptr_ty.castTag(.pointer).?.data.pointee_type,27298 .pointer => prev_ptr_ty.castTag(.pointer).?.data.pointee_type,
27238 else => return null,27299 else => return null,
27239 };27300 };
27240 if (prev_ptr_child_ty.zigTypeTag() == .Vector) break prev_ptr;27301 if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr;
27241 ptr_inst = Air.refToIndex(prev_ptr) orelse return null;27302 ptr_inst = Air.refToIndex(prev_ptr) orelse return null;
27242 } else return null;27303 } else return null;
2724327304
...@@ -27263,6 +27324,7 @@ fn storePtrVal(...@@ -27263,6 +27324,7 @@ fn storePtrVal(
27263 operand_val: Value,27324 operand_val: Value,
27264 operand_ty: Type,27325 operand_ty: Type,
27265) !void {27326) !void {
27327 const mod = sema.mod;
27266 var mut_kit = try sema.beginComptimePtrMutation(block, src, ptr_val, operand_ty);27328 var mut_kit = try sema.beginComptimePtrMutation(block, src, ptr_val, operand_ty);
27267 try sema.checkComptimeVarStore(block, src, mut_kit.decl_ref_mut);27329 try sema.checkComptimeVarStore(block, src, mut_kit.decl_ref_mut);
2726827330
...@@ -27281,8 +27343,7 @@ fn storePtrVal(...@@ -27281,8 +27343,7 @@ fn storePtrVal(
27281 val_ptr.* = try operand_val.copy(arena);27343 val_ptr.* = try operand_val.copy(arena);
27282 },27344 },
27283 .reinterpret => |reinterpret| {27345 .reinterpret => |reinterpret| {
27284 const target = sema.mod.getTarget();27346 const abi_size = try sema.usizeCast(block, src, mut_kit.ty.abiSize(mod));
27285 const abi_size = try sema.usizeCast(block, src, mut_kit.ty.abiSize(target));
27286 const buffer = try sema.gpa.alloc(u8, abi_size);27347 const buffer = try sema.gpa.alloc(u8, abi_size);
27287 defer sema.gpa.free(buffer);27348 defer sema.gpa.free(buffer);
27288 reinterpret.val_ptr.*.writeToMemory(mut_kit.ty, sema.mod, buffer) catch |err| switch (err) {27349 reinterpret.val_ptr.*.writeToMemory(mut_kit.ty, sema.mod, buffer) catch |err| switch (err) {
...@@ -27354,7 +27415,7 @@ fn beginComptimePtrMutation(...@@ -27354,7 +27415,7 @@ fn beginComptimePtrMutation(
27354 ptr_val: Value,27415 ptr_val: Value,
27355 ptr_elem_ty: Type,27416 ptr_elem_ty: Type,
27356) CompileError!ComptimePtrMutationKit {27417) CompileError!ComptimePtrMutationKit {
27357 const target = sema.mod.getTarget();27418 const mod = sema.mod;
27358 switch (ptr_val.tag()) {27419 switch (ptr_val.tag()) {
27359 .decl_ref_mut => {27420 .decl_ref_mut => {
27360 const decl_ref_mut = ptr_val.castTag(.decl_ref_mut).?.data;27421 const decl_ref_mut = ptr_val.castTag(.decl_ref_mut).?.data;
...@@ -27375,7 +27436,7 @@ fn beginComptimePtrMutation(...@@ -27375,7 +27436,7 @@ fn beginComptimePtrMutation(
27375 var parent = try sema.beginComptimePtrMutation(block, src, elem_ptr.array_ptr, elem_ptr.elem_ty);27436 var parent = try sema.beginComptimePtrMutation(block, src, elem_ptr.array_ptr, elem_ptr.elem_ty);
2737627437
27377 switch (parent.pointee) {27438 switch (parent.pointee) {
27378 .direct => |val_ptr| switch (parent.ty.zigTypeTag()) {27439 .direct => |val_ptr| switch (parent.ty.zigTypeTag(mod)) {
27379 .Array, .Vector => {27440 .Array, .Vector => {
27380 const check_len = parent.ty.arrayLenIncludingSentinel();27441 const check_len = parent.ty.arrayLenIncludingSentinel();
27381 if (elem_ptr.index >= check_len) {27442 if (elem_ptr.index >= check_len) {
...@@ -27570,7 +27631,7 @@ fn beginComptimePtrMutation(...@@ -27570,7 +27631,7 @@ fn beginComptimePtrMutation(
27570 },27631 },
27571 },27632 },
27572 .reinterpret => |reinterpret| {27633 .reinterpret => |reinterpret| {
27573 if (!elem_ptr.elem_ty.hasWellDefinedLayout()) {27634 if (!elem_ptr.elem_ty.hasWellDefinedLayout(mod)) {
27574 // Even though the parent value type has well-defined memory layout, our27635 // Even though the parent value type has well-defined memory layout, our
27575 // pointer type does not.27636 // pointer type does not.
27576 return ComptimePtrMutationKit{27637 return ComptimePtrMutationKit{
...@@ -27608,7 +27669,7 @@ fn beginComptimePtrMutation(...@@ -27608,7 +27669,7 @@ fn beginComptimePtrMutation(
27608 const arena = parent.beginArena(sema.mod);27669 const arena = parent.beginArena(sema.mod);
27609 defer parent.finishArena(sema.mod);27670 defer parent.finishArena(sema.mod);
2761027671
27611 switch (parent.ty.zigTypeTag()) {27672 switch (parent.ty.zigTypeTag(mod)) {
27612 .Struct => {27673 .Struct => {
27613 const fields = try arena.alloc(Value, parent.ty.structFieldCount());27674 const fields = try arena.alloc(Value, parent.ty.structFieldCount());
27614 @memset(fields, Value.undef);27675 @memset(fields, Value.undef);
...@@ -27746,7 +27807,7 @@ fn beginComptimePtrMutation(...@@ -27746,7 +27807,7 @@ fn beginComptimePtrMutation(
27746 else => unreachable,27807 else => unreachable,
27747 },27808 },
27748 .reinterpret => |reinterpret| {27809 .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);
27750 const field_offset = try sema.usizeCast(block, src, field_offset_u64);27811 const field_offset = try sema.usizeCast(block, src, field_offset_u64);
27751 return ComptimePtrMutationKit{27812 return ComptimePtrMutationKit{
27752 .decl_ref_mut = parent.decl_ref_mut,27813 .decl_ref_mut = parent.decl_ref_mut,
...@@ -27872,7 +27933,8 @@ fn beginComptimePtrMutationInner(...@@ -27872,7 +27933,8 @@ fn beginComptimePtrMutationInner(
27872 ptr_elem_ty: Type,27933 ptr_elem_ty: Type,
27873 decl_ref_mut: Value.Payload.DeclRefMut.Data,27934 decl_ref_mut: Value.Payload.DeclRefMut.Data,
27874) CompileError!ComptimePtrMutationKit {27935) CompileError!ComptimePtrMutationKit {
27875 const target = sema.mod.getTarget();27936 const mod = sema.mod;
27937 const target = mod.getTarget();
27876 const coerce_ok = (try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_ty, true, target, src, src)) == .ok;27938 const coerce_ok = (try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_ty, true, target, src, src)) == .ok;
27877 if (coerce_ok) {27939 if (coerce_ok) {
27878 return ComptimePtrMutationKit{27940 return ComptimePtrMutationKit{
...@@ -27883,7 +27945,7 @@ fn beginComptimePtrMutationInner(...@@ -27883,7 +27945,7 @@ fn beginComptimePtrMutationInner(
27883 }27945 }
2788427946
27885 // Handle the case that the decl is an array and we're actually trying to point to an element.27947 // 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)) {
27887 const decl_elem_ty = decl_ty.childType();27949 const decl_elem_ty = decl_ty.childType();
27888 if ((try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_elem_ty, true, target, src, src)) == .ok) {27950 if ((try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_elem_ty, true, target, src, src)) == .ok) {
27889 return ComptimePtrMutationKit{27951 return ComptimePtrMutationKit{
...@@ -27894,14 +27956,14 @@ fn beginComptimePtrMutationInner(...@@ -27894,14 +27956,14 @@ fn beginComptimePtrMutationInner(
27894 }27956 }
27895 }27957 }
2789627958
27897 if (!decl_ty.hasWellDefinedLayout()) {27959 if (!decl_ty.hasWellDefinedLayout(mod)) {
27898 return ComptimePtrMutationKit{27960 return ComptimePtrMutationKit{
27899 .decl_ref_mut = decl_ref_mut,27961 .decl_ref_mut = decl_ref_mut,
27900 .pointee = .{ .bad_decl_ty = {} },27962 .pointee = .{ .bad_decl_ty = {} },
27901 .ty = decl_ty,27963 .ty = decl_ty,
27902 };27964 };
27903 }27965 }
27904 if (!ptr_elem_ty.hasWellDefinedLayout()) {27966 if (!ptr_elem_ty.hasWellDefinedLayout(mod)) {
27905 return ComptimePtrMutationKit{27967 return ComptimePtrMutationKit{
27906 .decl_ref_mut = decl_ref_mut,27968 .decl_ref_mut = decl_ref_mut,
27907 .pointee = .{ .bad_ptr_ty = {} },27969 .pointee = .{ .bad_ptr_ty = {} },
...@@ -27951,6 +28013,7 @@ fn beginComptimePtrLoad(...@@ -27951,6 +28013,7 @@ fn beginComptimePtrLoad(
27951 ptr_val: Value,28013 ptr_val: Value,
27952 maybe_array_ty: ?Type,28014 maybe_array_ty: ?Type,
27953) ComptimePtrLoadError!ComptimePtrLoadKit {28015) ComptimePtrLoadError!ComptimePtrLoadKit {
28016 const mod = sema.mod;
27954 const target = sema.mod.getTarget();28017 const target = sema.mod.getTarget();
27955 var deref: ComptimePtrLoadKit = switch (ptr_val.tag()) {28018 var deref: ComptimePtrLoadKit = switch (ptr_val.tag()) {
27956 .decl_ref,28019 .decl_ref,
...@@ -27966,7 +28029,7 @@ fn beginComptimePtrLoad(...@@ -27966,7 +28029,7 @@ fn beginComptimePtrLoad(
27966 const decl_tv = try decl.typedValue();28029 const decl_tv = try decl.typedValue();
27967 if (decl_tv.val.tag() == .variable) return error.RuntimeLoad;28030 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);
27970 break :blk ComptimePtrLoadKit{28033 break :blk ComptimePtrLoadKit{
27971 .parent = if (layout_defined) .{ .tv = decl_tv, .byte_offset = 0 } else null,28034 .parent = if (layout_defined) .{ .tv = decl_tv, .byte_offset = 0 } else null,
27972 .pointee = decl_tv,28035 .pointee = decl_tv,
...@@ -27988,7 +28051,7 @@ fn beginComptimePtrLoad(...@@ -27988,7 +28051,7 @@ fn beginComptimePtrLoad(
27988 }28051 }
2798928052
27990 if (elem_ptr.index != 0) {28053 if (elem_ptr.index != 0) {
27991 if (elem_ty.hasWellDefinedLayout()) {28054 if (elem_ty.hasWellDefinedLayout(mod)) {
27992 if (deref.parent) |*parent| {28055 if (deref.parent) |*parent| {
27993 // Update the byte offset (in-place)28056 // Update the byte offset (in-place)
27994 const elem_size = try sema.typeAbiSize(elem_ty);28057 const elem_size = try sema.typeAbiSize(elem_ty);
...@@ -28003,7 +28066,7 @@ fn beginComptimePtrLoad(...@@ -28003,7 +28066,7 @@ fn beginComptimePtrLoad(
2800328066
28004 // If we're loading an elem_ptr that was derived from a different type28067 // If we're loading an elem_ptr that was derived from a different type
28005 // than the true type of the underlying decl, we cannot deref directly28068 // 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: {
28007 const deref_elem_ty = deref.pointee.?.ty.childType();28070 const deref_elem_ty = deref.pointee.?.ty.childType();
28008 break :x (try sema.coerceInMemoryAllowed(block, deref_elem_ty, elem_ty, false, target, src, src)) == .ok or28071 break :x (try sema.coerceInMemoryAllowed(block, deref_elem_ty, elem_ty, false, target, src, src)) == .ok or
28009 (try sema.coerceInMemoryAllowed(block, elem_ty, deref_elem_ty, false, target, src, src)) == .ok;28072 (try sema.coerceInMemoryAllowed(block, elem_ty, deref_elem_ty, false, target, src, src)) == .ok;
...@@ -28018,7 +28081,7 @@ fn beginComptimePtrLoad(...@@ -28018,7 +28081,7 @@ fn beginComptimePtrLoad(
28018 if (maybe_array_ty) |load_ty| {28081 if (maybe_array_ty) |load_ty| {
28019 // It's possible that we're loading a [N]T, in which case we'd like to slice28082 // It's possible that we're loading a [N]T, in which case we'd like to slice
28020 // the pointee array directly from our parent array.28083 // 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)) {
28022 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel());28085 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel());
28023 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{28086 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{
28024 .ty = try Type.array(sema.arena, N, null, elem_ty, sema.mod),28087 .ty = try Type.array(sema.arena, N, null, elem_ty, sema.mod),
...@@ -28058,7 +28121,7 @@ fn beginComptimePtrLoad(...@@ -28058,7 +28121,7 @@ fn beginComptimePtrLoad(
28058 const field_index = @intCast(u32, field_ptr.field_index);28121 const field_index = @intCast(u32, field_ptr.field_index);
28059 var deref = try sema.beginComptimePtrLoad(block, src, field_ptr.container_ptr, field_ptr.container_ty);28122 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)) {
28062 const struct_ty = field_ptr.container_ty.castTag(.@"struct");28125 const struct_ty = field_ptr.container_ty.castTag(.@"struct");
28063 if (struct_ty != null and struct_ty.?.data.layout == .Packed) {28126 if (struct_ty != null and struct_ty.?.data.layout == .Packed) {
28064 // packed structs are not byte addressable28127 // packed structs are not byte addressable
...@@ -28066,7 +28129,7 @@ fn beginComptimePtrLoad(...@@ -28066,7 +28129,7 @@ fn beginComptimePtrLoad(
28066 } else if (deref.parent) |*parent| {28129 } else if (deref.parent) |*parent| {
28067 // Update the byte offset (in-place)28130 // Update the byte offset (in-place)
28068 try sema.resolveTypeLayout(field_ptr.container_ty);28131 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);
28070 parent.byte_offset = try sema.usizeCast(block, src, parent.byte_offset + field_offset);28133 parent.byte_offset = try sema.usizeCast(block, src, parent.byte_offset + field_offset);
28071 }28134 }
28072 } else {28135 } else {
...@@ -28103,7 +28166,7 @@ fn beginComptimePtrLoad(...@@ -28103,7 +28166,7 @@ fn beginComptimePtrLoad(
28103 const field_ty = field_ptr.container_ty.structFieldType(field_index);28166 const field_ty = field_ptr.container_ty.structFieldType(field_index);
28104 deref.pointee = TypedValue{28167 deref.pointee = TypedValue{
28105 .ty = field_ty,28168 .ty = field_ty,
28106 .val = tv.val.fieldValue(tv.ty, field_index),28169 .val = tv.val.fieldValue(tv.ty, mod, field_index),
28107 };28170 };
28108 }28171 }
28109 break :blk deref;28172 break :blk deref;
...@@ -28146,7 +28209,7 @@ fn beginComptimePtrLoad(...@@ -28146,7 +28209,7 @@ fn beginComptimePtrLoad(
28146 return sema.fail(block, src, "attempt to unwrap error: {s}", .{tv.val.castTag(.@"error").?.data.name});28209 return sema.fail(block, src, "attempt to unwrap error: {s}", .{tv.val.castTag(.@"error").?.data.name});
28147 },28210 },
28148 .opt_payload_ptr => if (tv.val.castTag(.opt_payload)) |some| some.data else opt: {28211 .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", .{});
28150 break :opt tv.val;28213 break :opt tv.val;
28151 },28214 },
28152 else => unreachable,28215 else => unreachable,
...@@ -28181,7 +28244,7 @@ fn beginComptimePtrLoad(...@@ -28181,7 +28244,7 @@ fn beginComptimePtrLoad(
28181 };28244 };
2818228245
28183 if (deref.pointee) |tv| {28246 if (deref.pointee) |tv| {
28184 if (deref.parent == null and tv.ty.hasWellDefinedLayout()) {28247 if (deref.parent == null and tv.ty.hasWellDefinedLayout(mod)) {
28185 deref.parent = .{ .tv = tv, .byte_offset = 0 };28248 deref.parent = .{ .tv = tv, .byte_offset = 0 };
28186 }28249 }
28187 }28250 }
...@@ -28196,15 +28259,15 @@ fn bitCast(...@@ -28196,15 +28259,15 @@ fn bitCast(
28196 inst_src: LazySrcLoc,28259 inst_src: LazySrcLoc,
28197 operand_src: ?LazySrcLoc,28260 operand_src: ?LazySrcLoc,
28198) CompileError!Air.Inst.Ref {28261) CompileError!Air.Inst.Ref {
28262 const mod = sema.mod;
28199 const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);28263 const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);
28200 try sema.resolveTypeLayout(dest_ty);28264 try sema.resolveTypeLayout(dest_ty);
2820128265
28202 const old_ty = try sema.resolveTypeFields(sema.typeOf(inst));28266 const old_ty = try sema.resolveTypeFields(sema.typeOf(inst));
28203 try sema.resolveTypeLayout(old_ty);28267 try sema.resolveTypeLayout(old_ty);
2820428268
28205 const target = sema.mod.getTarget();28269 const dest_bits = dest_ty.bitSize(mod);
28206 const dest_bits = dest_ty.bitSize(target);28270 const old_bits = old_ty.bitSize(mod);
28207 const old_bits = old_ty.bitSize(target);
2820828271
28209 if (old_bits != dest_bits) {28272 if (old_bits != dest_bits) {
28210 return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{}' has {d} bits but source type '{}' has {d} bits", .{28273 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(...@@ -28233,20 +28296,20 @@ fn bitCastVal(
28233 new_ty: Type,28296 new_ty: Type,
28234 buffer_offset: usize,28297 buffer_offset: usize,
28235) !?Value {28298) !?Value {
28236 const target = sema.mod.getTarget();28299 const mod = sema.mod;
28237 if (old_ty.eql(new_ty, sema.mod)) return val;28300 if (old_ty.eql(new_ty, mod)) return val;
2823828301
28239 // For types with well-defined memory layouts, we serialize them a byte buffer,28302 // For types with well-defined memory layouts, we serialize them a byte buffer,
28240 // then deserialize to the new type.28303 // 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));
28242 const buffer = try sema.gpa.alloc(u8, abi_size);28305 const buffer = try sema.gpa.alloc(u8, abi_size);
28243 defer sema.gpa.free(buffer);28306 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) {
28245 error.ReinterpretDeclRef => return null,28308 error.ReinterpretDeclRef => return null,
28246 error.IllDefinedMemoryLayout => unreachable, // Sema was supposed to emit a compile error already28309 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)}),
28248 };28311 };
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);
28250}28313}
2825128314
28252fn coerceArrayPtrToSlice(28315fn coerceArrayPtrToSlice(
...@@ -28272,7 +28335,8 @@ fn coerceArrayPtrToSlice(...@@ -28272,7 +28335,8 @@ fn coerceArrayPtrToSlice(
28272fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool {28335fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool {
28273 const dest_info = dest_ty.ptrInfo().data;28336 const dest_info = dest_ty.ptrInfo().data;
28274 const inst_info = inst_ty.ptrInfo().data;28337 const inst_info = inst_ty.ptrInfo().data;
28275 const len0 = (inst_info.pointee_type.zigTypeTag() == .Array and (inst_info.pointee_type.arrayLenIncludingSentinel() == 0 or28338 const mod = sema.mod;
28339 const len0 = (inst_info.pointee_type.zigTypeTag(mod) == .Array and (inst_info.pointee_type.arrayLenIncludingSentinel() == 0 or
28276 (inst_info.pointee_type.arrayLen() == 0 and dest_info.sentinel == null and dest_info.size != .C and dest_info.size != .Many))) or28340 (inst_info.pointee_type.arrayLen() == 0 and dest_info.sentinel == null and dest_info.size != .C and dest_info.size != .Many))) or
28277 (inst_info.pointee_type.isTuple() and inst_info.pointee_type.structFieldCount() == 0);28341 (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...@@ -28298,17 +28362,16 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul
28298 }28362 }
28299 if (inst_info.@"align" == 0 and dest_info.@"align" == 0) return true;28363 if (inst_info.@"align" == 0 and dest_info.@"align" == 0) return true;
28300 if (len0) return true;28364 if (len0) return true;
28301 const target = sema.mod.getTarget();
2830228365
28303 const inst_align = if (inst_info.@"align" != 0)28366 const inst_align = if (inst_info.@"align" != 0)
28304 inst_info.@"align"28367 inst_info.@"align"
28305 else28368 else
28306 inst_info.pointee_type.abiAlignment(target);28369 inst_info.pointee_type.abiAlignment(mod);
2830728370
28308 const dest_align = if (dest_info.@"align" != 0)28371 const dest_align = if (dest_info.@"align" != 0)
28309 dest_info.@"align"28372 dest_info.@"align"
28310 else28373 else
28311 dest_info.pointee_type.abiAlignment(target);28374 dest_info.pointee_type.abiAlignment(mod);
2831228375
28313 if (dest_align > inst_align) {28376 if (dest_align > inst_align) {
28314 in_memory_result.* = .{ .ptr_alignment = .{28377 in_memory_result.* = .{ .ptr_alignment = .{
...@@ -28327,18 +28390,19 @@ fn coerceCompatiblePtrs(...@@ -28327,18 +28390,19 @@ fn coerceCompatiblePtrs(
28327 inst: Air.Inst.Ref,28390 inst: Air.Inst.Ref,
28328 inst_src: LazySrcLoc,28391 inst_src: LazySrcLoc,
28329) !Air.Inst.Ref {28392) !Air.Inst.Ref {
28393 const mod = sema.mod;
28330 const inst_ty = sema.typeOf(inst);28394 const inst_ty = sema.typeOf(inst);
28331 if (try sema.resolveMaybeUndefVal(inst)) |val| {28395 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)) {
28333 return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)});28397 return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)});
28334 }28398 }
28335 // The comptime Value representation is compatible with both types.28399 // The comptime Value representation is compatible with both types.
28336 return sema.addConstant(dest_ty, val);28400 return sema.addConstant(dest_ty, val);
28337 }28401 }
28338 try sema.requireRuntimeBlock(block, inst_src, null);28402 try sema.requireRuntimeBlock(block, inst_src, null);
28339 const inst_allows_zero = inst_ty.zigTypeTag() != .Pointer or inst_ty.ptrAllowsZero();28403 const inst_allows_zero = inst_ty.zigTypeTag(mod) != .Pointer or inst_ty.ptrAllowsZero(mod);
28340 if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero() and28404 if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero(mod) and
28341 (try sema.typeHasRuntimeBits(dest_ty.elemType2()) or dest_ty.elemType2().zigTypeTag() == .Fn))28405 (try sema.typeHasRuntimeBits(dest_ty.elemType2(mod)) or dest_ty.elemType2(mod).zigTypeTag(mod) == .Fn))
28342 {28406 {
28343 const actual_ptr = if (inst_ty.isSlice())28407 const actual_ptr = if (inst_ty.isSlice())
28344 try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty)28408 try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty)
...@@ -28364,6 +28428,7 @@ fn coerceEnumToUnion(...@@ -28364,6 +28428,7 @@ fn coerceEnumToUnion(
28364 inst: Air.Inst.Ref,28428 inst: Air.Inst.Ref,
28365 inst_src: LazySrcLoc,28429 inst_src: LazySrcLoc,
28366) !Air.Inst.Ref {28430) !Air.Inst.Ref {
28431 const mod = sema.mod;
28367 const inst_ty = sema.typeOf(inst);28432 const inst_ty = sema.typeOf(inst);
2836828433
28369 const tag_ty = union_ty.unionTagType() orelse {28434 const tag_ty = union_ty.unionTagType() orelse {
...@@ -28396,7 +28461,7 @@ fn coerceEnumToUnion(...@@ -28396,7 +28461,7 @@ fn coerceEnumToUnion(
28396 const union_obj = union_ty.cast(Type.Payload.Union).?.data;28461 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
28397 const field = union_obj.fields.values()[field_index];28462 const field = union_obj.fields.values()[field_index];
28398 const field_ty = try sema.resolveTypeFields(field.ty);28463 const field_ty = try sema.resolveTypeFields(field.ty);
28399 if (field_ty.zigTypeTag() == .NoReturn) {28464 if (field_ty.zigTypeTag(mod) == .NoReturn) {
28400 const msg = msg: {28465 const msg = msg: {
28401 const msg = try sema.errMsg(block, inst_src, "cannot initialize 'noreturn' field of union", .{});28466 const msg = try sema.errMsg(block, inst_src, "cannot initialize 'noreturn' field of union", .{});
28402 errdefer msg.destroy(sema.gpa);28467 errdefer msg.destroy(sema.gpa);
...@@ -28449,7 +28514,7 @@ fn coerceEnumToUnion(...@@ -28449,7 +28514,7 @@ fn coerceEnumToUnion(
28449 errdefer if (msg) |some| some.destroy(sema.gpa);28514 errdefer if (msg) |some| some.destroy(sema.gpa);
2845028515
28451 for (union_obj.fields.values(), 0..) |field, i| {28516 for (union_obj.fields.values(), 0..) |field, i| {
28452 if (field.ty.zigTypeTag() == .NoReturn) {28517 if (field.ty.zigTypeTag(mod) == .NoReturn) {
28453 const err_msg = msg orelse try sema.errMsg(28518 const err_msg = msg orelse try sema.errMsg(
28454 block,28519 block,
28455 inst_src,28520 inst_src,
...@@ -28469,7 +28534,7 @@ fn coerceEnumToUnion(...@@ -28469,7 +28534,7 @@ fn coerceEnumToUnion(
28469 }28534 }
2847028535
28471 // If the union has all fields 0 bits, the union value is just the enum value.28536 // 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)) {
28473 return block.addBitCast(union_ty, enum_tag);28538 return block.addBitCast(union_ty, enum_tag);
28474 }28539 }
2847528540
...@@ -28487,7 +28552,7 @@ fn coerceEnumToUnion(...@@ -28487,7 +28552,7 @@ fn coerceEnumToUnion(
28487 while (it.next()) |field| : (field_index += 1) {28552 while (it.next()) |field| : (field_index += 1) {
28488 const field_name = field.key_ptr.*;28553 const field_name = field.key_ptr.*;
28489 const field_ty = field.value_ptr.ty;28554 const field_ty = field.value_ptr.ty;
28490 if (!field_ty.hasRuntimeBits()) continue;28555 if (!(try sema.typeHasRuntimeBits(field_ty))) continue;
28491 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) });28556 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) });
28492 }28557 }
28493 try sema.addDeclaredHereNote(msg, union_ty);28558 try sema.addDeclaredHereNote(msg, union_ty);
...@@ -29066,12 +29131,13 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo...@@ -29066,12 +29131,13 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo
29066}29131}
2906729132
29068fn maybeQueueFuncBodyAnalysis(sema: *Sema, decl_index: Decl.Index) !void {29133fn 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);
29070 const tv = try decl.typedValue();29136 const tv = try decl.typedValue();
29071 if (tv.ty.zigTypeTag() != .Fn) return;29137 if (tv.ty.zigTypeTag(mod) != .Fn) return;
29072 if (!try sema.fnHasRuntimeBits(tv.ty)) return;29138 if (!try sema.fnHasRuntimeBits(tv.ty)) return;
29073 const func = tv.val.castTag(.function) orelse return; // undef or extern_fn29139 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);
29075}29141}
2907629142
29077fn analyzeRef(29143fn analyzeRef(
...@@ -29124,8 +29190,9 @@ fn analyzeLoad(...@@ -29124,8 +29190,9 @@ fn analyzeLoad(
29124 ptr: Air.Inst.Ref,29190 ptr: Air.Inst.Ref,
29125 ptr_src: LazySrcLoc,29191 ptr_src: LazySrcLoc,
29126) CompileError!Air.Inst.Ref {29192) CompileError!Air.Inst.Ref {
29193 const mod = sema.mod;
29127 const ptr_ty = sema.typeOf(ptr);29194 const ptr_ty = sema.typeOf(ptr);
29128 const elem_ty = switch (ptr_ty.zigTypeTag()) {29195 const elem_ty = switch (ptr_ty.zigTypeTag(mod)) {
29129 .Pointer => ptr_ty.childType(),29196 .Pointer => ptr_ty.childType(),
29130 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)}),29197 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)}),
29131 };29198 };
...@@ -29196,12 +29263,13 @@ fn analyzeIsNull(...@@ -29196,12 +29263,13 @@ fn analyzeIsNull(
29196 operand: Air.Inst.Ref,29263 operand: Air.Inst.Ref,
29197 invert_logic: bool,29264 invert_logic: bool,
29198) CompileError!Air.Inst.Ref {29265) CompileError!Air.Inst.Ref {
29266 const mod = sema.mod;
29199 const result_ty = Type.bool;29267 const result_ty = Type.bool;
29200 if (try sema.resolveMaybeUndefVal(operand)) |opt_val| {29268 if (try sema.resolveMaybeUndefVal(operand)) |opt_val| {
29201 if (opt_val.isUndef()) {29269 if (opt_val.isUndef()) {
29202 return sema.addConstUndef(result_ty);29270 return sema.addConstUndef(result_ty);
29203 }29271 }
29204 const is_null = opt_val.isNull();29272 const is_null = opt_val.isNull(mod);
29205 const bool_value = if (invert_logic) !is_null else is_null;29273 const bool_value = if (invert_logic) !is_null else is_null;
29206 if (bool_value) {29274 if (bool_value) {
29207 return Air.Inst.Ref.bool_true;29275 return Air.Inst.Ref.bool_true;
...@@ -29213,10 +29281,10 @@ fn analyzeIsNull(...@@ -29213,10 +29281,10 @@ fn analyzeIsNull(
29213 const inverted_non_null_res = if (invert_logic) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;29281 const inverted_non_null_res = if (invert_logic) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
29214 const operand_ty = sema.typeOf(operand);29282 const operand_ty = sema.typeOf(operand);
29215 var buf: Type.Payload.ElemType = undefined;29283 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) {
29217 return inverted_non_null_res;29285 return inverted_non_null_res;
29218 }29286 }
29219 if (operand_ty.zigTypeTag() != .Optional and !operand_ty.isPtrLikeOptional()) {29287 if (operand_ty.zigTypeTag(mod) != .Optional and !operand_ty.isPtrLikeOptional(mod)) {
29220 return inverted_non_null_res;29288 return inverted_non_null_res;
29221 }29289 }
29222 try sema.requireRuntimeBlock(block, src, null);29290 try sema.requireRuntimeBlock(block, src, null);
...@@ -29230,11 +29298,12 @@ fn analyzePtrIsNonErrComptimeOnly(...@@ -29230,11 +29298,12 @@ fn analyzePtrIsNonErrComptimeOnly(
29230 src: LazySrcLoc,29298 src: LazySrcLoc,
29231 operand: Air.Inst.Ref,29299 operand: Air.Inst.Ref,
29232) CompileError!Air.Inst.Ref {29300) CompileError!Air.Inst.Ref {
29301 const mod = sema.mod;
29233 const ptr_ty = sema.typeOf(operand);29302 const ptr_ty = sema.typeOf(operand);
29234 assert(ptr_ty.zigTypeTag() == .Pointer);29303 assert(ptr_ty.zigTypeTag(mod) == .Pointer);
29235 const child_ty = ptr_ty.childType();29304 const child_ty = ptr_ty.childType();
2923629305
29237 const child_tag = child_ty.zigTypeTag();29306 const child_tag = child_ty.zigTypeTag(mod);
29238 if (child_tag != .ErrorSet and child_tag != .ErrorUnion) return Air.Inst.Ref.bool_true;29307 if (child_tag != .ErrorSet and child_tag != .ErrorUnion) return Air.Inst.Ref.bool_true;
29239 if (child_tag == .ErrorSet) return Air.Inst.Ref.bool_false;29308 if (child_tag == .ErrorSet) return Air.Inst.Ref.bool_false;
29240 assert(child_tag == .ErrorUnion);29309 assert(child_tag == .ErrorUnion);
...@@ -29251,14 +29320,15 @@ fn analyzeIsNonErrComptimeOnly(...@@ -29251,14 +29320,15 @@ fn analyzeIsNonErrComptimeOnly(
29251 src: LazySrcLoc,29320 src: LazySrcLoc,
29252 operand: Air.Inst.Ref,29321 operand: Air.Inst.Ref,
29253) CompileError!Air.Inst.Ref {29322) CompileError!Air.Inst.Ref {
29323 const mod = sema.mod;
29254 const operand_ty = sema.typeOf(operand);29324 const operand_ty = sema.typeOf(operand);
29255 const ot = operand_ty.zigTypeTag();29325 const ot = operand_ty.zigTypeTag(mod);
29256 if (ot != .ErrorSet and ot != .ErrorUnion) return Air.Inst.Ref.bool_true;29326 if (ot != .ErrorSet and ot != .ErrorUnion) return Air.Inst.Ref.bool_true;
29257 if (ot == .ErrorSet) return Air.Inst.Ref.bool_false;29327 if (ot == .ErrorSet) return Air.Inst.Ref.bool_false;
29258 assert(ot == .ErrorUnion);29328 assert(ot == .ErrorUnion);
2925929329
29260 const payload_ty = operand_ty.errorUnionPayload();29330 const payload_ty = operand_ty.errorUnionPayload();
29261 if (payload_ty.zigTypeTag() == .NoReturn) {29331 if (payload_ty.zigTypeTag(mod) == .NoReturn) {
29262 return Air.Inst.Ref.bool_false;29332 return Air.Inst.Ref.bool_false;
29263 }29333 }
2926429334
...@@ -29375,22 +29445,21 @@ fn analyzeSlice(...@@ -29375,22 +29445,21 @@ fn analyzeSlice(
29375 end_src: LazySrcLoc,29445 end_src: LazySrcLoc,
29376 by_length: bool,29446 by_length: bool,
29377) CompileError!Air.Inst.Ref {29447) CompileError!Air.Inst.Ref {
29448 const mod = sema.mod;
29378 // Slice expressions can operate on a variable whose type is an array. This requires29449 // Slice expressions can operate on a variable whose type is an array. This requires
29379 // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer.29450 // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer.
29380 const ptr_ptr_ty = sema.typeOf(ptr_ptr);29451 const ptr_ptr_ty = sema.typeOf(ptr_ptr);
29381 const target = sema.mod.getTarget();29452 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(mod)) {
29382 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag()) {
29383 .Pointer => ptr_ptr_ty.elemType(),29453 .Pointer => ptr_ptr_ty.elemType(),
29384 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(sema.mod)}),29454 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(sema.mod)}),
29385 };29455 };
29386 const mod = sema.mod;
2938729456
29388 var array_ty = ptr_ptr_child_ty;29457 var array_ty = ptr_ptr_child_ty;
29389 var slice_ty = ptr_ptr_ty;29458 var slice_ty = ptr_ptr_ty;
29390 var ptr_or_slice = ptr_ptr;29459 var ptr_or_slice = ptr_ptr;
29391 var elem_ty: Type = undefined;29460 var elem_ty: Type = undefined;
29392 var ptr_sentinel: ?Value = null;29461 var ptr_sentinel: ?Value = null;
29393 switch (ptr_ptr_child_ty.zigTypeTag()) {29462 switch (ptr_ptr_child_ty.zigTypeTag(mod)) {
29394 .Array => {29463 .Array => {
29395 ptr_sentinel = ptr_ptr_child_ty.sentinel();29464 ptr_sentinel = ptr_ptr_child_ty.sentinel();
29396 elem_ty = ptr_ptr_child_ty.childType();29465 elem_ty = ptr_ptr_child_ty.childType();
...@@ -29398,7 +29467,7 @@ fn analyzeSlice(...@@ -29398,7 +29467,7 @@ fn analyzeSlice(
29398 .Pointer => switch (ptr_ptr_child_ty.ptrSize()) {29467 .Pointer => switch (ptr_ptr_child_ty.ptrSize()) {
29399 .One => {29468 .One => {
29400 const double_child_ty = ptr_ptr_child_ty.childType();29469 const double_child_ty = ptr_ptr_child_ty.childType();
29401 if (double_child_ty.zigTypeTag() == .Array) {29470 if (double_child_ty.zigTypeTag(mod) == .Array) {
29402 ptr_sentinel = double_child_ty.sentinel();29471 ptr_sentinel = double_child_ty.sentinel();
29403 ptr_or_slice = try sema.analyzeLoad(block, src, ptr_ptr, ptr_src);29472 ptr_or_slice = try sema.analyzeLoad(block, src, ptr_ptr, ptr_src);
29404 slice_ty = ptr_ptr_child_ty;29473 slice_ty = ptr_ptr_child_ty;
...@@ -29417,7 +29486,7 @@ fn analyzeSlice(...@@ -29417,7 +29486,7 @@ fn analyzeSlice(
2941729486
29418 if (ptr_ptr_child_ty.ptrSize() == .C) {29487 if (ptr_ptr_child_ty.ptrSize() == .C) {
29419 if (try sema.resolveDefinedValue(block, ptr_src, ptr_or_slice)) |ptr_val| {29488 if (try sema.resolveDefinedValue(block, ptr_src, ptr_or_slice)) |ptr_val| {
29420 if (ptr_val.isNull()) {29489 if (ptr_val.isNull(mod)) {
29421 return sema.fail(block, src, "slice of null pointer", .{});29490 return sema.fail(block, src, "slice of null pointer", .{});
29422 }29491 }
29423 }29492 }
...@@ -29448,7 +29517,7 @@ fn analyzeSlice(...@@ -29448,7 +29517,7 @@ fn analyzeSlice(
29448 // we might learn of the length because it is a comptime-known slice value.29517 // we might learn of the length because it is a comptime-known slice value.
29449 var end_is_len = uncasted_end_opt == .none;29518 var end_is_len = uncasted_end_opt == .none;
29450 const end = e: {29519 const end = e: {
29451 if (array_ty.zigTypeTag() == .Array) {29520 if (array_ty.zigTypeTag(mod) == .Array) {
29452 const len_val = try Value.Tag.int_u64.create(sema.arena, array_ty.arrayLen());29521 const len_val = try Value.Tag.int_u64.create(sema.arena, array_ty.arrayLen());
2945329522
29454 if (!end_is_len) {29523 if (!end_is_len) {
...@@ -29587,8 +29656,8 @@ fn analyzeSlice(...@@ -29587,8 +29656,8 @@ fn analyzeSlice(
29587 }29656 }
29588 if (try sema.resolveMaybeUndefVal(new_ptr)) |ptr_val| sentinel_check: {29657 if (try sema.resolveMaybeUndefVal(new_ptr)) |ptr_val| sentinel_check: {
29589 const expected_sentinel = sentinel orelse break :sentinel_check;29658 const expected_sentinel = sentinel orelse break :sentinel_check;
29590 const start_int = start_val.getUnsignedInt(sema.mod.getTarget()).?;29659 const start_int = start_val.getUnsignedInt(mod).?;
29591 const end_int = end_val.getUnsignedInt(sema.mod.getTarget()).?;29660 const end_int = end_val.getUnsignedInt(mod).?;
29592 const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int);29661 const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int);
2959329662
29594 const elem_ptr = try ptr_val.elemPtr(sema.typeOf(new_ptr), sema.arena, sentinel_index, sema.mod);29663 const elem_ptr = try ptr_val.elemPtr(sema.typeOf(new_ptr), sema.arena, sentinel_index, sema.mod);
...@@ -29641,7 +29710,7 @@ fn analyzeSlice(...@@ -29641,7 +29710,7 @@ fn analyzeSlice(
29641 const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize() != .C;29710 const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize() != .C;
2964229711
29643 if (opt_new_len_val) |new_len_val| {29712 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
29646 const return_ty = try Type.ptr(sema.arena, mod, .{29715 const return_ty = try Type.ptr(sema.arena, mod, .{
29647 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, mod),29716 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, mod),
...@@ -29724,7 +29793,7 @@ fn analyzeSlice(...@@ -29724,7 +29793,7 @@ fn analyzeSlice(
29724 }29793 }
2972529794
29726 // requirement: end <= len29795 // requirement: end <= len
29727 const opt_len_inst = if (array_ty.zigTypeTag() == .Array)29796 const opt_len_inst = if (array_ty.zigTypeTag(mod) == .Array)
29728 try sema.addIntUnsigned(Type.usize, array_ty.arrayLenIncludingSentinel())29797 try sema.addIntUnsigned(Type.usize, array_ty.arrayLenIncludingSentinel())
29729 else if (slice_ty.isSlice()) blk: {29798 else if (slice_ty.isSlice()) blk: {
29730 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {29799 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
...@@ -29778,14 +29847,15 @@ fn cmpNumeric(...@@ -29778,14 +29847,15 @@ fn cmpNumeric(
29778 lhs_src: LazySrcLoc,29847 lhs_src: LazySrcLoc,
29779 rhs_src: LazySrcLoc,29848 rhs_src: LazySrcLoc,
29780) CompileError!Air.Inst.Ref {29849) CompileError!Air.Inst.Ref {
29850 const mod = sema.mod;
29781 const lhs_ty = sema.typeOf(uncasted_lhs);29851 const lhs_ty = sema.typeOf(uncasted_lhs);
29782 const rhs_ty = sema.typeOf(uncasted_rhs);29852 const rhs_ty = sema.typeOf(uncasted_rhs);
2978329853
29784 assert(lhs_ty.isNumeric());29854 assert(lhs_ty.isNumeric(mod));
29785 assert(rhs_ty.isNumeric());29855 assert(rhs_ty.isNumeric(mod));
2978629856
29787 const lhs_ty_tag = lhs_ty.zigTypeTag();29857 const lhs_ty_tag = lhs_ty.zigTypeTag(mod);
29788 const rhs_ty_tag = rhs_ty.zigTypeTag();29858 const rhs_ty_tag = rhs_ty.zigTypeTag(mod);
29789 const target = sema.mod.getTarget();29859 const target = sema.mod.getTarget();
2979029860
29791 // One exception to heterogeneous comparison: comptime_float needs to29861 // One exception to heterogeneous comparison: comptime_float needs to
...@@ -29805,14 +29875,14 @@ fn cmpNumeric(...@@ -29805,14 +29875,14 @@ fn cmpNumeric(
29805 if (try sema.resolveMaybeUndefVal(lhs)) |lhs_val| {29875 if (try sema.resolveMaybeUndefVal(lhs)) |lhs_val| {
29806 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {29876 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {
29807 // Compare ints: const vs. undefined (or vice versa)29877 // 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()) {
29809 try sema.resolveLazyValue(lhs_val);29879 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| {
29811 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;29881 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
29812 }29882 }
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()) {
29814 try sema.resolveLazyValue(rhs_val);29884 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| {
29816 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;29886 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
29817 }29887 }
29818 }29888 }
...@@ -29827,16 +29897,16 @@ fn cmpNumeric(...@@ -29827,16 +29897,16 @@ fn cmpNumeric(
29827 return Air.Inst.Ref.bool_false;29897 return Air.Inst.Ref.bool_false;
29828 }29898 }
29829 }29899 }
29830 if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, target, sema)) {29900 if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, mod, sema)) {
29831 return Air.Inst.Ref.bool_true;29901 return Air.Inst.Ref.bool_true;
29832 } else {29902 } else {
29833 return Air.Inst.Ref.bool_false;29903 return Air.Inst.Ref.bool_false;
29834 }29904 }
29835 } else {29905 } 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)) {
29837 // Compare ints: const vs. var29907 // Compare ints: const vs. var
29838 try sema.resolveLazyValue(lhs_val);29908 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| {
29840 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;29910 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
29841 }29911 }
29842 }29912 }
...@@ -29844,10 +29914,10 @@ fn cmpNumeric(...@@ -29844,10 +29914,10 @@ fn cmpNumeric(
29844 }29914 }
29845 } else {29915 } else {
29846 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {29916 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)) {
29848 // Compare ints: var vs. const29918 // Compare ints: var vs. const
29849 try sema.resolveLazyValue(rhs_val);29919 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| {
29851 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;29921 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
29852 }29922 }
29853 }29923 }
...@@ -29901,11 +29971,11 @@ fn cmpNumeric(...@@ -29901,11 +29971,11 @@ fn cmpNumeric(
29901 const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val|29971 const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val|
29902 !(try lhs_val.compareAllWithZeroAdvanced(.gte, sema))29972 !(try lhs_val.compareAllWithZeroAdvanced(.gte, sema))
29903 else29973 else
29904 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt());29974 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(mod));
29905 const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val|29975 const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val|
29906 !(try rhs_val.compareAllWithZeroAdvanced(.gte, sema))29976 !(try rhs_val.compareAllWithZeroAdvanced(.gte, sema))
29907 else29977 else
29908 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt());29978 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(mod));
29909 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;29979 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;
2991029980
29911 var dest_float_type: ?Type = null;29981 var dest_float_type: ?Type = null;
...@@ -29926,7 +29996,7 @@ fn cmpNumeric(...@@ -29926,7 +29996,7 @@ fn cmpNumeric(
29926 .lt, .lte => return if (lhs_val.isNegativeInf()) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false,29996 .lt, .lte => return if (lhs_val.isNegativeInf()) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false,
29927 };29997 };
29928 if (!rhs_is_signed) {29998 if (!rhs_is_signed) {
29929 switch (lhs_val.orderAgainstZero()) {29999 switch (lhs_val.orderAgainstZero(mod)) {
29930 .gt => {},30000 .gt => {},
29931 .eq => switch (op) { // LHS = 0, RHS is unsigned30001 .eq => switch (op) { // LHS = 0, RHS is unsigned
29932 .lte => return Air.Inst.Ref.bool_true,30002 .lte => return Air.Inst.Ref.bool_true,
...@@ -29959,13 +30029,13 @@ fn cmpNumeric(...@@ -29959,13 +30029,13 @@ fn cmpNumeric(
29959 }30029 }
29960 lhs_bits = bigint.toConst().bitCountTwosComp();30030 lhs_bits = bigint.toConst().bitCountTwosComp();
29961 } else {30031 } else {
29962 lhs_bits = lhs_val.intBitCountTwosComp(target);30032 lhs_bits = lhs_val.intBitCountTwosComp(mod);
29963 }30033 }
29964 lhs_bits += @boolToInt(!lhs_is_signed and dest_int_is_signed);30034 lhs_bits += @boolToInt(!lhs_is_signed and dest_int_is_signed);
29965 } else if (lhs_is_float) {30035 } else if (lhs_is_float) {
29966 dest_float_type = lhs_ty;30036 dest_float_type = lhs_ty;
29967 } else {30037 } else {
29968 const int_info = lhs_ty.intInfo(target);30038 const int_info = lhs_ty.intInfo(mod);
29969 lhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);30039 lhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);
29970 }30040 }
2997130041
...@@ -29985,7 +30055,7 @@ fn cmpNumeric(...@@ -29985,7 +30055,7 @@ fn cmpNumeric(
29985 .lt, .lte => return if (rhs_val.isNegativeInf()) Air.Inst.Ref.bool_false else Air.Inst.Ref.bool_true,30055 .lt, .lte => return if (rhs_val.isNegativeInf()) Air.Inst.Ref.bool_false else Air.Inst.Ref.bool_true,
29986 };30056 };
29987 if (!lhs_is_signed) {30057 if (!lhs_is_signed) {
29988 switch (rhs_val.orderAgainstZero()) {30058 switch (rhs_val.orderAgainstZero(mod)) {
29989 .gt => {},30059 .gt => {},
29990 .eq => switch (op) { // RHS = 0, LHS is unsigned30060 .eq => switch (op) { // RHS = 0, LHS is unsigned
29991 .gte => return Air.Inst.Ref.bool_true,30061 .gte => return Air.Inst.Ref.bool_true,
...@@ -30018,13 +30088,13 @@ fn cmpNumeric(...@@ -30018,13 +30088,13 @@ fn cmpNumeric(
30018 }30088 }
30019 rhs_bits = bigint.toConst().bitCountTwosComp();30089 rhs_bits = bigint.toConst().bitCountTwosComp();
30020 } else {30090 } else {
30021 rhs_bits = rhs_val.intBitCountTwosComp(target);30091 rhs_bits = rhs_val.intBitCountTwosComp(mod);
30022 }30092 }
30023 rhs_bits += @boolToInt(!rhs_is_signed and dest_int_is_signed);30093 rhs_bits += @boolToInt(!rhs_is_signed and dest_int_is_signed);
30024 } else if (rhs_is_float) {30094 } else if (rhs_is_float) {
30025 dest_float_type = rhs_ty;30095 dest_float_type = rhs_ty;
30026 } else {30096 } else {
30027 const int_info = rhs_ty.intInfo(target);30097 const int_info = rhs_ty.intInfo(mod);
30028 rhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);30098 rhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);
30029 }30099 }
3003030100
...@@ -30032,7 +30102,7 @@ fn cmpNumeric(...@@ -30032,7 +30102,7 @@ fn cmpNumeric(
30032 const max_bits = std.math.max(lhs_bits, rhs_bits);30102 const max_bits = std.math.max(lhs_bits, rhs_bits);
30033 const casted_bits = std.math.cast(u16, max_bits) orelse return sema.fail(block, src, "{d} exceeds maximum integer bit count", .{max_bits});30103 const casted_bits = std.math.cast(u16, max_bits) orelse return sema.fail(block, src, "{d} exceeds maximum integer bit count", .{max_bits});
30034 const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned;30104 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);
30036 };30106 };
30037 const casted_lhs = try sema.coerce(block, dest_ty, lhs, lhs_src);30107 const casted_lhs = try sema.coerce(block, dest_ty, lhs, lhs_src);
30038 const casted_rhs = try sema.coerce(block, dest_ty, rhs, rhs_src);30108 const casted_rhs = try sema.coerce(block, dest_ty, rhs, rhs_src);
...@@ -30040,13 +30110,20 @@ fn cmpNumeric(...@@ -30040,13 +30110,20 @@ fn cmpNumeric(
30040 return block.addBinOp(Air.Inst.Tag.fromCmpOp(op, block.float_mode == .Optimized), casted_lhs, casted_rhs);30110 return block.addBinOp(Air.Inst.Tag.fromCmpOp(op, block.float_mode == .Optimized), casted_lhs, casted_rhs);
30041}30111}
3004230112
30043/// Asserts that LHS value is an int or comptime int and not undefined, and that RHS type is an int.30113/// Asserts that LHS value is an int or comptime int and not undefined, and
30044/// Given a const LHS and an unknown RHS, attempt to determine whether `op` has a guaranteed result.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.
30045/// If it cannot be determined, returns null.30116/// If it cannot be determined, returns null.
30046/// Otherwise returns a bool for the guaranteed comparison operation.30117/// 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 {30118fn compareIntsOnlyPossibleResult(
30048 const rhs_info = rhs_ty.intInfo(target);30119 sema: *Sema,
30049 const vs_zero = lhs_val.orderAgainstZeroAdvanced(sema) catch unreachable;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;
30050 const is_zero = vs_zero == .eq;30127 const is_zero = vs_zero == .eq;
30051 const is_negative = vs_zero == .lt;30128 const is_negative = vs_zero == .lt;
30052 const is_positive = vs_zero == .gt;30129 const is_positive = vs_zero == .gt;
...@@ -30078,7 +30155,7 @@ fn compareIntsOnlyPossibleResult(sema: *Sema, target: std.Target, lhs_val: Value...@@ -30078,7 +30155,7 @@ fn compareIntsOnlyPossibleResult(sema: *Sema, target: std.Target, lhs_val: Value
30078 };30155 };
3007930156
30080 const sign_adj = @boolToInt(!is_negative and rhs_info.signedness == .signed);30157 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
30083 // No sized type can have more than 65535 bits.30160 // No sized type can have more than 65535 bits.
30084 // The RHS type operand is either a runtime value or sized (but undefined) constant.30161 // 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...@@ -30111,12 +30188,11 @@ fn compareIntsOnlyPossibleResult(sema: *Sema, target: std.Target, lhs_val: Value
30111 .max = false,30188 .max = false,
30112 };30189 };
3011330190
30114 var ty_buffer: Type.Payload.Bits = .{30191 const ty = try mod.intType(
30115 .base = .{ .tag = if (is_negative) .int_signed else .int_unsigned },30192 if (is_negative) .signed else .unsigned,
30116 .data = @intCast(u16, req_bits),30193 @intCast(u16, req_bits),
30117 };30194 );
30118 const ty = Type.initPayload(&ty_buffer.base);30195 const pop_count = lhs_val.popCount(ty, mod);
30119 const pop_count = lhs_val.popCount(ty, target);
3012030196
30121 if (is_negative) {30197 if (is_negative) {
30122 break :edge .{30198 break :edge .{
...@@ -30152,10 +30228,11 @@ fn cmpVector(...@@ -30152,10 +30228,11 @@ fn cmpVector(
30152 lhs_src: LazySrcLoc,30228 lhs_src: LazySrcLoc,
30153 rhs_src: LazySrcLoc,30229 rhs_src: LazySrcLoc,
30154) CompileError!Air.Inst.Ref {30230) CompileError!Air.Inst.Ref {
30231 const mod = sema.mod;
30155 const lhs_ty = sema.typeOf(lhs);30232 const lhs_ty = sema.typeOf(lhs);
30156 const rhs_ty = sema.typeOf(rhs);30233 const rhs_ty = sema.typeOf(rhs);
30157 assert(lhs_ty.zigTypeTag() == .Vector);30234 assert(lhs_ty.zigTypeTag(mod) == .Vector);
30158 assert(rhs_ty.zigTypeTag() == .Vector);30235 assert(rhs_ty.zigTypeTag(mod) == .Vector);
30159 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);30236 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
3016030237
30161 const resolved_ty = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ .override = &.{ lhs_src, rhs_src } });30238 const resolved_ty = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ .override = &.{ lhs_src, rhs_src } });
...@@ -30296,16 +30373,17 @@ fn resolvePeerTypes(...@@ -30296,16 +30373,17 @@ fn resolvePeerTypes(
30296 instructions: []const Air.Inst.Ref,30373 instructions: []const Air.Inst.Ref,
30297 candidate_srcs: Module.PeerTypeCandidateSrc,30374 candidate_srcs: Module.PeerTypeCandidateSrc,
30298) !Type {30375) !Type {
30376 const mod = sema.mod;
30299 switch (instructions.len) {30377 switch (instructions.len) {
30300 0 => return Type.initTag(.noreturn),30378 0 => return Type.initTag(.noreturn),
30301 1 => return sema.typeOf(instructions[0]),30379 1 => return sema.typeOf(instructions[0]),
30302 else => {},30380 else => {},
30303 }30381 }
3030430382
30305 const target = sema.mod.getTarget();30383 const target = mod.getTarget();
3030630384
30307 var chosen = instructions[0];30385 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).
30309 // * ErrorSet: this is an override30387 // * ErrorSet: this is an override
30310 // * ErrorUnion: this is an override of the error set only30388 // * ErrorUnion: this is an override of the error set only
30311 // * other: at the end we make an ErrorUnion with the other thing and this30389 // * other: at the end we make an ErrorUnion with the other thing and this
...@@ -30318,8 +30396,8 @@ fn resolvePeerTypes(...@@ -30318,8 +30396,8 @@ fn resolvePeerTypes(
30318 const candidate_ty = sema.typeOf(candidate);30396 const candidate_ty = sema.typeOf(candidate);
30319 const chosen_ty = sema.typeOf(chosen);30397 const chosen_ty = sema.typeOf(chosen);
3032030398
30321 const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison();30399 const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison(mod);
30322 const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison();30400 const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison(mod);
3032330401
30324 // If the candidate can coerce into our chosen type, we're done.30402 // If the candidate can coerce into our chosen type, we're done.
30325 // If the chosen type can coerce into the candidate, use that.30403 // If the chosen type can coerce into the candidate, use that.
...@@ -30347,8 +30425,8 @@ fn resolvePeerTypes(...@@ -30347,8 +30425,8 @@ fn resolvePeerTypes(
30347 continue;30425 continue;
30348 },30426 },
30349 .Int => {30427 .Int => {
30350 const chosen_info = chosen_ty.intInfo(target);30428 const chosen_info = chosen_ty.intInfo(mod);
30351 const candidate_info = candidate_ty.intInfo(target);30429 const candidate_info = candidate_ty.intInfo(mod);
3035230430
30353 if (chosen_info.bits < candidate_info.bits) {30431 if (chosen_info.bits < candidate_info.bits) {
30354 chosen = candidate;30432 chosen = candidate;
...@@ -30537,7 +30615,7 @@ fn resolvePeerTypes(...@@ -30537,7 +30615,7 @@ fn resolvePeerTypes(
30537 // *[N]T to []T30615 // *[N]T to []T
30538 if ((cand_info.size == .Many or cand_info.size == .Slice) and30616 if ((cand_info.size == .Many or cand_info.size == .Slice) and
30539 chosen_info.size == .One and30617 chosen_info.size == .One and
30540 chosen_info.pointee_type.zigTypeTag() == .Array)30618 chosen_info.pointee_type.zigTypeTag(mod) == .Array)
30541 {30619 {
30542 // In case we see i.e.: `*[1]T`, `*[2]T`, `[*]T`30620 // In case we see i.e.: `*[1]T`, `*[2]T`, `[*]T`
30543 convert_to_slice = false;30621 convert_to_slice = false;
...@@ -30546,7 +30624,7 @@ fn resolvePeerTypes(...@@ -30546,7 +30624,7 @@ fn resolvePeerTypes(
30546 continue;30624 continue;
30547 }30625 }
30548 if (cand_info.size == .One and30626 if (cand_info.size == .One and
30549 cand_info.pointee_type.zigTypeTag() == .Array and30627 cand_info.pointee_type.zigTypeTag(mod) == .Array and
30550 (chosen_info.size == .Many or chosen_info.size == .Slice))30628 (chosen_info.size == .Many or chosen_info.size == .Slice))
30551 {30629 {
30552 // In case we see i.e.: `*[1]T`, `*[2]T`, `[*]T`30630 // In case we see i.e.: `*[1]T`, `*[2]T`, `[*]T`
...@@ -30559,8 +30637,8 @@ fn resolvePeerTypes(...@@ -30559,8 +30637,8 @@ fn resolvePeerTypes(
30559 // Keep the one whose element type can be coerced into.30637 // Keep the one whose element type can be coerced into.
30560 if (chosen_info.size == .One and30638 if (chosen_info.size == .One and
30561 cand_info.size == .One and30639 cand_info.size == .One and
30562 chosen_info.pointee_type.zigTypeTag() == .Array and30640 chosen_info.pointee_type.zigTypeTag(mod) == .Array and
30563 cand_info.pointee_type.zigTypeTag() == .Array)30641 cand_info.pointee_type.zigTypeTag(mod) == .Array)
30564 {30642 {
30565 const chosen_elem_ty = chosen_info.pointee_type.childType();30643 const chosen_elem_ty = chosen_info.pointee_type.childType();
30566 const cand_elem_ty = cand_info.pointee_type.childType();30644 const cand_elem_ty = cand_info.pointee_type.childType();
...@@ -30631,7 +30709,7 @@ fn resolvePeerTypes(...@@ -30631,7 +30709,7 @@ fn resolvePeerTypes(
30631 .Optional => {30709 .Optional => {
30632 var opt_child_buf: Type.Payload.ElemType = undefined;30710 var opt_child_buf: Type.Payload.ElemType = undefined;
30633 const chosen_ptr_ty = chosen_ty.optionalChild(&opt_child_buf);30711 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) {
30635 const chosen_info = chosen_ptr_ty.ptrInfo().data;30713 const chosen_info = chosen_ptr_ty.ptrInfo().data;
3063630714
30637 seen_const = seen_const or !chosen_info.mutable or !cand_info.mutable;30715 seen_const = seen_const or !chosen_info.mutable or !cand_info.mutable;
...@@ -30639,7 +30717,7 @@ fn resolvePeerTypes(...@@ -30639,7 +30717,7 @@ fn resolvePeerTypes(
30639 // *[N]T to ?![*]T30717 // *[N]T to ?![*]T
30640 // *[N]T to ?![]T30718 // *[N]T to ?![]T
30641 if (cand_info.size == .One and30719 if (cand_info.size == .One and
30642 cand_info.pointee_type.zigTypeTag() == .Array and30720 cand_info.pointee_type.zigTypeTag(mod) == .Array and
30643 (chosen_info.size == .Many or chosen_info.size == .Slice))30721 (chosen_info.size == .Many or chosen_info.size == .Slice))
30644 {30722 {
30645 continue;30723 continue;
...@@ -30648,7 +30726,7 @@ fn resolvePeerTypes(...@@ -30648,7 +30726,7 @@ fn resolvePeerTypes(
30648 },30726 },
30649 .ErrorUnion => {30727 .ErrorUnion => {
30650 const chosen_ptr_ty = chosen_ty.errorUnionPayload();30728 const chosen_ptr_ty = chosen_ty.errorUnionPayload();
30651 if (chosen_ptr_ty.zigTypeTag() == .Pointer) {30729 if (chosen_ptr_ty.zigTypeTag(mod) == .Pointer) {
30652 const chosen_info = chosen_ptr_ty.ptrInfo().data;30730 const chosen_info = chosen_ptr_ty.ptrInfo().data;
3065330731
30654 seen_const = seen_const or !chosen_info.mutable or !cand_info.mutable;30732 seen_const = seen_const or !chosen_info.mutable or !cand_info.mutable;
...@@ -30656,7 +30734,7 @@ fn resolvePeerTypes(...@@ -30656,7 +30734,7 @@ fn resolvePeerTypes(
30656 // *[N]T to E![*]T30734 // *[N]T to E![*]T
30657 // *[N]T to E![]T30735 // *[N]T to E![]T
30658 if (cand_info.size == .One and30736 if (cand_info.size == .One and
30659 cand_info.pointee_type.zigTypeTag() == .Array and30737 cand_info.pointee_type.zigTypeTag(mod) == .Array and
30660 (chosen_info.size == .Many or chosen_info.size == .Slice))30738 (chosen_info.size == .Many or chosen_info.size == .Slice))
30661 {30739 {
30662 continue;30740 continue;
...@@ -30664,7 +30742,7 @@ fn resolvePeerTypes(...@@ -30664,7 +30742,7 @@ fn resolvePeerTypes(
30664 }30742 }
30665 },30743 },
30666 .Fn => {30744 .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)) {
30668 chosen = candidate;30746 chosen = candidate;
30669 chosen_i = candidate_i + 1;30747 chosen_i = candidate_i + 1;
30670 continue;30748 continue;
...@@ -30697,16 +30775,16 @@ fn resolvePeerTypes(...@@ -30697,16 +30775,16 @@ fn resolvePeerTypes(
3069730775
30698 const chosen_child_ty = chosen_ty.childType();30776 const chosen_child_ty = chosen_ty.childType();
30699 const candidate_child_ty = candidate_ty.childType();30777 const candidate_child_ty = candidate_ty.childType();
30700 if (chosen_child_ty.zigTypeTag() == .Int and candidate_child_ty.zigTypeTag() == .Int) {30778 if (chosen_child_ty.zigTypeTag(mod) == .Int and candidate_child_ty.zigTypeTag(mod) == .Int) {
30701 const chosen_info = chosen_child_ty.intInfo(target);30779 const chosen_info = chosen_child_ty.intInfo(mod);
30702 const candidate_info = candidate_child_ty.intInfo(target);30780 const candidate_info = candidate_child_ty.intInfo(mod);
30703 if (chosen_info.bits < candidate_info.bits) {30781 if (chosen_info.bits < candidate_info.bits) {
30704 chosen = candidate;30782 chosen = candidate;
30705 chosen_i = candidate_i + 1;30783 chosen_i = candidate_i + 1;
30706 }30784 }
30707 continue;30785 continue;
30708 }30786 }
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) {
30710 if (chosen_ty.floatBits(target) < candidate_ty.floatBits(target)) {30788 if (chosen_ty.floatBits(target) < candidate_ty.floatBits(target)) {
30711 chosen = candidate;30789 chosen = candidate;
30712 chosen_i = candidate_i + 1;30790 chosen_i = candidate_i + 1;
...@@ -30725,7 +30803,7 @@ fn resolvePeerTypes(...@@ -30725,7 +30803,7 @@ fn resolvePeerTypes(
30725 .Vector => continue,30803 .Vector => continue,
30726 else => {},30804 else => {},
30727 },30805 },
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) {
30729 if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(), candidate_ty, target, src, src)) {30807 if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(), candidate_ty, target, src, src)) {
30730 continue;30808 continue;
30731 }30809 }
...@@ -30790,27 +30868,27 @@ fn resolvePeerTypes(...@@ -30790,27 +30868,27 @@ fn resolvePeerTypes(
30790 // the source locations.30868 // the source locations.
30791 const chosen_src = candidate_srcs.resolve(30869 const chosen_src = candidate_srcs.resolve(
30792 sema.gpa,30870 sema.gpa,
30793 sema.mod.declPtr(block.src_decl),30871 mod.declPtr(block.src_decl),
30794 chosen_i,30872 chosen_i,
30795 );30873 );
30796 const candidate_src = candidate_srcs.resolve(30874 const candidate_src = candidate_srcs.resolve(
30797 sema.gpa,30875 sema.gpa,
30798 sema.mod.declPtr(block.src_decl),30876 mod.declPtr(block.src_decl),
30799 candidate_i + 1,30877 candidate_i + 1,
30800 );30878 );
3080130879
30802 const msg = msg: {30880 const msg = msg: {
30803 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{30881 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{
30804 chosen_ty.fmt(sema.mod),30882 chosen_ty.fmt(mod),
30805 candidate_ty.fmt(sema.mod),30883 candidate_ty.fmt(mod),
30806 });30884 });
30807 errdefer msg.destroy(sema.gpa);30885 errdefer msg.destroy(sema.gpa);
3080830886
30809 if (chosen_src) |src_loc|30887 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
30812 if (candidate_src) |src_loc|30890 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
30815 break :msg msg;30893 break :msg msg;
30816 };30894 };
...@@ -30826,72 +30904,73 @@ fn resolvePeerTypes(...@@ -30826,72 +30904,73 @@ fn resolvePeerTypes(
30826 info.data.sentinel = chosen_child_ty.sentinel();30904 info.data.sentinel = chosen_child_ty.sentinel();
30827 info.data.size = .Slice;30905 info.data.size = .Slice;
30828 info.data.mutable = !(seen_const or chosen_child_ty.isConstPtr());30906 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);
30832 const opt_ptr_ty = if (any_are_null)30910 const opt_ptr_ty = if (any_are_null)
30833 try Type.optional(sema.arena, new_ptr_ty)30911 try Type.optional(sema.arena, new_ptr_ty)
30834 else30912 else
30835 new_ptr_ty;30913 new_ptr_ty;
30836 const set_ty = err_set_ty orelse return opt_ptr_ty;30914 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);
30838 }30916 }
3083930917
30840 if (seen_const) {30918 if (seen_const) {
30841 // turn []T => []const T30919 // turn []T => []const T
30842 switch (chosen_ty.zigTypeTag()) {30920 switch (chosen_ty.zigTypeTag(mod)) {
30843 .ErrorUnion => {30921 .ErrorUnion => {
30844 const ptr_ty = chosen_ty.errorUnionPayload();30922 const ptr_ty = chosen_ty.errorUnionPayload();
30845 var info = ptr_ty.ptrInfo();30923 var info = ptr_ty.ptrInfo();
30846 info.data.mutable = false;30924 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);
30848 const opt_ptr_ty = if (any_are_null)30926 const opt_ptr_ty = if (any_are_null)
30849 try Type.optional(sema.arena, new_ptr_ty)30927 try Type.optional(sema.arena, new_ptr_ty)
30850 else30928 else
30851 new_ptr_ty;30929 new_ptr_ty;
30852 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet();30930 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);
30854 },30932 },
30855 .Pointer => {30933 .Pointer => {
30856 var info = chosen_ty.ptrInfo();30934 var info = chosen_ty.ptrInfo();
30857 info.data.mutable = false;30935 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);
30859 const opt_ptr_ty = if (any_are_null)30937 const opt_ptr_ty = if (any_are_null)
30860 try Type.optional(sema.arena, new_ptr_ty)30938 try Type.optional(sema.arena, new_ptr_ty)
30861 else30939 else
30862 new_ptr_ty;30940 new_ptr_ty;
30863 const set_ty = err_set_ty orelse return opt_ptr_ty;30941 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);
30865 },30943 },
30866 else => return chosen_ty,30944 else => return chosen_ty,
30867 }30945 }
30868 }30946 }
3086930947
30870 if (any_are_null) {30948 if (any_are_null) {
30871 const opt_ty = switch (chosen_ty.zigTypeTag()) {30949 const opt_ty = switch (chosen_ty.zigTypeTag(mod)) {
30872 .Null, .Optional => chosen_ty,30950 .Null, .Optional => chosen_ty,
30873 else => try Type.optional(sema.arena, chosen_ty),30951 else => try Type.optional(sema.arena, chosen_ty),
30874 };30952 };
30875 const set_ty = err_set_ty orelse return opt_ty;30953 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);
30877 }30955 }
3087830956
30879 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) {30957 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag(mod)) {
30880 .ErrorSet => return ty,30958 .ErrorSet => return ty,
30881 .ErrorUnion => {30959 .ErrorUnion => {
30882 const payload_ty = chosen_ty.errorUnionPayload();30960 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);
30884 },30962 },
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),
30886 };30964 };
3088730965
30888 return chosen_ty;30966 return chosen_ty;
30889}30967}
3089030968
30891pub fn resolveFnTypes(sema: *Sema, fn_info: Type.Payload.Function.Data) CompileError!void {30969pub fn resolveFnTypes(sema: *Sema, fn_info: Type.Payload.Function.Data) CompileError!void {
30970 const mod = sema.mod;
30892 try sema.resolveTypeFully(fn_info.return_type);30971 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)) {
30895 // Ensure the type exists so that backends can assume that.30974 // Ensure the type exists so that backends can assume that.
30896 _ = try sema.getBuiltinType("StackTrace");30975 _ = try sema.getBuiltinType("StackTrace");
30897 }30976 }
...@@ -30943,7 +31022,8 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!void {...@@ -30943,7 +31022,8 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!void {
30943}31022}
3094431023
30945pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {31024pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {
30946 switch (ty.zigTypeTag()) {31025 const mod = sema.mod;
31026 switch (ty.zigTypeTag(mod)) {
30947 .Struct => return sema.resolveStructLayout(ty),31027 .Struct => return sema.resolveStructLayout(ty),
30948 .Union => return sema.resolveUnionLayout(ty),31028 .Union => return sema.resolveUnionLayout(ty),
30949 .Array => {31029 .Array => {
...@@ -31021,7 +31101,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -31021,7 +31101,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
31021 struct_obj.status = .have_layout;31101 struct_obj.status = .have_layout;
31022 _ = try sema.resolveTypeRequiresComptime(resolved_ty);31102 _ = 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))) {
31025 const msg = try Module.ErrorMsg.create(31105 const msg = try Module.ErrorMsg.create(
31026 sema.gpa,31106 sema.gpa,
31027 struct_obj.srcLoc(sema.mod),31107 struct_obj.srcLoc(sema.mod),
...@@ -31043,7 +31123,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -31043,7 +31123,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
31043 };31123 };
3104431124
31045 for (struct_obj.fields.values(), 0..) |field, i| {31125 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)))
31047 @intCast(u32, i)31127 @intCast(u32, i)
31048 else31128 else
31049 Module.Struct.omitted_field;31129 Module.Struct.omitted_field;
...@@ -31054,11 +31134,11 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -31054,11 +31134,11 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
31054 sema: *Sema,31134 sema: *Sema,
3105531135
31056 fn lessThan(ctx: @This(), a: u32, b: u32) bool {31136 fn lessThan(ctx: @This(), a: u32, b: u32) bool {
31137 const m = ctx.sema.mod;
31057 if (a == Module.Struct.omitted_field) return false;31138 if (a == Module.Struct.omitted_field) return false;
31058 if (b == Module.Struct.omitted_field) return true;31139 if (b == Module.Struct.omitted_field) return true;
31059 const target = ctx.sema.mod.getTarget();31140 return ctx.struct_obj.fields.values()[a].ty.abiAlignment(m) >
31060 return ctx.struct_obj.fields.values()[a].ty.abiAlignment(target) >31141 ctx.struct_obj.fields.values()[b].ty.abiAlignment(m);
31061 ctx.struct_obj.fields.values()[b].ty.abiAlignment(target);
31062 }31142 }
31063 };31143 };
31064 mem.sort(u32, optimized_order, AlignSortContext{31144 mem.sort(u32, optimized_order, AlignSortContext{
...@@ -31073,11 +31153,10 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -31073,11 +31153,10 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3107331153
31074fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!void {31154fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!void {
31075 const gpa = mod.gpa;31155 const gpa = mod.gpa;
31076 const target = mod.getTarget();
3107731156
31078 var fields_bit_sum: u64 = 0;31157 var fields_bit_sum: u64 = 0;
31079 for (struct_obj.fields.values()) |field| {31158 for (struct_obj.fields.values()) |field| {
31080 fields_bit_sum += field.ty.bitSize(target);31159 fields_bit_sum += field.ty.bitSize(mod);
31081 }31160 }
3108231161
31083 const decl_index = struct_obj.owner_decl;31162 const decl_index = struct_obj.owner_decl;
...@@ -31178,32 +31257,29 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi...@@ -31178,32 +31257,29 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
31178 };31257 };
31179 return sema.fail(&block, LazySrcLoc.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});31258 return sema.fail(&block, LazySrcLoc.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});
31180 }31259 }
31181 var buf: Type.Payload.Bits = .{31260 struct_obj.backing_int_ty = try mod.intType(.unsigned, @intCast(u16, fields_bit_sum));
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);
31186 }31261 }
31187}31262}
3118831263
31189fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void {31264fn 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)) {
31193 return sema.fail(block, src, "expected backing integer type, found '{}'", .{backing_int_ty.fmt(sema.mod)});31268 return sema.fail(block, src, "expected backing integer type, found '{}'", .{backing_int_ty.fmt(sema.mod)});
31194 }31269 }
31195 if (backing_int_ty.bitSize(target) != fields_bit_sum) {31270 if (backing_int_ty.bitSize(mod) != fields_bit_sum) {
31196 return sema.fail(31271 return sema.fail(
31197 block,31272 block,
31198 src,31273 src,
31199 "backing integer type '{}' has bit size {} but the struct fields have a total bit size of {}",31274 "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 },
31201 );31276 );
31202 }31277 }
31203}31278}
3120431279
31205fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {31280fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
31206 if (!ty.isIndexable()) {31281 const mod = sema.mod;
31282 if (!ty.isIndexable(mod)) {
31207 const msg = msg: {31283 const msg = msg: {
31208 const msg = try sema.errMsg(block, src, "type '{}' does not support indexing", .{ty.fmt(sema.mod)});31284 const msg = try sema.errMsg(block, src, "type '{}' does not support indexing", .{ty.fmt(sema.mod)});
31209 errdefer msg.destroy(sema.gpa);31285 errdefer msg.destroy(sema.gpa);
...@@ -31215,12 +31291,13 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {...@@ -31215,12 +31291,13 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
31215}31291}
3121631292
31217fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {31293fn 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) {
31219 switch (ty.ptrSize()) {31296 switch (ty.ptrSize()) {
31220 .Slice, .Many, .C => return,31297 .Slice, .Many, .C => return,
31221 .One => {31298 .One => {
31222 const elem_ty = ty.childType();31299 const elem_ty = ty.childType();
31223 if (elem_ty.zigTypeTag() == .Array) return;31300 if (elem_ty.zigTypeTag(mod) == .Array) return;
31224 // TODO https://github.com/ziglang/zig/issues/1547931301 // TODO https://github.com/ziglang/zig/issues/15479
31225 // if (elem_ty.isTuple()) return;31302 // if (elem_ty.isTuple()) return;
31226 },31303 },
...@@ -31270,7 +31347,7 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -31270,7 +31347,7 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
31270 union_obj.status = .have_layout;31347 union_obj.status = .have_layout;
31271 _ = try sema.resolveTypeRequiresComptime(resolved_ty);31348 _ = 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))) {
31274 const msg = try Module.ErrorMsg.create(31351 const msg = try Module.ErrorMsg.create(
31275 sema.gpa,31352 sema.gpa,
31276 union_obj.srcLoc(sema.mod),31353 union_obj.srcLoc(sema.mod),
...@@ -31285,6 +31362,23 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -31285,6 +31362,23 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
31285// for hasRuntimeBits() of each field, so we need "requires comptime"31362// for hasRuntimeBits() of each field, so we need "requires comptime"
31286// to be known already before this function returns.31363// to be known already before this function returns.
31287pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {31364pub 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
31288 return switch (ty.tag()) {31382 return switch (ty.tag()) {
31289 .u1,31383 .u1,
31290 .u8,31384 .u8,
...@@ -31349,8 +31443,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -31349,8 +31443,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
31349 .generic_poison,31443 .generic_poison,
31350 .array_u8,31444 .array_u8,
31351 .array_u8_sentinel_0,31445 .array_u8_sentinel_0,
31352 .int_signed,
31353 .int_unsigned,
31354 .enum_simple,31446 .enum_simple,
31355 => false,31447 => false,
3135631448
...@@ -31360,11 +31452,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -31360,11 +31452,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
31360 .comptime_float,31452 .comptime_float,
31361 .enum_literal,31453 .enum_literal,
31362 .type_info,31454 .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,
31368 .function,31455 .function,
31369 => true,31456 => true,
3137031457
...@@ -31387,7 +31474,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -31387,7 +31474,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
31387 .mut_slice,31474 .mut_slice,
31388 => {31475 => {
31389 const child_ty = ty.childType();31476 const child_ty = ty.childType();
31390 if (child_ty.zigTypeTag() == .Fn) {31477 if (child_ty.zigTypeTag(mod) == .Fn) {
31391 return child_ty.fnInfo().is_generic;31478 return child_ty.fnInfo().is_generic;
31392 } else {31479 } else {
31393 return sema.resolveTypeRequiresComptime(child_ty);31480 return sema.resolveTypeRequiresComptime(child_ty);
...@@ -31474,7 +31561,8 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -31474,7 +31561,8 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
31474/// Returns `error.AnalysisFail` if any of the types (recursively) failed to31561/// Returns `error.AnalysisFail` if any of the types (recursively) failed to
31475/// be resolved.31562/// be resolved.
31476pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {31563pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
31477 switch (ty.zigTypeTag()) {31564 const mod = sema.mod;
31565 switch (ty.zigTypeTag(mod)) {
31478 .Pointer => {31566 .Pointer => {
31479 const child_ty = try sema.resolveTypeFields(ty.childType());31567 const child_ty = try sema.resolveTypeFields(ty.childType());
31480 return sema.resolveTypeFully(child_ty);31568 return sema.resolveTypeFully(child_ty);
...@@ -31840,7 +31928,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -31840,7 +31928,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
31840 type_body_len: u32 = 0,31928 type_body_len: u32 = 0,
31841 align_body_len: u32 = 0,31929 align_body_len: u32 = 0,
31842 init_body_len: u32 = 0,31930 init_body_len: u32 = 0,
31843 type_ref: Air.Inst.Ref = .none,31931 type_ref: Zir.Inst.Ref = .none,
31844 };31932 };
31845 const fields = try sema.arena.alloc(Field, fields_len);31933 const fields = try sema.arena.alloc(Field, fields_len);
31846 var any_inits = false;31934 var any_inits = false;
...@@ -31967,7 +32055,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -31967,7 +32055,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
31967 const field = &struct_obj.fields.values()[field_i];32055 const field = &struct_obj.fields.values()[field_i];
31968 field.ty = try field_ty.copy(decl_arena_allocator);32056 field.ty = try field_ty.copy(decl_arena_allocator);
3196932057
31970 if (field_ty.zigTypeTag() == .Opaque) {32058 if (field_ty.zigTypeTag(mod) == .Opaque) {
31971 const msg = msg: {32059 const msg = msg: {
31972 const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{32060 const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{
31973 .index = field_i,32061 .index = field_i,
...@@ -31981,7 +32069,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -31981,7 +32069,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
31981 };32069 };
31982 return sema.failWithOwnedErrorMsg(msg);32070 return sema.failWithOwnedErrorMsg(msg);
31983 }32071 }
31984 if (field_ty.zigTypeTag() == .NoReturn) {32072 if (field_ty.zigTypeTag(mod) == .NoReturn) {
31985 const msg = msg: {32073 const msg = msg: {
31986 const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{32074 const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{
31987 .index = field_i,32075 .index = field_i,
...@@ -32010,7 +32098,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -32010,7 +32098,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
32010 break :msg msg;32098 break :msg msg;
32011 };32099 };
32012 return sema.failWithOwnedErrorMsg(msg);32100 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))) {
32014 const msg = msg: {32102 const msg = msg: {
32015 const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{32103 const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{
32016 .index = field_i,32104 .index = field_i,
...@@ -32191,7 +32279,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32191,7 +32279,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32191 if (small.auto_enum_tag) {32279 if (small.auto_enum_tag) {
32192 // The provided type is an integer type and we must construct the enum tag type here.32280 // The provided type is an integer type and we must construct the enum tag type here.
32193 int_tag_ty = provided_ty;32281 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) {
32195 return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(sema.mod)});32283 return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(sema.mod)});
32196 }32284 }
3219732285
...@@ -32220,7 +32308,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32220,7 +32308,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32220 } else {32308 } else {
32221 // The provided type is the enum tag type.32309 // The provided type is the enum tag type.
32222 union_obj.tag_ty = try provided_ty.copy(decl_arena_allocator);32310 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) {
32224 return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(sema.mod)});32312 return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(sema.mod)});
32225 }32313 }
32226 // The fields of the union must match the enum exactly.32314 // The fields of the union must match the enum exactly.
...@@ -32281,7 +32369,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32281,7 +32369,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32281 break :blk align_ref;32369 break :blk align_ref;
32282 } else .none;32370 } 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: {
32285 const tag_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);32373 const tag_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
32286 extra_index += 1;32374 extra_index += 1;
32287 break :blk try sema.resolveInst(tag_ref);32375 break :blk try sema.resolveInst(tag_ref);
...@@ -32391,7 +32479,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32391,7 +32479,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32391 }32479 }
32392 }32480 }
3239332481
32394 if (field_ty.zigTypeTag() == .Opaque) {32482 if (field_ty.zigTypeTag(mod) == .Opaque) {
32395 const msg = msg: {32483 const msg = msg: {
32396 const ty_src = union_obj.fieldSrcLoc(sema.mod, .{32484 const ty_src = union_obj.fieldSrcLoc(sema.mod, .{
32397 .index = field_i,32485 .index = field_i,
...@@ -32420,7 +32508,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32420,7 +32508,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32420 break :msg msg;32508 break :msg msg;
32421 };32509 };
32422 return sema.failWithOwnedErrorMsg(msg);32510 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))) {
32424 const msg = msg: {32512 const msg = msg: {
32425 const ty_src = union_obj.fieldSrcLoc(sema.mod, .{32513 const ty_src = union_obj.fieldSrcLoc(sema.mod, .{
32426 .index = field_i,32514 .index = field_i,
...@@ -32673,6 +32761,29 @@ fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {...@@ -32673,6 +32761,29 @@ fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
32673/// that the types are already resolved.32761/// that the types are already resolved.
32674/// TODO assert the return value matches `ty.onePossibleValue`32762/// TODO assert the return value matches `ty.onePossibleValue`
32675pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {32763pub 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
32676 switch (ty.tag()) {32787 switch (ty.tag()) {
32677 .f16,32788 .f16,
32678 .f32,32789 .f32,
...@@ -32712,10 +32823,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -32712,10 +32823,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
32712 .error_set,32823 .error_set,
32713 .error_set_merged,32824 .error_set_merged,
32714 .error_union,32825 .error_union,
32715 .fn_noreturn_no_args,
32716 .fn_void_no_args,
32717 .fn_naked_noreturn_no_args,
32718 .fn_ccc_void_no_args,
32719 .function,32826 .function,
32720 .single_const_pointer_to_comptime_int,32827 .single_const_pointer_to_comptime_int,
32721 .array_sentinel,32828 .array_sentinel,
...@@ -32803,7 +32910,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -32803,7 +32910,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
32803 const resolved_ty = try sema.resolveTypeFields(ty);32910 const resolved_ty = try sema.resolveTypeFields(ty);
32804 const enum_obj = resolved_ty.castTag(.enum_numbered).?.data;32911 const enum_obj = resolved_ty.castTag(.enum_numbered).?.data;
32805 // An explicit tag type is always provided for enum_numbered.32912 // 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))) {
32807 return null;32914 return null;
32808 }32915 }
32809 if (enum_obj.fields.count() == 1) {32916 if (enum_obj.fields.count() == 1) {
...@@ -32819,7 +32926,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -32819,7 +32926,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
32819 .enum_full => {32926 .enum_full => {
32820 const resolved_ty = try sema.resolveTypeFields(ty);32927 const resolved_ty = try sema.resolveTypeFields(ty);
32821 const enum_obj = resolved_ty.castTag(.enum_full).?.data;32928 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))) {
32823 return null;32930 return null;
32824 }32931 }
32825 switch (enum_obj.fields.count()) {32932 switch (enum_obj.fields.count()) {
...@@ -32843,7 +32950,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -32843,7 +32950,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
32843 },32950 },
32844 .enum_nonexhaustive => {32951 .enum_nonexhaustive => {
32845 const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;32952 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))) {
32847 return Value.zero;32954 return Value.zero;
32848 } else {32955 } else {
32849 return null;32956 return null;
...@@ -32883,13 +32990,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -32883,13 +32990,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
32883 .null => return Value.null,32990 .null => return Value.null,
32884 .undefined => return Value.initTag(.undef),32991 .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 },
32893 .vector, .array, .array_u8 => {32993 .vector, .array, .array_u8 => {
32894 if (ty.arrayLen() == 0)32994 if (ty.arrayLen() == 0)
32895 return Value.initTag(.empty_array);32995 return Value.initTag(.empty_array);
...@@ -32919,6 +33019,89 @@ pub fn getTmpAir(sema: Sema) Air {...@@ -32919,6 +33019,89 @@ pub fn getTmpAir(sema: Sema) Air {
32919}33019}
3292033020
32921pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {33021pub 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 }
32922 switch (ty.tag()) {33105 switch (ty.tag()) {
32923 .u1 => return .u1_type,33106 .u1 => return .u1_type,
32924 .u8 => return .u8_type,33107 .u8 => return .u8_type,
...@@ -32934,6 +33117,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {...@@ -32934,6 +33117,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
32934 .i128 => return .i128_type,33117 .i128 => return .i128_type,
32935 .usize => return .usize_type,33118 .usize => return .usize_type,
32936 .isize => return .isize_type,33119 .isize => return .isize_type,
33120 .c_char => return .c_char_type,
32937 .c_short => return .c_short_type,33121 .c_short => return .c_short_type,
32938 .c_ushort => return .c_ushort_type,33122 .c_ushort => return .c_ushort_type,
32939 .c_int => return .c_int_type,33123 .c_int => return .c_int_type,
...@@ -32966,17 +33150,13 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {...@@ -32966,17 +33150,13 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
32966 .address_space => return .address_space_type,33150 .address_space => return .address_space_type,
32967 .float_mode => return .float_mode_type,33151 .float_mode => return .float_mode_type,
32968 .reduce_op => return .reduce_op_type,33152 .reduce_op => return .reduce_op_type,
32969 .modifier => return .modifier_type,33153 .modifier => return .call_modifier_type,
32970 .prefetch_options => return .prefetch_options_type,33154 .prefetch_options => return .prefetch_options_type,
32971 .export_options => return .export_options_type,33155 .export_options => return .export_options_type,
32972 .extern_options => return .extern_options_type,33156 .extern_options => return .extern_options_type,
32973 .type_info => return .type_info_type,33157 .type_info => return .type_info_type,
32974 .manyptr_u8 => return .manyptr_u8_type,33158 .manyptr_u8 => return .manyptr_u8_type,
32975 .manyptr_const_u8 => return .manyptr_const_u8_type,33159 .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,
32980 .single_const_pointer_to_comptime_int => return .single_const_pointer_to_comptime_int_type,33160 .single_const_pointer_to_comptime_int => return .single_const_pointer_to_comptime_int_type,
32981 .const_slice_u8 => return .const_slice_u8_type,33161 .const_slice_u8 => return .const_slice_u8_type,
32982 .anyerror_void_error_union => return .anyerror_void_error_union_type,33162 .anyerror_void_error_union => return .anyerror_void_error_union_type,
...@@ -33186,7 +33366,8 @@ const DerefResult = union(enum) {...@@ -33186,7 +33366,8 @@ const DerefResult = union(enum) {
33186};33366};
3318733367
33188fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, load_ty: Type, want_mutable: bool) CompileError!DerefResult {33368fn 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();
33190 const deref = sema.beginComptimePtrLoad(block, src, ptr_val, load_ty) catch |err| switch (err) {33371 const deref = sema.beginComptimePtrLoad(block, src, ptr_val, load_ty) catch |err| switch (err) {
33191 error.RuntimeLoad => return DerefResult{ .runtime_load = {} },33372 error.RuntimeLoad => return DerefResult{ .runtime_load = {} },
33192 else => |e| return e,33373 else => |e| return e,
...@@ -33211,7 +33392,7 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value...@@ -33211,7 +33392,7 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value
3321133392
33212 // The type is not in-memory coercible or the direct dereference failed, so it must33393 // The type is not in-memory coercible or the direct dereference failed, so it must
33213 // be bitcast according to the pointer type we are performing the load through.33394 // be bitcast according to the pointer type we are performing the load through.
33214 if (!load_ty.hasWellDefinedLayout()) {33395 if (!load_ty.hasWellDefinedLayout(mod)) {
33215 return DerefResult{ .needed_well_defined = load_ty };33396 return DerefResult{ .needed_well_defined = load_ty };
33216 }33397 }
3321733398
...@@ -33253,6 +33434,7 @@ fn typePtrOrOptionalPtrTy(...@@ -33253,6 +33434,7 @@ fn typePtrOrOptionalPtrTy(
33253 ty: Type,33434 ty: Type,
33254 buf: *Type.Payload.ElemType,33435 buf: *Type.Payload.ElemType,
33255) !?Type {33436) !?Type {
33437 const mod = sema.mod;
33256 switch (ty.tag()) {33438 switch (ty.tag()) {
33257 .optional_single_const_pointer,33439 .optional_single_const_pointer,
33258 .optional_single_mut_pointer,33440 .optional_single_mut_pointer,
...@@ -33281,7 +33463,7 @@ fn typePtrOrOptionalPtrTy(...@@ -33281,7 +33463,7 @@ fn typePtrOrOptionalPtrTy(
3328133463
33282 .optional => {33464 .optional => {
33283 const child_type = ty.optionalChild(buf);33465 const child_type = ty.optionalChild(buf);
33284 if (child_type.zigTypeTag() != .Pointer) return null;33466 if (child_type.zigTypeTag(mod) != .Pointer) return null;
3328533467
33286 const info = child_type.ptrInfo().data;33468 const info = child_type.ptrInfo().data;
33287 switch (info.size) {33469 switch (info.size) {
...@@ -33310,6 +33492,23 @@ fn typePtrOrOptionalPtrTy(...@@ -33310,6 +33492,23 @@ fn typePtrOrOptionalPtrTy(
33310/// TODO merge these implementations together with the "advanced"/opt_sema pattern seen33492/// TODO merge these implementations together with the "advanced"/opt_sema pattern seen
33311/// elsewhere in value.zig33493/// elsewhere in value.zig
33312pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {33494pub 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 }
33313 return switch (ty.tag()) {33512 return switch (ty.tag()) {
33314 .u1,33513 .u1,
33315 .u8,33514 .u8,
...@@ -33374,8 +33573,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -33374,8 +33573,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33374 .generic_poison,33573 .generic_poison,
33375 .array_u8,33574 .array_u8,
33376 .array_u8_sentinel_0,33575 .array_u8_sentinel_0,
33377 .int_signed,
33378 .int_unsigned,
33379 .enum_simple,33576 .enum_simple,
33380 => false,33577 => false,
3338133578
...@@ -33385,11 +33582,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -33385,11 +33582,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33385 .comptime_float,33582 .comptime_float,
33386 .enum_literal,33583 .enum_literal,
33387 .type_info,33584 .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,
33393 .function,33585 .function,
33394 => true,33586 => true,
3339533587
...@@ -33412,7 +33604,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -33412,7 +33604,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33412 .mut_slice,33604 .mut_slice,
33413 => {33605 => {
33414 const child_ty = ty.childType();33606 const child_ty = ty.childType();
33415 if (child_ty.zigTypeTag() == .Fn) {33607 if (child_ty.zigTypeTag(mod) == .Fn) {
33416 return child_ty.fnInfo().is_generic;33608 return child_ty.fnInfo().is_generic;
33417 } else {33609 } else {
33418 return sema.typeRequiresComptime(child_ty);33610 return sema.typeRequiresComptime(child_ty);
...@@ -33504,7 +33696,8 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -33504,7 +33696,8 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33504}33696}
3350533697
33506pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {33698pub 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) {
33508 error.NeedLazy => unreachable,33701 error.NeedLazy => unreachable,
33509 else => |e| return e,33702 else => |e| return e,
33510 };33703 };
...@@ -33512,19 +33705,18 @@ pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {...@@ -33512,19 +33705,18 @@ pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {
3351233705
33513fn typeAbiSize(sema: *Sema, ty: Type) !u64 {33706fn typeAbiSize(sema: *Sema, ty: Type) !u64 {
33514 try sema.resolveTypeLayout(ty);33707 try sema.resolveTypeLayout(ty);
33515 const target = sema.mod.getTarget();33708 return ty.abiSize(sema.mod);
33516 return ty.abiSize(target);
33517}33709}
3351833710
33519fn typeAbiAlignment(sema: *Sema, ty: Type) CompileError!u32 {33711fn typeAbiAlignment(sema: *Sema, ty: Type) CompileError!u32 {
33520 const target = sema.mod.getTarget();33712 return (try ty.abiAlignmentAdvanced(sema.mod, .{ .sema = sema })).scalar;
33521 return (try ty.abiAlignmentAdvanced(target, .{ .sema = sema })).scalar;
33522}33713}
3352333714
33524/// Not valid to call for packed unions.33715/// Not valid to call for packed unions.
33525/// Keep implementation in sync with `Module.Union.Field.normalAlignment`.33716/// Keep implementation in sync with `Module.Union.Field.normalAlignment`.
33526fn unionFieldAlignment(sema: *Sema, field: Module.Union.Field) !u32 {33717fn 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) {
33528 return @as(u32, 0);33720 return @as(u32, 0);
33529 } else if (field.abi_align == 0) {33721 } else if (field.abi_align == 0) {
33530 return sema.typeAbiAlignment(field.ty);33722 return sema.typeAbiAlignment(field.ty);
...@@ -33605,13 +33797,14 @@ fn queueFullTypeResolution(sema: *Sema, ty: Type) !void {...@@ -33605,13 +33797,14 @@ fn queueFullTypeResolution(sema: *Sema, ty: Type) !void {
33605}33797}
3360633798
33607fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value {33799fn 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) {
33609 const result_data = try sema.arena.alloc(Value, ty.vectorLen());33802 const result_data = try sema.arena.alloc(Value, ty.vectorLen());
33610 for (result_data, 0..) |*scalar, i| {33803 for (result_data, 0..) |*scalar, i| {
33611 var lhs_buf: Value.ElemValueBuffer = undefined;33804 var lhs_buf: Value.ElemValueBuffer = undefined;
33612 var rhs_buf: Value.ElemValueBuffer = undefined;33805 var rhs_buf: Value.ElemValueBuffer = undefined;
33613 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);33806 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
33614 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);33807 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
33615 scalar.* = try sema.intAddScalar(lhs_elem, rhs_elem);33808 scalar.* = try sema.intAddScalar(lhs_elem, rhs_elem);
33616 }33809 }
33617 return Value.Tag.aggregate.create(sema.arena, result_data);33810 return Value.Tag.aggregate.create(sema.arena, result_data);
...@@ -33620,13 +33813,13 @@ fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value {...@@ -33620,13 +33813,13 @@ fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value {
33620}33813}
3362133814
33622fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value) !Value {33815fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value) !Value {
33816 const mod = sema.mod;
33623 // TODO is this a performance issue? maybe we should try the operation without33817 // TODO is this a performance issue? maybe we should try the operation without
33624 // resorting to BigInt first.33818 // resorting to BigInt first.
33625 var lhs_space: Value.BigIntSpace = undefined;33819 var lhs_space: Value.BigIntSpace = undefined;
33626 var rhs_space: Value.BigIntSpace = undefined;33820 var rhs_space: Value.BigIntSpace = undefined;
33627 const target = sema.mod.getTarget();33821 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
33628 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema);33822 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
33629 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema);
33630 const limbs = try sema.arena.alloc(33823 const limbs = try sema.arena.alloc(
33631 std.math.big.Limb,33824 std.math.big.Limb,
33632 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,33825 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
...@@ -33645,7 +33838,8 @@ fn numberAddWrapScalar(...@@ -33645,7 +33838,8 @@ fn numberAddWrapScalar(
33645) !Value {33838) !Value {
33646 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);33839 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) {
33649 return sema.intAdd(lhs, rhs, ty);33843 return sema.intAdd(lhs, rhs, ty);
33650 }33844 }
3365133845
...@@ -33663,7 +33857,8 @@ fn intSub(...@@ -33663,7 +33857,8 @@ fn intSub(
33663 rhs: Value,33857 rhs: Value,
33664 ty: Type,33858 ty: Type,
33665) !Value {33859) !Value {
33666 if (ty.zigTypeTag() == .Vector) {33860 const mod = sema.mod;
33861 if (ty.zigTypeTag(mod) == .Vector) {
33667 const result_data = try sema.arena.alloc(Value, ty.vectorLen());33862 const result_data = try sema.arena.alloc(Value, ty.vectorLen());
33668 for (result_data, 0..) |*scalar, i| {33863 for (result_data, 0..) |*scalar, i| {
33669 var lhs_buf: Value.ElemValueBuffer = undefined;33864 var lhs_buf: Value.ElemValueBuffer = undefined;
...@@ -33678,13 +33873,13 @@ fn intSub(...@@ -33678,13 +33873,13 @@ fn intSub(
33678}33873}
3367933874
33680fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value) !Value {33875fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value) !Value {
33876 const mod = sema.mod;
33681 // TODO is this a performance issue? maybe we should try the operation without33877 // TODO is this a performance issue? maybe we should try the operation without
33682 // resorting to BigInt first.33878 // resorting to BigInt first.
33683 var lhs_space: Value.BigIntSpace = undefined;33879 var lhs_space: Value.BigIntSpace = undefined;
33684 var rhs_space: Value.BigIntSpace = undefined;33880 var rhs_space: Value.BigIntSpace = undefined;
33685 const target = sema.mod.getTarget();33881 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
33686 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema);33882 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
33687 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema);
33688 const limbs = try sema.arena.alloc(33883 const limbs = try sema.arena.alloc(
33689 std.math.big.Limb,33884 std.math.big.Limb,
33690 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,33885 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
...@@ -33703,7 +33898,8 @@ fn numberSubWrapScalar(...@@ -33703,7 +33898,8 @@ fn numberSubWrapScalar(
33703) !Value {33898) !Value {
33704 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);33899 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) {
33707 return sema.intSub(lhs, rhs, ty);33903 return sema.intSub(lhs, rhs, ty);
33708 }33904 }
3370933905
...@@ -33721,14 +33917,15 @@ fn floatAdd(...@@ -33721,14 +33917,15 @@ fn floatAdd(
33721 rhs: Value,33917 rhs: Value,
33722 float_type: Type,33918 float_type: Type,
33723) !Value {33919) !Value {
33724 if (float_type.zigTypeTag() == .Vector) {33920 const mod = sema.mod;
33921 if (float_type.zigTypeTag(mod) == .Vector) {
33725 const result_data = try sema.arena.alloc(Value, float_type.vectorLen());33922 const result_data = try sema.arena.alloc(Value, float_type.vectorLen());
33726 for (result_data, 0..) |*scalar, i| {33923 for (result_data, 0..) |*scalar, i| {
33727 var lhs_buf: Value.ElemValueBuffer = undefined;33924 var lhs_buf: Value.ElemValueBuffer = undefined;
33728 var rhs_buf: Value.ElemValueBuffer = undefined;33925 var rhs_buf: Value.ElemValueBuffer = undefined;
33729 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);33926 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
33730 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);33927 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));
33732 }33929 }
33733 return Value.Tag.aggregate.create(sema.arena, result_data);33930 return Value.Tag.aggregate.create(sema.arena, result_data);
33734 }33931 }
...@@ -33778,14 +33975,15 @@ fn floatSub(...@@ -33778,14 +33975,15 @@ fn floatSub(
33778 rhs: Value,33975 rhs: Value,
33779 float_type: Type,33976 float_type: Type,
33780) !Value {33977) !Value {
33781 if (float_type.zigTypeTag() == .Vector) {33978 const mod = sema.mod;
33979 if (float_type.zigTypeTag(mod) == .Vector) {
33782 const result_data = try sema.arena.alloc(Value, float_type.vectorLen());33980 const result_data = try sema.arena.alloc(Value, float_type.vectorLen());
33783 for (result_data, 0..) |*scalar, i| {33981 for (result_data, 0..) |*scalar, i| {
33784 var lhs_buf: Value.ElemValueBuffer = undefined;33982 var lhs_buf: Value.ElemValueBuffer = undefined;
33785 var rhs_buf: Value.ElemValueBuffer = undefined;33983 var rhs_buf: Value.ElemValueBuffer = undefined;
33786 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);33984 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
33787 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);33985 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));
33789 }33987 }
33790 return Value.Tag.aggregate.create(sema.arena, result_data);33988 return Value.Tag.aggregate.create(sema.arena, result_data);
33791 }33989 }
...@@ -33835,7 +34033,8 @@ fn intSubWithOverflow(...@@ -33835,7 +34033,8 @@ fn intSubWithOverflow(
33835 rhs: Value,34033 rhs: Value,
33836 ty: Type,34034 ty: Type,
33837) !Value.OverflowArithmeticResult {34035) !Value.OverflowArithmeticResult {
33838 if (ty.zigTypeTag() == .Vector) {34036 const mod = sema.mod;
34037 if (ty.zigTypeTag(mod) == .Vector) {
33839 const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen());34038 const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen());
33840 const result_data = try sema.arena.alloc(Value, ty.vectorLen());34039 const result_data = try sema.arena.alloc(Value, ty.vectorLen());
33841 for (result_data, 0..) |*scalar, i| {34040 for (result_data, 0..) |*scalar, i| {
...@@ -33843,7 +34042,7 @@ fn intSubWithOverflow(...@@ -33843,7 +34042,7 @@ fn intSubWithOverflow(
33843 var rhs_buf: Value.ElemValueBuffer = undefined;34042 var rhs_buf: Value.ElemValueBuffer = undefined;
33844 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);34043 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
33845 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);34044 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));
33847 overflowed_data[i] = of_math_result.overflow_bit;34046 overflowed_data[i] = of_math_result.overflow_bit;
33848 scalar.* = of_math_result.wrapped_result;34047 scalar.* = of_math_result.wrapped_result;
33849 }34048 }
...@@ -33861,13 +34060,13 @@ fn intSubWithOverflowScalar(...@@ -33861,13 +34060,13 @@ fn intSubWithOverflowScalar(
33861 rhs: Value,34060 rhs: Value,
33862 ty: Type,34061 ty: Type,
33863) !Value.OverflowArithmeticResult {34062) !Value.OverflowArithmeticResult {
33864 const target = sema.mod.getTarget();34063 const mod = sema.mod;
33865 const info = ty.intInfo(target);34064 const info = ty.intInfo(mod);
3386634065
33867 var lhs_space: Value.BigIntSpace = undefined;34066 var lhs_space: Value.BigIntSpace = undefined;
33868 var rhs_space: Value.BigIntSpace = undefined;34067 var rhs_space: Value.BigIntSpace = undefined;
33869 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema);34068 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
33870 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema);34069 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
33871 const limbs = try sema.arena.alloc(34070 const limbs = try sema.arena.alloc(
33872 std.math.big.Limb,34071 std.math.big.Limb,
33873 std.math.big.int.calcTwosCompLimbCount(info.bits),34072 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -33889,13 +34088,14 @@ fn floatToInt(...@@ -33889,13 +34088,14 @@ fn floatToInt(
33889 float_ty: Type,34088 float_ty: Type,
33890 int_ty: Type,34089 int_ty: Type,
33891) CompileError!Value {34090) CompileError!Value {
33892 if (float_ty.zigTypeTag() == .Vector) {34091 const mod = sema.mod;
34092 if (float_ty.zigTypeTag(mod) == .Vector) {
33893 const elem_ty = float_ty.childType();34093 const elem_ty = float_ty.childType();
33894 const result_data = try sema.arena.alloc(Value, float_ty.vectorLen());34094 const result_data = try sema.arena.alloc(Value, float_ty.vectorLen());
33895 for (result_data, 0..) |*scalar, i| {34095 for (result_data, 0..) |*scalar, i| {
33896 var buf: Value.ElemValueBuffer = undefined;34096 var buf: Value.ElemValueBuffer = undefined;
33897 const elem_val = val.elemValueBuffer(sema.mod, i, &buf);34097 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));
33899 }34099 }
33900 return Value.Tag.aggregate.create(sema.arena, result_data);34100 return Value.Tag.aggregate.create(sema.arena, result_data);
33901 }34101 }
...@@ -33976,7 +34176,8 @@ fn intFitsInType(...@@ -33976,7 +34176,8 @@ fn intFitsInType(
33976 ty: Type,34176 ty: Type,
33977 vector_index: ?*usize,34177 vector_index: ?*usize,
33978) CompileError!bool {34178) CompileError!bool {
33979 const target = sema.mod.getTarget();34179 const mod = sema.mod;
34180 const target = mod.getTarget();
33980 switch (val.tag()) {34181 switch (val.tag()) {
33981 .zero,34182 .zero,
33982 .undef,34183 .undef,
...@@ -33985,9 +34186,9 @@ fn intFitsInType(...@@ -33985,9 +34186,9 @@ fn intFitsInType(
3398534186
33986 .one,34187 .one,
33987 .bool_true,34188 .bool_true,
33988 => switch (ty.zigTypeTag()) {34189 => switch (ty.zigTypeTag(mod)) {
33989 .Int => {34190 .Int => {
33990 const info = ty.intInfo(target);34191 const info = ty.intInfo(mod);
33991 return switch (info.signedness) {34192 return switch (info.signedness) {
33992 .signed => info.bits >= 2,34193 .signed => info.bits >= 2,
33993 .unsigned => info.bits >= 1,34194 .unsigned => info.bits >= 1,
...@@ -33997,9 +34198,9 @@ fn intFitsInType(...@@ -33997,9 +34198,9 @@ fn intFitsInType(
33997 else => unreachable,34198 else => unreachable,
33998 },34199 },
3399934200
34000 .lazy_align => switch (ty.zigTypeTag()) {34201 .lazy_align => switch (ty.zigTypeTag(mod)) {
34001 .Int => {34202 .Int => {
34002 const info = ty.intInfo(target);34203 const info = ty.intInfo(mod);
34003 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);34204 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
34004 // If it is u16 or bigger we know the alignment fits without resolving it.34205 // If it is u16 or bigger we know the alignment fits without resolving it.
34005 if (info.bits >= max_needed_bits) return true;34206 if (info.bits >= max_needed_bits) return true;
...@@ -34011,9 +34212,9 @@ fn intFitsInType(...@@ -34011,9 +34212,9 @@ fn intFitsInType(
34011 .ComptimeInt => return true,34212 .ComptimeInt => return true,
34012 else => unreachable,34213 else => unreachable,
34013 },34214 },
34014 .lazy_size => switch (ty.zigTypeTag()) {34215 .lazy_size => switch (ty.zigTypeTag(mod)) {
34015 .Int => {34216 .Int => {
34016 const info = ty.intInfo(target);34217 const info = ty.intInfo(mod);
34017 const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed);34218 const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed);
34018 // If it is u64 or bigger we know the size fits without resolving it.34219 // If it is u64 or bigger we know the size fits without resolving it.
34019 if (info.bits >= max_needed_bits) return true;34220 if (info.bits >= max_needed_bits) return true;
...@@ -34026,41 +34227,41 @@ fn intFitsInType(...@@ -34026,41 +34227,41 @@ fn intFitsInType(
34026 else => unreachable,34227 else => unreachable,
34027 },34228 },
3402834229
34029 .int_u64 => switch (ty.zigTypeTag()) {34230 .int_u64 => switch (ty.zigTypeTag(mod)) {
34030 .Int => {34231 .Int => {
34031 const x = val.castTag(.int_u64).?.data;34232 const x = val.castTag(.int_u64).?.data;
34032 if (x == 0) return true;34233 if (x == 0) return true;
34033 const info = ty.intInfo(target);34234 const info = ty.intInfo(mod);
34034 const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);34235 const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
34035 return info.bits >= needed_bits;34236 return info.bits >= needed_bits;
34036 },34237 },
34037 .ComptimeInt => return true,34238 .ComptimeInt => return true,
34038 else => unreachable,34239 else => unreachable,
34039 },34240 },
34040 .int_i64 => switch (ty.zigTypeTag()) {34241 .int_i64 => switch (ty.zigTypeTag(mod)) {
34041 .Int => {34242 .Int => {
34042 const x = val.castTag(.int_i64).?.data;34243 const x = val.castTag(.int_i64).?.data;
34043 if (x == 0) return true;34244 if (x == 0) return true;
34044 const info = ty.intInfo(target);34245 const info = ty.intInfo(mod);
34045 if (info.signedness == .unsigned and x < 0)34246 if (info.signedness == .unsigned and x < 0)
34046 return false;34247 return false;
34047 var buffer: Value.BigIntSpace = undefined;34248 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);
34049 },34250 },
34050 .ComptimeInt => return true,34251 .ComptimeInt => return true,
34051 else => unreachable,34252 else => unreachable,
34052 },34253 },
34053 .int_big_positive => switch (ty.zigTypeTag()) {34254 .int_big_positive => switch (ty.zigTypeTag(mod)) {
34054 .Int => {34255 .Int => {
34055 const info = ty.intInfo(target);34256 const info = ty.intInfo(mod);
34056 return val.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);34257 return val.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
34057 },34258 },
34058 .ComptimeInt => return true,34259 .ComptimeInt => return true,
34059 else => unreachable,34260 else => unreachable,
34060 },34261 },
34061 .int_big_negative => switch (ty.zigTypeTag()) {34262 .int_big_negative => switch (ty.zigTypeTag(mod)) {
34062 .Int => {34263 .Int => {
34063 const info = ty.intInfo(target);34264 const info = ty.intInfo(mod);
34064 return val.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);34265 return val.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
34065 },34266 },
34066 .ComptimeInt => return true,34267 .ComptimeInt => return true,
...@@ -34068,7 +34269,7 @@ fn intFitsInType(...@@ -34068,7 +34269,7 @@ fn intFitsInType(
34068 },34269 },
3406934270
34070 .the_only_possible_value => {34271 .the_only_possible_value => {
34071 assert(ty.intInfo(target).bits == 0);34272 assert(ty.intInfo(mod).bits == 0);
34072 return true;34273 return true;
34073 },34274 },
3407434275
...@@ -34077,9 +34278,9 @@ fn intFitsInType(...@@ -34077,9 +34278,9 @@ fn intFitsInType(
34077 .decl_ref,34278 .decl_ref,
34078 .function,34279 .function,
34079 .variable,34280 .variable,
34080 => switch (ty.zigTypeTag()) {34281 => switch (ty.zigTypeTag(mod)) {
34081 .Int => {34282 .Int => {
34082 const info = ty.intInfo(target);34283 const info = ty.intInfo(mod);
34083 const ptr_bits = target.ptrBitWidth();34284 const ptr_bits = target.ptrBitWidth();
34084 return switch (info.signedness) {34285 return switch (info.signedness) {
34085 .signed => info.bits > ptr_bits,34286 .signed => info.bits > ptr_bits,
...@@ -34091,9 +34292,9 @@ fn intFitsInType(...@@ -34091,9 +34292,9 @@ fn intFitsInType(
34091 },34292 },
3409234293
34093 .aggregate => {34294 .aggregate => {
34094 assert(ty.zigTypeTag() == .Vector);34295 assert(ty.zigTypeTag(mod) == .Vector);
34095 for (val.castTag(.aggregate).?.data, 0..) |elem, i| {34296 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))) {
34097 if (vector_index) |some| some.* = i;34298 if (vector_index) |some| some.* = i;
34098 return false;34299 return false;
34099 }34300 }
...@@ -34122,11 +34323,8 @@ fn intInRange(...@@ -34122,11 +34323,8 @@ fn intInRange(
34122}34323}
3412334324
34124/// Asserts the type is an enum.34325/// Asserts the type is an enum.
34125fn enumHasInt(34326fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {
34126 sema: *Sema,34327 const mod = sema.mod;
34127 ty: Type,
34128 int: Value,
34129) CompileError!bool {
34130 switch (ty.tag()) {34328 switch (ty.tag()) {
34131 .enum_nonexhaustive => unreachable,34329 .enum_nonexhaustive => unreachable,
34132 .enum_full => {34330 .enum_full => {
...@@ -34157,11 +34355,7 @@ fn enumHasInt(...@@ -34157,11 +34355,7 @@ fn enumHasInt(
34157 const enum_simple = ty.castTag(.enum_simple).?.data;34355 const enum_simple = ty.castTag(.enum_simple).?.data;
34158 const fields_len = enum_simple.fields.count();34356 const fields_len = enum_simple.fields.count();
34159 const bits = std.math.log2_int_ceil(usize, fields_len);34357 const bits = std.math.log2_int_ceil(usize, fields_len);
34160 var buffer: Type.Payload.Bits = .{34358 const tag_ty = try mod.intType(.unsigned, bits);
34161 .base = .{ .tag = .int_unsigned },
34162 .data = bits,
34163 };
34164 const tag_ty = Type.initPayload(&buffer.base);
34165 return sema.intInRange(tag_ty, int, fields_len);34359 return sema.intInRange(tag_ty, int, fields_len);
34166 },34360 },
34167 .atomic_order,34361 .atomic_order,
...@@ -34186,7 +34380,8 @@ fn intAddWithOverflow(...@@ -34186,7 +34380,8 @@ fn intAddWithOverflow(
34186 rhs: Value,34380 rhs: Value,
34187 ty: Type,34381 ty: Type,
34188) !Value.OverflowArithmeticResult {34382) !Value.OverflowArithmeticResult {
34189 if (ty.zigTypeTag() == .Vector) {34383 const mod = sema.mod;
34384 if (ty.zigTypeTag(mod) == .Vector) {
34190 const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen());34385 const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen());
34191 const result_data = try sema.arena.alloc(Value, ty.vectorLen());34386 const result_data = try sema.arena.alloc(Value, ty.vectorLen());
34192 for (result_data, 0..) |*scalar, i| {34387 for (result_data, 0..) |*scalar, i| {
...@@ -34194,7 +34389,7 @@ fn intAddWithOverflow(...@@ -34194,7 +34389,7 @@ fn intAddWithOverflow(
34194 var rhs_buf: Value.ElemValueBuffer = undefined;34389 var rhs_buf: Value.ElemValueBuffer = undefined;
34195 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);34390 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
34196 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);34391 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));
34198 overflowed_data[i] = of_math_result.overflow_bit;34393 overflowed_data[i] = of_math_result.overflow_bit;
34199 scalar.* = of_math_result.wrapped_result;34394 scalar.* = of_math_result.wrapped_result;
34200 }34395 }
...@@ -34212,13 +34407,13 @@ fn intAddWithOverflowScalar(...@@ -34212,13 +34407,13 @@ fn intAddWithOverflowScalar(
34212 rhs: Value,34407 rhs: Value,
34213 ty: Type,34408 ty: Type,
34214) !Value.OverflowArithmeticResult {34409) !Value.OverflowArithmeticResult {
34215 const target = sema.mod.getTarget();34410 const mod = sema.mod;
34216 const info = ty.intInfo(target);34411 const info = ty.intInfo(mod);
3421734412
34218 var lhs_space: Value.BigIntSpace = undefined;34413 var lhs_space: Value.BigIntSpace = undefined;
34219 var rhs_space: Value.BigIntSpace = undefined;34414 var rhs_space: Value.BigIntSpace = undefined;
34220 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema);34415 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
34221 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema);34416 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
34222 const limbs = try sema.arena.alloc(34417 const limbs = try sema.arena.alloc(
34223 std.math.big.Limb,34418 std.math.big.Limb,
34224 std.math.big.int.calcTwosCompLimbCount(info.bits),34419 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -34243,14 +34438,15 @@ fn compareAll(...@@ -34243,14 +34438,15 @@ fn compareAll(
34243 rhs: Value,34438 rhs: Value,
34244 ty: Type,34439 ty: Type,
34245) CompileError!bool {34440) CompileError!bool {
34246 if (ty.zigTypeTag() == .Vector) {34441 const mod = sema.mod;
34442 if (ty.zigTypeTag(mod) == .Vector) {
34247 var i: usize = 0;34443 var i: usize = 0;
34248 while (i < ty.vectorLen()) : (i += 1) {34444 while (i < ty.vectorLen()) : (i += 1) {
34249 var lhs_buf: Value.ElemValueBuffer = undefined;34445 var lhs_buf: Value.ElemValueBuffer = undefined;
34250 var rhs_buf: Value.ElemValueBuffer = undefined;34446 var rhs_buf: Value.ElemValueBuffer = undefined;
34251 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);34447 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
34252 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);34448 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)))) {
34254 return false;34450 return false;
34255 }34451 }
34256 }34452 }
...@@ -34270,7 +34466,7 @@ fn compareScalar(...@@ -34270,7 +34466,7 @@ fn compareScalar(
34270 switch (op) {34466 switch (op) {
34271 .eq => return sema.valuesEqual(lhs, rhs, ty),34467 .eq => return sema.valuesEqual(lhs, rhs, ty),
34272 .neq => return !(try sema.valuesEqual(lhs, rhs, ty)),34468 .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),
34274 }34470 }
34275}34471}
3427634472
...@@ -34291,14 +34487,15 @@ fn compareVector(...@@ -34291,14 +34487,15 @@ fn compareVector(
34291 rhs: Value,34487 rhs: Value,
34292 ty: Type,34488 ty: Type,
34293) !Value {34489) !Value {
34294 assert(ty.zigTypeTag() == .Vector);34490 const mod = sema.mod;
34491 assert(ty.zigTypeTag(mod) == .Vector);
34295 const result_data = try sema.arena.alloc(Value, ty.vectorLen());34492 const result_data = try sema.arena.alloc(Value, ty.vectorLen());
34296 for (result_data, 0..) |*scalar, i| {34493 for (result_data, 0..) |*scalar, i| {
34297 var lhs_buf: Value.ElemValueBuffer = undefined;34494 var lhs_buf: Value.ElemValueBuffer = undefined;
34298 var rhs_buf: Value.ElemValueBuffer = undefined;34495 var rhs_buf: Value.ElemValueBuffer = undefined;
34299 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);34496 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
34300 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);34497 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));
34302 scalar.* = Value.makeBool(res_bool);34499 scalar.* = Value.makeBool(res_bool);
34303 }34500 }
34304 return Value.Tag.aggregate.create(sema.arena, result_data);34501 return Value.Tag.aggregate.create(sema.arena, result_data);
...@@ -34312,10 +34509,10 @@ fn compareVector(...@@ -34312,10 +34509,10 @@ fn compareVector(
34312/// Handles const-ness and address spaces in particular.34509/// Handles const-ness and address spaces in particular.
34313/// This code is duplicated in `analyzePtrArithmetic`.34510/// This code is duplicated in `analyzePtrArithmetic`.
34314fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {34511fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
34512 const mod = sema.mod;
34315 const ptr_info = ptr_ty.ptrInfo().data;34513 const ptr_info = ptr_ty.ptrInfo().data;
34316 const elem_ty = ptr_ty.elemType2();34514 const elem_ty = ptr_ty.elemType2(mod);
34317 const allow_zero = ptr_info.@"allowzero" and (offset orelse 0) == 0;34515 const allow_zero = ptr_info.@"allowzero" and (offset orelse 0) == 0;
34318 const target = sema.mod.getTarget();
34319 const parent_ty = ptr_ty.childType();34516 const parent_ty = ptr_ty.childType();
3432034517
34321 const VI = Type.Payload.Pointer.Data.VectorIndex;34518 const VI = Type.Payload.Pointer.Data.VectorIndex;
...@@ -34325,14 +34522,14 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {...@@ -34325,14 +34522,14 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
34325 alignment: u32 = 0,34522 alignment: u32 = 0,
34326 vector_index: VI = .none,34523 vector_index: VI = .none,
34327 } = if (parent_ty.tag() == .vector and ptr_info.size == .One) blk: {34524 } = 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);
34329 if (elem_bits == 0) break :blk .{};34526 if (elem_bits == 0) break :blk .{};
34330 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);34527 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);
34331 if (!is_packed) break :blk .{};34528 if (!is_packed) break :blk .{};
3433234529
34333 break :blk .{34530 break :blk .{
34334 .host_size = @intCast(u16, parent_ty.arrayLen()),34531 .host_size = @intCast(u16, parent_ty.arrayLen()),
34335 .alignment = @intCast(u16, parent_ty.abiAlignment(target)),34532 .alignment = @intCast(u16, parent_ty.abiAlignment(mod)),
34336 .vector_index = if (offset) |some| @intToEnum(VI, some) else .runtime,34533 .vector_index = if (offset) |some| @intToEnum(VI, some) else .runtime,
34337 };34534 };
34338 } else .{};34535 } else .{};
src/TypedValue.zig+15-27
...@@ -71,7 +71,6 @@ pub fn print(...@@ -71,7 +71,6 @@ pub fn print(
71 level: u8,71 level: u8,
72 mod: *Module,72 mod: *Module,
73) @TypeOf(writer).Error!void {73) @TypeOf(writer).Error!void {
74 const target = mod.getTarget();
75 var val = tv.val;74 var val = tv.val;
76 var ty = tv.ty;75 var ty = tv.ty;
77 if (val.isVariable(mod))76 if (val.isVariable(mod))
...@@ -117,10 +116,6 @@ pub fn print(...@@ -117,10 +116,6 @@ pub fn print(
117 .noreturn_type => return writer.writeAll("noreturn"),116 .noreturn_type => return writer.writeAll("noreturn"),
118 .null_type => return writer.writeAll("@Type(.Null)"),117 .null_type => return writer.writeAll("@Type(.Null)"),
119 .undefined_type => return writer.writeAll("@Type(.Undefined)"),118 .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"),
124 .single_const_pointer_to_comptime_int_type => return writer.writeAll("*const comptime_int"),119 .single_const_pointer_to_comptime_int_type => return writer.writeAll("*const comptime_int"),
125 .anyframe_type => return writer.writeAll("anyframe"),120 .anyframe_type => return writer.writeAll("anyframe"),
126 .const_slice_u8_type => return writer.writeAll("[]const u8"),121 .const_slice_u8_type => return writer.writeAll("[]const u8"),
...@@ -147,7 +142,7 @@ pub fn print(...@@ -147,7 +142,7 @@ pub fn print(
147 if (level == 0) {142 if (level == 0) {
148 return writer.writeAll(".{ ... }");143 return writer.writeAll(".{ ... }");
149 }144 }
150 if (ty.zigTypeTag() == .Struct) {145 if (ty.zigTypeTag(mod) == .Struct) {
151 try writer.writeAll(".{");146 try writer.writeAll(".{");
152 const max_len = std.math.min(ty.structFieldCount(), max_aggregate_items);147 const max_len = std.math.min(ty.structFieldCount(), max_aggregate_items);
153148
...@@ -160,7 +155,7 @@ pub fn print(...@@ -160,7 +155,7 @@ pub fn print(
160 }155 }
161 try print(.{156 try print(.{
162 .ty = ty.structFieldType(i),157 .ty = ty.structFieldType(i),
163 .val = val.fieldValue(ty, i),158 .val = val.fieldValue(ty, mod, i),
164 }, writer, level - 1, mod);159 }, writer, level - 1, mod);
165 }160 }
166 if (ty.structFieldCount() > max_aggregate_items) {161 if (ty.structFieldCount() > max_aggregate_items) {
...@@ -168,7 +163,7 @@ pub fn print(...@@ -168,7 +163,7 @@ pub fn print(
168 }163 }
169 return writer.writeAll("}");164 return writer.writeAll("}");
170 } else {165 } else {
171 const elem_ty = ty.elemType2();166 const elem_ty = ty.elemType2(mod);
172 const len = ty.arrayLen();167 const len = ty.arrayLen();
173168
174 if (elem_ty.eql(Type.u8, mod)) str: {169 if (elem_ty.eql(Type.u8, mod)) str: {
...@@ -177,9 +172,9 @@ pub fn print(...@@ -177,9 +172,9 @@ pub fn print(
177172
178 var i: u32 = 0;173 var i: u32 = 0;
179 while (i < max_len) : (i += 1) {174 while (i < max_len) : (i += 1) {
180 const elem = val.fieldValue(ty, i);175 const elem = val.fieldValue(ty, mod, i);
181 if (elem.isUndef()) break :str;176 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;
183 }178 }
184179
185 const truncated = if (len > max_string_len) " (truncated)" else "";180 const truncated = if (len > max_string_len) " (truncated)" else "";
...@@ -194,7 +189,7 @@ pub fn print(...@@ -194,7 +189,7 @@ pub fn print(
194 if (i != 0) try writer.writeAll(", ");189 if (i != 0) try writer.writeAll(", ");
195 try print(.{190 try print(.{
196 .ty = elem_ty,191 .ty = elem_ty,
197 .val = val.fieldValue(ty, i),192 .val = val.fieldValue(ty, mod, i),
198 }, writer, level - 1, mod);193 }, writer, level - 1, mod);
199 }194 }
200 if (len > max_aggregate_items) {195 if (len > max_aggregate_items) {
...@@ -232,25 +227,18 @@ pub fn print(...@@ -232,25 +227,18 @@ pub fn print(
232 .bool_true => return writer.writeAll("true"),227 .bool_true => return writer.writeAll("true"),
233 .bool_false => return writer.writeAll("false"),228 .bool_false => return writer.writeAll("false"),
234 .ty => return val.castTag(.ty).?.data.print(writer, mod),229 .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 },
242 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", .{}, writer),230 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", .{}, writer),
243 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", .{}, writer),231 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", .{}, writer),
244 .int_big_positive => return writer.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),232 .int_big_positive => return writer.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),
245 .int_big_negative => return writer.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),233 .int_big_negative => return writer.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),
246 .lazy_align => {234 .lazy_align => {
247 const sub_ty = val.castTag(.lazy_align).?.data;235 const sub_ty = val.castTag(.lazy_align).?.data;
248 const x = sub_ty.abiAlignment(target);236 const x = sub_ty.abiAlignment(mod);
249 return writer.print("{d}", .{x});237 return writer.print("{d}", .{x});
250 },238 },
251 .lazy_size => {239 .lazy_size => {
252 const sub_ty = val.castTag(.lazy_size).?.data;240 const sub_ty = val.castTag(.lazy_size).?.data;
253 const x = sub_ty.abiSize(target);241 const x = sub_ty.abiSize(mod);
254 return writer.print("{d}", .{x});242 return writer.print("{d}", .{x});
255 },243 },
256 .function => return writer.print("(function '{s}')", .{244 .function => return writer.print("(function '{s}')", .{
...@@ -315,7 +303,7 @@ pub fn print(...@@ -315,7 +303,7 @@ pub fn print(
315 }, writer, level - 1, mod);303 }, writer, level - 1, mod);
316 }304 }
317305
318 if (field_ptr.container_ty.zigTypeTag() == .Struct) {306 if (field_ptr.container_ty.zigTypeTag(mod) == .Struct) {
319 switch (field_ptr.container_ty.tag()) {307 switch (field_ptr.container_ty.tag()) {
320 .tuple => return writer.print(".@\"{d}\"", .{field_ptr.field_index}),308 .tuple => return writer.print(".@\"{d}\"", .{field_ptr.field_index}),
321 else => {309 else => {
...@@ -323,7 +311,7 @@ pub fn print(...@@ -323,7 +311,7 @@ pub fn print(
323 return writer.print(".{s}", .{field_name});311 return writer.print(".{s}", .{field_name});
324 },312 },
325 }313 }
326 } else if (field_ptr.container_ty.zigTypeTag() == .Union) {314 } else if (field_ptr.container_ty.zigTypeTag(mod) == .Union) {
327 const field_name = field_ptr.container_ty.unionFields().keys()[field_ptr.field_index];315 const field_name = field_ptr.container_ty.unionFields().keys()[field_ptr.field_index];
328 return writer.print(".{s}", .{field_name});316 return writer.print(".{s}", .{field_name});
329 } else if (field_ptr.container_ty.isSlice()) {317 } else if (field_ptr.container_ty.isSlice()) {
...@@ -352,7 +340,7 @@ pub fn print(...@@ -352,7 +340,7 @@ pub fn print(
352 var i: u32 = 0;340 var i: u32 = 0;
353 try writer.writeAll(".{ ");341 try writer.writeAll(".{ ");
354 const elem_tv = TypedValue{342 const elem_tv = TypedValue{
355 .ty = ty.elemType2(),343 .ty = ty.elemType2(mod),
356 .val = val.castTag(.repeated).?.data,344 .val = val.castTag(.repeated).?.data,
357 };345 };
358 const len = ty.arrayLen();346 const len = ty.arrayLen();
...@@ -372,7 +360,7 @@ pub fn print(...@@ -372,7 +360,7 @@ pub fn print(
372 }360 }
373 try writer.writeAll(".{ ");361 try writer.writeAll(".{ ");
374 try print(.{362 try print(.{
375 .ty = ty.elemType2(),363 .ty = ty.elemType2(mod),
376 .val = ty.sentinel().?,364 .val = ty.sentinel().?,
377 }, writer, level - 1, mod);365 }, writer, level - 1, mod);
378 return writer.writeAll(" }");366 return writer.writeAll(" }");
...@@ -382,8 +370,8 @@ pub fn print(...@@ -382,8 +370,8 @@ pub fn print(
382 return writer.writeAll(".{ ... }");370 return writer.writeAll(".{ ... }");
383 }371 }
384 const payload = val.castTag(.slice).?.data;372 const payload = val.castTag(.slice).?.data;
385 const elem_ty = ty.elemType2();373 const elem_ty = ty.elemType2(mod);
386 const len = payload.len.toUnsignedInt(target);374 const len = payload.len.toUnsignedInt(mod);
387375
388 if (elem_ty.eql(Type.u8, mod)) str: {376 if (elem_ty.eql(Type.u8, mod)) str: {
389 const max_len = @intCast(usize, std.math.min(len, max_string_len));377 const max_len = @intCast(usize, std.math.min(len, max_string_len));
...@@ -394,7 +382,7 @@ pub fn print(...@@ -394,7 +382,7 @@ pub fn print(
394 var elem_buf: Value.ElemValueBuffer = undefined;382 var elem_buf: Value.ElemValueBuffer = undefined;
395 const elem_val = payload.ptr.elemValueBuffer(mod, i, &elem_buf);383 const elem_val = payload.ptr.elemValueBuffer(mod, i, &elem_buf);
396 if (elem_val.isUndef()) break :str;384 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;
398 }386 }
399387
400 // TODO would be nice if this had a bit of unicode awareness.388 // 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;...@@ -19,6 +19,7 @@ const BigIntConst = std.math.big.int.Const;
19const BigIntMutable = std.math.big.int.Mutable;19const BigIntMutable = std.math.big.int.Mutable;
20const Ast = std.zig.Ast;20const Ast = std.zig.Ast;
2121
22const InternPool = @import("InternPool.zig");
22const Zir = @This();23const Zir = @This();
23const Type = @import("type.zig").Type;24const Type = @import("type.zig").Type;
24const Value = @import("value.zig").Value;25const Value = @import("value.zig").Value;
...@@ -2041,448 +2042,95 @@ pub const Inst = struct {...@@ -2041,448 +2042,95 @@ pub const Inst = struct {
2041 /// The position of a ZIR instruction within the `Zir` instructions array.2042 /// The position of a ZIR instruction within the `Zir` instructions array.
2042 pub const Index = u32;2043 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.
2045 ///2046 ///
2046 /// If the Ref has a tag in this enum, it refers to a TypedValue.2047 /// If the integer tag value is < InternPool.static_len, then it
2047 ///2048 /// corresponds to an InternPool index. Otherwise, this refers to a ZIR
2048 /// If the value of a Ref does not have a tag, it refers to a ZIR instruction.2049 /// 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.
2055 ///2050 ///
2056 /// The tag type is specified so that it is safe to bitcast between `[]u32`2051 /// The tag type is specified so that it is safe to bitcast between `[]u32`
2057 /// and `[]Ref`.2052 /// and `[]Ref`.
2058 pub const Ref = enum(u32) {2053 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
2059 /// This Ref does not correspond to any ZIR instruction or constant2130 /// This Ref does not correspond to any ZIR instruction or constant
2060 /// value and may instead be used as a sentinel to indicate null.2131 /// value and may instead be used as a sentinel to indicate null.
2061 none,2132 none = std.math.maxInt(u32),
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
2160 _,2133 _,
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),
2486 };2134 };
24872135
2488 /// All instructions have an 8-byte payload, which is contained within2136 /// 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 {...@@ -4163,7 +3811,7 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
4163 };3811 };
4164}3812}
41653813
4166const ref_start_index: u32 = Inst.Ref.typed_value_map.len;3814const ref_start_index: u32 = InternPool.static_len;
41673815
4168pub fn indexToRef(inst: Inst.Index) Inst.Ref {3816pub fn indexToRef(inst: Inst.Index) Inst.Ref {
4169 return @intToEnum(Inst.Ref, ref_start_index + inst);3817 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 {...@@ -471,6 +471,7 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
471}471}
472472
473fn gen(self: *Self) !void {473fn gen(self: *Self) !void {
474 const mod = self.bin_file.options.module.?;
474 const cc = self.fn_type.fnCallingConvention();475 const cc = self.fn_type.fnCallingConvention();
475 if (cc != .Naked) {476 if (cc != .Naked) {
476 // stp fp, lr, [sp, #-16]!477 // stp fp, lr, [sp, #-16]!
...@@ -522,8 +523,8 @@ fn gen(self: *Self) !void {...@@ -522,8 +523,8 @@ fn gen(self: *Self) !void {
522523
523 const ty = self.air.typeOfIndex(inst);524 const ty = self.air.typeOfIndex(inst);
524525
525 const abi_size = @intCast(u32, ty.abiSize(self.target.*));526 const abi_size = @intCast(u32, ty.abiSize(mod));
526 const abi_align = ty.abiAlignment(self.target.*);527 const abi_align = ty.abiAlignment(mod);
527 const stack_offset = try self.allocMem(abi_size, abi_align, inst);528 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
528 try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });529 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...@@ -951,8 +952,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
951 tomb_bits >>= 1;952 tomb_bits >>= 1;
952 if (!dies) continue;953 if (!dies) continue;
953 const op_int = @enumToInt(op);954 const op_int = @enumToInt(op);
954 if (op_int < Air.Inst.Ref.typed_value_map.len) continue;955 if (op_int < Air.ref_start_index) continue;
955 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);956 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
956 self.processDeath(op_index);957 self.processDeath(op_index);
957 }958 }
958 const is_used = @truncate(u1, tomb_bits) == 0;959 const is_used = @truncate(u1, tomb_bits) == 0;
...@@ -1026,31 +1027,31 @@ fn allocMem(...@@ -1026,31 +1027,31 @@ fn allocMem(
10261027
1027/// Use a pointer instruction as the basis for allocating stack memory.1028/// Use a pointer instruction as the basis for allocating stack memory.
1028fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {1029fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1030 const mod = self.bin_file.options.module.?;
1029 const elem_ty = self.air.typeOfIndex(inst).elemType();1031 const elem_ty = self.air.typeOfIndex(inst).elemType();
10301032
1031 if (!elem_ty.hasRuntimeBits()) {1033 if (!elem_ty.hasRuntimeBits(mod)) {
1032 // return the stack offset 0. Stack offset 0 will be where all1034 // return the stack offset 0. Stack offset 0 will be where all
1033 // zero-sized stack allocations live as non-zero-sized1035 // zero-sized stack allocations live as non-zero-sized
1034 // allocations will always have an offset > 0.1036 // allocations will always have an offset > 0.
1035 return @as(u32, 0);1037 return @as(u32, 0);
1036 }1038 }
10371039
1038 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {1040 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
1039 const mod = self.bin_file.options.module.?;
1040 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});1041 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
1041 };1042 };
1042 // TODO swap this for inst.ty.ptrAlign1043 // 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
1045 return self.allocMem(abi_size, abi_align, inst);1046 return self.allocMem(abi_size, abi_align, inst);
1046}1047}
10471048
1048fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {1049fn 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 {
1051 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});1052 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
1052 };1053 };
1053 const abi_align = elem_ty.abiAlignment(self.target.*);1054 const abi_align = elem_ty.abiAlignment(mod);
10541055
1055 if (reg_ok) {1056 if (reg_ok) {
1056 // Make sure the type can fit in a register before we try to allocate one.1057 // 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 {...@@ -1177,13 +1178,14 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1177 if (self.liveness.isUnused(inst))1178 if (self.liveness.isUnused(inst))
1178 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });1179 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
11791180
1181 const mod = self.bin_file.options.module.?;
1180 const operand = ty_op.operand;1182 const operand = ty_op.operand;
1181 const operand_mcv = try self.resolveInst(operand);1183 const operand_mcv = try self.resolveInst(operand);
1182 const operand_ty = self.air.typeOf(operand);1184 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
1185 const dest_ty = self.air.typeOfIndex(inst);1187 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
1188 const result: MCValue = result: {1190 const result: MCValue = result: {
1189 const operand_lock: ?RegisterLock = switch (operand_mcv) {1191 const operand_lock: ?RegisterLock = switch (operand_mcv) {
...@@ -1257,8 +1259,9 @@ fn trunc(...@@ -1257,8 +1259,9 @@ fn trunc(
1257 operand_ty: Type,1259 operand_ty: Type,
1258 dest_ty: Type,1260 dest_ty: Type,
1259) !MCValue {1261) !MCValue {
1260 const info_a = operand_ty.intInfo(self.target.*);1262 const mod = self.bin_file.options.module.?;
1261 const info_b = dest_ty.intInfo(self.target.*);1263 const info_a = operand_ty.intInfo(mod);
1264 const info_b = dest_ty.intInfo(mod);
12621265
1263 if (info_b.bits <= 64) {1266 if (info_b.bits <= 64) {
1264 const operand_reg = switch (operand) {1267 const operand_reg = switch (operand) {
...@@ -1319,6 +1322,7 @@ fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -1319,6 +1322,7 @@ fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {
13191322
1320fn airNot(self: *Self, inst: Air.Inst.Index) !void {1323fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1321 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1324 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1325 const mod = self.bin_file.options.module.?;
1322 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1326 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1323 const operand = try self.resolveInst(ty_op.operand);1327 const operand = try self.resolveInst(ty_op.operand);
1324 const operand_ty = self.air.typeOf(ty_op.operand);1328 const operand_ty = self.air.typeOf(ty_op.operand);
...@@ -1327,7 +1331,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {...@@ -1327,7 +1331,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1327 .unreach => unreachable,1331 .unreach => unreachable,
1328 .compare_flags => |cond| break :result MCValue{ .compare_flags = cond.negate() },1332 .compare_flags => |cond| break :result MCValue{ .compare_flags = cond.negate() },
1329 else => {1333 else => {
1330 switch (operand_ty.zigTypeTag()) {1334 switch (operand_ty.zigTypeTag(mod)) {
1331 .Bool => {1335 .Bool => {
1332 // TODO convert this to mvn + and1336 // TODO convert this to mvn + and
1333 const op_reg = switch (operand) {1337 const op_reg = switch (operand) {
...@@ -1361,7 +1365,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {...@@ -1361,7 +1365,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1361 },1365 },
1362 .Vector => return self.fail("TODO bitwise not for vectors", .{}),1366 .Vector => return self.fail("TODO bitwise not for vectors", .{}),
1363 .Int => {1367 .Int => {
1364 const int_info = operand_ty.intInfo(self.target.*);1368 const int_info = operand_ty.intInfo(mod);
1365 if (int_info.bits <= 64) {1369 if (int_info.bits <= 64) {
1366 const op_reg = switch (operand) {1370 const op_reg = switch (operand) {
1367 .register => |r| r,1371 .register => |r| r,
...@@ -1413,13 +1417,13 @@ fn minMax(...@@ -1413,13 +1417,13 @@ fn minMax(
1413 rhs_ty: Type,1417 rhs_ty: Type,
1414 maybe_inst: ?Air.Inst.Index,1418 maybe_inst: ?Air.Inst.Index,
1415) !MCValue {1419) !MCValue {
1416 switch (lhs_ty.zigTypeTag()) {1420 const mod = self.bin_file.options.module.?;
1421 switch (lhs_ty.zigTypeTag(mod)) {
1417 .Float => return self.fail("TODO ARM min/max on floats", .{}),1422 .Float => return self.fail("TODO ARM min/max on floats", .{}),
1418 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),1423 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),
1419 .Int => {1424 .Int => {
1420 const mod = self.bin_file.options.module.?;
1421 assert(lhs_ty.eql(rhs_ty, mod));1425 assert(lhs_ty.eql(rhs_ty, mod));
1422 const int_info = lhs_ty.intInfo(self.target.*);1426 const int_info = lhs_ty.intInfo(mod);
1423 if (int_info.bits <= 64) {1427 if (int_info.bits <= 64) {
1424 var lhs_reg: Register = undefined;1428 var lhs_reg: Register = undefined;
1425 var rhs_reg: Register = undefined;1429 var rhs_reg: Register = undefined;
...@@ -1907,12 +1911,12 @@ fn addSub(...@@ -1907,12 +1911,12 @@ fn addSub(
1907 maybe_inst: ?Air.Inst.Index,1911 maybe_inst: ?Air.Inst.Index,
1908) InnerError!MCValue {1912) InnerError!MCValue {
1909 const mod = self.bin_file.options.module.?;1913 const mod = self.bin_file.options.module.?;
1910 switch (lhs_ty.zigTypeTag()) {1914 switch (lhs_ty.zigTypeTag(mod)) {
1911 .Float => return self.fail("TODO binary operations on floats", .{}),1915 .Float => return self.fail("TODO binary operations on floats", .{}),
1912 .Vector => return self.fail("TODO binary operations on vectors", .{}),1916 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1913 .Int => {1917 .Int => {
1914 assert(lhs_ty.eql(rhs_ty, mod));1918 assert(lhs_ty.eql(rhs_ty, mod));
1915 const int_info = lhs_ty.intInfo(self.target.*);1919 const int_info = lhs_ty.intInfo(mod);
1916 if (int_info.bits <= 64) {1920 if (int_info.bits <= 64) {
1917 const lhs_immediate = try lhs_bind.resolveToImmediate(self);1921 const lhs_immediate = try lhs_bind.resolveToImmediate(self);
1918 const rhs_immediate = try rhs_bind.resolveToImmediate(self);1922 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
...@@ -1968,11 +1972,11 @@ fn mul(...@@ -1968,11 +1972,11 @@ fn mul(
1968 maybe_inst: ?Air.Inst.Index,1972 maybe_inst: ?Air.Inst.Index,
1969) InnerError!MCValue {1973) InnerError!MCValue {
1970 const mod = self.bin_file.options.module.?;1974 const mod = self.bin_file.options.module.?;
1971 switch (lhs_ty.zigTypeTag()) {1975 switch (lhs_ty.zigTypeTag(mod)) {
1972 .Vector => return self.fail("TODO binary operations on vectors", .{}),1976 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1973 .Int => {1977 .Int => {
1974 assert(lhs_ty.eql(rhs_ty, mod));1978 assert(lhs_ty.eql(rhs_ty, mod));
1975 const int_info = lhs_ty.intInfo(self.target.*);1979 const int_info = lhs_ty.intInfo(mod);
1976 if (int_info.bits <= 64) {1980 if (int_info.bits <= 64) {
1977 // TODO add optimisations for multiplication1981 // TODO add optimisations for multiplication
1978 // with immediates, for example a * 2 can be1982 // with immediates, for example a * 2 can be
...@@ -1999,7 +2003,8 @@ fn divFloat(...@@ -1999,7 +2003,8 @@ fn divFloat(
1999 _ = rhs_ty;2003 _ = rhs_ty;
2000 _ = maybe_inst;2004 _ = maybe_inst;
20012005
2002 switch (lhs_ty.zigTypeTag()) {2006 const mod = self.bin_file.options.module.?;
2007 switch (lhs_ty.zigTypeTag(mod)) {
2003 .Float => return self.fail("TODO div_float", .{}),2008 .Float => return self.fail("TODO div_float", .{}),
2004 .Vector => return self.fail("TODO div_float on vectors", .{}),2009 .Vector => return self.fail("TODO div_float on vectors", .{}),
2005 else => unreachable,2010 else => unreachable,
...@@ -2015,12 +2020,12 @@ fn divTrunc(...@@ -2015,12 +2020,12 @@ fn divTrunc(
2015 maybe_inst: ?Air.Inst.Index,2020 maybe_inst: ?Air.Inst.Index,
2016) InnerError!MCValue {2021) InnerError!MCValue {
2017 const mod = self.bin_file.options.module.?;2022 const mod = self.bin_file.options.module.?;
2018 switch (lhs_ty.zigTypeTag()) {2023 switch (lhs_ty.zigTypeTag(mod)) {
2019 .Float => return self.fail("TODO div on floats", .{}),2024 .Float => return self.fail("TODO div on floats", .{}),
2020 .Vector => return self.fail("TODO div on vectors", .{}),2025 .Vector => return self.fail("TODO div on vectors", .{}),
2021 .Int => {2026 .Int => {
2022 assert(lhs_ty.eql(rhs_ty, mod));2027 assert(lhs_ty.eql(rhs_ty, mod));
2023 const int_info = lhs_ty.intInfo(self.target.*);2028 const int_info = lhs_ty.intInfo(mod);
2024 if (int_info.bits <= 64) {2029 if (int_info.bits <= 64) {
2025 switch (int_info.signedness) {2030 switch (int_info.signedness) {
2026 .signed => {2031 .signed => {
...@@ -2049,12 +2054,12 @@ fn divFloor(...@@ -2049,12 +2054,12 @@ fn divFloor(
2049 maybe_inst: ?Air.Inst.Index,2054 maybe_inst: ?Air.Inst.Index,
2050) InnerError!MCValue {2055) InnerError!MCValue {
2051 const mod = self.bin_file.options.module.?;2056 const mod = self.bin_file.options.module.?;
2052 switch (lhs_ty.zigTypeTag()) {2057 switch (lhs_ty.zigTypeTag(mod)) {
2053 .Float => return self.fail("TODO div on floats", .{}),2058 .Float => return self.fail("TODO div on floats", .{}),
2054 .Vector => return self.fail("TODO div on vectors", .{}),2059 .Vector => return self.fail("TODO div on vectors", .{}),
2055 .Int => {2060 .Int => {
2056 assert(lhs_ty.eql(rhs_ty, mod));2061 assert(lhs_ty.eql(rhs_ty, mod));
2057 const int_info = lhs_ty.intInfo(self.target.*);2062 const int_info = lhs_ty.intInfo(mod);
2058 if (int_info.bits <= 64) {2063 if (int_info.bits <= 64) {
2059 switch (int_info.signedness) {2064 switch (int_info.signedness) {
2060 .signed => {2065 .signed => {
...@@ -2082,12 +2087,12 @@ fn divExact(...@@ -2082,12 +2087,12 @@ fn divExact(
2082 maybe_inst: ?Air.Inst.Index,2087 maybe_inst: ?Air.Inst.Index,
2083) InnerError!MCValue {2088) InnerError!MCValue {
2084 const mod = self.bin_file.options.module.?;2089 const mod = self.bin_file.options.module.?;
2085 switch (lhs_ty.zigTypeTag()) {2090 switch (lhs_ty.zigTypeTag(mod)) {
2086 .Float => return self.fail("TODO div on floats", .{}),2091 .Float => return self.fail("TODO div on floats", .{}),
2087 .Vector => return self.fail("TODO div on vectors", .{}),2092 .Vector => return self.fail("TODO div on vectors", .{}),
2088 .Int => {2093 .Int => {
2089 assert(lhs_ty.eql(rhs_ty, mod));2094 assert(lhs_ty.eql(rhs_ty, mod));
2090 const int_info = lhs_ty.intInfo(self.target.*);2095 const int_info = lhs_ty.intInfo(mod);
2091 if (int_info.bits <= 64) {2096 if (int_info.bits <= 64) {
2092 switch (int_info.signedness) {2097 switch (int_info.signedness) {
2093 .signed => {2098 .signed => {
...@@ -2118,12 +2123,12 @@ fn rem(...@@ -2118,12 +2123,12 @@ fn rem(
2118 _ = maybe_inst;2123 _ = maybe_inst;
21192124
2120 const mod = self.bin_file.options.module.?;2125 const mod = self.bin_file.options.module.?;
2121 switch (lhs_ty.zigTypeTag()) {2126 switch (lhs_ty.zigTypeTag(mod)) {
2122 .Float => return self.fail("TODO rem/mod on floats", .{}),2127 .Float => return self.fail("TODO rem/mod on floats", .{}),
2123 .Vector => return self.fail("TODO rem/mod on vectors", .{}),2128 .Vector => return self.fail("TODO rem/mod on vectors", .{}),
2124 .Int => {2129 .Int => {
2125 assert(lhs_ty.eql(rhs_ty, mod));2130 assert(lhs_ty.eql(rhs_ty, mod));
2126 const int_info = lhs_ty.intInfo(self.target.*);2131 const int_info = lhs_ty.intInfo(mod);
2127 if (int_info.bits <= 64) {2132 if (int_info.bits <= 64) {
2128 var lhs_reg: Register = undefined;2133 var lhs_reg: Register = undefined;
2129 var rhs_reg: Register = undefined;2134 var rhs_reg: Register = undefined;
...@@ -2188,7 +2193,8 @@ fn modulo(...@@ -2188,7 +2193,8 @@ fn modulo(
2188 _ = rhs_ty;2193 _ = rhs_ty;
2189 _ = maybe_inst;2194 _ = maybe_inst;
21902195
2191 switch (lhs_ty.zigTypeTag()) {2196 const mod = self.bin_file.options.module.?;
2197 switch (lhs_ty.zigTypeTag(mod)) {
2192 .Float => return self.fail("TODO mod on floats", .{}),2198 .Float => return self.fail("TODO mod on floats", .{}),
2193 .Vector => return self.fail("TODO mod on vectors", .{}),2199 .Vector => return self.fail("TODO mod on vectors", .{}),
2194 .Int => return self.fail("TODO mod on ints", .{}),2200 .Int => return self.fail("TODO mod on ints", .{}),
...@@ -2205,10 +2211,11 @@ fn wrappingArithmetic(...@@ -2205,10 +2211,11 @@ fn wrappingArithmetic(
2205 rhs_ty: Type,2211 rhs_ty: Type,
2206 maybe_inst: ?Air.Inst.Index,2212 maybe_inst: ?Air.Inst.Index,
2207) InnerError!MCValue {2213) InnerError!MCValue {
2208 switch (lhs_ty.zigTypeTag()) {2214 const mod = self.bin_file.options.module.?;
2215 switch (lhs_ty.zigTypeTag(mod)) {
2209 .Vector => return self.fail("TODO binary operations on vectors", .{}),2216 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2210 .Int => {2217 .Int => {
2211 const int_info = lhs_ty.intInfo(self.target.*);2218 const int_info = lhs_ty.intInfo(mod);
2212 if (int_info.bits <= 64) {2219 if (int_info.bits <= 64) {
2213 // Generate an add/sub/mul2220 // Generate an add/sub/mul
2214 const result: MCValue = switch (tag) {2221 const result: MCValue = switch (tag) {
...@@ -2240,11 +2247,11 @@ fn bitwise(...@@ -2240,11 +2247,11 @@ fn bitwise(
2240 maybe_inst: ?Air.Inst.Index,2247 maybe_inst: ?Air.Inst.Index,
2241) InnerError!MCValue {2248) InnerError!MCValue {
2242 const mod = self.bin_file.options.module.?;2249 const mod = self.bin_file.options.module.?;
2243 switch (lhs_ty.zigTypeTag()) {2250 switch (lhs_ty.zigTypeTag(mod)) {
2244 .Vector => return self.fail("TODO binary operations on vectors", .{}),2251 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2245 .Int => {2252 .Int => {
2246 assert(lhs_ty.eql(rhs_ty, mod));2253 assert(lhs_ty.eql(rhs_ty, mod));
2247 const int_info = lhs_ty.intInfo(self.target.*);2254 const int_info = lhs_ty.intInfo(mod);
2248 if (int_info.bits <= 64) {2255 if (int_info.bits <= 64) {
2249 // TODO implement bitwise operations with immediates2256 // TODO implement bitwise operations with immediates
2250 const mir_tag: Mir.Inst.Tag = switch (tag) {2257 const mir_tag: Mir.Inst.Tag = switch (tag) {
...@@ -2274,10 +2281,11 @@ fn shiftExact(...@@ -2274,10 +2281,11 @@ fn shiftExact(
2274) InnerError!MCValue {2281) InnerError!MCValue {
2275 _ = rhs_ty;2282 _ = rhs_ty;
22762283
2277 switch (lhs_ty.zigTypeTag()) {2284 const mod = self.bin_file.options.module.?;
2285 switch (lhs_ty.zigTypeTag(mod)) {
2278 .Vector => return self.fail("TODO binary operations on vectors", .{}),2286 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2279 .Int => {2287 .Int => {
2280 const int_info = lhs_ty.intInfo(self.target.*);2288 const int_info = lhs_ty.intInfo(mod);
2281 if (int_info.bits <= 64) {2289 if (int_info.bits <= 64) {
2282 const rhs_immediate = try rhs_bind.resolveToImmediate(self);2290 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
22832291
...@@ -2323,10 +2331,11 @@ fn shiftNormal(...@@ -2323,10 +2331,11 @@ fn shiftNormal(
2323 rhs_ty: Type,2331 rhs_ty: Type,
2324 maybe_inst: ?Air.Inst.Index,2332 maybe_inst: ?Air.Inst.Index,
2325) InnerError!MCValue {2333) InnerError!MCValue {
2326 switch (lhs_ty.zigTypeTag()) {2334 const mod = self.bin_file.options.module.?;
2335 switch (lhs_ty.zigTypeTag(mod)) {
2327 .Vector => return self.fail("TODO binary operations on vectors", .{}),2336 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2328 .Int => {2337 .Int => {
2329 const int_info = lhs_ty.intInfo(self.target.*);2338 const int_info = lhs_ty.intInfo(mod);
2330 if (int_info.bits <= 64) {2339 if (int_info.bits <= 64) {
2331 // Generate a shl_exact/shr_exact2340 // Generate a shl_exact/shr_exact
2332 const result: MCValue = switch (tag) {2341 const result: MCValue = switch (tag) {
...@@ -2362,7 +2371,8 @@ fn booleanOp(...@@ -2362,7 +2371,8 @@ fn booleanOp(
2362 rhs_ty: Type,2371 rhs_ty: Type,
2363 maybe_inst: ?Air.Inst.Index,2372 maybe_inst: ?Air.Inst.Index,
2364) InnerError!MCValue {2373) InnerError!MCValue {
2365 switch (lhs_ty.zigTypeTag()) {2374 const mod = self.bin_file.options.module.?;
2375 switch (lhs_ty.zigTypeTag(mod)) {
2366 .Bool => {2376 .Bool => {
2367 assert((try lhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema2377 assert((try lhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema
2368 assert((try rhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema2378 assert((try rhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema
...@@ -2388,9 +2398,9 @@ fn ptrArithmetic(...@@ -2388,9 +2398,9 @@ fn ptrArithmetic(
2388 rhs_ty: Type,2398 rhs_ty: Type,
2389 maybe_inst: ?Air.Inst.Index,2399 maybe_inst: ?Air.Inst.Index,
2390) InnerError!MCValue {2400) InnerError!MCValue {
2391 switch (lhs_ty.zigTypeTag()) {2401 const mod = self.bin_file.options.module.?;
2402 switch (lhs_ty.zigTypeTag(mod)) {
2392 .Pointer => {2403 .Pointer => {
2393 const mod = self.bin_file.options.module.?;
2394 assert(rhs_ty.eql(Type.usize, mod));2404 assert(rhs_ty.eql(Type.usize, mod));
23952405
2396 const ptr_ty = lhs_ty;2406 const ptr_ty = lhs_ty;
...@@ -2398,7 +2408,7 @@ fn ptrArithmetic(...@@ -2398,7 +2408,7 @@ fn ptrArithmetic(
2398 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type2408 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type
2399 else => ptr_ty.childType(),2409 else => ptr_ty.childType(),
2400 };2410 };
2401 const elem_size = elem_ty.abiSize(self.target.*);2411 const elem_size = elem_ty.abiSize(mod);
24022412
2403 const base_tag: Air.Inst.Tag = switch (tag) {2413 const base_tag: Air.Inst.Tag = switch (tag) {
2404 .ptr_add => .add,2414 .ptr_add => .add,
...@@ -2511,6 +2521,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2511,6 +2521,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
2511 const tag = self.air.instructions.items(.tag)[inst];2521 const tag = self.air.instructions.items(.tag)[inst];
2512 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2522 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2513 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;2523 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2524 const mod = self.bin_file.options.module.?;
2514 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2525 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2515 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };2526 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
2516 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };2527 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
...@@ -2518,16 +2529,15 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2518,16 +2529,15 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
2518 const rhs_ty = self.air.typeOf(extra.rhs);2529 const rhs_ty = self.air.typeOf(extra.rhs);
25192530
2520 const tuple_ty = self.air.typeOfIndex(inst);2531 const tuple_ty = self.air.typeOfIndex(inst);
2521 const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*));2532 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
2522 const tuple_align = tuple_ty.abiAlignment(self.target.*);2533 const tuple_align = tuple_ty.abiAlignment(mod);
2523 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, self.target.*));2534 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
25242535
2525 switch (lhs_ty.zigTypeTag()) {2536 switch (lhs_ty.zigTypeTag(mod)) {
2526 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),2537 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),
2527 .Int => {2538 .Int => {
2528 const mod = self.bin_file.options.module.?;
2529 assert(lhs_ty.eql(rhs_ty, mod));2539 assert(lhs_ty.eql(rhs_ty, mod));
2530 const int_info = lhs_ty.intInfo(self.target.*);2540 const int_info = lhs_ty.intInfo(mod);
2531 switch (int_info.bits) {2541 switch (int_info.bits) {
2532 1...31, 33...63 => {2542 1...31, 33...63 => {
2533 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);2543 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);
...@@ -2639,24 +2649,23 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2639,24 +2649,23 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2639 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2649 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2640 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;2650 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2641 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });2651 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
2652 const mod = self.bin_file.options.module.?;
2642 const result: MCValue = result: {2653 const result: MCValue = result: {
2643 const mod = self.bin_file.options.module.?;
2644
2645 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };2654 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
2646 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };2655 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
2647 const lhs_ty = self.air.typeOf(extra.lhs);2656 const lhs_ty = self.air.typeOf(extra.lhs);
2648 const rhs_ty = self.air.typeOf(extra.rhs);2657 const rhs_ty = self.air.typeOf(extra.rhs);
26492658
2650 const tuple_ty = self.air.typeOfIndex(inst);2659 const tuple_ty = self.air.typeOfIndex(inst);
2651 const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*));2660 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
2652 const tuple_align = tuple_ty.abiAlignment(self.target.*);2661 const tuple_align = tuple_ty.abiAlignment(mod);
2653 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, self.target.*));2662 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
26542663
2655 switch (lhs_ty.zigTypeTag()) {2664 switch (lhs_ty.zigTypeTag(mod)) {
2656 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),2665 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
2657 .Int => {2666 .Int => {
2658 assert(lhs_ty.eql(rhs_ty, mod));2667 assert(lhs_ty.eql(rhs_ty, mod));
2659 const int_info = lhs_ty.intInfo(self.target.*);2668 const int_info = lhs_ty.intInfo(mod);
2660 if (int_info.bits <= 32) {2669 if (int_info.bits <= 32) {
2661 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);2670 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 {...@@ -2864,6 +2873,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2864 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2873 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2865 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;2874 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2866 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });2875 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
2876 const mod = self.bin_file.options.module.?;
2867 const result: MCValue = result: {2877 const result: MCValue = result: {
2868 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };2878 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
2869 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };2879 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
...@@ -2871,14 +2881,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2871,14 +2881,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2871 const rhs_ty = self.air.typeOf(extra.rhs);2881 const rhs_ty = self.air.typeOf(extra.rhs);
28722882
2873 const tuple_ty = self.air.typeOfIndex(inst);2883 const tuple_ty = self.air.typeOfIndex(inst);
2874 const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*));2884 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
2875 const tuple_align = tuple_ty.abiAlignment(self.target.*);2885 const tuple_align = tuple_ty.abiAlignment(mod);
2876 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, self.target.*));2886 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
28772887
2878 switch (lhs_ty.zigTypeTag()) {2888 switch (lhs_ty.zigTypeTag(mod)) {
2879 .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}),2889 .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}),
2880 .Int => {2890 .Int => {
2881 const int_info = lhs_ty.intInfo(self.target.*);2891 const int_info = lhs_ty.intInfo(mod);
2882 if (int_info.bits <= 64) {2892 if (int_info.bits <= 64) {
2883 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);2893 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 {...@@ -3011,10 +3021,11 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
3011}3021}
30123022
3013fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: Type) !MCValue {3023fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: Type) !MCValue {
3024 const mod = self.bin_file.options.module.?;
3014 var opt_buf: Type.Payload.ElemType = undefined;3025 var opt_buf: Type.Payload.ElemType = undefined;
3015 const payload_ty = optional_ty.optionalChild(&opt_buf);3026 const payload_ty = optional_ty.optionalChild(&opt_buf);
3016 if (!payload_ty.hasRuntimeBits()) return MCValue.none;3027 if (!payload_ty.hasRuntimeBits(mod)) return MCValue.none;
3017 if (optional_ty.isPtrLikeOptional()) {3028 if (optional_ty.isPtrLikeOptional(mod)) {
3018 // TODO should we reuse the operand here?3029 // TODO should we reuse the operand here?
3019 const raw_reg = try self.register_manager.allocReg(inst, gp);3030 const raw_reg = try self.register_manager.allocReg(inst, gp);
3020 const reg = self.registerAlias(raw_reg, payload_ty);3031 const reg = self.registerAlias(raw_reg, payload_ty);
...@@ -3055,16 +3066,17 @@ fn errUnionErr(...@@ -3055,16 +3066,17 @@ fn errUnionErr(
3055 error_union_ty: Type,3066 error_union_ty: Type,
3056 maybe_inst: ?Air.Inst.Index,3067 maybe_inst: ?Air.Inst.Index,
3057) !MCValue {3068) !MCValue {
3069 const mod = self.bin_file.options.module.?;
3058 const err_ty = error_union_ty.errorUnionSet();3070 const err_ty = error_union_ty.errorUnionSet();
3059 const payload_ty = error_union_ty.errorUnionPayload();3071 const payload_ty = error_union_ty.errorUnionPayload();
3060 if (err_ty.errorSetIsEmpty()) {3072 if (err_ty.errorSetIsEmpty()) {
3061 return MCValue{ .immediate = 0 };3073 return MCValue{ .immediate = 0 };
3062 }3074 }
3063 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3075 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3064 return try error_union_bind.resolveToMcv(self);3076 return try error_union_bind.resolveToMcv(self);
3065 }3077 }
30663078
3067 const err_offset = @intCast(u32, errUnionErrorOffset(payload_ty, self.target.*));3079 const err_offset = @intCast(u32, errUnionErrorOffset(payload_ty, mod));
3068 switch (try error_union_bind.resolveToMcv(self)) {3080 switch (try error_union_bind.resolveToMcv(self)) {
3069 .register => {3081 .register => {
3070 var operand_reg: Register = undefined;3082 var operand_reg: Register = undefined;
...@@ -3086,7 +3098,7 @@ fn errUnionErr(...@@ -3086,7 +3098,7 @@ fn errUnionErr(
3086 );3098 );
30873099
3088 const err_bit_offset = err_offset * 8;3100 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
3091 _ = try self.addInst(.{3103 _ = try self.addInst(.{
3092 .tag = .ubfx, // errors are unsigned integers3104 .tag = .ubfx, // errors are unsigned integers
...@@ -3134,16 +3146,17 @@ fn errUnionPayload(...@@ -3134,16 +3146,17 @@ fn errUnionPayload(
3134 error_union_ty: Type,3146 error_union_ty: Type,
3135 maybe_inst: ?Air.Inst.Index,3147 maybe_inst: ?Air.Inst.Index,
3136) !MCValue {3148) !MCValue {
3149 const mod = self.bin_file.options.module.?;
3137 const err_ty = error_union_ty.errorUnionSet();3150 const err_ty = error_union_ty.errorUnionSet();
3138 const payload_ty = error_union_ty.errorUnionPayload();3151 const payload_ty = error_union_ty.errorUnionPayload();
3139 if (err_ty.errorSetIsEmpty()) {3152 if (err_ty.errorSetIsEmpty()) {
3140 return try error_union_bind.resolveToMcv(self);3153 return try error_union_bind.resolveToMcv(self);
3141 }3154 }
3142 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3155 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3143 return MCValue.none;3156 return MCValue.none;
3144 }3157 }
31453158
3146 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, self.target.*));3159 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, mod));
3147 switch (try error_union_bind.resolveToMcv(self)) {3160 switch (try error_union_bind.resolveToMcv(self)) {
3148 .register => {3161 .register => {
3149 var operand_reg: Register = undefined;3162 var operand_reg: Register = undefined;
...@@ -3165,10 +3178,10 @@ fn errUnionPayload(...@@ -3165,10 +3178,10 @@ fn errUnionPayload(
3165 );3178 );
31663179
3167 const payload_bit_offset = payload_offset * 8;3180 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
3170 _ = try self.addInst(.{3183 _ = 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,
3172 .data = .{3185 .data = .{
3173 .rr_lsb_width = .{3186 .rr_lsb_width = .{
3174 // Set both registers to the X variant to get the full width3187 // 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 {...@@ -3245,6 +3258,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
3245}3258}
32463259
3247fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {3260fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3261 const mod = self.bin_file.options.module.?;
3248 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3262 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
32493263
3250 if (self.liveness.isUnused(inst)) {3264 if (self.liveness.isUnused(inst)) {
...@@ -3253,7 +3267,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -3253,7 +3267,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
32533267
3254 const result: MCValue = result: {3268 const result: MCValue = result: {
3255 const payload_ty = self.air.typeOf(ty_op.operand);3269 const payload_ty = self.air.typeOf(ty_op.operand);
3256 if (!payload_ty.hasRuntimeBits()) {3270 if (!payload_ty.hasRuntimeBits(mod)) {
3257 break :result MCValue{ .immediate = 1 };3271 break :result MCValue{ .immediate = 1 };
3258 }3272 }
32593273
...@@ -3265,7 +3279,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -3265,7 +3279,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3265 };3279 };
3266 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);3280 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
32673281
3268 if (optional_ty.isPtrLikeOptional()) {3282 if (optional_ty.isPtrLikeOptional(mod)) {
3269 // TODO should we check if we can reuse the operand?3283 // TODO should we check if we can reuse the operand?
3270 const raw_reg = try self.register_manager.allocReg(inst, gp);3284 const raw_reg = try self.register_manager.allocReg(inst, gp);
3271 const reg = self.registerAlias(raw_reg, payload_ty);3285 const reg = self.registerAlias(raw_reg, payload_ty);
...@@ -3273,9 +3287,9 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -3273,9 +3287,9 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3273 break :result MCValue{ .register = reg };3287 break :result MCValue{ .register = reg };
3274 }3288 }
32753289
3276 const optional_abi_size = @intCast(u32, optional_ty.abiSize(self.target.*));3290 const optional_abi_size = @intCast(u32, optional_ty.abiSize(mod));
3277 const optional_abi_align = optional_ty.abiAlignment(self.target.*);3291 const optional_abi_align = optional_ty.abiAlignment(mod);
3278 const offset = @intCast(u32, payload_ty.abiSize(self.target.*));3292 const offset = @intCast(u32, payload_ty.abiSize(mod));
32793293
3280 const stack_offset = try self.allocMem(optional_abi_size, optional_abi_align, inst);3294 const stack_offset = try self.allocMem(optional_abi_size, optional_abi_align, inst);
3281 try self.genSetStack(payload_ty, stack_offset, operand);3295 try self.genSetStack(payload_ty, stack_offset, operand);
...@@ -3289,19 +3303,20 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -3289,19 +3303,20 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
32893303
3290/// T to E!T3304/// T to E!T
3291fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {3305fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3306 const mod = self.bin_file.options.module.?;
3292 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3307 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3293 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3308 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3294 const error_union_ty = self.air.getRefType(ty_op.ty);3309 const error_union_ty = self.air.getRefType(ty_op.ty);
3295 const error_ty = error_union_ty.errorUnionSet();3310 const error_ty = error_union_ty.errorUnionSet();
3296 const payload_ty = error_union_ty.errorUnionPayload();3311 const payload_ty = error_union_ty.errorUnionPayload();
3297 const operand = try self.resolveInst(ty_op.operand);3312 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.*));3315 const abi_size = @intCast(u32, error_union_ty.abiSize(mod));
3301 const abi_align = error_union_ty.abiAlignment(self.target.*);3316 const abi_align = error_union_ty.abiAlignment(mod);
3302 const stack_offset = try self.allocMem(abi_size, abi_align, inst);3317 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
3303 const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);3318 const payload_off = errUnionPayloadOffset(payload_ty, mod);
3304 const err_off = errUnionErrorOffset(payload_ty, self.target.*);3319 const err_off = errUnionErrorOffset(payload_ty, mod);
3305 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), operand);3320 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), operand);
3306 try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), .{ .immediate = 0 });3321 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 {...@@ -3314,17 +3329,18 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3314fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {3329fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3315 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3330 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3316 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3331 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3332 const mod = self.bin_file.options.module.?;
3317 const error_union_ty = self.air.getRefType(ty_op.ty);3333 const error_union_ty = self.air.getRefType(ty_op.ty);
3318 const error_ty = error_union_ty.errorUnionSet();3334 const error_ty = error_union_ty.errorUnionSet();
3319 const payload_ty = error_union_ty.errorUnionPayload();3335 const payload_ty = error_union_ty.errorUnionPayload();
3320 const operand = try self.resolveInst(ty_op.operand);3336 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.*));3339 const abi_size = @intCast(u32, error_union_ty.abiSize(mod));
3324 const abi_align = error_union_ty.abiAlignment(self.target.*);3340 const abi_align = error_union_ty.abiAlignment(mod);
3325 const stack_offset = try self.allocMem(abi_size, abi_align, inst);3341 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
3326 const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);3342 const payload_off = errUnionPayloadOffset(payload_ty, mod);
3327 const err_off = errUnionErrorOffset(payload_ty, self.target.*);3343 const err_off = errUnionErrorOffset(payload_ty, mod);
3328 try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), operand);3344 try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), operand);
3329 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), .undef);3345 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), .undef);
33303346
...@@ -3440,8 +3456,9 @@ fn ptrElemVal(...@@ -3440,8 +3456,9 @@ fn ptrElemVal(
3440 ptr_ty: Type,3456 ptr_ty: Type,
3441 maybe_inst: ?Air.Inst.Index,3457 maybe_inst: ?Air.Inst.Index,
3442) !MCValue {3458) !MCValue {
3459 const mod = self.bin_file.options.module.?;
3443 const elem_ty = ptr_ty.childType();3460 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
3446 // TODO optimize for elem_sizes of 1, 2, 4, 83463 // TODO optimize for elem_sizes of 1, 2, 4, 8
3447 switch (elem_size) {3464 switch (elem_size) {
...@@ -3597,8 +3614,9 @@ fn reuseOperand(...@@ -3597,8 +3614,9 @@ fn reuseOperand(
3597}3614}
35983615
3599fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {3616fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
3617 const mod = self.bin_file.options.module.?;
3600 const elem_ty = ptr_ty.elemType();3618 const elem_ty = ptr_ty.elemType();
3601 const elem_size = elem_ty.abiSize(self.target.*);3619 const elem_size = elem_ty.abiSize(mod);
36023620
3603 switch (ptr) {3621 switch (ptr) {
3604 .none => unreachable,3622 .none => unreachable,
...@@ -3846,9 +3864,10 @@ fn genInlineMemsetCode(...@@ -3846,9 +3864,10 @@ fn genInlineMemsetCode(
3846fn airLoad(self: *Self, inst: Air.Inst.Index) !void {3864fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
3847 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3865 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3848 const elem_ty = self.air.typeOfIndex(inst);3866 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);
3850 const result: MCValue = result: {3869 const result: MCValue = result: {
3851 if (!elem_ty.hasRuntimeBits())3870 if (!elem_ty.hasRuntimeBits(mod))
3852 break :result MCValue.none;3871 break :result MCValue.none;
38533872
3854 const ptr = try self.resolveInst(ty_op.operand);3873 const ptr = try self.resolveInst(ty_op.operand);
...@@ -3874,11 +3893,12 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -3874,11 +3893,12 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
3874}3893}
38753894
3876fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void {3895fn 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
3879 const tag: Mir.Inst.Tag = switch (abi_size) {3899 const tag: Mir.Inst.Tag = switch (abi_size) {
3880 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb_immediate else .ldrb_immediate,3900 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_immediate else .ldrb_immediate,
3881 2 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsh_immediate else .ldrh_immediate,3901 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh_immediate else .ldrh_immediate,
3882 4 => .ldr_immediate,3902 4 => .ldr_immediate,
3883 8 => .ldr_immediate,3903 8 => .ldr_immediate,
3884 3, 5, 6, 7 => return self.fail("TODO: genLdrRegister for more abi_sizes", .{}),3904 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...@@ -3896,7 +3916,8 @@ fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type
3896}3916}
38973917
3898fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void {3918fn 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
3901 const tag: Mir.Inst.Tag = switch (abi_size) {3922 const tag: Mir.Inst.Tag = switch (abi_size) {
3902 1 => .strb_immediate,3923 1 => .strb_immediate,
...@@ -3917,8 +3938,9 @@ fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type...@@ -3917,8 +3938,9 @@ fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type
3917}3938}
39183939
3919fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {3940fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
3941 const mod = self.bin_file.options.module.?;
3920 log.debug("store: storing {} to {}", .{ value, ptr });3942 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
3923 switch (ptr) {3945 switch (ptr) {
3924 .none => unreachable,3946 .none => unreachable,
...@@ -4069,10 +4091,11 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {...@@ -4069,10 +4091,11 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
40694091
4070fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {4092fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
4071 return if (self.liveness.isUnused(inst)) .dead else result: {4093 return if (self.liveness.isUnused(inst)) .dead else result: {
4094 const mod = self.bin_file.options.module.?;
4072 const mcv = try self.resolveInst(operand);4095 const mcv = try self.resolveInst(operand);
4073 const ptr_ty = self.air.typeOf(operand);4096 const ptr_ty = self.air.typeOf(operand);
4074 const struct_ty = ptr_ty.childType();4097 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));
4076 switch (mcv) {4099 switch (mcv) {
4077 .ptr_stack_offset => |off| {4100 .ptr_stack_offset => |off| {
4078 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };4101 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
...@@ -4093,10 +4116,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4093,10 +4116,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
4093 const operand = extra.struct_operand;4116 const operand = extra.struct_operand;
4094 const index = extra.field_index;4117 const index = extra.field_index;
4095 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4118 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4119 const mod = self.bin_file.options.module.?;
4096 const mcv = try self.resolveInst(operand);4120 const mcv = try self.resolveInst(operand);
4097 const struct_ty = self.air.typeOf(operand);4121 const struct_ty = self.air.typeOf(operand);
4098 const struct_field_ty = struct_ty.structFieldType(index);4122 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
4101 switch (mcv) {4125 switch (mcv) {
4102 .dead, .unreach => unreachable,4126 .dead, .unreach => unreachable,
...@@ -4142,12 +4166,13 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4142,12 +4166,13 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
4142}4166}
41434167
4144fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {4168fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
4169 const mod = self.bin_file.options.module.?;
4145 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;4170 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
4146 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;4171 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
4147 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4172 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4148 const field_ptr = try self.resolveInst(extra.field_ptr);4173 const field_ptr = try self.resolveInst(extra.field_ptr);
4149 const struct_ty = self.air.getRefType(ty_pl.ty).childType();4174 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));
4151 switch (field_ptr) {4176 switch (field_ptr) {
4152 .ptr_stack_offset => |off| {4177 .ptr_stack_offset => |off| {
4153 break :result MCValue{ .ptr_stack_offset = off + struct_field_offset };4178 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...@@ -4223,8 +4248,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4223 const extra = self.air.extraData(Air.Call, pl_op.payload);4248 const extra = self.air.extraData(Air.Call, pl_op.payload);
4224 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);4249 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
4225 const ty = self.air.typeOf(callee);4250 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)) {
4228 .Fn => ty,4254 .Fn => ty,
4229 .Pointer => ty.childType(),4255 .Pointer => ty.childType(),
4230 else => unreachable,4256 else => unreachable,
...@@ -4246,8 +4272,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4246,8 +4272,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4246 if (info.return_value == .stack_offset) {4272 if (info.return_value == .stack_offset) {
4247 log.debug("airCall: return by reference", .{});4273 log.debug("airCall: return by reference", .{});
4248 const ret_ty = fn_ty.fnReturnType();4274 const ret_ty = fn_ty.fnReturnType();
4249 const ret_abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));4275 const ret_abi_size = @intCast(u32, ret_ty.abiSize(mod));
4250 const ret_abi_align = @intCast(u32, ret_ty.abiAlignment(self.target.*));4276 const ret_abi_align = @intCast(u32, ret_ty.abiAlignment(mod));
4251 const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst);4277 const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst);
42524278
4253 const ret_ptr_reg = self.registerAlias(.x0, Type.usize);4279 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...@@ -4289,8 +4315,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42894315
4290 // Due to incremental compilation, how function calls are generated depends4316 // Due to incremental compilation, how function calls are generated depends
4291 // on linking.4317 // on linking.
4292 const mod = self.bin_file.options.module.?;4318 if (self.air.value(callee, mod)) |func_value| {
4293 if (self.air.value(callee)) |func_value| {
4294 if (func_value.castTag(.function)) |func_payload| {4319 if (func_value.castTag(.function)) |func_payload| {
4295 const func = func_payload.data;4320 const func = func_payload.data;
42964321
...@@ -4369,7 +4394,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4369,7 +4394,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4369 return self.fail("TODO implement calling bitcasted functions", .{});4394 return self.fail("TODO implement calling bitcasted functions", .{});
4370 }4395 }
4371 } else {4396 } else {
4372 assert(ty.zigTypeTag() == .Pointer);4397 assert(ty.zigTypeTag(mod) == .Pointer);
4373 const mcv = try self.resolveInst(callee);4398 const mcv = try self.resolveInst(callee);
4374 try self.genSetReg(ty, .x30, mcv);4399 try self.genSetReg(ty, .x30, mcv);
43754400
...@@ -4410,11 +4435,12 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {...@@ -4410,11 +4435,12 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4410 const un_op = self.air.instructions.items(.data)[inst].un_op;4435 const un_op = self.air.instructions.items(.data)[inst].un_op;
4411 const operand = try self.resolveInst(un_op);4436 const operand = try self.resolveInst(un_op);
4412 const ret_ty = self.fn_type.fnReturnType();4437 const ret_ty = self.fn_type.fnReturnType();
4438 const mod = self.bin_file.options.module.?;
44134439
4414 switch (self.ret_mcv) {4440 switch (self.ret_mcv) {
4415 .none => {},4441 .none => {},
4416 .immediate => {4442 .immediate => {
4417 assert(ret_ty.isError());4443 assert(ret_ty.isError(mod));
4418 },4444 },
4419 .register => |reg| {4445 .register => |reg| {
4420 // Return result by value4446 // Return result by value
...@@ -4465,8 +4491,9 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -4465,8 +4491,9 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
4465 // location.4491 // location.
4466 const op_inst = Air.refToIndex(un_op).?;4492 const op_inst = Air.refToIndex(un_op).?;
4467 if (self.air.instructions.items(.tag)[op_inst] != .ret_ptr) {4493 if (self.air.instructions.items(.tag)[op_inst] != .ret_ptr) {
4468 const abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));4494 const mod = self.bin_file.options.module.?;
4469 const abi_align = ret_ty.abiAlignment(self.target.*);4495 const abi_size = @intCast(u32, ret_ty.abiSize(mod));
4496 const abi_align = ret_ty.abiAlignment(mod);
44704497
4471 const offset = try self.allocMem(abi_size, abi_align, null);4498 const offset = try self.allocMem(abi_size, abi_align, null);
44724499
...@@ -4501,21 +4528,21 @@ fn cmp(...@@ -4501,21 +4528,21 @@ fn cmp(
4501 lhs_ty: Type,4528 lhs_ty: Type,
4502 op: math.CompareOperator,4529 op: math.CompareOperator,
4503) !MCValue {4530) !MCValue {
4504 var int_buffer: Type.Payload.Bits = undefined;4531 const mod = self.bin_file.options.module.?;
4505 const int_ty = switch (lhs_ty.zigTypeTag()) {4532 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
4506 .Optional => blk: {4533 .Optional => blk: {
4507 var opt_buffer: Type.Payload.ElemType = undefined;4534 var opt_buffer: Type.Payload.ElemType = undefined;
4508 const payload_ty = lhs_ty.optionalChild(&opt_buffer);4535 const payload_ty = lhs_ty.optionalChild(&opt_buffer);
4509 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {4536 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4510 break :blk Type.initTag(.u1);4537 break :blk Type.initTag(.u1);
4511 } else if (lhs_ty.isPtrLikeOptional()) {4538 } else if (lhs_ty.isPtrLikeOptional(mod)) {
4512 break :blk Type.usize;4539 break :blk Type.usize;
4513 } else {4540 } else {
4514 return self.fail("TODO ARM cmp non-pointer optionals", .{});4541 return self.fail("TODO ARM cmp non-pointer optionals", .{});
4515 }4542 }
4516 },4543 },
4517 .Float => return self.fail("TODO ARM cmp floats", .{}),4544 .Float => return self.fail("TODO ARM cmp floats", .{}),
4518 .Enum => lhs_ty.intTagType(&int_buffer),4545 .Enum => lhs_ty.intTagType(),
4519 .Int => lhs_ty,4546 .Int => lhs_ty,
4520 .Bool => Type.initTag(.u1),4547 .Bool => Type.initTag(.u1),
4521 .Pointer => Type.usize,4548 .Pointer => Type.usize,
...@@ -4523,7 +4550,7 @@ fn cmp(...@@ -4523,7 +4550,7 @@ fn cmp(
4523 else => unreachable,4550 else => unreachable,
4524 };4551 };
45254552
4526 const int_info = int_ty.intInfo(self.target.*);4553 const int_info = int_ty.intInfo(mod);
4527 if (int_info.bits <= 64) {4554 if (int_info.bits <= 64) {
4528 try self.spillCompareFlagsIfOccupied();4555 try self.spillCompareFlagsIfOccupied();
45294556
...@@ -4687,8 +4714,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4687,8 +4714,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
4687 // whether it needs to be spilled in the branches4714 // whether it needs to be spilled in the branches
4688 if (self.liveness.operandDies(inst, 0)) {4715 if (self.liveness.operandDies(inst, 0)) {
4689 const op_int = @enumToInt(pl_op.operand);4716 const op_int = @enumToInt(pl_op.operand);
4690 if (op_int >= Air.Inst.Ref.typed_value_map.len) {4717 if (op_int >= Air.ref_start_index) {
4691 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);4718 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
4692 self.processDeath(op_index);4719 self.processDeath(op_index);
4693 }4720 }
4694 }4721 }
...@@ -4819,13 +4846,14 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4819,13 +4846,14 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
4819}4846}
48204847
4821fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue {4848fn 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: {
4823 var buf: Type.Payload.ElemType = undefined;4851 var buf: Type.Payload.ElemType = undefined;
4824 const payload_ty = operand_ty.optionalChild(&buf);4852 const payload_ty = operand_ty.optionalChild(&buf);
4825 if (!payload_ty.hasRuntimeBitsIgnoreComptime())4853 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
4826 break :blk .{ .ty = operand_ty, .bind = operand_bind };4854 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));
4829 const operand_mcv = try operand_bind.resolveToMcv(self);4857 const operand_mcv = try operand_bind.resolveToMcv(self);
4830 const new_mcv: MCValue = switch (operand_mcv) {4858 const new_mcv: MCValue = switch (operand_mcv) {
4831 .register => |source_reg| new: {4859 .register => |source_reg| new: {
...@@ -4838,7 +4866,7 @@ fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue {...@@ -4838,7 +4866,7 @@ fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue {
4838 try self.genSetReg(payload_ty, dest_reg, operand_mcv);4866 try self.genSetReg(payload_ty, dest_reg, operand_mcv);
4839 } else {4867 } else {
4840 _ = try self.addInst(.{4868 _ = try self.addInst(.{
4841 .tag = if (payload_ty.isSignedInt())4869 .tag = if (payload_ty.isSignedInt(mod))
4842 Mir.Inst.Tag.asr_immediate4870 Mir.Inst.Tag.asr_immediate
4843 else4871 else
4844 Mir.Inst.Tag.lsr_immediate,4872 Mir.Inst.Tag.lsr_immediate,
...@@ -5210,9 +5238,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5210,9 +5238,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
5210}5238}
52115239
5212fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {5240fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
5241 const mod = self.bin_file.options.module.?;
5213 const block_data = self.blocks.getPtr(block).?;5242 const block_data = self.blocks.getPtr(block).?;
52145243
5215 if (self.air.typeOf(operand).hasRuntimeBits()) {5244 if (self.air.typeOf(operand).hasRuntimeBits(mod)) {
5216 const operand_mcv = try self.resolveInst(operand);5245 const operand_mcv = try self.resolveInst(operand);
5217 const block_mcv = block_data.mcv;5246 const block_mcv = block_data.mcv;
5218 if (block_mcv == .none) {5247 if (block_mcv == .none) {
...@@ -5386,7 +5415,8 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {...@@ -5386,7 +5415,8 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
5386}5415}
53875416
5388fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {5417fn 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));
5390 switch (mcv) {5420 switch (mcv) {
5391 .dead => unreachable,5421 .dead => unreachable,
5392 .unreach, .none => return, // Nothing to do.5422 .unreach, .none => return, // Nothing to do.
...@@ -5445,7 +5475,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5445,7 +5475,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5445 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });5475 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });
54465476
5447 const overflow_bit_ty = ty.structFieldType(1);5477 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));
5449 const raw_cond_reg = try self.register_manager.allocReg(null, gp);5479 const raw_cond_reg = try self.register_manager.allocReg(null, gp);
5450 const cond_reg = self.registerAlias(raw_cond_reg, overflow_bit_ty);5480 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...@@ -5559,6 +5589,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5559}5589}
55605590
5561fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {5591fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
5592 const mod = self.bin_file.options.module.?;
5562 switch (mcv) {5593 switch (mcv) {
5563 .dead => unreachable,5594 .dead => unreachable,
5564 .unreach, .none => return, // Nothing to do.5595 .unreach, .none => return, // Nothing to do.
...@@ -5669,13 +5700,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5669,13 +5700,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5669 try self.genLdrRegister(reg, reg.toX(), ty);5700 try self.genLdrRegister(reg, reg.toX(), ty);
5670 },5701 },
5671 .stack_offset => |off| {5702 .stack_offset => |off| {
5672 const abi_size = ty.abiSize(self.target.*);5703 const abi_size = ty.abiSize(mod);
56735704
5674 switch (abi_size) {5705 switch (abi_size) {
5675 1, 2, 4, 8 => {5706 1, 2, 4, 8 => {
5676 const tag: Mir.Inst.Tag = switch (abi_size) {5707 const tag: Mir.Inst.Tag = switch (abi_size) {
5677 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb_stack else .ldrb_stack,5708 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_stack else .ldrb_stack,
5678 2 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsh_stack else .ldrh_stack,5709 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh_stack else .ldrh_stack,
5679 4, 8 => .ldr_stack,5710 4, 8 => .ldr_stack,
5680 else => unreachable, // unexpected abi size5711 else => unreachable, // unexpected abi size
5681 };5712 };
...@@ -5693,13 +5724,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5693,13 +5724,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5693 }5724 }
5694 },5725 },
5695 .stack_argument_offset => |off| {5726 .stack_argument_offset => |off| {
5696 const abi_size = ty.abiSize(self.target.*);5727 const abi_size = ty.abiSize(mod);
56975728
5698 switch (abi_size) {5729 switch (abi_size) {
5699 1, 2, 4, 8 => {5730 1, 2, 4, 8 => {
5700 const tag: Mir.Inst.Tag = switch (abi_size) {5731 const tag: Mir.Inst.Tag = switch (abi_size) {
5701 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument,5732 1 => if (ty.isSignedInt(mod)) 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,5733 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh_stack_argument else .ldrh_stack_argument,
5703 4, 8 => .ldr_stack_argument,5734 4, 8 => .ldr_stack_argument,
5704 else => unreachable, // unexpected abi size5735 else => unreachable, // unexpected abi size
5705 };5736 };
...@@ -5720,7 +5751,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5720,7 +5751,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5720}5751}
57215752
5722fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {5753fn 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));
5724 switch (mcv) {5756 switch (mcv) {
5725 .dead => unreachable,5757 .dead => unreachable,
5726 .none, .unreach => return,5758 .none, .unreach => return,
...@@ -5728,7 +5760,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -5728,7 +5760,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
5728 if (!self.wantSafety())5760 if (!self.wantSafety())
5729 return; // The already existing value will do just fine.5761 return; // The already existing value will do just fine.
5730 // TODO Upgrade this to a memset call when we have that available.5762 // TODO Upgrade this to a memset call when we have that available.
5731 switch (ty.abiSize(self.target.*)) {5763 switch (ty.abiSize(mod)) {
5732 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }),5764 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }),
5733 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),5765 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),
5734 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),5766 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),
...@@ -6087,14 +6119,15 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -6087,14 +6119,15 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
6087}6119}
60886120
6089fn airTry(self: *Self, inst: Air.Inst.Index) !void {6121fn airTry(self: *Self, inst: Air.Inst.Index) !void {
6122 const mod = self.bin_file.options.module.?;
6090 const pl_op = self.air.instructions.items(.data)[inst].pl_op;6123 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
6091 const extra = self.air.extraData(Air.Try, pl_op.payload);6124 const extra = self.air.extraData(Air.Try, pl_op.payload);
6092 const body = self.air.extra[extra.end..][0..extra.data.body_len];6125 const body = self.air.extra[extra.end..][0..extra.data.body_len];
6093 const result: MCValue = result: {6126 const result: MCValue = result: {
6094 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };6127 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
6095 const error_union_ty = self.air.typeOf(pl_op.operand);6128 const error_union_ty = self.air.typeOf(pl_op.operand);
6096 const error_union_size = @intCast(u32, error_union_ty.abiSize(self.target.*));6129 const error_union_size = @intCast(u32, error_union_ty.abiSize(mod));
6097 const error_union_align = error_union_ty.abiAlignment(self.target.*);6130 const error_union_align = error_union_ty.abiAlignment(mod);
60986131
6099 // The error union will die in the body. However, we need the6132 // The error union will die in the body. However, we need the
6100 // error union after the body in order to extract the payload6133 // error union after the body in order to extract the payload
...@@ -6123,22 +6156,18 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -6123,22 +6156,18 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
6123}6156}
61246157
6125fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {6158fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
6126 // First section of indexes correspond to a set number of constant values.6159 const mod = self.bin_file.options.module.?;
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 }
61356160
6136 // If the type has no codegen bits, no need to store it.6161 // If the type has no codegen bits, no need to store it.
6137 const inst_ty = self.air.typeOf(inst);6162 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))
6139 return MCValue{ .none = {} };6164 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
6142 switch (self.air.instructions.items(.tag)[inst_index]) {6171 switch (self.air.instructions.items(.tag)[inst_index]) {
6143 .constant => {6172 .constant => {
6144 // Constants have static lifetimes, so they are always memoized in the outer most table.6173 // 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 {...@@ -6222,6 +6251,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6222 errdefer self.gpa.free(result.args);6251 errdefer self.gpa.free(result.args);
62236252
6224 const ret_ty = fn_ty.fnReturnType();6253 const ret_ty = fn_ty.fnReturnType();
6254 const mod = self.bin_file.options.module.?;
62256255
6226 switch (cc) {6256 switch (cc) {
6227 .Naked => {6257 .Naked => {
...@@ -6236,14 +6266,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6236,14 +6266,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6236 var ncrn: usize = 0; // Next Core Register Number6266 var ncrn: usize = 0; // Next Core Register Number
6237 var nsaa: u32 = 0; // Next stacked argument address6267 var nsaa: u32 = 0; // Next stacked argument address
62386268
6239 if (ret_ty.zigTypeTag() == .NoReturn) {6269 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
6240 result.return_value = .{ .unreach = {} };6270 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)) {
6242 result.return_value = .{ .none = {} };6272 result.return_value = .{ .none = {} };
6243 } else {6273 } else {
6244 const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*));6274 const ret_ty_size = @intCast(u32, ret_ty.abiSize(mod));
6245 if (ret_ty_size == 0) {6275 if (ret_ty_size == 0) {
6246 assert(ret_ty.isError());6276 assert(ret_ty.isError(mod));
6247 result.return_value = .{ .immediate = 0 };6277 result.return_value = .{ .immediate = 0 };
6248 } else if (ret_ty_size <= 8) {6278 } else if (ret_ty_size <= 8) {
6249 result.return_value = .{ .register = self.registerAlias(c_abi_int_return_regs[0], ret_ty) };6279 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 {...@@ -6253,7 +6283,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6253 }6283 }
62546284
6255 for (param_types, 0..) |ty, i| {6285 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));
6257 if (param_size == 0) {6287 if (param_size == 0) {
6258 result.args[i] = .{ .none = {} };6288 result.args[i] = .{ .none = {} };
6259 continue;6289 continue;
...@@ -6261,7 +6291,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6261,7 +6291,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62616291
6262 // We round up NCRN only for non-Apple platforms which allow the 16-byte aligned6292 // We round up NCRN only for non-Apple platforms which allow the 16-byte aligned
6263 // values to spread across odd-numbered registers.6293 // 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()) {
6265 // Round up NCRN to the next even number6295 // Round up NCRN to the next even number
6266 ncrn += ncrn % 2;6296 ncrn += ncrn % 2;
6267 }6297 }
...@@ -6279,7 +6309,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6279,7 +6309,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6279 ncrn = 8;6309 ncrn = 8;
6280 // TODO Apple allows the arguments on the stack to be non-8-byte aligned provided6310 // TODO Apple allows the arguments on the stack to be non-8-byte aligned provided
6281 // that the entire stack space consumed by the arguments is 8-byte aligned.6311 // 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) {
6283 if (nsaa % 8 != 0) {6313 if (nsaa % 8 != 0) {
6284 nsaa += 8 - (nsaa % 8);6314 nsaa += 8 - (nsaa % 8);
6285 }6315 }
...@@ -6294,14 +6324,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6294,14 +6324,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6294 result.stack_align = 16;6324 result.stack_align = 16;
6295 },6325 },
6296 .Unspecified => {6326 .Unspecified => {
6297 if (ret_ty.zigTypeTag() == .NoReturn) {6327 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
6298 result.return_value = .{ .unreach = {} };6328 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)) {
6300 result.return_value = .{ .none = {} };6330 result.return_value = .{ .none = {} };
6301 } else {6331 } else {
6302 const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*));6332 const ret_ty_size = @intCast(u32, ret_ty.abiSize(mod));
6303 if (ret_ty_size == 0) {6333 if (ret_ty_size == 0) {
6304 assert(ret_ty.isError());6334 assert(ret_ty.isError(mod));
6305 result.return_value = .{ .immediate = 0 };6335 result.return_value = .{ .immediate = 0 };
6306 } else if (ret_ty_size <= 8) {6336 } else if (ret_ty_size <= 8) {
6307 result.return_value = .{ .register = self.registerAlias(.x0, ret_ty) };6337 result.return_value = .{ .register = self.registerAlias(.x0, ret_ty) };
...@@ -6318,9 +6348,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6318,9 +6348,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6318 var stack_offset: u32 = 0;6348 var stack_offset: u32 = 0;
63196349
6320 for (param_types, 0..) |ty, i| {6350 for (param_types, 0..) |ty, i| {
6321 if (ty.abiSize(self.target.*) > 0) {6351 if (ty.abiSize(mod) > 0) {
6322 const param_size = @intCast(u32, ty.abiSize(self.target.*));6352 const param_size = @intCast(u32, ty.abiSize(mod));
6323 const param_alignment = ty.abiAlignment(self.target.*);6353 const param_alignment = ty.abiAlignment(mod);
63246354
6325 stack_offset = std.mem.alignForwardGeneric(u32, stack_offset, param_alignment);6355 stack_offset = std.mem.alignForwardGeneric(u32, stack_offset, param_alignment);
6326 result.args[i] = .{ .stack_argument_offset = stack_offset };6356 result.args[i] = .{ .stack_argument_offset = stack_offset };
...@@ -6371,7 +6401,8 @@ fn parseRegName(name: []const u8) ?Register {...@@ -6371,7 +6401,8 @@ fn parseRegName(name: []const u8) ?Register {
6371}6401}
63726402
6373fn registerAlias(self: *Self, reg: Register, ty: Type) Register {6403fn 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
6376 switch (reg.class()) {6407 switch (reg.class()) {
6377 .general_purpose => {6408 .general_purpose => {
src/arch/aarch64/abi.zig+19-17
...@@ -4,6 +4,7 @@ const bits = @import("bits.zig");...@@ -4,6 +4,7 @@ const bits = @import("bits.zig");
4const Register = bits.Register;4const Register = bits.Register;
5const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;5const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
6const Type = @import("../../type.zig").Type;6const Type = @import("../../type.zig").Type;
7const Module = @import("../../Module.zig");
78
8pub const Class = union(enum) {9pub const Class = union(enum) {
9 memory,10 memory,
...@@ -14,40 +15,40 @@ pub const Class = union(enum) {...@@ -14,40 +15,40 @@ pub const Class = union(enum) {
14};15};
1516
16/// For `float_array` the second element will be the amount of floats.17/// For `float_array` the second element will be the amount of floats.
17pub fn classifyType(ty: Type, target: std.Target) Class {18pub fn classifyType(ty: Type, mod: *const Module) Class {
18 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime());19 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod));
1920
20 var maybe_float_bits: ?u16 = null;21 var maybe_float_bits: ?u16 = null;
21 switch (ty.zigTypeTag()) {22 switch (ty.zigTypeTag(mod)) {
22 .Struct => {23 .Struct => {
23 if (ty.containerLayout() == .Packed) return .byval;24 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);
25 if (float_count <= sret_float_count) return .{ .float_array = float_count };26 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);
28 if (bit_size > 128) return .memory;29 if (bit_size > 128) return .memory;
29 if (bit_size > 64) return .double_integer;30 if (bit_size > 64) return .double_integer;
30 return .integer;31 return .integer;
31 },32 },
32 .Union => {33 .Union => {
33 if (ty.containerLayout() == .Packed) return .byval;34 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);
35 if (float_count <= sret_float_count) return .{ .float_array = float_count };36 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);
38 if (bit_size > 128) return .memory;39 if (bit_size > 128) return .memory;
39 if (bit_size > 64) return .double_integer;40 if (bit_size > 64) return .double_integer;
40 return .integer;41 return .integer;
41 },42 },
42 .Int, .Enum, .ErrorSet, .Float, .Bool => return .byval,43 .Int, .Enum, .ErrorSet, .Float, .Bool => return .byval,
43 .Vector => {44 .Vector => {
44 const bit_size = ty.bitSize(target);45 const bit_size = ty.bitSize(mod);
45 // TODO is this controlled by a cpu feature?46 // TODO is this controlled by a cpu feature?
46 if (bit_size > 128) return .memory;47 if (bit_size > 128) return .memory;
47 return .byval;48 return .byval;
48 },49 },
49 .Optional => {50 .Optional => {
50 std.debug.assert(ty.isPtrLikeOptional());51 std.debug.assert(ty.isPtrLikeOptional(mod));
51 return .byval;52 return .byval;
52 },53 },
53 .Pointer => {54 .Pointer => {
...@@ -73,14 +74,15 @@ pub fn classifyType(ty: Type, target: std.Target) Class {...@@ -73,14 +74,15 @@ pub fn classifyType(ty: Type, target: std.Target) Class {
73}74}
7475
75const sret_float_count = 4;76const 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();
77 const invalid = std.math.maxInt(u8);79 const invalid = std.math.maxInt(u8);
78 switch (ty.zigTypeTag()) {80 switch (ty.zigTypeTag(mod)) {
79 .Union => {81 .Union => {
80 const fields = ty.unionFields();82 const fields = ty.unionFields();
81 var max_count: u8 = 0;83 var max_count: u8 = 0;
82 for (fields.values()) |field| {84 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);
84 if (field_count == invalid) return invalid;86 if (field_count == invalid) return invalid;
85 if (field_count > max_count) max_count = field_count;87 if (field_count > max_count) max_count = field_count;
86 if (max_count > sret_float_count) return invalid;88 if (max_count > sret_float_count) return invalid;
...@@ -93,7 +95,7 @@ fn countFloats(ty: Type, target: std.Target, maybe_float_bits: *?u16) u8 {...@@ -93,7 +95,7 @@ fn countFloats(ty: Type, target: std.Target, maybe_float_bits: *?u16) u8 {
93 var i: u32 = 0;95 var i: u32 = 0;
94 while (i < fields_len) : (i += 1) {96 while (i < fields_len) : (i += 1) {
95 const field_ty = ty.structFieldType(i);97 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);
97 if (field_count == invalid) return invalid;99 if (field_count == invalid) return invalid;
98 count += field_count;100 count += field_count;
99 if (count > sret_float_count) return invalid;101 if (count > sret_float_count) return invalid;
...@@ -113,12 +115,12 @@ fn countFloats(ty: Type, target: std.Target, maybe_float_bits: *?u16) u8 {...@@ -113,12 +115,12 @@ fn countFloats(ty: Type, target: std.Target, maybe_float_bits: *?u16) u8 {
113 }115 }
114}116}
115117
116pub fn getFloatArrayType(ty: Type) ?Type {118pub fn getFloatArrayType(ty: Type, mod: *const Module) ?Type {
117 switch (ty.zigTypeTag()) {119 switch (ty.zigTypeTag(mod)) {
118 .Union => {120 .Union => {
119 const fields = ty.unionFields();121 const fields = ty.unionFields();
120 for (fields.values()) |field| {122 for (fields.values()) |field| {
121 if (getFloatArrayType(field.ty)) |some| return some;123 if (getFloatArrayType(field.ty, mod)) |some| return some;
122 }124 }
123 return null;125 return null;
124 },126 },
...@@ -127,7 +129,7 @@ pub fn getFloatArrayType(ty: Type) ?Type {...@@ -127,7 +129,7 @@ pub fn getFloatArrayType(ty: Type) ?Type {
127 var i: u32 = 0;129 var i: u32 = 0;
128 while (i < fields_len) : (i += 1) {130 while (i < fields_len) : (i += 1) {
129 const field_ty = ty.structFieldType(i);131 const field_ty = ty.structFieldType(i);
130 if (getFloatArrayType(field_ty)) |some| return some;132 if (getFloatArrayType(field_ty, mod)) |some| return some;
131 }133 }
132 return null;134 return null;
133 },135 },
src/arch/arm/CodeGen.zig+187-155
...@@ -520,8 +520,9 @@ fn gen(self: *Self) !void {...@@ -520,8 +520,9 @@ fn gen(self: *Self) !void {
520520
521 const ty = self.air.typeOfIndex(inst);521 const ty = self.air.typeOfIndex(inst);
522522
523 const abi_size = @intCast(u32, ty.abiSize(self.target.*));523 const mod = self.bin_file.options.module.?;
524 const abi_align = ty.abiAlignment(self.target.*);524 const abi_size = @intCast(u32, ty.abiSize(mod));
525 const abi_align = ty.abiAlignment(mod);
525 const stack_offset = try self.allocMem(abi_size, abi_align, inst);526 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
526 try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });527 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...@@ -937,8 +938,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
937 tomb_bits >>= 1;938 tomb_bits >>= 1;
938 if (!dies) continue;939 if (!dies) continue;
939 const op_int = @enumToInt(op);940 const op_int = @enumToInt(op);
940 if (op_int < Air.Inst.Ref.typed_value_map.len) continue;941 if (op_int < Air.ref_start_index) continue;
941 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);942 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
942 self.processDeath(op_index);943 self.processDeath(op_index);
943 }944 }
944 const is_used = @truncate(u1, tomb_bits) == 0;945 const is_used = @truncate(u1, tomb_bits) == 0;
...@@ -1006,9 +1007,10 @@ fn allocMem(...@@ -1006,9 +1007,10 @@ fn allocMem(
10061007
1007/// Use a pointer instruction as the basis for allocating stack memory.1008/// Use a pointer instruction as the basis for allocating stack memory.
1008fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {1009fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1010 const mod = self.bin_file.options.module.?;
1009 const elem_ty = self.air.typeOfIndex(inst).elemType();1011 const elem_ty = self.air.typeOfIndex(inst).elemType();
10101012
1011 if (!elem_ty.hasRuntimeBits()) {1013 if (!elem_ty.hasRuntimeBits(mod)) {
1012 // As this stack item will never be dereferenced at runtime,1014 // As this stack item will never be dereferenced at runtime,
1013 // return the stack offset 0. Stack offset 0 will be where all1015 // return the stack offset 0. Stack offset 0 will be where all
1014 // zero-sized stack allocations live as non-zero-sized1016 // zero-sized stack allocations live as non-zero-sized
...@@ -1016,22 +1018,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -1016,22 +1018,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1016 return @as(u32, 0);1018 return @as(u32, 0);
1017 }1019 }
10181020
1019 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {1021 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
1020 const mod = self.bin_file.options.module.?;
1021 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});1022 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
1022 };1023 };
1023 // TODO swap this for inst.ty.ptrAlign1024 // 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
1026 return self.allocMem(abi_size, abi_align, inst);1027 return self.allocMem(abi_size, abi_align, inst);
1027}1028}
10281029
1029fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {1030fn 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 {
1032 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});1033 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
1033 };1034 };
1034 const abi_align = elem_ty.abiAlignment(self.target.*);1035 const abi_align = elem_ty.abiAlignment(mod);
10351036
1036 if (reg_ok) {1037 if (reg_ok) {
1037 // Make sure the type can fit in a register before we try to allocate one.1038 // 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 {...@@ -1158,10 +1159,11 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1158 const operand_ty = self.air.typeOf(ty_op.operand);1159 const operand_ty = self.air.typeOf(ty_op.operand);
1159 const dest_ty = self.air.typeOfIndex(inst);1160 const dest_ty = self.air.typeOfIndex(inst);
11601161
1161 const operand_abi_size = operand_ty.abiSize(self.target.*);1162 const mod = self.bin_file.options.module.?;
1162 const dest_abi_size = dest_ty.abiSize(self.target.*);1163 const operand_abi_size = operand_ty.abiSize(mod);
1163 const info_a = operand_ty.intInfo(self.target.*);1164 const dest_abi_size = dest_ty.abiSize(mod);
1164 const info_b = dest_ty.intInfo(self.target.*);1165 const info_a = operand_ty.intInfo(mod);
1166 const info_b = dest_ty.intInfo(mod);
11651167
1166 const dst_mcv: MCValue = blk: {1168 const dst_mcv: MCValue = blk: {
1167 if (info_a.bits == info_b.bits) {1169 if (info_a.bits == info_b.bits) {
...@@ -1215,8 +1217,9 @@ fn trunc(...@@ -1215,8 +1217,9 @@ fn trunc(
1215 operand_ty: Type,1217 operand_ty: Type,
1216 dest_ty: Type,1218 dest_ty: Type,
1217) !MCValue {1219) !MCValue {
1218 const info_a = operand_ty.intInfo(self.target.*);1220 const mod = self.bin_file.options.module.?;
1219 const info_b = dest_ty.intInfo(self.target.*);1221 const info_a = operand_ty.intInfo(mod);
1222 const info_b = dest_ty.intInfo(mod);
12201223
1221 if (info_b.bits <= 32) {1224 if (info_b.bits <= 32) {
1222 if (info_a.bits > 32) {1225 if (info_a.bits > 32) {
...@@ -1278,6 +1281,7 @@ fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -1278,6 +1281,7 @@ fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {
12781281
1279fn airNot(self: *Self, inst: Air.Inst.Index) !void {1282fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1280 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1283 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1284 const mod = self.bin_file.options.module.?;
1281 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1285 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1282 const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };1286 const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
1283 const operand_ty = self.air.typeOf(ty_op.operand);1287 const operand_ty = self.air.typeOf(ty_op.operand);
...@@ -1286,7 +1290,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {...@@ -1286,7 +1290,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1286 .unreach => unreachable,1290 .unreach => unreachable,
1287 .cpsr_flags => |cond| break :result MCValue{ .cpsr_flags = cond.negate() },1291 .cpsr_flags => |cond| break :result MCValue{ .cpsr_flags = cond.negate() },
1288 else => {1292 else => {
1289 switch (operand_ty.zigTypeTag()) {1293 switch (operand_ty.zigTypeTag(mod)) {
1290 .Bool => {1294 .Bool => {
1291 var op_reg: Register = undefined;1295 var op_reg: Register = undefined;
1292 var dest_reg: Register = undefined;1296 var dest_reg: Register = undefined;
...@@ -1319,7 +1323,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {...@@ -1319,7 +1323,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1319 },1323 },
1320 .Vector => return self.fail("TODO bitwise not for vectors", .{}),1324 .Vector => return self.fail("TODO bitwise not for vectors", .{}),
1321 .Int => {1325 .Int => {
1322 const int_info = operand_ty.intInfo(self.target.*);1326 const int_info = operand_ty.intInfo(mod);
1323 if (int_info.bits <= 32) {1327 if (int_info.bits <= 32) {
1324 var op_reg: Register = undefined;1328 var op_reg: Register = undefined;
1325 var dest_reg: Register = undefined;1329 var dest_reg: Register = undefined;
...@@ -1373,13 +1377,13 @@ fn minMax(...@@ -1373,13 +1377,13 @@ fn minMax(
1373 rhs_ty: Type,1377 rhs_ty: Type,
1374 maybe_inst: ?Air.Inst.Index,1378 maybe_inst: ?Air.Inst.Index,
1375) !MCValue {1379) !MCValue {
1376 switch (lhs_ty.zigTypeTag()) {1380 const mod = self.bin_file.options.module.?;
1381 switch (lhs_ty.zigTypeTag(mod)) {
1377 .Float => return self.fail("TODO ARM min/max on floats", .{}),1382 .Float => return self.fail("TODO ARM min/max on floats", .{}),
1378 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),1383 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),
1379 .Int => {1384 .Int => {
1380 const mod = self.bin_file.options.module.?;
1381 assert(lhs_ty.eql(rhs_ty, mod));1385 assert(lhs_ty.eql(rhs_ty, mod));
1382 const int_info = lhs_ty.intInfo(self.target.*);1386 const int_info = lhs_ty.intInfo(mod);
1383 if (int_info.bits <= 32) {1387 if (int_info.bits <= 32) {
1384 var lhs_reg: Register = undefined;1388 var lhs_reg: Register = undefined;
1385 var rhs_reg: Register = undefined;1389 var rhs_reg: Register = undefined;
...@@ -1582,6 +1586,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1582,6 +1586,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
1582 const tag = self.air.instructions.items(.tag)[inst];1586 const tag = self.air.instructions.items(.tag)[inst];
1583 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;1587 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1584 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;1588 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
1589 const mod = self.bin_file.options.module.?;
1585 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1590 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1586 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };1591 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
1587 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };1592 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
...@@ -1589,16 +1594,15 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1589,16 +1594,15 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
1589 const rhs_ty = self.air.typeOf(extra.rhs);1594 const rhs_ty = self.air.typeOf(extra.rhs);
15901595
1591 const tuple_ty = self.air.typeOfIndex(inst);1596 const tuple_ty = self.air.typeOfIndex(inst);
1592 const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*));1597 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
1593 const tuple_align = tuple_ty.abiAlignment(self.target.*);1598 const tuple_align = tuple_ty.abiAlignment(mod);
1594 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, self.target.*));1599 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
15951600
1596 switch (lhs_ty.zigTypeTag()) {1601 switch (lhs_ty.zigTypeTag(mod)) {
1597 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),1602 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),
1598 .Int => {1603 .Int => {
1599 const mod = self.bin_file.options.module.?;
1600 assert(lhs_ty.eql(rhs_ty, mod));1604 assert(lhs_ty.eql(rhs_ty, mod));
1601 const int_info = lhs_ty.intInfo(self.target.*);1605 const int_info = lhs_ty.intInfo(mod);
1602 if (int_info.bits < 32) {1606 if (int_info.bits < 32) {
1603 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);1607 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 {...@@ -1695,6 +1699,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1695 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;1699 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1696 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;1700 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
1697 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });1701 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
1702 const mod = self.bin_file.options.module.?;
1698 const result: MCValue = result: {1703 const result: MCValue = result: {
1699 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };1704 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
1700 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };1705 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
...@@ -1702,16 +1707,15 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1702,16 +1707,15 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1702 const rhs_ty = self.air.typeOf(extra.rhs);1707 const rhs_ty = self.air.typeOf(extra.rhs);
17031708
1704 const tuple_ty = self.air.typeOfIndex(inst);1709 const tuple_ty = self.air.typeOfIndex(inst);
1705 const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*));1710 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
1706 const tuple_align = tuple_ty.abiAlignment(self.target.*);1711 const tuple_align = tuple_ty.abiAlignment(mod);
1707 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, self.target.*));1712 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
17081713
1709 switch (lhs_ty.zigTypeTag()) {1714 switch (lhs_ty.zigTypeTag(mod)) {
1710 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),1715 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
1711 .Int => {1716 .Int => {
1712 const mod = self.bin_file.options.module.?;
1713 assert(lhs_ty.eql(rhs_ty, mod));1717 assert(lhs_ty.eql(rhs_ty, mod));
1714 const int_info = lhs_ty.intInfo(self.target.*);1718 const int_info = lhs_ty.intInfo(mod);
1715 if (int_info.bits <= 16) {1719 if (int_info.bits <= 16) {
1716 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);1720 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 {...@@ -1859,19 +1863,20 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1859 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;1863 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1860 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;1864 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
1861 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });1865 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
1866 const mod = self.bin_file.options.module.?;
1862 const result: MCValue = result: {1867 const result: MCValue = result: {
1863 const lhs_ty = self.air.typeOf(extra.lhs);1868 const lhs_ty = self.air.typeOf(extra.lhs);
1864 const rhs_ty = self.air.typeOf(extra.rhs);1869 const rhs_ty = self.air.typeOf(extra.rhs);
18651870
1866 const tuple_ty = self.air.typeOfIndex(inst);1871 const tuple_ty = self.air.typeOfIndex(inst);
1867 const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*));1872 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
1868 const tuple_align = tuple_ty.abiAlignment(self.target.*);1873 const tuple_align = tuple_ty.abiAlignment(mod);
1869 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, self.target.*));1874 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
18701875
1871 switch (lhs_ty.zigTypeTag()) {1876 switch (lhs_ty.zigTypeTag(mod)) {
1872 .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}),1877 .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}),
1873 .Int => {1878 .Int => {
1874 const int_info = lhs_ty.intInfo(self.target.*);1879 const int_info = lhs_ty.intInfo(mod);
1875 if (int_info.bits <= 32) {1880 if (int_info.bits <= 32) {
1876 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);1881 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 {...@@ -2017,7 +2022,8 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
2017 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2022 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2018 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2023 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2019 const optional_ty = self.air.typeOfIndex(inst);2024 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
2022 // Optional with a zero-bit payload type is just a boolean true2028 // Optional with a zero-bit payload type is just a boolean true
2023 if (abi_size == 1) {2029 if (abi_size == 1) {
...@@ -2036,16 +2042,17 @@ fn errUnionErr(...@@ -2036,16 +2042,17 @@ fn errUnionErr(
2036 error_union_ty: Type,2042 error_union_ty: Type,
2037 maybe_inst: ?Air.Inst.Index,2043 maybe_inst: ?Air.Inst.Index,
2038) !MCValue {2044) !MCValue {
2045 const mod = self.bin_file.options.module.?;
2039 const err_ty = error_union_ty.errorUnionSet();2046 const err_ty = error_union_ty.errorUnionSet();
2040 const payload_ty = error_union_ty.errorUnionPayload();2047 const payload_ty = error_union_ty.errorUnionPayload();
2041 if (err_ty.errorSetIsEmpty()) {2048 if (err_ty.errorSetIsEmpty()) {
2042 return MCValue{ .immediate = 0 };2049 return MCValue{ .immediate = 0 };
2043 }2050 }
2044 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {2051 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2045 return try error_union_bind.resolveToMcv(self);2052 return try error_union_bind.resolveToMcv(self);
2046 }2053 }
20472054
2048 const err_offset = @intCast(u32, errUnionErrorOffset(payload_ty, self.target.*));2055 const err_offset = @intCast(u32, errUnionErrorOffset(payload_ty, mod));
2049 switch (try error_union_bind.resolveToMcv(self)) {2056 switch (try error_union_bind.resolveToMcv(self)) {
2050 .register => {2057 .register => {
2051 var operand_reg: Register = undefined;2058 var operand_reg: Register = undefined;
...@@ -2067,7 +2074,7 @@ fn errUnionErr(...@@ -2067,7 +2074,7 @@ fn errUnionErr(
2067 );2074 );
20682075
2069 const err_bit_offset = err_offset * 8;2076 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
2072 _ = try self.addInst(.{2079 _ = try self.addInst(.{
2073 .tag = .ubfx, // errors are unsigned integers2080 .tag = .ubfx, // errors are unsigned integers
...@@ -2112,16 +2119,17 @@ fn errUnionPayload(...@@ -2112,16 +2119,17 @@ fn errUnionPayload(
2112 error_union_ty: Type,2119 error_union_ty: Type,
2113 maybe_inst: ?Air.Inst.Index,2120 maybe_inst: ?Air.Inst.Index,
2114) !MCValue {2121) !MCValue {
2122 const mod = self.bin_file.options.module.?;
2115 const err_ty = error_union_ty.errorUnionSet();2123 const err_ty = error_union_ty.errorUnionSet();
2116 const payload_ty = error_union_ty.errorUnionPayload();2124 const payload_ty = error_union_ty.errorUnionPayload();
2117 if (err_ty.errorSetIsEmpty()) {2125 if (err_ty.errorSetIsEmpty()) {
2118 return try error_union_bind.resolveToMcv(self);2126 return try error_union_bind.resolveToMcv(self);
2119 }2127 }
2120 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {2128 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2121 return MCValue.none;2129 return MCValue.none;
2122 }2130 }
21232131
2124 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, self.target.*));2132 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, mod));
2125 switch (try error_union_bind.resolveToMcv(self)) {2133 switch (try error_union_bind.resolveToMcv(self)) {
2126 .register => {2134 .register => {
2127 var operand_reg: Register = undefined;2135 var operand_reg: Register = undefined;
...@@ -2143,10 +2151,10 @@ fn errUnionPayload(...@@ -2143,10 +2151,10 @@ fn errUnionPayload(
2143 );2151 );
21442152
2145 const payload_bit_offset = payload_offset * 8;2153 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
2148 _ = try self.addInst(.{2156 _ = 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,
2150 .data = .{ .rr_lsb_width = .{2158 .data = .{ .rr_lsb_width = .{
2151 .rd = dest_reg,2159 .rd = dest_reg,
2152 .rn = operand_reg,2160 .rn = operand_reg,
...@@ -2221,19 +2229,20 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {...@@ -2221,19 +2229,20 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
22212229
2222/// T to E!T2230/// T to E!T
2223fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {2231fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
2232 const mod = self.bin_file.options.module.?;
2224 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2233 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2225 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2234 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2226 const error_union_ty = self.air.getRefType(ty_op.ty);2235 const error_union_ty = self.air.getRefType(ty_op.ty);
2227 const error_ty = error_union_ty.errorUnionSet();2236 const error_ty = error_union_ty.errorUnionSet();
2228 const payload_ty = error_union_ty.errorUnionPayload();2237 const payload_ty = error_union_ty.errorUnionPayload();
2229 const operand = try self.resolveInst(ty_op.operand);2238 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.*));2241 const abi_size = @intCast(u32, error_union_ty.abiSize(mod));
2233 const abi_align = error_union_ty.abiAlignment(self.target.*);2242 const abi_align = error_union_ty.abiAlignment(mod);
2234 const stack_offset = @intCast(u32, try self.allocMem(abi_size, abi_align, inst));2243 const stack_offset = @intCast(u32, try self.allocMem(abi_size, abi_align, inst));
2235 const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);2244 const payload_off = errUnionPayloadOffset(payload_ty, mod);
2236 const err_off = errUnionErrorOffset(payload_ty, self.target.*);2245 const err_off = errUnionErrorOffset(payload_ty, mod);
2237 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), operand);2246 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), operand);
2238 try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), .{ .immediate = 0 });2247 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 {...@@ -2244,19 +2253,20 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
22442253
2245/// E to E!T2254/// E to E!T
2246fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {2255fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
2256 const mod = self.bin_file.options.module.?;
2247 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2257 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2248 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2258 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2249 const error_union_ty = self.air.getRefType(ty_op.ty);2259 const error_union_ty = self.air.getRefType(ty_op.ty);
2250 const error_ty = error_union_ty.errorUnionSet();2260 const error_ty = error_union_ty.errorUnionSet();
2251 const payload_ty = error_union_ty.errorUnionPayload();2261 const payload_ty = error_union_ty.errorUnionPayload();
2252 const operand = try self.resolveInst(ty_op.operand);2262 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.*));2265 const abi_size = @intCast(u32, error_union_ty.abiSize(mod));
2256 const abi_align = error_union_ty.abiAlignment(self.target.*);2266 const abi_align = error_union_ty.abiAlignment(mod);
2257 const stack_offset = @intCast(u32, try self.allocMem(abi_size, abi_align, inst));2267 const stack_offset = @intCast(u32, try self.allocMem(abi_size, abi_align, inst));
2258 const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);2268 const payload_off = errUnionPayloadOffset(payload_ty, mod);
2259 const err_off = errUnionErrorOffset(payload_ty, self.target.*);2269 const err_off = errUnionErrorOffset(payload_ty, mod);
2260 try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), operand);2270 try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), operand);
2261 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), .undef);2271 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), .undef);
22622272
...@@ -2361,7 +2371,8 @@ fn ptrElemVal(...@@ -2361,7 +2371,8 @@ fn ptrElemVal(
2361 maybe_inst: ?Air.Inst.Index,2371 maybe_inst: ?Air.Inst.Index,
2362) !MCValue {2372) !MCValue {
2363 const elem_ty = ptr_ty.childType();2373 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
2366 switch (elem_size) {2377 switch (elem_size) {
2367 1, 4 => {2378 1, 4 => {
...@@ -2647,7 +2658,8 @@ fn reuseOperand(...@@ -2647,7 +2658,8 @@ fn reuseOperand(
26472658
2648fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {2659fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
2649 const elem_ty = ptr_ty.elemType();2660 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
2652 switch (ptr) {2664 switch (ptr) {
2653 .none => unreachable,2665 .none => unreachable,
...@@ -2722,10 +2734,11 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -2722,10 +2734,11 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
2722}2734}
27232735
2724fn airLoad(self: *Self, inst: Air.Inst.Index) !void {2736fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
2737 const mod = self.bin_file.options.module.?;
2725 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2738 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2726 const elem_ty = self.air.typeOfIndex(inst);2739 const elem_ty = self.air.typeOfIndex(inst);
2727 const result: MCValue = result: {2740 const result: MCValue = result: {
2728 if (!elem_ty.hasRuntimeBits())2741 if (!elem_ty.hasRuntimeBits(mod))
2729 break :result MCValue.none;2742 break :result MCValue.none;
27302743
2731 const ptr = try self.resolveInst(ty_op.operand);2744 const ptr = try self.resolveInst(ty_op.operand);
...@@ -2734,7 +2747,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -2734,7 +2747,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
2734 break :result MCValue.dead;2747 break :result MCValue.dead;
27352748
2736 const dest_mcv: MCValue = blk: {2749 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;
2738 if (ptr_fits_dest and self.reuseOperand(inst, ty_op.operand, 0, ptr)) {2751 if (ptr_fits_dest and self.reuseOperand(inst, ty_op.operand, 0, ptr)) {
2739 // The MCValue that holds the pointer can be re-used as the value.2752 // The MCValue that holds the pointer can be re-used as the value.
2740 break :blk ptr;2753 break :blk ptr;
...@@ -2750,7 +2763,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -2750,7 +2763,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
2750}2763}
27512764
2752fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {2765fn 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
2755 switch (ptr) {2769 switch (ptr) {
2756 .none => unreachable,2770 .none => unreachable,
...@@ -2869,10 +2883,11 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {...@@ -2869,10 +2883,11 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
28692883
2870fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {2884fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
2871 return if (self.liveness.isUnused(inst)) .dead else result: {2885 return if (self.liveness.isUnused(inst)) .dead else result: {
2886 const mod = self.bin_file.options.module.?;
2872 const mcv = try self.resolveInst(operand);2887 const mcv = try self.resolveInst(operand);
2873 const ptr_ty = self.air.typeOf(operand);2888 const ptr_ty = self.air.typeOf(operand);
2874 const struct_ty = ptr_ty.childType();2889 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));
2876 switch (mcv) {2891 switch (mcv) {
2877 .ptr_stack_offset => |off| {2892 .ptr_stack_offset => |off| {
2878 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };2893 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
...@@ -2892,10 +2907,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2892,10 +2907,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2892 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;2907 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
2893 const operand = extra.struct_operand;2908 const operand = extra.struct_operand;
2894 const index = extra.field_index;2909 const index = extra.field_index;
2910 const mod = self.bin_file.options.module.?;
2895 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2911 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2896 const mcv = try self.resolveInst(operand);2912 const mcv = try self.resolveInst(operand);
2897 const struct_ty = self.air.typeOf(operand);2913 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));
2899 const struct_field_ty = struct_ty.structFieldType(index);2915 const struct_field_ty = struct_ty.structFieldType(index);
29002916
2901 switch (mcv) {2917 switch (mcv) {
...@@ -2959,10 +2975,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2959,10 +2975,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2959 );2975 );
29602976
2961 const field_bit_offset = struct_field_offset * 8;2977 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
2964 _ = try self.addInst(.{2980 _ = 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,
2966 .data = .{ .rr_lsb_width = .{2982 .data = .{ .rr_lsb_width = .{
2967 .rd = dest_reg,2983 .rd = dest_reg,
2968 .rn = operand_reg,2984 .rn = operand_reg,
...@@ -2981,17 +2997,18 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2981,17 +2997,18 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2981}2997}
29822998
2983fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {2999fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
3000 const mod = self.bin_file.options.module.?;
2984 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;3001 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2985 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;3002 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
2986 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3003 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2987 const field_ptr = try self.resolveInst(extra.field_ptr);3004 const field_ptr = try self.resolveInst(extra.field_ptr);
2988 const struct_ty = self.air.getRefType(ty_pl.ty).childType();3005 const struct_ty = self.air.getRefType(ty_pl.ty).childType();
29893006
2990 if (struct_ty.zigTypeTag() == .Union) {3007 if (struct_ty.zigTypeTag(mod) == .Union) {
2991 return self.fail("TODO implement @fieldParentPtr codegen for unions", .{});3008 return self.fail("TODO implement @fieldParentPtr codegen for unions", .{});
2992 }3009 }
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));
2995 switch (field_ptr) {3012 switch (field_ptr) {
2996 .ptr_stack_offset => |off| {3013 .ptr_stack_offset => |off| {
2997 break :result MCValue{ .ptr_stack_offset = off + struct_field_offset };3014 break :result MCValue{ .ptr_stack_offset = off + struct_field_offset };
...@@ -3375,12 +3392,12 @@ fn addSub(...@@ -3375,12 +3392,12 @@ fn addSub(
3375 maybe_inst: ?Air.Inst.Index,3392 maybe_inst: ?Air.Inst.Index,
3376) InnerError!MCValue {3393) InnerError!MCValue {
3377 const mod = self.bin_file.options.module.?;3394 const mod = self.bin_file.options.module.?;
3378 switch (lhs_ty.zigTypeTag()) {3395 switch (lhs_ty.zigTypeTag(mod)) {
3379 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3396 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3380 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3397 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3381 .Int => {3398 .Int => {
3382 assert(lhs_ty.eql(rhs_ty, mod));3399 assert(lhs_ty.eql(rhs_ty, mod));
3383 const int_info = lhs_ty.intInfo(self.target.*);3400 const int_info = lhs_ty.intInfo(mod);
3384 if (int_info.bits <= 32) {3401 if (int_info.bits <= 32) {
3385 const lhs_immediate = try lhs_bind.resolveToImmediate(self);3402 const lhs_immediate = try lhs_bind.resolveToImmediate(self);
3386 const rhs_immediate = try rhs_bind.resolveToImmediate(self);3403 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
...@@ -3431,12 +3448,12 @@ fn mul(...@@ -3431,12 +3448,12 @@ fn mul(
3431 maybe_inst: ?Air.Inst.Index,3448 maybe_inst: ?Air.Inst.Index,
3432) InnerError!MCValue {3449) InnerError!MCValue {
3433 const mod = self.bin_file.options.module.?;3450 const mod = self.bin_file.options.module.?;
3434 switch (lhs_ty.zigTypeTag()) {3451 switch (lhs_ty.zigTypeTag(mod)) {
3435 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3452 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3436 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3453 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3437 .Int => {3454 .Int => {
3438 assert(lhs_ty.eql(rhs_ty, mod));3455 assert(lhs_ty.eql(rhs_ty, mod));
3439 const int_info = lhs_ty.intInfo(self.target.*);3456 const int_info = lhs_ty.intInfo(mod);
3440 if (int_info.bits <= 32) {3457 if (int_info.bits <= 32) {
3441 // TODO add optimisations for multiplication3458 // TODO add optimisations for multiplication
3442 // with immediates, for example a * 2 can be3459 // with immediates, for example a * 2 can be
...@@ -3463,7 +3480,8 @@ fn divFloat(...@@ -3463,7 +3480,8 @@ fn divFloat(
3463 _ = rhs_ty;3480 _ = rhs_ty;
3464 _ = maybe_inst;3481 _ = maybe_inst;
34653482
3466 switch (lhs_ty.zigTypeTag()) {3483 const mod = self.bin_file.options.module.?;
3484 switch (lhs_ty.zigTypeTag(mod)) {
3467 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3485 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3468 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3486 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3469 else => unreachable,3487 else => unreachable,
...@@ -3479,12 +3497,12 @@ fn divTrunc(...@@ -3479,12 +3497,12 @@ fn divTrunc(
3479 maybe_inst: ?Air.Inst.Index,3497 maybe_inst: ?Air.Inst.Index,
3480) InnerError!MCValue {3498) InnerError!MCValue {
3481 const mod = self.bin_file.options.module.?;3499 const mod = self.bin_file.options.module.?;
3482 switch (lhs_ty.zigTypeTag()) {3500 switch (lhs_ty.zigTypeTag(mod)) {
3483 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3501 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3484 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3502 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3485 .Int => {3503 .Int => {
3486 assert(lhs_ty.eql(rhs_ty, mod));3504 assert(lhs_ty.eql(rhs_ty, mod));
3487 const int_info = lhs_ty.intInfo(self.target.*);3505 const int_info = lhs_ty.intInfo(mod);
3488 if (int_info.bits <= 32) {3506 if (int_info.bits <= 32) {
3489 switch (int_info.signedness) {3507 switch (int_info.signedness) {
3490 .signed => {3508 .signed => {
...@@ -3522,12 +3540,12 @@ fn divFloor(...@@ -3522,12 +3540,12 @@ fn divFloor(
3522 maybe_inst: ?Air.Inst.Index,3540 maybe_inst: ?Air.Inst.Index,
3523) InnerError!MCValue {3541) InnerError!MCValue {
3524 const mod = self.bin_file.options.module.?;3542 const mod = self.bin_file.options.module.?;
3525 switch (lhs_ty.zigTypeTag()) {3543 switch (lhs_ty.zigTypeTag(mod)) {
3526 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3544 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3527 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3545 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3528 .Int => {3546 .Int => {
3529 assert(lhs_ty.eql(rhs_ty, mod));3547 assert(lhs_ty.eql(rhs_ty, mod));
3530 const int_info = lhs_ty.intInfo(self.target.*);3548 const int_info = lhs_ty.intInfo(mod);
3531 if (int_info.bits <= 32) {3549 if (int_info.bits <= 32) {
3532 switch (int_info.signedness) {3550 switch (int_info.signedness) {
3533 .signed => {3551 .signed => {
...@@ -3569,7 +3587,8 @@ fn divExact(...@@ -3569,7 +3587,8 @@ fn divExact(
3569 _ = rhs_ty;3587 _ = rhs_ty;
3570 _ = maybe_inst;3588 _ = maybe_inst;
35713589
3572 switch (lhs_ty.zigTypeTag()) {3590 const mod = self.bin_file.options.module.?;
3591 switch (lhs_ty.zigTypeTag(mod)) {
3573 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3592 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3574 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3593 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3575 .Int => return self.fail("TODO ARM div_exact", .{}),3594 .Int => return self.fail("TODO ARM div_exact", .{}),
...@@ -3586,12 +3605,12 @@ fn rem(...@@ -3586,12 +3605,12 @@ fn rem(
3586 maybe_inst: ?Air.Inst.Index,3605 maybe_inst: ?Air.Inst.Index,
3587) InnerError!MCValue {3606) InnerError!MCValue {
3588 const mod = self.bin_file.options.module.?;3607 const mod = self.bin_file.options.module.?;
3589 switch (lhs_ty.zigTypeTag()) {3608 switch (lhs_ty.zigTypeTag(mod)) {
3590 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3609 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3591 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3610 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3592 .Int => {3611 .Int => {
3593 assert(lhs_ty.eql(rhs_ty, mod));3612 assert(lhs_ty.eql(rhs_ty, mod));
3594 const int_info = lhs_ty.intInfo(self.target.*);3613 const int_info = lhs_ty.intInfo(mod);
3595 if (int_info.bits <= 32) {3614 if (int_info.bits <= 32) {
3596 switch (int_info.signedness) {3615 switch (int_info.signedness) {
3597 .signed => {3616 .signed => {
...@@ -3654,7 +3673,8 @@ fn modulo(...@@ -3654,7 +3673,8 @@ fn modulo(
3654 _ = rhs_ty;3673 _ = rhs_ty;
3655 _ = maybe_inst;3674 _ = maybe_inst;
36563675
3657 switch (lhs_ty.zigTypeTag()) {3676 const mod = self.bin_file.options.module.?;
3677 switch (lhs_ty.zigTypeTag(mod)) {
3658 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3678 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3659 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3679 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3660 .Int => return self.fail("TODO ARM mod", .{}),3680 .Int => return self.fail("TODO ARM mod", .{}),
...@@ -3671,10 +3691,11 @@ fn wrappingArithmetic(...@@ -3671,10 +3691,11 @@ fn wrappingArithmetic(
3671 rhs_ty: Type,3691 rhs_ty: Type,
3672 maybe_inst: ?Air.Inst.Index,3692 maybe_inst: ?Air.Inst.Index,
3673) InnerError!MCValue {3693) InnerError!MCValue {
3674 switch (lhs_ty.zigTypeTag()) {3694 const mod = self.bin_file.options.module.?;
3695 switch (lhs_ty.zigTypeTag(mod)) {
3675 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3696 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3676 .Int => {3697 .Int => {
3677 const int_info = lhs_ty.intInfo(self.target.*);3698 const int_info = lhs_ty.intInfo(mod);
3678 if (int_info.bits <= 32) {3699 if (int_info.bits <= 32) {
3679 // Generate an add/sub/mul3700 // Generate an add/sub/mul
3680 const result: MCValue = switch (tag) {3701 const result: MCValue = switch (tag) {
...@@ -3708,12 +3729,12 @@ fn bitwise(...@@ -3708,12 +3729,12 @@ fn bitwise(
3708 rhs_ty: Type,3729 rhs_ty: Type,
3709 maybe_inst: ?Air.Inst.Index,3730 maybe_inst: ?Air.Inst.Index,
3710) InnerError!MCValue {3731) InnerError!MCValue {
3711 switch (lhs_ty.zigTypeTag()) {3732 const mod = self.bin_file.options.module.?;
3733 switch (lhs_ty.zigTypeTag(mod)) {
3712 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3734 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3713 .Int => {3735 .Int => {
3714 const mod = self.bin_file.options.module.?;
3715 assert(lhs_ty.eql(rhs_ty, mod));3736 assert(lhs_ty.eql(rhs_ty, mod));
3716 const int_info = lhs_ty.intInfo(self.target.*);3737 const int_info = lhs_ty.intInfo(mod);
3717 if (int_info.bits <= 32) {3738 if (int_info.bits <= 32) {
3718 const lhs_immediate = try lhs_bind.resolveToImmediate(self);3739 const lhs_immediate = try lhs_bind.resolveToImmediate(self);
3719 const rhs_immediate = try rhs_bind.resolveToImmediate(self);3740 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
...@@ -3753,16 +3774,17 @@ fn shiftExact(...@@ -3753,16 +3774,17 @@ fn shiftExact(
3753 rhs_ty: Type,3774 rhs_ty: Type,
3754 maybe_inst: ?Air.Inst.Index,3775 maybe_inst: ?Air.Inst.Index,
3755) InnerError!MCValue {3776) InnerError!MCValue {
3756 switch (lhs_ty.zigTypeTag()) {3777 const mod = self.bin_file.options.module.?;
3778 switch (lhs_ty.zigTypeTag(mod)) {
3757 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3779 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3758 .Int => {3780 .Int => {
3759 const int_info = lhs_ty.intInfo(self.target.*);3781 const int_info = lhs_ty.intInfo(mod);
3760 if (int_info.bits <= 32) {3782 if (int_info.bits <= 32) {
3761 const rhs_immediate = try rhs_bind.resolveToImmediate(self);3783 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
37623784
3763 const mir_tag: Mir.Inst.Tag = switch (tag) {3785 const mir_tag: Mir.Inst.Tag = switch (tag) {
3764 .shl_exact => .lsl,3786 .shl_exact => .lsl,
3765 .shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) {3787 .shr_exact => switch (lhs_ty.intInfo(mod).signedness) {
3766 .signed => Mir.Inst.Tag.asr,3788 .signed => Mir.Inst.Tag.asr,
3767 .unsigned => Mir.Inst.Tag.lsr,3789 .unsigned => Mir.Inst.Tag.lsr,
3768 },3790 },
...@@ -3791,10 +3813,11 @@ fn shiftNormal(...@@ -3791,10 +3813,11 @@ fn shiftNormal(
3791 rhs_ty: Type,3813 rhs_ty: Type,
3792 maybe_inst: ?Air.Inst.Index,3814 maybe_inst: ?Air.Inst.Index,
3793) InnerError!MCValue {3815) InnerError!MCValue {
3794 switch (lhs_ty.zigTypeTag()) {3816 const mod = self.bin_file.options.module.?;
3817 switch (lhs_ty.zigTypeTag(mod)) {
3795 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3818 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3796 .Int => {3819 .Int => {
3797 const int_info = lhs_ty.intInfo(self.target.*);3820 const int_info = lhs_ty.intInfo(mod);
3798 if (int_info.bits <= 32) {3821 if (int_info.bits <= 32) {
3799 // Generate a shl_exact/shr_exact3822 // Generate a shl_exact/shr_exact
3800 const result: MCValue = switch (tag) {3823 const result: MCValue = switch (tag) {
...@@ -3833,7 +3856,8 @@ fn booleanOp(...@@ -3833,7 +3856,8 @@ fn booleanOp(
3833 rhs_ty: Type,3856 rhs_ty: Type,
3834 maybe_inst: ?Air.Inst.Index,3857 maybe_inst: ?Air.Inst.Index,
3835) InnerError!MCValue {3858) InnerError!MCValue {
3836 switch (lhs_ty.zigTypeTag()) {3859 const mod = self.bin_file.options.module.?;
3860 switch (lhs_ty.zigTypeTag(mod)) {
3837 .Bool => {3861 .Bool => {
3838 const lhs_immediate = try lhs_bind.resolveToImmediate(self);3862 const lhs_immediate = try lhs_bind.resolveToImmediate(self);
3839 const rhs_immediate = try rhs_bind.resolveToImmediate(self);3863 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
...@@ -3866,9 +3890,9 @@ fn ptrArithmetic(...@@ -3866,9 +3890,9 @@ fn ptrArithmetic(
3866 rhs_ty: Type,3890 rhs_ty: Type,
3867 maybe_inst: ?Air.Inst.Index,3891 maybe_inst: ?Air.Inst.Index,
3868) InnerError!MCValue {3892) InnerError!MCValue {
3869 switch (lhs_ty.zigTypeTag()) {3893 const mod = self.bin_file.options.module.?;
3894 switch (lhs_ty.zigTypeTag(mod)) {
3870 .Pointer => {3895 .Pointer => {
3871 const mod = self.bin_file.options.module.?;
3872 assert(rhs_ty.eql(Type.usize, mod));3896 assert(rhs_ty.eql(Type.usize, mod));
38733897
3874 const ptr_ty = lhs_ty;3898 const ptr_ty = lhs_ty;
...@@ -3876,7 +3900,7 @@ fn ptrArithmetic(...@@ -3876,7 +3900,7 @@ fn ptrArithmetic(
3876 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type3900 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type
3877 else => ptr_ty.childType(),3901 else => ptr_ty.childType(),
3878 };3902 };
3879 const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));3903 const elem_size = @intCast(u32, elem_ty.abiSize(mod));
38803904
3881 const base_tag: Air.Inst.Tag = switch (tag) {3905 const base_tag: Air.Inst.Tag = switch (tag) {
3882 .ptr_add => .add,3906 .ptr_add => .add,
...@@ -3903,11 +3927,12 @@ fn ptrArithmetic(...@@ -3903,11 +3927,12 @@ fn ptrArithmetic(
3903}3927}
39043928
3905fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) !void {3929fn 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
3908 const tag: Mir.Inst.Tag = switch (abi_size) {3933 const tag: Mir.Inst.Tag = switch (abi_size) {
3909 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb else .ldrb,3934 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb,
3910 2 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsh else .ldrh,3935 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh else .ldrh,
3911 3, 4 => .ldr,3936 3, 4 => .ldr,
3912 else => unreachable,3937 else => unreachable,
3913 };3938 };
...@@ -3924,7 +3949,7 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type)...@@ -3924,7 +3949,7 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type)
3924 } };3949 } };
39253950
3926 const data: Mir.Inst.Data = switch (abi_size) {3951 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,
3928 2 => rr_extra_offset,3953 2 => rr_extra_offset,
3929 3, 4 => rr_offset,3954 3, 4 => rr_offset,
3930 else => unreachable,3955 else => unreachable,
...@@ -3937,7 +3962,8 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type)...@@ -3937,7 +3962,8 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type)
3937}3962}
39383963
3939fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Type) !void {3964fn 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
3942 const tag: Mir.Inst.Tag = switch (abi_size) {3968 const tag: Mir.Inst.Tag = switch (abi_size) {
3943 1 => .strb,3969 1 => .strb,
...@@ -4197,8 +4223,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4197,8 +4223,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4197 const extra = self.air.extraData(Air.Call, pl_op.payload);4223 const extra = self.air.extraData(Air.Call, pl_op.payload);
4198 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);4224 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
4199 const ty = self.air.typeOf(callee);4225 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)) {
4202 .Fn => ty,4229 .Fn => ty,
4203 .Pointer => ty.childType(),4230 .Pointer => ty.childType(),
4204 else => unreachable,4231 else => unreachable,
...@@ -4226,8 +4253,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4226,8 +4253,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4226 const r0_lock: ?RegisterLock = if (info.return_value == .stack_offset) blk: {4253 const r0_lock: ?RegisterLock = if (info.return_value == .stack_offset) blk: {
4227 log.debug("airCall: return by reference", .{});4254 log.debug("airCall: return by reference", .{});
4228 const ret_ty = fn_ty.fnReturnType();4255 const ret_ty = fn_ty.fnReturnType();
4229 const ret_abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));4256 const ret_abi_size = @intCast(u32, ret_ty.abiSize(mod));
4230 const ret_abi_align = @intCast(u32, ret_ty.abiAlignment(self.target.*));4257 const ret_abi_align = @intCast(u32, ret_ty.abiAlignment(mod));
4231 const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst);4258 const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst);
42324259
4233 var ptr_ty_payload: Type.Payload.ElemType = .{4260 var ptr_ty_payload: Type.Payload.ElemType = .{
...@@ -4270,7 +4297,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4270,7 +4297,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42704297
4271 // Due to incremental compilation, how function calls are generated depends4298 // Due to incremental compilation, how function calls are generated depends
4272 // on linking.4299 // on linking.
4273 if (self.air.value(callee)) |func_value| {4300 if (self.air.value(callee, mod)) |func_value| {
4274 if (func_value.castTag(.function)) |func_payload| {4301 if (func_value.castTag(.function)) |func_payload| {
4275 const func = func_payload.data;4302 const func = func_payload.data;
42764303
...@@ -4294,7 +4321,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4294,7 +4321,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4294 return self.fail("TODO implement calling bitcasted functions", .{});4321 return self.fail("TODO implement calling bitcasted functions", .{});
4295 }4322 }
4296 } else {4323 } else {
4297 assert(ty.zigTypeTag() == .Pointer);4324 assert(ty.zigTypeTag(mod) == .Pointer);
4298 const mcv = try self.resolveInst(callee);4325 const mcv = try self.resolveInst(callee);
42994326
4300 try self.genSetReg(Type.initTag(.usize), .lr, mcv);4327 try self.genSetReg(Type.initTag(.usize), .lr, mcv);
...@@ -4356,11 +4383,12 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {...@@ -4356,11 +4383,12 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4356 const un_op = self.air.instructions.items(.data)[inst].un_op;4383 const un_op = self.air.instructions.items(.data)[inst].un_op;
4357 const operand = try self.resolveInst(un_op);4384 const operand = try self.resolveInst(un_op);
4358 const ret_ty = self.fn_type.fnReturnType();4385 const ret_ty = self.fn_type.fnReturnType();
4386 const mod = self.bin_file.options.module.?;
43594387
4360 switch (self.ret_mcv) {4388 switch (self.ret_mcv) {
4361 .none => {},4389 .none => {},
4362 .immediate => {4390 .immediate => {
4363 assert(ret_ty.isError());4391 assert(ret_ty.isError(mod));
4364 },4392 },
4365 .register => |reg| {4393 .register => |reg| {
4366 // Return result by value4394 // Return result by value
...@@ -4411,8 +4439,9 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -4411,8 +4439,9 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
4411 // location.4439 // location.
4412 const op_inst = Air.refToIndex(un_op).?;4440 const op_inst = Air.refToIndex(un_op).?;
4413 if (self.air.instructions.items(.tag)[op_inst] != .ret_ptr) {4441 if (self.air.instructions.items(.tag)[op_inst] != .ret_ptr) {
4414 const abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));4442 const mod = self.bin_file.options.module.?;
4415 const abi_align = ret_ty.abiAlignment(self.target.*);4443 const abi_size = @intCast(u32, ret_ty.abiSize(mod));
4444 const abi_align = ret_ty.abiAlignment(mod);
44164445
4417 const offset = try self.allocMem(abi_size, abi_align, null);4446 const offset = try self.allocMem(abi_size, abi_align, null);
44184447
...@@ -4448,21 +4477,21 @@ fn cmp(...@@ -4448,21 +4477,21 @@ fn cmp(
4448 lhs_ty: Type,4477 lhs_ty: Type,
4449 op: math.CompareOperator,4478 op: math.CompareOperator,
4450) !MCValue {4479) !MCValue {
4451 var int_buffer: Type.Payload.Bits = undefined;4480 const mod = self.bin_file.options.module.?;
4452 const int_ty = switch (lhs_ty.zigTypeTag()) {4481 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
4453 .Optional => blk: {4482 .Optional => blk: {
4454 var opt_buffer: Type.Payload.ElemType = undefined;4483 var opt_buffer: Type.Payload.ElemType = undefined;
4455 const payload_ty = lhs_ty.optionalChild(&opt_buffer);4484 const payload_ty = lhs_ty.optionalChild(&opt_buffer);
4456 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {4485 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4457 break :blk Type.initTag(.u1);4486 break :blk Type.initTag(.u1);
4458 } else if (lhs_ty.isPtrLikeOptional()) {4487 } else if (lhs_ty.isPtrLikeOptional(mod)) {
4459 break :blk Type.usize;4488 break :blk Type.usize;
4460 } else {4489 } else {
4461 return self.fail("TODO ARM cmp non-pointer optionals", .{});4490 return self.fail("TODO ARM cmp non-pointer optionals", .{});
4462 }4491 }
4463 },4492 },
4464 .Float => return self.fail("TODO ARM cmp floats", .{}),4493 .Float => return self.fail("TODO ARM cmp floats", .{}),
4465 .Enum => lhs_ty.intTagType(&int_buffer),4494 .Enum => lhs_ty.intTagType(),
4466 .Int => lhs_ty,4495 .Int => lhs_ty,
4467 .Bool => Type.initTag(.u1),4496 .Bool => Type.initTag(.u1),
4468 .Pointer => Type.usize,4497 .Pointer => Type.usize,
...@@ -4470,7 +4499,7 @@ fn cmp(...@@ -4470,7 +4499,7 @@ fn cmp(
4470 else => unreachable,4499 else => unreachable,
4471 };4500 };
44724501
4473 const int_info = int_ty.intInfo(self.target.*);4502 const int_info = int_ty.intInfo(mod);
4474 if (int_info.bits <= 32) {4503 if (int_info.bits <= 32) {
4475 try self.spillCompareFlagsIfOccupied();4504 try self.spillCompareFlagsIfOccupied();
44764505
...@@ -4636,8 +4665,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4636,8 +4665,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
4636 // whether it needs to be spilled in the branches4665 // whether it needs to be spilled in the branches
4637 if (self.liveness.operandDies(inst, 0)) {4666 if (self.liveness.operandDies(inst, 0)) {
4638 const op_int = @enumToInt(pl_op.operand);4667 const op_int = @enumToInt(pl_op.operand);
4639 if (op_int >= Air.Inst.Ref.typed_value_map.len) {4668 if (op_int >= Air.ref_start_index) {
4640 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);4669 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
4641 self.processDeath(op_index);4670 self.processDeath(op_index);
4642 }4671 }
4643 }4672 }
...@@ -4772,8 +4801,9 @@ fn isNull(...@@ -4772,8 +4801,9 @@ fn isNull(
4772 operand_bind: ReadArg.Bind,4801 operand_bind: ReadArg.Bind,
4773 operand_ty: Type,4802 operand_ty: Type,
4774) !MCValue {4803) !MCValue {
4775 if (operand_ty.isPtrLikeOptional()) {4804 const mod = self.bin_file.options.module.?;
4776 assert(operand_ty.abiSize(self.target.*) == 4);4805 if (operand_ty.isPtrLikeOptional(mod)) {
4806 assert(operand_ty.abiSize(mod) == 4);
47774807
4778 const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } };4808 const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } };
4779 return self.cmp(operand_bind, imm_bind, Type.usize, .eq);4809 return self.cmp(operand_bind, imm_bind, Type.usize, .eq);
...@@ -5131,9 +5161,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5131,9 +5161,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
5131}5161}
51325162
5133fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {5163fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
5164 const mod = self.bin_file.options.module.?;
5134 const block_data = self.blocks.getPtr(block).?;5165 const block_data = self.blocks.getPtr(block).?;
51355166
5136 if (self.air.typeOf(operand).hasRuntimeBits()) {5167 if (self.air.typeOf(operand).hasRuntimeBits(mod)) {
5137 const operand_mcv = try self.resolveInst(operand);5168 const operand_mcv = try self.resolveInst(operand);
5138 const block_mcv = block_data.mcv;5169 const block_mcv = block_data.mcv;
5139 if (block_mcv == .none) {5170 if (block_mcv == .none) {
...@@ -5301,7 +5332,8 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {...@@ -5301,7 +5332,8 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
5301}5332}
53025333
5303fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {5334fn 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));
5305 switch (mcv) {5337 switch (mcv) {
5306 .dead => unreachable,5338 .dead => unreachable,
5307 .unreach, .none => return, // Nothing to do.5339 .unreach, .none => return, // Nothing to do.
...@@ -5382,7 +5414,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5382,7 +5414,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5382 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = reg });5414 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = reg });
53835415
5384 const overflow_bit_ty = ty.structFieldType(1);5416 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));
5386 const cond_reg = try self.register_manager.allocReg(null, gp);5418 const cond_reg = try self.register_manager.allocReg(null, gp);
53875419
5388 // C flag: movcs reg, #15420 // C flag: movcs reg, #1
...@@ -5466,6 +5498,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5466,6 +5498,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5466}5498}
54675499
5468fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {5500fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
5501 const mod = self.bin_file.options.module.?;
5469 switch (mcv) {5502 switch (mcv) {
5470 .dead => unreachable,5503 .dead => unreachable,
5471 .unreach, .none => return, // Nothing to do.5504 .unreach, .none => return, // Nothing to do.
...@@ -5640,17 +5673,17 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5640,17 +5673,17 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5640 },5673 },
5641 .stack_offset => |off| {5674 .stack_offset => |off| {
5642 // TODO: maybe addressing from sp instead of fp5675 // 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
5645 const tag: Mir.Inst.Tag = switch (abi_size) {5678 const tag: Mir.Inst.Tag = switch (abi_size) {
5646 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb else .ldrb,5679 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb,
5647 2 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsh else .ldrh,5680 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh else .ldrh,
5648 3, 4 => .ldr,5681 3, 4 => .ldr,
5649 else => unreachable,5682 else => unreachable,
5650 };5683 };
56515684
5652 const extra_offset = switch (abi_size) {5685 const extra_offset = switch (abi_size) {
5653 1 => ty.isSignedInt(),5686 1 => ty.isSignedInt(mod),
5654 2 => true,5687 2 => true,
5655 3, 4 => false,5688 3, 4 => false,
5656 else => unreachable,5689 else => unreachable,
...@@ -5691,11 +5724,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5691,11 +5724,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5691 }5724 }
5692 },5725 },
5693 .stack_argument_offset => |off| {5726 .stack_argument_offset => |off| {
5694 const abi_size = ty.abiSize(self.target.*);5727 const abi_size = ty.abiSize(mod);
56955728
5696 const tag: Mir.Inst.Tag = switch (abi_size) {5729 const tag: Mir.Inst.Tag = switch (abi_size) {
5697 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument,5730 1 => if (ty.isSignedInt(mod)) 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,5731 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh_stack_argument else .ldrh_stack_argument,
5699 3, 4 => .ldr_stack_argument,5732 3, 4 => .ldr_stack_argument,
5700 else => unreachable,5733 else => unreachable,
5701 };5734 };
...@@ -5712,7 +5745,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5712,7 +5745,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5712}5745}
57135746
5714fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {5747fn 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));
5716 switch (mcv) {5750 switch (mcv) {
5717 .dead => unreachable,5751 .dead => unreachable,
5718 .none, .unreach => return,5752 .none, .unreach => return,
...@@ -6039,8 +6073,9 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {...@@ -6039,8 +6073,9 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
6039 const result: MCValue = result: {6073 const result: MCValue = result: {
6040 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };6074 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
6041 const error_union_ty = self.air.typeOf(pl_op.operand);6075 const error_union_ty = self.air.typeOf(pl_op.operand);
6042 const error_union_size = @intCast(u32, error_union_ty.abiSize(self.target.*));6076 const mod = self.bin_file.options.module.?;
6043 const error_union_align = error_union_ty.abiAlignment(self.target.*);6077 const error_union_size = @intCast(u32, error_union_ty.abiSize(mod));
6078 const error_union_align = error_union_ty.abiAlignment(mod);
60446079
6045 // The error union will die in the body. However, we need the6080 // The error union will die in the body. However, we need the
6046 // error union after the body in order to extract the payload6081 // error union after the body in order to extract the payload
...@@ -6069,22 +6104,18 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -6069,22 +6104,18 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
6069}6104}
60706105
6071fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {6106fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
6072 // First section of indexes correspond to a set number of constant values.6107 const mod = self.bin_file.options.module.?;
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 }
60816108
6082 // If the type has no codegen bits, no need to store it.6109 // If the type has no codegen bits, no need to store it.
6083 const inst_ty = self.air.typeOf(inst);6110 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))
6085 return MCValue{ .none = {} };6112 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
6088 switch (self.air.instructions.items(.tag)[inst_index]) {6119 switch (self.air.instructions.items(.tag)[inst_index]) {
6089 .constant => {6120 .constant => {
6090 // Constants have static lifetimes, so they are always memoized in the outer most table.6121 // 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 {...@@ -6166,6 +6197,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6166 errdefer self.gpa.free(result.args);6197 errdefer self.gpa.free(result.args);
61676198
6168 const ret_ty = fn_ty.fnReturnType();6199 const ret_ty = fn_ty.fnReturnType();
6200 const mod = self.bin_file.options.module.?;
61696201
6170 switch (cc) {6202 switch (cc) {
6171 .Naked => {6203 .Naked => {
...@@ -6180,12 +6212,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6180,12 +6212,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6180 var ncrn: usize = 0; // Next Core Register Number6212 var ncrn: usize = 0; // Next Core Register Number
6181 var nsaa: u32 = 0; // Next stacked argument address6213 var nsaa: u32 = 0; // Next stacked argument address
61826214
6183 if (ret_ty.zigTypeTag() == .NoReturn) {6215 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
6184 result.return_value = .{ .unreach = {} };6216 result.return_value = .{ .unreach = {} };
6185 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {6217 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6186 result.return_value = .{ .none = {} };6218 result.return_value = .{ .none = {} };
6187 } else {6219 } else {
6188 const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*));6220 const ret_ty_size = @intCast(u32, ret_ty.abiSize(mod));
6189 // TODO handle cases where multiple registers are used6221 // TODO handle cases where multiple registers are used
6190 if (ret_ty_size <= 4) {6222 if (ret_ty_size <= 4) {
6191 result.return_value = .{ .register = c_abi_int_return_regs[0] };6223 result.return_value = .{ .register = c_abi_int_return_regs[0] };
...@@ -6200,10 +6232,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6200,10 +6232,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6200 }6232 }
62016233
6202 for (param_types, 0..) |ty, i| {6234 for (param_types, 0..) |ty, i| {
6203 if (ty.abiAlignment(self.target.*) == 8)6235 if (ty.abiAlignment(mod) == 8)
6204 ncrn = std.mem.alignForwardGeneric(usize, ncrn, 2);6236 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));
6207 if (std.math.divCeil(u32, param_size, 4) catch unreachable <= 4 - ncrn) {6239 if (std.math.divCeil(u32, param_size, 4) catch unreachable <= 4 - ncrn) {
6208 if (param_size <= 4) {6240 if (param_size <= 4) {
6209 result.args[i] = .{ .register = c_abi_int_param_regs[ncrn] };6241 result.args[i] = .{ .register = c_abi_int_param_regs[ncrn] };
...@@ -6215,7 +6247,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6215,7 +6247,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6215 return self.fail("TODO MCValues split between registers and stack", .{});6247 return self.fail("TODO MCValues split between registers and stack", .{});
6216 } else {6248 } else {
6217 ncrn = 4;6249 ncrn = 4;
6218 if (ty.abiAlignment(self.target.*) == 8)6250 if (ty.abiAlignment(mod) == 8)
6219 nsaa = std.mem.alignForwardGeneric(u32, nsaa, 8);6251 nsaa = std.mem.alignForwardGeneric(u32, nsaa, 8);
62206252
6221 result.args[i] = .{ .stack_argument_offset = nsaa };6253 result.args[i] = .{ .stack_argument_offset = nsaa };
...@@ -6227,14 +6259,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6227,14 +6259,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6227 result.stack_align = 8;6259 result.stack_align = 8;
6228 },6260 },
6229 .Unspecified => {6261 .Unspecified => {
6230 if (ret_ty.zigTypeTag() == .NoReturn) {6262 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
6231 result.return_value = .{ .unreach = {} };6263 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)) {
6233 result.return_value = .{ .none = {} };6265 result.return_value = .{ .none = {} };
6234 } else {6266 } else {
6235 const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*));6267 const ret_ty_size = @intCast(u32, ret_ty.abiSize(mod));
6236 if (ret_ty_size == 0) {6268 if (ret_ty_size == 0) {
6237 assert(ret_ty.isError());6269 assert(ret_ty.isError(mod));
6238 result.return_value = .{ .immediate = 0 };6270 result.return_value = .{ .immediate = 0 };
6239 } else if (ret_ty_size <= 4) {6271 } else if (ret_ty_size <= 4) {
6240 result.return_value = .{ .register = .r0 };6272 result.return_value = .{ .register = .r0 };
...@@ -6250,9 +6282,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6250,9 +6282,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6250 var stack_offset: u32 = 0;6282 var stack_offset: u32 = 0;
62516283
6252 for (param_types, 0..) |ty, i| {6284 for (param_types, 0..) |ty, i| {
6253 if (ty.abiSize(self.target.*) > 0) {6285 if (ty.abiSize(mod) > 0) {
6254 const param_size = @intCast(u32, ty.abiSize(self.target.*));6286 const param_size = @intCast(u32, ty.abiSize(mod));
6255 const param_alignment = ty.abiAlignment(self.target.*);6287 const param_alignment = ty.abiAlignment(mod);
62566288
6257 stack_offset = std.mem.alignForwardGeneric(u32, stack_offset, param_alignment);6289 stack_offset = std.mem.alignForwardGeneric(u32, stack_offset, param_alignment);
6258 result.args[i] = .{ .stack_argument_offset = stack_offset };6290 result.args[i] = .{ .stack_argument_offset = stack_offset };
src/arch/arm/abi.zig+22-19
...@@ -1,8 +1,10 @@...@@ -1,8 +1,10 @@
1const std = @import("std");1const std = @import("std");
2const assert = std.debug.assert;
2const bits = @import("bits.zig");3const bits = @import("bits.zig");
3const Register = bits.Register;4const Register = bits.Register;
4const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;5const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
5const Type = @import("../../type.zig").Type;6const Type = @import("../../type.zig").Type;
7const Module = @import("../../Module.zig");
68
7pub const Class = union(enum) {9pub const Class = union(enum) {
8 memory,10 memory,
...@@ -22,28 +24,28 @@ pub const Class = union(enum) {...@@ -22,28 +24,28 @@ pub const Class = union(enum) {
2224
23pub const Context = enum { ret, arg };25pub const Context = enum { ret, arg };
2426
25pub fn classifyType(ty: Type, target: std.Target, ctx: Context) Class {27pub fn classifyType(ty: Type, mod: *const Module, ctx: Context) Class {
26 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime());28 assert(ty.hasRuntimeBitsIgnoreComptime(mod));
2729
28 var maybe_float_bits: ?u16 = null;30 var maybe_float_bits: ?u16 = null;
29 const max_byval_size = 512;31 const max_byval_size = 512;
30 switch (ty.zigTypeTag()) {32 switch (ty.zigTypeTag(mod)) {
31 .Struct => {33 .Struct => {
32 const bit_size = ty.bitSize(target);34 const bit_size = ty.bitSize(mod);
33 if (ty.containerLayout() == .Packed) {35 if (ty.containerLayout() == .Packed) {
34 if (bit_size > 64) return .memory;36 if (bit_size > 64) return .memory;
35 return .byval;37 return .byval;
36 }38 }
37 if (bit_size > max_byval_size) return .memory;39 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);
39 if (float_count <= byval_float_count) return .byval;41 if (float_count <= byval_float_count) return .byval;
4042
41 const fields = ty.structFieldCount();43 const fields = ty.structFieldCount();
42 var i: u32 = 0;44 var i: u32 = 0;
43 while (i < fields) : (i += 1) {45 while (i < fields) : (i += 1) {
44 const field_ty = ty.structFieldType(i);46 const field_ty = ty.structFieldType(i);
45 const field_alignment = ty.structFieldAlign(i, target);47 const field_alignment = ty.structFieldAlign(i, mod);
46 const field_size = field_ty.bitSize(target);48 const field_size = field_ty.bitSize(mod);
47 if (field_size > 32 or field_alignment > 32) {49 if (field_size > 32 or field_alignment > 32) {
48 return Class.arrSize(bit_size, 64);50 return Class.arrSize(bit_size, 64);
49 }51 }
...@@ -51,17 +53,17 @@ pub fn classifyType(ty: Type, target: std.Target, ctx: Context) Class {...@@ -51,17 +53,17 @@ pub fn classifyType(ty: Type, target: std.Target, ctx: Context) Class {
51 return Class.arrSize(bit_size, 32);53 return Class.arrSize(bit_size, 32);
52 },54 },
53 .Union => {55 .Union => {
54 const bit_size = ty.bitSize(target);56 const bit_size = ty.bitSize(mod);
55 if (ty.containerLayout() == .Packed) {57 if (ty.containerLayout() == .Packed) {
56 if (bit_size > 64) return .memory;58 if (bit_size > 64) return .memory;
57 return .byval;59 return .byval;
58 }60 }
59 if (bit_size > max_byval_size) return .memory;61 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);
61 if (float_count <= byval_float_count) return .byval;63 if (float_count <= byval_float_count) return .byval;
6264
63 for (ty.unionFields().values()) |field| {65 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) {
65 return Class.arrSize(bit_size, 64);67 return Class.arrSize(bit_size, 64);
66 }68 }
67 }69 }
...@@ -71,28 +73,28 @@ pub fn classifyType(ty: Type, target: std.Target, ctx: Context) Class {...@@ -71,28 +73,28 @@ pub fn classifyType(ty: Type, target: std.Target, ctx: Context) Class {
71 .Int => {73 .Int => {
72 // TODO this is incorrect for _BitInt(128) but implementing74 // TODO this is incorrect for _BitInt(128) but implementing
73 // this correctly makes implementing compiler-rt impossible.75 // this correctly makes implementing compiler-rt impossible.
74 // const bit_size = ty.bitSize(target);76 // const bit_size = ty.bitSize(mod);
75 // if (bit_size > 64) return .memory;77 // if (bit_size > 64) return .memory;
76 return .byval;78 return .byval;
77 },79 },
78 .Enum, .ErrorSet => {80 .Enum, .ErrorSet => {
79 const bit_size = ty.bitSize(target);81 const bit_size = ty.bitSize(mod);
80 if (bit_size > 64) return .memory;82 if (bit_size > 64) return .memory;
81 return .byval;83 return .byval;
82 },84 },
83 .Vector => {85 .Vector => {
84 const bit_size = ty.bitSize(target);86 const bit_size = ty.bitSize(mod);
85 // TODO is this controlled by a cpu feature?87 // TODO is this controlled by a cpu feature?
86 if (ctx == .ret and bit_size > 128) return .memory;88 if (ctx == .ret and bit_size > 128) return .memory;
87 if (bit_size > 512) return .memory;89 if (bit_size > 512) return .memory;
88 return .byval;90 return .byval;
89 },91 },
90 .Optional => {92 .Optional => {
91 std.debug.assert(ty.isPtrLikeOptional());93 assert(ty.isPtrLikeOptional(mod));
92 return .byval;94 return .byval;
93 },95 },
94 .Pointer => {96 .Pointer => {
95 std.debug.assert(!ty.isSlice());97 assert(!ty.isSlice());
96 return .byval;98 return .byval;
97 },99 },
98 .ErrorUnion,100 .ErrorUnion,
...@@ -114,14 +116,15 @@ pub fn classifyType(ty: Type, target: std.Target, ctx: Context) Class {...@@ -114,14 +116,15 @@ pub fn classifyType(ty: Type, target: std.Target, ctx: Context) Class {
114}116}
115117
116const byval_float_count = 4;118const 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();
118 const invalid = std.math.maxInt(u32);121 const invalid = std.math.maxInt(u32);
119 switch (ty.zigTypeTag()) {122 switch (ty.zigTypeTag(mod)) {
120 .Union => {123 .Union => {
121 const fields = ty.unionFields();124 const fields = ty.unionFields();
122 var max_count: u32 = 0;125 var max_count: u32 = 0;
123 for (fields.values()) |field| {126 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);
125 if (field_count == invalid) return invalid;128 if (field_count == invalid) return invalid;
126 if (field_count > max_count) max_count = field_count;129 if (field_count > max_count) max_count = field_count;
127 if (max_count > byval_float_count) return invalid;130 if (max_count > byval_float_count) return invalid;
...@@ -134,7 +137,7 @@ fn countFloats(ty: Type, target: std.Target, maybe_float_bits: *?u16) u32 {...@@ -134,7 +137,7 @@ fn countFloats(ty: Type, target: std.Target, maybe_float_bits: *?u16) u32 {
134 var i: u32 = 0;137 var i: u32 = 0;
135 while (i < fields_len) : (i += 1) {138 while (i < fields_len) : (i += 1) {
136 const field_ty = ty.structFieldType(i);139 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);
138 if (field_count == invalid) return invalid;141 if (field_count == invalid) return invalid;
139 count += field_count;142 count += field_count;
140 if (count > byval_float_count) return invalid;143 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...@@ -755,8 +755,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
755 tomb_bits >>= 1;755 tomb_bits >>= 1;
756 if (!dies) continue;756 if (!dies) continue;
757 const op_int = @enumToInt(op);757 const op_int = @enumToInt(op);
758 if (op_int < Air.Inst.Ref.typed_value_map.len) continue;758 if (op_int < Air.ref_start_index) continue;
759 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);759 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
760 self.processDeath(op_index);760 self.processDeath(op_index);
761 }761 }
762 const is_used = @truncate(u1, tomb_bits) == 0;762 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...@@ -805,22 +805,22 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
805/// Use a pointer instruction as the basis for allocating stack memory.805/// Use a pointer instruction as the basis for allocating stack memory.
806fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {806fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
807 const elem_ty = self.air.typeOfIndex(inst).elemType();807 const elem_ty = self.air.typeOfIndex(inst).elemType();
808 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {808 const mod = self.bin_file.options.module.?;
809 const mod = self.bin_file.options.module.?;809 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
810 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});810 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
811 };811 };
812 // TODO swap this for inst.ty.ptrAlign812 // TODO swap this for inst.ty.ptrAlign
813 const abi_align = elem_ty.abiAlignment(self.target.*);813 const abi_align = elem_ty.abiAlignment(mod);
814 return self.allocMem(inst, abi_size, abi_align);814 return self.allocMem(inst, abi_size, abi_align);
815}815}
816816
817fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {817fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
818 const elem_ty = self.air.typeOfIndex(inst);818 const elem_ty = self.air.typeOfIndex(inst);
819 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {819 const mod = self.bin_file.options.module.?;
820 const mod = self.bin_file.options.module.?;820 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
821 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});821 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
822 };822 };
823 const abi_align = elem_ty.abiAlignment(self.target.*);823 const abi_align = elem_ty.abiAlignment(mod);
824 if (abi_align > self.stack_align)824 if (abi_align > self.stack_align)
825 self.stack_align = abi_align;825 self.stack_align = abi_align;
826826
...@@ -893,10 +893,11 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -893,10 +893,11 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
893 if (self.liveness.isUnused(inst))893 if (self.liveness.isUnused(inst))
894 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });894 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
895895
896 const mod = self.bin_file.options.module.?;
896 const operand_ty = self.air.typeOf(ty_op.operand);897 const operand_ty = self.air.typeOf(ty_op.operand);
897 const operand = try self.resolveInst(ty_op.operand);898 const operand = try self.resolveInst(ty_op.operand);
898 const info_a = operand_ty.intInfo(self.target.*);899 const info_a = operand_ty.intInfo(mod);
899 const info_b = self.air.typeOfIndex(inst).intInfo(self.target.*);900 const info_b = self.air.typeOfIndex(inst).intInfo(mod);
900 if (info_a.signedness != info_b.signedness)901 if (info_a.signedness != info_b.signedness)
901 return self.fail("TODO gen intcast sign safety in semantic analysis", .{});902 return self.fail("TODO gen intcast sign safety in semantic analysis", .{});
902903
...@@ -1068,18 +1069,18 @@ fn binOp(...@@ -1068,18 +1069,18 @@ fn binOp(
1068 lhs_ty: Type,1069 lhs_ty: Type,
1069 rhs_ty: Type,1070 rhs_ty: Type,
1070) InnerError!MCValue {1071) InnerError!MCValue {
1072 const mod = self.bin_file.options.module.?;
1071 switch (tag) {1073 switch (tag) {
1072 // Arithmetic operations on integers and floats1074 // Arithmetic operations on integers and floats
1073 .add,1075 .add,
1074 .sub,1076 .sub,
1075 => {1077 => {
1076 switch (lhs_ty.zigTypeTag()) {1078 switch (lhs_ty.zigTypeTag(mod)) {
1077 .Float => return self.fail("TODO binary operations on floats", .{}),1079 .Float => return self.fail("TODO binary operations on floats", .{}),
1078 .Vector => return self.fail("TODO binary operations on vectors", .{}),1080 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1079 .Int => {1081 .Int => {
1080 const mod = self.bin_file.options.module.?;
1081 assert(lhs_ty.eql(rhs_ty, mod));1082 assert(lhs_ty.eql(rhs_ty, mod));
1082 const int_info = lhs_ty.intInfo(self.target.*);1083 const int_info = lhs_ty.intInfo(mod);
1083 if (int_info.bits <= 64) {1084 if (int_info.bits <= 64) {
1084 // TODO immediate operands1085 // TODO immediate operands
1085 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);1086 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
...@@ -1093,14 +1094,14 @@ fn binOp(...@@ -1093,14 +1094,14 @@ fn binOp(
1093 .ptr_add,1094 .ptr_add,
1094 .ptr_sub,1095 .ptr_sub,
1095 => {1096 => {
1096 switch (lhs_ty.zigTypeTag()) {1097 switch (lhs_ty.zigTypeTag(mod)) {
1097 .Pointer => {1098 .Pointer => {
1098 const ptr_ty = lhs_ty;1099 const ptr_ty = lhs_ty;
1099 const elem_ty = switch (ptr_ty.ptrSize()) {1100 const elem_ty = switch (ptr_ty.ptrSize()) {
1100 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type1101 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type
1101 else => ptr_ty.childType(),1102 else => ptr_ty.childType(),
1102 };1103 };
1103 const elem_size = elem_ty.abiSize(self.target.*);1104 const elem_size = elem_ty.abiSize(mod);
11041105
1105 if (elem_size == 1) {1106 if (elem_size == 1) {
1106 const base_tag: Air.Inst.Tag = switch (tag) {1107 const base_tag: Air.Inst.Tag = switch (tag) {
...@@ -1331,10 +1332,11 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {...@@ -1331,10 +1332,11 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
1331fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {1332fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
1332 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1333 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1333 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1334 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1335 const mod = self.bin_file.options.module.?;
1334 const optional_ty = self.air.typeOfIndex(inst);1336 const optional_ty = self.air.typeOfIndex(inst);
13351337
1336 // Optional with a zero-bit payload type is just a boolean true1338 // 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)
1338 break :result MCValue{ .immediate = 1 };1340 break :result MCValue{ .immediate = 1 };
13391341
1340 return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch});1342 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 {...@@ -1526,7 +1528,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
1526 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1528 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1527 const elem_ty = self.air.typeOfIndex(inst);1529 const elem_ty = self.air.typeOfIndex(inst);
1528 const result: MCValue = result: {1530 const result: MCValue = result: {
1529 if (!elem_ty.hasRuntimeBits())1531 const mod = self.bin_file.options.module.?;
1532 if (!elem_ty.hasRuntimeBits(mod))
1530 break :result MCValue.none;1533 break :result MCValue.none;
15311534
1532 const ptr = try self.resolveInst(ty_op.operand);1535 const ptr = try self.resolveInst(ty_op.operand);
...@@ -1698,6 +1701,7 @@ fn airFence(self: *Self) !void {...@@ -1698,6 +1701,7 @@ fn airFence(self: *Self) !void {
1698}1701}
16991702
1700fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {1703fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {
1704 const mod = self.bin_file.options.module.?;
1701 if (modifier == .always_tail) return self.fail("TODO implement tail calls for riscv64", .{});1705 if (modifier == .always_tail) return self.fail("TODO implement tail calls for riscv64", .{});
1702 const pl_op = self.air.instructions.items(.data)[inst].pl_op;1706 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
1703 const fn_ty = self.air.typeOf(pl_op.operand);1707 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...@@ -1736,7 +1740,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
1736 }1740 }
1737 }1741 }
17381742
1739 if (self.air.value(callee)) |func_value| {1743 if (self.air.value(callee, mod)) |func_value| {
1740 if (func_value.castTag(.function)) |func_payload| {1744 if (func_value.castTag(.function)) |func_payload| {
1741 const func = func_payload.data;1745 const func = func_payload.data;
1742 const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);1746 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 {...@@ -1828,7 +1832,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1828 const ty = self.air.typeOf(bin_op.lhs);1832 const ty = self.air.typeOf(bin_op.lhs);
1829 const mod = self.bin_file.options.module.?;1833 const mod = self.bin_file.options.module.?;
1830 assert(ty.eql(self.air.typeOf(bin_op.rhs), mod));1834 assert(ty.eql(self.air.typeOf(bin_op.rhs), mod));
1831 if (ty.zigTypeTag() == .ErrorSet)1835 if (ty.zigTypeTag(mod) == .ErrorSet)
1832 return self.fail("TODO implement cmp for errors", .{});1836 return self.fail("TODO implement cmp for errors", .{});
18331837
1834 const lhs = try self.resolveInst(bin_op.lhs);1838 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -2107,7 +2111,8 @@ fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -2107,7 +2111,8 @@ fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {
2107fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {2111fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
2108 const block_data = self.blocks.getPtr(block).?;2112 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)) {
2111 const operand_mcv = try self.resolveInst(operand);2116 const operand_mcv = try self.resolveInst(operand);
2112 const block_mcv = block_data.mcv;2117 const block_mcv = block_data.mcv;
2113 if (block_mcv == .none) {2118 if (block_mcv == .none) {
...@@ -2533,22 +2538,18 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -2533,22 +2538,18 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
2533}2538}
25342539
2535fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {2540fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
2536 // First section of indexes correspond to a set number of constant values.2541 const mod = self.bin_file.options.module.?;
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 }
25452542
2546 // If the type has no codegen bits, no need to store it.2543 // If the type has no codegen bits, no need to store it.
2547 const inst_ty = self.air.typeOf(inst);2544 const inst_ty = self.air.typeOf(inst);
2548 if (!inst_ty.hasRuntimeBits())2545 if (!inst_ty.hasRuntimeBits(mod))
2549 return MCValue{ .none = {} };2546 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
2552 switch (self.air.instructions.items(.tag)[inst_index]) {2553 switch (self.air.instructions.items(.tag)[inst_index]) {
2553 .constant => {2554 .constant => {
2554 // Constants have static lifetimes, so they are always memoized in the outer most table.2555 // 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 {...@@ -2630,6 +2631,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
2630 errdefer self.gpa.free(result.args);2631 errdefer self.gpa.free(result.args);
26312632
2632 const ret_ty = fn_ty.fnReturnType();2633 const ret_ty = fn_ty.fnReturnType();
2634 const mod = self.bin_file.options.module.?;
26332635
2634 switch (cc) {2636 switch (cc) {
2635 .Naked => {2637 .Naked => {
...@@ -2650,7 +2652,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -2650,7 +2652,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
2650 const argument_registers = [_]Register{ .a0, .a1, .a2, .a3, .a4, .a5, .a6, .a7 };2652 const argument_registers = [_]Register{ .a0, .a1, .a2, .a3, .a4, .a5, .a6, .a7 };
26512653
2652 for (param_types, 0..) |ty, i| {2654 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));
2654 if (param_size <= 8) {2656 if (param_size <= 8) {
2655 if (next_register < argument_registers.len) {2657 if (next_register < argument_registers.len) {
2656 result.args[i] = .{ .register = argument_registers[next_register] };2658 result.args[i] = .{ .register = argument_registers[next_register] };
...@@ -2680,14 +2682,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -2680,14 +2682,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
2680 else => return self.fail("TODO implement function parameters for {} on riscv64", .{cc}),2682 else => return self.fail("TODO implement function parameters for {} on riscv64", .{cc}),
2681 }2683 }
26822684
2683 if (ret_ty.zigTypeTag() == .NoReturn) {2685 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
2684 result.return_value = .{ .unreach = {} };2686 result.return_value = .{ .unreach = {} };
2685 } else if (!ret_ty.hasRuntimeBits()) {2687 } else if (!ret_ty.hasRuntimeBits(mod)) {
2686 result.return_value = .{ .none = {} };2688 result.return_value = .{ .none = {} };
2687 } else switch (cc) {2689 } else switch (cc) {
2688 .Naked => unreachable,2690 .Naked => unreachable,
2689 .Unspecified, .C => {2691 .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));
2691 if (ret_ty_size <= 8) {2693 if (ret_ty_size <= 8) {
2692 result.return_value = .{ .register = .a0 };2694 result.return_value = .{ .register = .a0 };
2693 } else if (ret_ty_size <= 16) {2695 } else if (ret_ty_size <= 16) {
src/arch/riscv64/abi.zig+10-8
...@@ -3,16 +3,18 @@ const bits = @import("bits.zig");...@@ -3,16 +3,18 @@ const bits = @import("bits.zig");
3const Register = bits.Register;3const Register = bits.Register;
4const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;4const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
5const Type = @import("../../type.zig").Type;5const Type = @import("../../type.zig").Type;
6const Module = @import("../../Module.zig");
67
7pub const Class = enum { memory, byval, integer, double_integer };8pub const Class = enum { memory, byval, integer, double_integer };
89
9pub fn classifyType(ty: Type, target: std.Target) Class {10pub fn classifyType(ty: Type, mod: *const Module) Class {
10 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime());11 const target = mod.getTarget();
12 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod));
1113
12 const max_byval_size = target.ptrBitWidth() * 2;14 const max_byval_size = target.ptrBitWidth() * 2;
13 switch (ty.zigTypeTag()) {15 switch (ty.zigTypeTag(mod)) {
14 .Struct => {16 .Struct => {
15 const bit_size = ty.bitSize(target);17 const bit_size = ty.bitSize(mod);
16 if (ty.containerLayout() == .Packed) {18 if (ty.containerLayout() == .Packed) {
17 if (bit_size > max_byval_size) return .memory;19 if (bit_size > max_byval_size) return .memory;
18 return .byval;20 return .byval;
...@@ -23,7 +25,7 @@ pub fn classifyType(ty: Type, target: std.Target) Class {...@@ -23,7 +25,7 @@ pub fn classifyType(ty: Type, target: std.Target) Class {
23 return .integer;25 return .integer;
24 },26 },
25 .Union => {27 .Union => {
26 const bit_size = ty.bitSize(target);28 const bit_size = ty.bitSize(mod);
27 if (ty.containerLayout() == .Packed) {29 if (ty.containerLayout() == .Packed) {
28 if (bit_size > max_byval_size) return .memory;30 if (bit_size > max_byval_size) return .memory;
29 return .byval;31 return .byval;
...@@ -36,17 +38,17 @@ pub fn classifyType(ty: Type, target: std.Target) Class {...@@ -36,17 +38,17 @@ pub fn classifyType(ty: Type, target: std.Target) Class {
36 .Bool => return .integer,38 .Bool => return .integer,
37 .Float => return .byval,39 .Float => return .byval,
38 .Int, .Enum, .ErrorSet => {40 .Int, .Enum, .ErrorSet => {
39 const bit_size = ty.bitSize(target);41 const bit_size = ty.bitSize(mod);
40 if (bit_size > max_byval_size) return .memory;42 if (bit_size > max_byval_size) return .memory;
41 return .byval;43 return .byval;
42 },44 },
43 .Vector => {45 .Vector => {
44 const bit_size = ty.bitSize(target);46 const bit_size = ty.bitSize(mod);
45 if (bit_size > max_byval_size) return .memory;47 if (bit_size > max_byval_size) return .memory;
46 return .integer;48 return .integer;
47 },49 },
48 .Optional => {50 .Optional => {
49 std.debug.assert(ty.isPtrLikeOptional());51 std.debug.assert(ty.isPtrLikeOptional(mod));
50 return .byval;52 return .byval;
51 },53 },
52 .Pointer => {54 .Pointer => {
src/arch/sparc64/CodeGen.zig+129-110
...@@ -758,18 +758,18 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -758,18 +758,18 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
758 const tag = self.air.instructions.items(.tag)[inst];758 const tag = self.air.instructions.items(.tag)[inst];
759 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;759 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
760 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;760 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
761 const mod = self.bin_file.options.module.?;
761 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {762 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
762 const lhs = try self.resolveInst(extra.lhs);763 const lhs = try self.resolveInst(extra.lhs);
763 const rhs = try self.resolveInst(extra.rhs);764 const rhs = try self.resolveInst(extra.rhs);
764 const lhs_ty = self.air.typeOf(extra.lhs);765 const lhs_ty = self.air.typeOf(extra.lhs);
765 const rhs_ty = self.air.typeOf(extra.rhs);766 const rhs_ty = self.air.typeOf(extra.rhs);
766767
767 switch (lhs_ty.zigTypeTag()) {768 switch (lhs_ty.zigTypeTag(mod)) {
768 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),769 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),
769 .Int => {770 .Int => {
770 const mod = self.bin_file.options.module.?;
771 assert(lhs_ty.eql(rhs_ty, mod));771 assert(lhs_ty.eql(rhs_ty, mod));
772 const int_info = lhs_ty.intInfo(self.target.*);772 const int_info = lhs_ty.intInfo(mod);
773 switch (int_info.bits) {773 switch (int_info.bits) {
774 32, 64 => {774 32, 64 => {
775 // Only say yes if the operation is775 // Only say yes if the operation is
...@@ -1018,7 +1018,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -1018,7 +1018,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1018 switch (arg) {1018 switch (arg) {
1019 .stack_offset => |off| {1019 .stack_offset => |off| {
1020 const mod = self.bin_file.options.module.?;1020 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 {
1022 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});1022 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});
1023 };1023 };
1024 const offset = off + abi_size;1024 const offset = off + abi_size;
...@@ -1203,6 +1203,7 @@ fn airBreakpoint(self: *Self) !void {...@@ -1203,6 +1203,7 @@ fn airBreakpoint(self: *Self) !void {
1203}1203}
12041204
1205fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {1205fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
1206 const mod = self.bin_file.options.module.?;
1206 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1207 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
12071208
1208 // We have hardware byteswapper in SPARCv9, don't let mainstream compilers mislead you.1209 // 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 {...@@ -1218,14 +1219,14 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
1218 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1219 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1219 const operand = try self.resolveInst(ty_op.operand);1220 const operand = try self.resolveInst(ty_op.operand);
1220 const operand_ty = self.air.typeOf(ty_op.operand);1221 const operand_ty = self.air.typeOf(ty_op.operand);
1221 switch (operand_ty.zigTypeTag()) {1222 switch (operand_ty.zigTypeTag(mod)) {
1222 .Vector => return self.fail("TODO byteswap for vectors", .{}),1223 .Vector => return self.fail("TODO byteswap for vectors", .{}),
1223 .Int => {1224 .Int => {
1224 const int_info = operand_ty.intInfo(self.target.*);1225 const int_info = operand_ty.intInfo(mod);
1225 if (int_info.bits == 8) break :result operand;1226 if (int_info.bits == 8) break :result operand;
12261227
1227 const abi_size = int_info.bits >> 3;1228 const abi_size = int_info.bits >> 3;
1228 const abi_align = operand_ty.abiAlignment(self.target.*);1229 const abi_align = operand_ty.abiAlignment(mod);
1229 const opposite_endian_asi = switch (self.target.cpu.arch.endian()) {1230 const opposite_endian_asi = switch (self.target.cpu.arch.endian()) {
1230 Endian.Big => ASI.asi_primary_little,1231 Endian.Big => ASI.asi_primary_little,
1231 Endian.Little => ASI.asi_primary,1232 Endian.Little => ASI.asi_primary,
...@@ -1294,7 +1295,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -1294,7 +1295,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
1294 const extra = self.air.extraData(Air.Call, pl_op.payload);1295 const extra = self.air.extraData(Air.Call, pl_op.payload);
1295 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end .. extra.end + extra.data.args_len]);1296 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end .. extra.end + extra.data.args_len]);
1296 const ty = self.air.typeOf(callee);1297 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)) {
1298 .Fn => ty,1300 .Fn => ty,
1299 .Pointer => ty.childType(),1301 .Pointer => ty.childType(),
1300 else => unreachable,1302 else => unreachable,
...@@ -1337,7 +1339,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -1337,7 +1339,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
13371339
1338 // Due to incremental compilation, how function calls are generated depends1340 // Due to incremental compilation, how function calls are generated depends
1339 // on linking.1341 // on linking.
1340 if (self.air.value(callee)) |func_value| {1342 if (self.air.value(callee, mod)) |func_value| {
1341 if (self.bin_file.tag == link.File.Elf.base_tag) {1343 if (self.bin_file.tag == link.File.Elf.base_tag) {
1342 if (func_value.castTag(.function)) |func_payload| {1344 if (func_value.castTag(.function)) |func_payload| {
1343 const func = func_payload.data;1345 const func = func_payload.data;
...@@ -1374,7 +1376,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -1374,7 +1376,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
1374 }1376 }
1375 } else @panic("TODO SPARCv9 currently does not support non-ELF binaries");1377 } else @panic("TODO SPARCv9 currently does not support non-ELF binaries");
1376 } else {1378 } else {
1377 assert(ty.zigTypeTag() == .Pointer);1379 assert(ty.zigTypeTag(mod) == .Pointer);
1378 const mcv = try self.resolveInst(callee);1380 const mcv = try self.resolveInst(callee);
1379 try self.genSetReg(ty, .o7, mcv);1381 try self.genSetReg(ty, .o7, mcv);
13801382
...@@ -1422,15 +1424,15 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -1422,15 +1424,15 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
14221424
1423fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {1425fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1424 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1426 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1427 const mod = self.bin_file.options.module.?;
1425 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1428 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1426 const lhs = try self.resolveInst(bin_op.lhs);1429 const lhs = try self.resolveInst(bin_op.lhs);
1427 const rhs = try self.resolveInst(bin_op.rhs);1430 const rhs = try self.resolveInst(bin_op.rhs);
1428 const lhs_ty = self.air.typeOf(bin_op.lhs);1431 const lhs_ty = self.air.typeOf(bin_op.lhs);
14291432
1430 var int_buffer: Type.Payload.Bits = undefined;1433 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
1431 const int_ty = switch (lhs_ty.zigTypeTag()) {
1432 .Vector => unreachable, // Handled by cmp_vector.1434 .Vector => unreachable, // Handled by cmp_vector.
1433 .Enum => lhs_ty.intTagType(&int_buffer),1435 .Enum => lhs_ty.intTagType(),
1434 .Int => lhs_ty,1436 .Int => lhs_ty,
1435 .Bool => Type.initTag(.u1),1437 .Bool => Type.initTag(.u1),
1436 .Pointer => Type.usize,1438 .Pointer => Type.usize,
...@@ -1438,9 +1440,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -1438,9 +1440,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1438 .Optional => blk: {1440 .Optional => blk: {
1439 var opt_buffer: Type.Payload.ElemType = undefined;1441 var opt_buffer: Type.Payload.ElemType = undefined;
1440 const payload_ty = lhs_ty.optionalChild(&opt_buffer);1442 const payload_ty = lhs_ty.optionalChild(&opt_buffer);
1441 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1443 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1442 break :blk Type.initTag(.u1);1444 break :blk Type.initTag(.u1);
1443 } else if (lhs_ty.isPtrLikeOptional()) {1445 } else if (lhs_ty.isPtrLikeOptional(mod)) {
1444 break :blk Type.usize;1446 break :blk Type.usize;
1445 } else {1447 } else {
1446 return self.fail("TODO SPARCv9 cmp non-pointer optionals", .{});1448 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 {...@@ -1450,7 +1452,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1450 else => unreachable,1452 else => unreachable,
1451 };1453 };
14521454
1453 const int_info = int_ty.intInfo(self.target.*);1455 const int_info = int_ty.intInfo(mod);
1454 if (int_info.bits <= 64) {1456 if (int_info.bits <= 64) {
1455 _ = try self.binOp(.cmp_eq, lhs, rhs, int_ty, int_ty, BinOpMetadata{1457 _ = try self.binOp(.cmp_eq, lhs, rhs, int_ty, int_ty, BinOpMetadata{
1456 .lhs = bin_op.lhs,1458 .lhs = bin_op.lhs,
...@@ -1512,8 +1514,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1512,8 +1514,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
1512 // whether it needs to be spilled in the branches1514 // whether it needs to be spilled in the branches
1513 if (self.liveness.operandDies(inst, 0)) {1515 if (self.liveness.operandDies(inst, 0)) {
1514 const op_int = @enumToInt(pl_op.operand);1516 const op_int = @enumToInt(pl_op.operand);
1515 if (op_int >= Air.Inst.Ref.typed_value_map.len) {1517 if (op_int >= Air.ref_start_index) {
1516 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);1518 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
1517 self.processDeath(op_index);1519 self.processDeath(op_index);
1518 }1520 }
1519 }1521 }
...@@ -1752,10 +1754,11 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -1752,10 +1754,11 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1752 if (self.liveness.isUnused(inst))1754 if (self.liveness.isUnused(inst))
1753 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });1755 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
17541756
1757 const mod = self.bin_file.options.module.?;
1755 const operand_ty = self.air.typeOf(ty_op.operand);1758 const operand_ty = self.air.typeOf(ty_op.operand);
1756 const operand = try self.resolveInst(ty_op.operand);1759 const operand = try self.resolveInst(ty_op.operand);
1757 const info_a = operand_ty.intInfo(self.target.*);1760 const info_a = operand_ty.intInfo(mod);
1758 const info_b = self.air.typeOfIndex(inst).intInfo(self.target.*);1761 const info_b = self.air.typeOfIndex(inst).intInfo(mod);
1759 if (info_a.signedness != info_b.signedness)1762 if (info_a.signedness != info_b.signedness)
1760 return self.fail("TODO gen intcast sign safety in semantic analysis", .{});1763 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 {...@@ -1814,9 +1817,10 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
1814fn airLoad(self: *Self, inst: Air.Inst.Index) !void {1817fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
1815 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1818 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1816 const elem_ty = self.air.typeOfIndex(inst);1819 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);
1818 const result: MCValue = result: {1822 const result: MCValue = result: {
1819 if (!elem_ty.hasRuntimeBits())1823 if (!elem_ty.hasRuntimeBits(mod))
1820 break :result MCValue.none;1824 break :result MCValue.none;
18211825
1822 const ptr = try self.resolveInst(ty_op.operand);1826 const ptr = try self.resolveInst(ty_op.operand);
...@@ -2037,18 +2041,18 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2037,18 +2041,18 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2037 //const tag = self.air.instructions.items(.tag)[inst];2041 //const tag = self.air.instructions.items(.tag)[inst];
2038 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2042 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2039 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;2043 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2044 const mod = self.bin_file.options.module.?;
2040 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2045 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2041 const lhs = try self.resolveInst(extra.lhs);2046 const lhs = try self.resolveInst(extra.lhs);
2042 const rhs = try self.resolveInst(extra.rhs);2047 const rhs = try self.resolveInst(extra.rhs);
2043 const lhs_ty = self.air.typeOf(extra.lhs);2048 const lhs_ty = self.air.typeOf(extra.lhs);
2044 const rhs_ty = self.air.typeOf(extra.rhs);2049 const rhs_ty = self.air.typeOf(extra.rhs);
20452050
2046 switch (lhs_ty.zigTypeTag()) {2051 switch (lhs_ty.zigTypeTag(mod)) {
2047 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),2052 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
2048 .Int => {2053 .Int => {
2049 const mod = self.bin_file.options.module.?;
2050 assert(lhs_ty.eql(rhs_ty, mod));2054 assert(lhs_ty.eql(rhs_ty, mod));
2051 const int_info = lhs_ty.intInfo(self.target.*);2055 const int_info = lhs_ty.intInfo(mod);
2052 switch (int_info.bits) {2056 switch (int_info.bits) {
2053 1...32 => {2057 1...32 => {
2054 try self.spillConditionFlagsIfOccupied();2058 try self.spillConditionFlagsIfOccupied();
...@@ -2101,6 +2105,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2101,6 +2105,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
21012105
2102fn airNot(self: *Self, inst: Air.Inst.Index) !void {2106fn airNot(self: *Self, inst: Air.Inst.Index) !void {
2103 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2107 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2108 const mod = self.bin_file.options.module.?;
2104 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2109 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2105 const operand = try self.resolveInst(ty_op.operand);2110 const operand = try self.resolveInst(ty_op.operand);
2106 const operand_ty = self.air.typeOf(ty_op.operand);2111 const operand_ty = self.air.typeOf(ty_op.operand);
...@@ -2116,7 +2121,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {...@@ -2116,7 +2121,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
2116 };2121 };
2117 },2122 },
2118 else => {2123 else => {
2119 switch (operand_ty.zigTypeTag()) {2124 switch (operand_ty.zigTypeTag(mod)) {
2120 .Bool => {2125 .Bool => {
2121 const op_reg = switch (operand) {2126 const op_reg = switch (operand) {
2122 .register => |r| r,2127 .register => |r| r,
...@@ -2150,7 +2155,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {...@@ -2150,7 +2155,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
2150 },2155 },
2151 .Vector => return self.fail("TODO bitwise not for vectors", .{}),2156 .Vector => return self.fail("TODO bitwise not for vectors", .{}),
2152 .Int => {2157 .Int => {
2153 const int_info = operand_ty.intInfo(self.target.*);2158 const int_info = operand_ty.intInfo(mod);
2154 if (int_info.bits <= 64) {2159 if (int_info.bits <= 64) {
2155 const op_reg = switch (operand) {2160 const op_reg = switch (operand) {
2156 .register => |r| r,2161 .register => |r| r,
...@@ -2332,16 +2337,17 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -2332,16 +2337,17 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
2332fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {2337fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2333 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2338 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2334 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;2339 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2340 const mod = self.bin_file.options.module.?;
2335 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2341 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2336 const lhs = try self.resolveInst(extra.lhs);2342 const lhs = try self.resolveInst(extra.lhs);
2337 const rhs = try self.resolveInst(extra.rhs);2343 const rhs = try self.resolveInst(extra.rhs);
2338 const lhs_ty = self.air.typeOf(extra.lhs);2344 const lhs_ty = self.air.typeOf(extra.lhs);
2339 const rhs_ty = self.air.typeOf(extra.rhs);2345 const rhs_ty = self.air.typeOf(extra.rhs);
23402346
2341 switch (lhs_ty.zigTypeTag()) {2347 switch (lhs_ty.zigTypeTag(mod)) {
2342 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),2348 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
2343 .Int => {2349 .Int => {
2344 const int_info = lhs_ty.intInfo(self.target.*);2350 const int_info = lhs_ty.intInfo(mod);
2345 if (int_info.bits <= 64) {2351 if (int_info.bits <= 64) {
2346 try self.spillConditionFlagsIfOccupied();2352 try self.spillConditionFlagsIfOccupied();
23472353
...@@ -2449,7 +2455,8 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2449,7 +2455,8 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
24492455
2450 const slice_ty = self.air.typeOf(bin_op.lhs);2456 const slice_ty = self.air.typeOf(bin_op.lhs);
2451 const elem_ty = slice_ty.childType();2457 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
2454 var buf: Type.SlicePtrFieldTypeBuffer = undefined;2461 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
2455 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);2462 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
...@@ -2564,9 +2571,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2564,9 +2571,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2564 const operand = extra.struct_operand;2571 const operand = extra.struct_operand;
2565 const index = extra.field_index;2572 const index = extra.field_index;
2566 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2573 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2574 const mod = self.bin_file.options.module.?;
2567 const mcv = try self.resolveInst(operand);2575 const mcv = try self.resolveInst(operand);
2568 const struct_ty = self.air.typeOf(operand);2576 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
2571 switch (mcv) {2579 switch (mcv) {
2572 .dead, .unreach => unreachable,2580 .dead, .unreach => unreachable,
...@@ -2701,7 +2709,8 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2701,7 +2709,8 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
2701 const error_union_ty = self.air.typeOf(ty_op.operand);2709 const error_union_ty = self.air.typeOf(ty_op.operand);
2702 const payload_ty = error_union_ty.errorUnionPayload();2710 const payload_ty = error_union_ty.errorUnionPayload();
2703 const mcv = try self.resolveInst(ty_op.operand);2711 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
2706 return self.fail("TODO implement unwrap error union error for non-empty payloads", .{});2715 return self.fail("TODO implement unwrap error union error for non-empty payloads", .{});
2707 };2716 };
...@@ -2713,7 +2722,8 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -2713,7 +2722,8 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
2713 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2722 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2714 const error_union_ty = self.air.typeOf(ty_op.operand);2723 const error_union_ty = self.air.typeOf(ty_op.operand);
2715 const payload_ty = error_union_ty.errorUnionPayload();2724 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
2718 return self.fail("TODO implement unwrap error union payload for non-empty payloads", .{});2728 return self.fail("TODO implement unwrap error union payload for non-empty payloads", .{});
2719 };2729 };
...@@ -2727,7 +2737,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2727,7 +2737,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
2727 const error_union_ty = self.air.getRefType(ty_op.ty);2737 const error_union_ty = self.air.getRefType(ty_op.ty);
2728 const payload_ty = error_union_ty.errorUnionPayload();2738 const payload_ty = error_union_ty.errorUnionPayload();
2729 const mcv = try self.resolveInst(ty_op.operand);2739 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
2732 return self.fail("TODO implement wrap errunion error for non-empty payloads", .{});2743 return self.fail("TODO implement wrap errunion error for non-empty payloads", .{});
2733 };2744 };
...@@ -2747,7 +2758,8 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -2747,7 +2758,8 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
2747 const optional_ty = self.air.typeOfIndex(inst);2758 const optional_ty = self.air.typeOfIndex(inst);
27482759
2749 // Optional with a zero-bit payload type is just a boolean true2760 // 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)
2751 break :result MCValue{ .immediate = 1 };2763 break :result MCValue{ .immediate = 1 };
27522764
2753 return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch});2765 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...@@ -2784,7 +2796,8 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
2784fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {2796fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
2785 const elem_ty = self.air.typeOfIndex(inst).elemType();2797 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)) {
2788 // As this stack item will never be dereferenced at runtime,2801 // As this stack item will never be dereferenced at runtime,
2789 // return the stack offset 0. Stack offset 0 will be where all2802 // return the stack offset 0. Stack offset 0 will be where all
2790 // zero-sized stack allocations live as non-zero-sized2803 // zero-sized stack allocations live as non-zero-sized
...@@ -2792,22 +2805,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -2792,22 +2805,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
2792 return @as(u32, 0);2805 return @as(u32, 0);
2793 }2806 }
27942807
2795 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {2808 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
2796 const mod = self.bin_file.options.module.?;
2797 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});2809 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
2798 };2810 };
2799 // TODO swap this for inst.ty.ptrAlign2811 // TODO swap this for inst.ty.ptrAlign
2800 const abi_align = elem_ty.abiAlignment(self.target.*);2812 const abi_align = elem_ty.abiAlignment(mod);
2801 return self.allocMem(inst, abi_size, abi_align);2813 return self.allocMem(inst, abi_size, abi_align);
2802}2814}
28032815
2804fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {2816fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
2805 const elem_ty = self.air.typeOfIndex(inst);2817 const elem_ty = self.air.typeOfIndex(inst);
2806 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {2818 const mod = self.bin_file.options.module.?;
2807 const mod = self.bin_file.options.module.?;2819 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
2808 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});2820 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
2809 };2821 };
2810 const abi_align = elem_ty.abiAlignment(self.target.*);2822 const abi_align = elem_ty.abiAlignment(mod);
2811 if (abi_align > self.stack_align)2823 if (abi_align > self.stack_align)
2812 self.stack_align = abi_align;2824 self.stack_align = abi_align;
28132825
...@@ -2860,12 +2872,12 @@ fn binOp(...@@ -2860,12 +2872,12 @@ fn binOp(
2860 .xor,2872 .xor,
2861 .cmp_eq,2873 .cmp_eq,
2862 => {2874 => {
2863 switch (lhs_ty.zigTypeTag()) {2875 switch (lhs_ty.zigTypeTag(mod)) {
2864 .Float => return self.fail("TODO binary operations on floats", .{}),2876 .Float => return self.fail("TODO binary operations on floats", .{}),
2865 .Vector => return self.fail("TODO binary operations on vectors", .{}),2877 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2866 .Int => {2878 .Int => {
2867 assert(lhs_ty.eql(rhs_ty, mod));2879 assert(lhs_ty.eql(rhs_ty, mod));
2868 const int_info = lhs_ty.intInfo(self.target.*);2880 const int_info = lhs_ty.intInfo(mod);
2869 if (int_info.bits <= 64) {2881 if (int_info.bits <= 64) {
2870 // Only say yes if the operation is2882 // Only say yes if the operation is
2871 // commutative, i.e. we can swap both of the2883 // commutative, i.e. we can swap both of the
...@@ -2934,10 +2946,10 @@ fn binOp(...@@ -2934,10 +2946,10 @@ fn binOp(
2934 const result = try self.binOp(base_tag, lhs, rhs, lhs_ty, rhs_ty, metadata);2946 const result = try self.binOp(base_tag, lhs, rhs, lhs_ty, rhs_ty, metadata);
29352947
2936 // Truncate if necessary2948 // Truncate if necessary
2937 switch (lhs_ty.zigTypeTag()) {2949 switch (lhs_ty.zigTypeTag(mod)) {
2938 .Vector => return self.fail("TODO binary operations on vectors", .{}),2950 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2939 .Int => {2951 .Int => {
2940 const int_info = lhs_ty.intInfo(self.target.*);2952 const int_info = lhs_ty.intInfo(mod);
2941 if (int_info.bits <= 64) {2953 if (int_info.bits <= 64) {
2942 const result_reg = result.register;2954 const result_reg = result.register;
2943 try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);2955 try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
...@@ -2951,11 +2963,11 @@ fn binOp(...@@ -2951,11 +2963,11 @@ fn binOp(
2951 },2963 },
29522964
2953 .div_trunc => {2965 .div_trunc => {
2954 switch (lhs_ty.zigTypeTag()) {2966 switch (lhs_ty.zigTypeTag(mod)) {
2955 .Vector => return self.fail("TODO binary operations on vectors", .{}),2967 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2956 .Int => {2968 .Int => {
2957 assert(lhs_ty.eql(rhs_ty, mod));2969 assert(lhs_ty.eql(rhs_ty, mod));
2958 const int_info = lhs_ty.intInfo(self.target.*);2970 const int_info = lhs_ty.intInfo(mod);
2959 if (int_info.bits <= 64) {2971 if (int_info.bits <= 64) {
2960 const rhs_immediate_ok = switch (tag) {2972 const rhs_immediate_ok = switch (tag) {
2961 .div_trunc => rhs == .immediate and rhs.immediate <= std.math.maxInt(u12),2973 .div_trunc => rhs == .immediate and rhs.immediate <= std.math.maxInt(u12),
...@@ -2984,14 +2996,14 @@ fn binOp(...@@ -2984,14 +2996,14 @@ fn binOp(
2984 },2996 },
29852997
2986 .ptr_add => {2998 .ptr_add => {
2987 switch (lhs_ty.zigTypeTag()) {2999 switch (lhs_ty.zigTypeTag(mod)) {
2988 .Pointer => {3000 .Pointer => {
2989 const ptr_ty = lhs_ty;3001 const ptr_ty = lhs_ty;
2990 const elem_ty = switch (ptr_ty.ptrSize()) {3002 const elem_ty = switch (ptr_ty.ptrSize()) {
2991 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type3003 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type
2992 else => ptr_ty.childType(),3004 else => ptr_ty.childType(),
2993 };3005 };
2994 const elem_size = elem_ty.abiSize(self.target.*);3006 const elem_size = elem_ty.abiSize(mod);
29953007
2996 if (elem_size == 1) {3008 if (elem_size == 1) {
2997 const base_tag: Mir.Inst.Tag = switch (tag) {3009 const base_tag: Mir.Inst.Tag = switch (tag) {
...@@ -3016,7 +3028,7 @@ fn binOp(...@@ -3016,7 +3028,7 @@ fn binOp(
3016 .bool_and,3028 .bool_and,
3017 .bool_or,3029 .bool_or,
3018 => {3030 => {
3019 switch (lhs_ty.zigTypeTag()) {3031 switch (lhs_ty.zigTypeTag(mod)) {
3020 .Bool => {3032 .Bool => {
3021 assert(lhs != .immediate); // should have been handled by Sema3033 assert(lhs != .immediate); // should have been handled by Sema
3022 assert(rhs != .immediate); // should have been handled by Sema3034 assert(rhs != .immediate); // should have been handled by Sema
...@@ -3046,10 +3058,10 @@ fn binOp(...@@ -3046,10 +3058,10 @@ fn binOp(
3046 const result = try self.binOp(base_tag, lhs, rhs, lhs_ty, rhs_ty, metadata);3058 const result = try self.binOp(base_tag, lhs, rhs, lhs_ty, rhs_ty, metadata);
30473059
3048 // Truncate if necessary3060 // Truncate if necessary
3049 switch (lhs_ty.zigTypeTag()) {3061 switch (lhs_ty.zigTypeTag(mod)) {
3050 .Vector => return self.fail("TODO binary operations on vectors", .{}),3062 .Vector => return self.fail("TODO binary operations on vectors", .{}),
3051 .Int => {3063 .Int => {
3052 const int_info = lhs_ty.intInfo(self.target.*);3064 const int_info = lhs_ty.intInfo(mod);
3053 if (int_info.bits <= 64) {3065 if (int_info.bits <= 64) {
3054 // 32 and 64 bit operands doesn't need truncating3066 // 32 and 64 bit operands doesn't need truncating
3055 if (int_info.bits == 32 or int_info.bits == 64) return result;3067 if (int_info.bits == 32 or int_info.bits == 64) return result;
...@@ -3068,10 +3080,10 @@ fn binOp(...@@ -3068,10 +3080,10 @@ fn binOp(
3068 .shl_exact,3080 .shl_exact,
3069 .shr_exact,3081 .shr_exact,
3070 => {3082 => {
3071 switch (lhs_ty.zigTypeTag()) {3083 switch (lhs_ty.zigTypeTag(mod)) {
3072 .Vector => return self.fail("TODO binary operations on vectors", .{}),3084 .Vector => return self.fail("TODO binary operations on vectors", .{}),
3073 .Int => {3085 .Int => {
3074 const int_info = lhs_ty.intInfo(self.target.*);3086 const int_info = lhs_ty.intInfo(mod);
3075 if (int_info.bits <= 64) {3087 if (int_info.bits <= 64) {
3076 const rhs_immediate_ok = rhs == .immediate;3088 const rhs_immediate_ok = rhs == .immediate;
30773089
...@@ -3393,7 +3405,8 @@ fn binOpRegister(...@@ -3393,7 +3405,8 @@ fn binOpRegister(
3393fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {3405fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
3394 const block_data = self.blocks.getPtr(block).?;3406 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)) {
3397 const operand_mcv = try self.resolveInst(operand);3410 const operand_mcv = try self.resolveInst(operand);
3398 const block_mcv = block_data.mcv;3411 const block_mcv = block_data.mcv;
3399 if (block_mcv == .none) {3412 if (block_mcv == .none) {
...@@ -3512,16 +3525,17 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {...@@ -3512,16 +3525,17 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {
35123525
3513/// Given an error union, returns the payload3526/// Given an error union, returns the payload
3514fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {3527fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {
3528 const mod = self.bin_file.options.module.?;
3515 const err_ty = error_union_ty.errorUnionSet();3529 const err_ty = error_union_ty.errorUnionSet();
3516 const payload_ty = error_union_ty.errorUnionPayload();3530 const payload_ty = error_union_ty.errorUnionPayload();
3517 if (err_ty.errorSetIsEmpty()) {3531 if (err_ty.errorSetIsEmpty()) {
3518 return error_union_mcv;3532 return error_union_mcv;
3519 }3533 }
3520 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3534 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3521 return MCValue.none;3535 return MCValue.none;
3522 }3536 }
35233537
3524 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, self.target.*));3538 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, mod));
3525 switch (error_union_mcv) {3539 switch (error_union_mcv) {
3526 .register => return self.fail("TODO errUnionPayload for registers", .{}),3540 .register => return self.fail("TODO errUnionPayload for registers", .{}),
3527 .stack_offset => |off| {3541 .stack_offset => |off| {
...@@ -3555,8 +3569,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live...@@ -3555,8 +3569,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
3555 tomb_bits >>= 1;3569 tomb_bits >>= 1;
3556 if (!dies) continue;3570 if (!dies) continue;
3557 const op_int = @enumToInt(op);3571 const op_int = @enumToInt(op);
3558 if (op_int < Air.Inst.Ref.typed_value_map.len) continue;3572 if (op_int < Air.ref_start_index) continue;
3559 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);3573 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
3560 self.processDeath(op_index);3574 self.processDeath(op_index);
3561 }3575 }
3562 const is_used = @truncate(u1, tomb_bits) == 0;3576 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...@@ -3730,6 +3744,7 @@ fn genLoadASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Reg
3730}3744}
37313745
3732fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {3746fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
3747 const mod = self.bin_file.options.module.?;
3733 switch (mcv) {3748 switch (mcv) {
3734 .dead => unreachable,3749 .dead => unreachable,
3735 .unreach, .none => return, // Nothing to do.3750 .unreach, .none => return, // Nothing to do.
...@@ -3928,19 +3943,20 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3928,19 +3943,20 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3928 // The value is in memory at a hard-coded address.3943 // The value is in memory at a hard-coded address.
3929 // If the type is a pointer, it means the pointer address is at this memory location.3944 // If the type is a pointer, it means the pointer address is at this memory location.
3930 try self.genSetReg(ty, reg, .{ .immediate = addr });3945 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));
3932 },3947 },
3933 .stack_offset => |off| {3948 .stack_offset => |off| {
3934 const real_offset = realStackOffset(off);3949 const real_offset = realStackOffset(off);
3935 const simm13 = math.cast(i13, real_offset) orelse3950 const simm13 = math.cast(i13, real_offset) orelse
3936 return self.fail("TODO larger stack offsets: {}", .{real_offset});3951 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));
3938 },3953 },
3939 }3954 }
3940}3955}
39413956
3942fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {3957fn 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);
3944 switch (mcv) {3960 switch (mcv) {
3945 .dead => unreachable,3961 .dead => unreachable,
3946 .unreach, .none => return, // Nothing to do.3962 .unreach, .none => return, // Nothing to do.
...@@ -3948,7 +3964,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -3948,7 +3964,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3948 if (!self.wantSafety())3964 if (!self.wantSafety())
3949 return; // The already existing value will do just fine.3965 return; // The already existing value will do just fine.
3950 // TODO Upgrade this to a memset call when we have that available.3966 // TODO Upgrade this to a memset call when we have that available.
3951 switch (ty.abiSize(self.target.*)) {3967 switch (ty.abiSize(mod)) {
3952 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }),3968 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }),
3953 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),3969 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),
3954 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),3970 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...@@ -3978,7 +3994,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3978 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });3994 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });
39793995
3980 const overflow_bit_ty = ty.structFieldType(1);3996 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));
3982 const cond_reg = try self.register_manager.allocReg(null, gp);3998 const cond_reg = try self.register_manager.allocReg(null, gp);
39833999
3984 // TODO handle floating point CCRs4000 // TODO handle floating point CCRs
...@@ -4152,13 +4168,14 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {...@@ -4152,13 +4168,14 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
4152}4168}
41534169
4154fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {4170fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
4171 const mod = self.bin_file.options.module.?;
4155 const error_type = ty.errorUnionSet();4172 const error_type = ty.errorUnionSet();
4156 const payload_type = ty.errorUnionPayload();4173 const payload_type = ty.errorUnionPayload();
41574174
4158 if (!error_type.hasRuntimeBits()) {4175 if (!error_type.hasRuntimeBits(mod)) {
4159 return MCValue{ .immediate = 0 }; // always false4176 return MCValue{ .immediate = 0 }; // always false
4160 } else if (!payload_type.hasRuntimeBits()) {4177 } else if (!payload_type.hasRuntimeBits(mod)) {
4161 if (error_type.abiSize(self.target.*) <= 8) {4178 if (error_type.abiSize(mod) <= 8) {
4162 const reg_mcv: MCValue = switch (operand) {4179 const reg_mcv: MCValue = switch (operand) {
4163 .register => operand,4180 .register => operand,
4164 else => .{ .register = try self.copyToTmpRegister(error_type, operand) },4181 else => .{ .register = try self.copyToTmpRegister(error_type, operand) },
...@@ -4249,8 +4266,9 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void {...@@ -4249,8 +4266,9 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void {
4249}4266}
42504267
4251fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {4268fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
4269 const mod = self.bin_file.options.module.?;
4252 const elem_ty = ptr_ty.elemType();4270 const elem_ty = ptr_ty.elemType();
4253 const elem_size = elem_ty.abiSize(self.target.*);4271 const elem_size = elem_ty.abiSize(mod);
42544272
4255 switch (ptr) {4273 switch (ptr) {
4256 .none => unreachable,4274 .none => unreachable,
...@@ -4321,11 +4339,11 @@ fn minMax(...@@ -4321,11 +4339,11 @@ fn minMax(
4321) InnerError!MCValue {4339) InnerError!MCValue {
4322 const mod = self.bin_file.options.module.?;4340 const mod = self.bin_file.options.module.?;
4323 assert(lhs_ty.eql(rhs_ty, mod));4341 assert(lhs_ty.eql(rhs_ty, mod));
4324 switch (lhs_ty.zigTypeTag()) {4342 switch (lhs_ty.zigTypeTag(mod)) {
4325 .Float => return self.fail("TODO min/max on floats", .{}),4343 .Float => return self.fail("TODO min/max on floats", .{}),
4326 .Vector => return self.fail("TODO min/max on vectors", .{}),4344 .Vector => return self.fail("TODO min/max on vectors", .{}),
4327 .Int => {4345 .Int => {
4328 const int_info = lhs_ty.intInfo(self.target.*);4346 const int_info = lhs_ty.intInfo(mod);
4329 if (int_info.bits <= 64) {4347 if (int_info.bits <= 64) {
4330 // TODO skip register setting when one of the operands4348 // TODO skip register setting when one of the operands
4331 // is a small (fits in i13) immediate.4349 // is a small (fits in i13) immediate.
...@@ -4455,6 +4473,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)...@@ -4455,6 +4473,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
4455 errdefer self.gpa.free(result.args);4473 errdefer self.gpa.free(result.args);
44564474
4457 const ret_ty = fn_ty.fnReturnType();4475 const ret_ty = fn_ty.fnReturnType();
4476 const mod = self.bin_file.options.module.?;
44584477
4459 switch (cc) {4478 switch (cc) {
4460 .Naked => {4479 .Naked => {
...@@ -4478,7 +4497,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)...@@ -4478,7 +4497,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
4478 };4497 };
44794498
4480 for (param_types, 0..) |ty, i| {4499 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));
4482 if (param_size <= 8) {4501 if (param_size <= 8) {
4483 if (next_register < argument_registers.len) {4502 if (next_register < argument_registers.len) {
4484 result.args[i] = .{ .register = argument_registers[next_register] };4503 result.args[i] = .{ .register = argument_registers[next_register] };
...@@ -4505,12 +4524,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)...@@ -4505,12 +4524,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
4505 result.stack_byte_count = next_stack_offset;4524 result.stack_byte_count = next_stack_offset;
4506 result.stack_align = 16;4525 result.stack_align = 16;
45074526
4508 if (ret_ty.zigTypeTag() == .NoReturn) {4527 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
4509 result.return_value = .{ .unreach = {} };4528 result.return_value = .{ .unreach = {} };
4510 } else if (!ret_ty.hasRuntimeBits()) {4529 } else if (!ret_ty.hasRuntimeBits(mod)) {
4511 result.return_value = .{ .none = {} };4530 result.return_value = .{ .none = {} };
4512 } else {4531 } else {
4513 const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*));4532 const ret_ty_size = @intCast(u32, ret_ty.abiSize(mod));
4514 // The callee puts the return values in %i0-%i3, which becomes %o0-%o3 inside the caller.4533 // The callee puts the return values in %i0-%i3, which becomes %o0-%o3 inside the caller.
4515 if (ret_ty_size <= 8) {4534 if (ret_ty_size <= 8) {
4516 result.return_value = switch (role) {4535 result.return_value = switch (role) {
...@@ -4528,40 +4547,37 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)...@@ -4528,40 +4547,37 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
4528 return result;4547 return result;
4529}4548}
45304549
4531fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {4550fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
4532 // First section of indexes correspond to a set number of constant values.4551 const mod = self.bin_file.options.module.?;
4533 const ref_int = @enumToInt(inst);4552 const ty = self.air.typeOf(ref);
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 }
45414553
4542 // If the type has no codegen bits, no need to store it.4554 // If the type has no codegen bits, no need to store it.
4543 const inst_ty = self.air.typeOf(inst);4555 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;
4544 if (!inst_ty.hasRuntimeBitsIgnoreComptime() and !inst_ty.isError())4556
4545 return MCValue{ .none = {} };4557 if (Air.refToIndex(ref)) |inst| {
45464558 switch (self.air.instructions.items(.tag)[inst]) {
4547 const inst_index = @intCast(Air.Inst.Index, ref_int - Air.Inst.Ref.typed_value_map.len);4559 .constant => {
4548 switch (self.air.instructions.items(.tag)[inst_index]) {4560 // Constants have static lifetimes, so they are always memoized in the outer most table.
4549 .constant => {4561 const branch = &self.branch_stack.items[0];
4550 // Constants have static lifetimes, so they are always memoized in the outer most table.4562 const gop = try branch.inst_table.getOrPut(self.gpa, inst);
4551 const branch = &self.branch_stack.items[0];4563 if (!gop.found_existing) {
4552 const gop = try branch.inst_table.getOrPut(self.gpa, inst_index);4564 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
4553 if (!gop.found_existing) {4565 gop.value_ptr.* = try self.genTypedValue(.{
4554 const ty_pl = self.air.instructions.items(.data)[inst_index].ty_pl;4566 .ty = ty,
4555 gop.value_ptr.* = try self.genTypedValue(.{4567 .val = self.air.values[ty_pl.payload],
4556 .ty = inst_ty,4568 });
4557 .val = self.air.values[ty_pl.payload],4569 }
4558 });4570 return gop.value_ptr.*;
4559 }4571 },
4560 return gop.value_ptr.*;4572 .const_ty => unreachable,
4561 },4573 else => return self.getResolvedInstValue(inst),
4562 .const_ty => unreachable,4574 }
4563 else => return self.getResolvedInstValue(inst_index),
4564 }4575 }
4576
4577 return self.genTypedValue(.{
4578 .ty = ty,
4579 .val = self.air.value(ref, mod).?,
4580 });
4565}4581}
45664582
4567fn ret(self: *Self, mcv: MCValue) !void {4583fn ret(self: *Self, mcv: MCValue) !void {
...@@ -4666,7 +4682,8 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void...@@ -4666,7 +4682,8 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
4666}4682}
46674683
4668fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {4684fn 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
4671 switch (ptr) {4688 switch (ptr) {
4672 .none => unreachable,4689 .none => unreachable,
...@@ -4707,10 +4724,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -4707,10 +4724,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
47074724
4708fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {4725fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
4709 return if (self.liveness.isUnused(inst)) .dead else result: {4726 return if (self.liveness.isUnused(inst)) .dead else result: {
4727 const mod = self.bin_file.options.module.?;
4710 const mcv = try self.resolveInst(operand);4728 const mcv = try self.resolveInst(operand);
4711 const ptr_ty = self.air.typeOf(operand);4729 const ptr_ty = self.air.typeOf(operand);
4712 const struct_ty = ptr_ty.childType();4730 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));
4714 switch (mcv) {4732 switch (mcv) {
4715 .ptr_stack_offset => |off| {4733 .ptr_stack_offset => |off| {
4716 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };4734 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
...@@ -4748,8 +4766,9 @@ fn trunc(...@@ -4748,8 +4766,9 @@ fn trunc(
4748 operand_ty: Type,4766 operand_ty: Type,
4749 dest_ty: Type,4767 dest_ty: Type,
4750) !MCValue {4768) !MCValue {
4751 const info_a = operand_ty.intInfo(self.target.*);4769 const mod = self.bin_file.options.module.?;
4752 const info_b = dest_ty.intInfo(self.target.*);4770 const info_a = operand_ty.intInfo(mod);
4771 const info_b = dest_ty.intInfo(mod);
47534772
4754 if (info_b.bits <= 64) {4773 if (info_b.bits <= 64) {
4755 const operand_reg = switch (operand) {4774 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 {...@@ -788,9 +788,10 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
788 const gop = try func.branches.items[0].values.getOrPut(func.gpa, ref);788 const gop = try func.branches.items[0].values.getOrPut(func.gpa, ref);
789 assert(!gop.found_existing);789 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).?;
792 const ty = func.air.typeOf(ref);793 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)) {
794 gop.value_ptr.* = WValue{ .none = {} };795 gop.value_ptr.* = WValue{ .none = {} };
795 return gop.value_ptr.*;796 return gop.value_ptr.*;
796 }797 }
...@@ -801,7 +802,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {...@@ -801,7 +802,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
801 //802 //
802 // In the other cases, we will simply lower the constant to a value that fits803 // In the other cases, we will simply lower the constant to a value that fits
803 // into a single local (such as a pointer, integer, bool, etc).804 // 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: {
805 const sym_index = try func.bin_file.lowerUnnamedConst(.{ .ty = ty, .val = val }, func.decl_index);806 const sym_index = try func.bin_file.lowerUnnamedConst(.{ .ty = ty, .val = val }, func.decl_index);
806 break :blk WValue{ .memory = sym_index };807 break :blk WValue{ .memory = sym_index };
807 } else try func.lowerConstant(val, ty);808 } else try func.lowerConstant(val, ty);
...@@ -987,8 +988,9 @@ fn addExtraAssumeCapacity(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32...@@ -987,8 +988,9 @@ fn addExtraAssumeCapacity(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32
987}988}
988989
989/// Using a given `Type`, returns the corresponding type990/// Using a given `Type`, returns the corresponding type
990fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {991fn typeToValtype(ty: Type, mod: *Module) wasm.Valtype {
991 return switch (ty.zigTypeTag()) {992 const target = mod.getTarget();
993 return switch (ty.zigTypeTag(mod)) {
992 .Float => blk: {994 .Float => blk: {
993 const bits = ty.floatBits(target);995 const bits = ty.floatBits(target);
994 if (bits == 16) return wasm.Valtype.i32; // stored/loaded as u16996 if (bits == 16) return wasm.Valtype.i32; // stored/loaded as u16
...@@ -998,7 +1000,7 @@ fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {...@@ -998,7 +1000,7 @@ fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {
998 return wasm.Valtype.i32; // represented as pointer to stack1000 return wasm.Valtype.i32; // represented as pointer to stack
999 },1001 },
1000 .Int, .Enum => blk: {1002 .Int, .Enum => blk: {
1001 const info = ty.intInfo(target);1003 const info = ty.intInfo(mod);
1002 if (info.bits <= 32) break :blk wasm.Valtype.i32;1004 if (info.bits <= 32) break :blk wasm.Valtype.i32;
1003 if (info.bits > 32 and info.bits <= 128) break :blk wasm.Valtype.i64;1005 if (info.bits > 32 and info.bits <= 128) break :blk wasm.Valtype.i64;
1004 break :blk wasm.Valtype.i32; // represented as pointer to stack1006 break :blk wasm.Valtype.i32; // represented as pointer to stack
...@@ -1006,22 +1008,18 @@ fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {...@@ -1006,22 +1008,18 @@ fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {
1006 .Struct => switch (ty.containerLayout()) {1008 .Struct => switch (ty.containerLayout()) {
1007 .Packed => {1009 .Packed => {
1008 const struct_obj = ty.castTag(.@"struct").?.data;1010 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);
1010 },1012 },
1011 else => wasm.Valtype.i32,1013 else => wasm.Valtype.i32,
1012 },1014 },
1013 .Vector => switch (determineSimdStoreStrategy(ty, target)) {1015 .Vector => switch (determineSimdStoreStrategy(ty, mod)) {
1014 .direct => wasm.Valtype.v128,1016 .direct => wasm.Valtype.v128,
1015 .unrolled => wasm.Valtype.i32,1017 .unrolled => wasm.Valtype.i32,
1016 },1018 },
1017 .Union => switch (ty.containerLayout()) {1019 .Union => switch (ty.containerLayout()) {
1018 .Packed => {1020 .Packed => {
1019 var int_ty_payload: Type.Payload.Bits = .{1021 const int_ty = mod.intType(.unsigned, @intCast(u16, ty.bitSize(mod))) catch @panic("out of memory");
1020 .base = .{ .tag = .int_unsigned },1022 return typeToValtype(int_ty, mod);
1021 .data = @intCast(u16, ty.bitSize(target)),
1022 };
1023 const int_ty = Type.initPayload(&int_ty_payload.base);
1024 return typeToValtype(int_ty, target);
1025 },1023 },
1026 else => wasm.Valtype.i32,1024 else => wasm.Valtype.i32,
1027 },1025 },
...@@ -1030,17 +1028,17 @@ fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {...@@ -1030,17 +1028,17 @@ fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {
1030}1028}
10311029
1032/// Using a given `Type`, returns the byte representation of its wasm value type1030/// Using a given `Type`, returns the byte representation of its wasm value type
1033fn genValtype(ty: Type, target: std.Target) u8 {1031fn genValtype(ty: Type, mod: *Module) u8 {
1034 return wasm.valtype(typeToValtype(ty, target));1032 return wasm.valtype(typeToValtype(ty, mod));
1035}1033}
10361034
1037/// Using a given `Type`, returns the corresponding wasm value type1035/// Using a given `Type`, returns the corresponding wasm value type
1038/// Differently from `genValtype` this also allows `void` to create a block1036/// Differently from `genValtype` this also allows `void` to create a block
1039/// with no return type1037/// with no return type
1040fn genBlockType(ty: Type, target: std.Target) u8 {1038fn genBlockType(ty: Type, mod: *Module) u8 {
1041 return switch (ty.tag()) {1039 return switch (ty.tag()) {
1042 .void, .noreturn => wasm.block_empty,1040 .void, .noreturn => wasm.block_empty,
1043 else => genValtype(ty, target),1041 else => genValtype(ty, mod),
1044 };1042 };
1045}1043}
10461044
...@@ -1101,7 +1099,8 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue {...@@ -1101,7 +1099,8 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue {
1101/// Creates one locals for a given `Type`.1099/// Creates one locals for a given `Type`.
1102/// Returns a corresponding `Wvalue` with `local` as active tag1100/// Returns a corresponding `Wvalue` with `local` as active tag
1103fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {1101fn 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);
1105 switch (valtype) {1104 switch (valtype) {
1106 .i32 => if (func.free_locals_i32.popOrNull()) |index| {1105 .i32 => if (func.free_locals_i32.popOrNull()) |index| {
1107 log.debug("reusing local ({d}) of type {}", .{ index, valtype });1106 log.debug("reusing local ({d}) of type {}", .{ index, valtype });
...@@ -1132,7 +1131,8 @@ fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -1132,7 +1131,8 @@ fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
1132/// Ensures a new local will be created. This is useful when it's useful1131/// Ensures a new local will be created. This is useful when it's useful
1133/// to use a zero-initialized local.1132/// to use a zero-initialized local.
1134fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {1133fn 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));
1136 const initial_index = func.local_index;1136 const initial_index = func.local_index;
1137 func.local_index += 1;1137 func.local_index += 1;
1138 return WValue{ .local = .{ .value = initial_index, .references = 1 } };1138 return WValue{ .local = .{ .value = initial_index, .references = 1 } };
...@@ -1140,48 +1140,54 @@ fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -1140,48 +1140,54 @@ fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
11401140
1141/// Generates a `wasm.Type` from a given function type.1141/// Generates a `wasm.Type` from a given function type.
1142/// Memory is owned by the caller.1142/// 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 {
1144 var temp_params = std.ArrayList(wasm.Valtype).init(gpa);1150 var temp_params = std.ArrayList(wasm.Valtype).init(gpa);
1145 defer temp_params.deinit();1151 defer temp_params.deinit();
1146 var returns = std.ArrayList(wasm.Valtype).init(gpa);1152 var returns = std.ArrayList(wasm.Valtype).init(gpa);
1147 defer returns.deinit();1153 defer returns.deinit();
11481154
1149 if (firstParamSRet(cc, return_type, target)) {1155 if (firstParamSRet(cc, return_type, mod)) {
1150 try temp_params.append(.i32); // memory address is always a 32-bit handle1156 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)) {
1152 if (cc == .C) {1158 if (cc == .C) {
1153 const res_classes = abi.classifyType(return_type, target);1159 const res_classes = abi.classifyType(return_type, mod);
1154 assert(res_classes[0] == .direct and res_classes[1] == .none);1160 assert(res_classes[0] == .direct and res_classes[1] == .none);
1155 const scalar_type = abi.scalarType(return_type, target);1161 const scalar_type = abi.scalarType(return_type, mod);
1156 try returns.append(typeToValtype(scalar_type, target));1162 try returns.append(typeToValtype(scalar_type, mod));
1157 } else {1163 } else {
1158 try returns.append(typeToValtype(return_type, target));1164 try returns.append(typeToValtype(return_type, mod));
1159 }1165 }
1160 } else if (return_type.isError()) {1166 } else if (return_type.isError(mod)) {
1161 try returns.append(.i32);1167 try returns.append(.i32);
1162 }1168 }
11631169
1164 // param types1170 // param types
1165 for (params) |param_type| {1171 for (params) |param_type| {
1166 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;1172 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;
11671173
1168 switch (cc) {1174 switch (cc) {
1169 .C => {1175 .C => {
1170 const param_classes = abi.classifyType(param_type, target);1176 const param_classes = abi.classifyType(param_type, mod);
1171 for (param_classes) |class| {1177 for (param_classes) |class| {
1172 if (class == .none) continue;1178 if (class == .none) continue;
1173 if (class == .direct) {1179 if (class == .direct) {
1174 const scalar_type = abi.scalarType(param_type, target);1180 const scalar_type = abi.scalarType(param_type, mod);
1175 try temp_params.append(typeToValtype(scalar_type, target));1181 try temp_params.append(typeToValtype(scalar_type, mod));
1176 } else {1182 } else {
1177 try temp_params.append(typeToValtype(param_type, target));1183 try temp_params.append(typeToValtype(param_type, mod));
1178 }1184 }
1179 }1185 }
1180 },1186 },
1181 else => if (isByRef(param_type, target))1187 else => if (isByRef(param_type, mod))
1182 try temp_params.append(.i32)1188 try temp_params.append(.i32)
1183 else1189 else
1184 try temp_params.append(typeToValtype(param_type, target)),1190 try temp_params.append(typeToValtype(param_type, mod)),
1185 }1191 }
1186 }1192 }
11871193
...@@ -1227,7 +1233,8 @@ pub fn generate(...@@ -1227,7 +1233,8 @@ pub fn generate(
12271233
1228fn genFunc(func: *CodeGen) InnerError!void {1234fn genFunc(func: *CodeGen) InnerError!void {
1229 const fn_info = func.decl.ty.fnInfo();1235 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);
1231 defer func_type.deinit(func.gpa);1238 defer func_type.deinit(func.gpa);
1232 _ = try func.bin_file.storeDeclType(func.decl_index, func_type);1239 _ = try func.bin_file.storeDeclType(func.decl_index, func_type);
12331240
...@@ -1254,7 +1261,7 @@ fn genFunc(func: *CodeGen) InnerError!void {...@@ -1254,7 +1261,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
1254 if (func_type.returns.len != 0 and func.air.instructions.len > 0) {1261 if (func_type.returns.len != 0 and func.air.instructions.len > 0) {
1255 const inst = @intCast(u32, func.air.instructions.len - 1);1262 const inst = @intCast(u32, func.air.instructions.len - 1);
1256 const last_inst_ty = func.air.typeOfIndex(inst);1263 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()) {
1258 try func.addTag(.@"unreachable");1265 try func.addTag(.@"unreachable");
1259 }1266 }
1260 }1267 }
...@@ -1335,6 +1342,7 @@ const CallWValues = struct {...@@ -1335,6 +1342,7 @@ const CallWValues = struct {
1335};1342};
13361343
1337fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWValues {1344fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWValues {
1345 const mod = func.bin_file.base.options.module.?;
1338 const cc = fn_ty.fnCallingConvention();1346 const cc = fn_ty.fnCallingConvention();
1339 const param_types = try func.gpa.alloc(Type, fn_ty.fnParamLen());1347 const param_types = try func.gpa.alloc(Type, fn_ty.fnParamLen());
1340 defer func.gpa.free(param_types);1348 defer func.gpa.free(param_types);
...@@ -1351,7 +1359,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV...@@ -1351,7 +1359,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
1351 // Check if we store the result as a pointer to the stack rather than1359 // Check if we store the result as a pointer to the stack rather than
1352 // by value1360 // by value
1353 const fn_info = fn_ty.fnInfo();1361 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)) {
1355 // the sret arg will be passed as first argument, therefore we1363 // the sret arg will be passed as first argument, therefore we
1356 // set the `return_value` before allocating locals for regular args.1364 // set the `return_value` before allocating locals for regular args.
1357 result.return_value = .{ .local = .{ .value = func.local_index, .references = 1 } };1365 result.return_value = .{ .local = .{ .value = func.local_index, .references = 1 } };
...@@ -1361,7 +1369,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV...@@ -1361,7 +1369,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
1361 switch (cc) {1369 switch (cc) {
1362 .Unspecified => {1370 .Unspecified => {
1363 for (param_types) |ty| {1371 for (param_types) |ty| {
1364 if (!ty.hasRuntimeBitsIgnoreComptime()) {1372 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
1365 continue;1373 continue;
1366 }1374 }
13671375
...@@ -1371,7 +1379,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV...@@ -1371,7 +1379,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
1371 },1379 },
1372 .C => {1380 .C => {
1373 for (param_types) |ty| {1381 for (param_types) |ty| {
1374 const ty_classes = abi.classifyType(ty, func.target);1382 const ty_classes = abi.classifyType(ty, mod);
1375 for (ty_classes) |class| {1383 for (ty_classes) |class| {
1376 if (class == .none) continue;1384 if (class == .none) continue;
1377 try args.append(.{ .local = .{ .value = func.local_index, .references = 1 } });1385 try args.append(.{ .local = .{ .value = func.local_index, .references = 1 } });
...@@ -1385,11 +1393,11 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV...@@ -1385,11 +1393,11 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
1385 return result;1393 return result;
1386}1394}
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 {
1389 switch (cc) {1397 switch (cc) {
1390 .Unspecified, .Inline => return isByRef(return_type, target),1398 .Unspecified, .Inline => return isByRef(return_type, mod),
1391 .C => {1399 .C => {
1392 const ty_classes = abi.classifyType(return_type, target);1400 const ty_classes = abi.classifyType(return_type, mod);
1393 if (ty_classes[0] == .indirect) return true;1401 if (ty_classes[0] == .indirect) return true;
1394 if (ty_classes[0] == .direct and ty_classes[1] == .direct) return true;1402 if (ty_classes[0] == .direct and ty_classes[1] == .direct) return true;
1395 return false;1403 return false;
...@@ -1405,16 +1413,17 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:...@@ -1405,16 +1413,17 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:
1405 return func.lowerToStack(value);1413 return func.lowerToStack(value);
1406 }1414 }
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);
1409 assert(ty_classes[0] != .none);1418 assert(ty_classes[0] != .none);
1410 switch (ty.zigTypeTag()) {1419 switch (ty.zigTypeTag(mod)) {
1411 .Struct, .Union => {1420 .Struct, .Union => {
1412 if (ty_classes[0] == .indirect) {1421 if (ty_classes[0] == .indirect) {
1413 return func.lowerToStack(value);1422 return func.lowerToStack(value);
1414 }1423 }
1415 assert(ty_classes[0] == .direct);1424 assert(ty_classes[0] == .direct);
1416 const scalar_type = abi.scalarType(ty, func.target);1425 const scalar_type = abi.scalarType(ty, mod);
1417 const abi_size = scalar_type.abiSize(func.target);1426 const abi_size = scalar_type.abiSize(mod);
1418 try func.emitWValue(value);1427 try func.emitWValue(value);
14191428
1420 // When the value lives in the virtual stack, we must load it onto the actual stack1429 // 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:...@@ -1422,12 +1431,12 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:
1422 const opcode = buildOpcode(.{1431 const opcode = buildOpcode(.{
1423 .op = .load,1432 .op = .load,
1424 .width = @intCast(u8, abi_size),1433 .width = @intCast(u8, abi_size),
1425 .signedness = if (scalar_type.isSignedInt()) .signed else .unsigned,1434 .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned,
1426 .valtype1 = typeToValtype(scalar_type, func.target),1435 .valtype1 = typeToValtype(scalar_type, mod),
1427 });1436 });
1428 try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{1437 try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{
1429 .offset = value.offset(),1438 .offset = value.offset(),
1430 .alignment = scalar_type.abiAlignment(func.target),1439 .alignment = scalar_type.abiAlignment(mod),
1431 });1440 });
1432 }1441 }
1433 },1442 },
...@@ -1436,7 +1445,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:...@@ -1436,7 +1445,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:
1436 return func.lowerToStack(value);1445 return func.lowerToStack(value);
1437 }1446 }
1438 assert(ty_classes[0] == .direct and ty_classes[1] == .direct);1447 assert(ty_classes[0] == .direct and ty_classes[1] == .direct);
1439 assert(ty.abiSize(func.target) == 16);1448 assert(ty.abiSize(mod) == 16);
1440 // in this case we have an integer or float that must be lowered as 2 i64's.1449 // in this case we have an integer or float that must be lowered as 2 i64's.
1441 try func.emitWValue(value);1450 try func.emitWValue(value);
1442 try func.addMemArg(.i64_load, .{ .offset = value.offset(), .alignment = 8 });1451 try func.addMemArg(.i64_load, .{ .offset = value.offset(), .alignment = 8 });
...@@ -1503,18 +1512,18 @@ fn restoreStackPointer(func: *CodeGen) !void {...@@ -1503,18 +1512,18 @@ fn restoreStackPointer(func: *CodeGen) !void {
1503///1512///
1504/// Asserts Type has codegenbits1513/// Asserts Type has codegenbits
1505fn allocStack(func: *CodeGen, ty: Type) !WValue {1514fn allocStack(func: *CodeGen, ty: Type) !WValue {
1506 assert(ty.hasRuntimeBitsIgnoreComptime());1515 const mod = func.bin_file.base.options.module.?;
1516 assert(ty.hasRuntimeBitsIgnoreComptime(mod));
1507 if (func.initial_stack_value == .none) {1517 if (func.initial_stack_value == .none) {
1508 try func.initializeStack();1518 try func.initializeStack();
1509 }1519 }
15101520
1511 const abi_size = std.math.cast(u32, ty.abiSize(func.target)) orelse {1521 const abi_size = std.math.cast(u32, ty.abiSize(mod)) orelse {
1512 const module = func.bin_file.base.options.module.?;
1513 return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{1522 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),
1515 });1524 });
1516 };1525 };
1517 const abi_align = ty.abiAlignment(func.target);1526 const abi_align = ty.abiAlignment(mod);
15181527
1519 if (abi_align > func.stack_alignment) {1528 if (abi_align > func.stack_alignment) {
1520 func.stack_alignment = abi_align;1529 func.stack_alignment = abi_align;
...@@ -1531,6 +1540,7 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue {...@@ -1531,6 +1540,7 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue {
1531/// This is different from allocStack where this will use the pointer's alignment1540/// This is different from allocStack where this will use the pointer's alignment
1532/// if it is set, to ensure the stack alignment will be set correctly.1541/// if it is set, to ensure the stack alignment will be set correctly.
1533fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {1542fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {
1543 const mod = func.bin_file.base.options.module.?;
1534 const ptr_ty = func.air.typeOfIndex(inst);1544 const ptr_ty = func.air.typeOfIndex(inst);
1535 const pointee_ty = ptr_ty.childType();1545 const pointee_ty = ptr_ty.childType();
15361546
...@@ -1538,15 +1548,14 @@ fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {...@@ -1538,15 +1548,14 @@ fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {
1538 try func.initializeStack();1548 try func.initializeStack();
1539 }1549 }
15401550
1541 if (!pointee_ty.hasRuntimeBitsIgnoreComptime()) {1551 if (!pointee_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1542 return func.allocStack(Type.usize); // create a value containing just the stack pointer.1552 return func.allocStack(Type.usize); // create a value containing just the stack pointer.
1543 }1553 }
15441554
1545 const abi_alignment = ptr_ty.ptrAlignment(func.target);1555 const abi_alignment = ptr_ty.ptrAlignment(mod);
1546 const abi_size = std.math.cast(u32, pointee_ty.abiSize(func.target)) orelse {1556 const abi_size = std.math.cast(u32, pointee_ty.abiSize(mod)) orelse {
1547 const module = func.bin_file.base.options.module.?;
1548 return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{1557 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),
1550 });1559 });
1551 };1560 };
1552 if (abi_alignment > func.stack_alignment) {1561 if (abi_alignment > func.stack_alignment) {
...@@ -1704,8 +1713,9 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch {...@@ -1704,8 +1713,9 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch {
17041713
1705/// For a given `Type`, will return true when the type will be passed1714/// For a given `Type`, will return true when the type will be passed
1706/// by reference, rather than by value1715/// by reference, rather than by value
1707fn isByRef(ty: Type, target: std.Target) bool {1716fn isByRef(ty: Type, mod: *const Module) bool {
1708 switch (ty.zigTypeTag()) {1717 const target = mod.getTarget();
1718 switch (ty.zigTypeTag(mod)) {
1709 .Type,1719 .Type,
1710 .ComptimeInt,1720 .ComptimeInt,
1711 .ComptimeFloat,1721 .ComptimeFloat,
...@@ -1726,40 +1736,40 @@ fn isByRef(ty: Type, target: std.Target) bool {...@@ -1726,40 +1736,40 @@ fn isByRef(ty: Type, target: std.Target) bool {
17261736
1727 .Array,1737 .Array,
1728 .Frame,1738 .Frame,
1729 => return ty.hasRuntimeBitsIgnoreComptime(),1739 => return ty.hasRuntimeBitsIgnoreComptime(mod),
1730 .Union => {1740 .Union => {
1731 if (ty.castTag(.@"union")) |union_ty| {1741 if (ty.castTag(.@"union")) |union_ty| {
1732 if (union_ty.data.layout == .Packed) {1742 if (union_ty.data.layout == .Packed) {
1733 return ty.abiSize(target) > 8;1743 return ty.abiSize(mod) > 8;
1734 }1744 }
1735 }1745 }
1736 return ty.hasRuntimeBitsIgnoreComptime();1746 return ty.hasRuntimeBitsIgnoreComptime(mod);
1737 },1747 },
1738 .Struct => {1748 .Struct => {
1739 if (ty.castTag(.@"struct")) |struct_ty| {1749 if (ty.castTag(.@"struct")) |struct_ty| {
1740 const struct_obj = struct_ty.data;1750 const struct_obj = struct_ty.data;
1741 if (struct_obj.layout == .Packed and struct_obj.haveFieldTypes()) {1751 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);
1743 }1753 }
1744 }1754 }
1745 return ty.hasRuntimeBitsIgnoreComptime();1755 return ty.hasRuntimeBitsIgnoreComptime(mod);
1746 },1756 },
1747 .Vector => return determineSimdStoreStrategy(ty, target) == .unrolled,1757 .Vector => return determineSimdStoreStrategy(ty, mod) == .unrolled,
1748 .Int => return ty.intInfo(target).bits > 64,1758 .Int => return ty.intInfo(mod).bits > 64,
1749 .Float => return ty.floatBits(target) > 64,1759 .Float => return ty.floatBits(target) > 64,
1750 .ErrorUnion => {1760 .ErrorUnion => {
1751 const pl_ty = ty.errorUnionPayload();1761 const pl_ty = ty.errorUnionPayload();
1752 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {1762 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1753 return false;1763 return false;
1754 }1764 }
1755 return true;1765 return true;
1756 },1766 },
1757 .Optional => {1767 .Optional => {
1758 if (ty.isPtrLikeOptional()) return false;1768 if (ty.isPtrLikeOptional(mod)) return false;
1759 var buf: Type.Payload.ElemType = undefined;1769 var buf: Type.Payload.ElemType = undefined;
1760 const pl_type = ty.optionalChild(&buf);1770 const pl_type = ty.optionalChild(&buf);
1761 if (pl_type.zigTypeTag() == .ErrorSet) return false;1771 if (pl_type.zigTypeTag(mod) == .ErrorSet) return false;
1762 return pl_type.hasRuntimeBitsIgnoreComptime();1772 return pl_type.hasRuntimeBitsIgnoreComptime(mod);
1763 },1773 },
1764 .Pointer => {1774 .Pointer => {
1765 // Slices act like struct and will be passed by reference1775 // Slices act like struct and will be passed by reference
...@@ -1778,10 +1788,11 @@ const SimdStoreStrategy = enum {...@@ -1778,10 +1788,11 @@ const SimdStoreStrategy = enum {
1778/// This means when a given type is 128 bits and either the simd128 or relaxed-simd1788/// This means when a given type is 128 bits and either the simd128 or relaxed-simd
1779/// features are enabled, the function will return `.direct`. This would allow to store1789/// features are enabled, the function will return `.direct`. This would allow to store
1780/// it using a instruction, rather than an unrolled version.1790/// it using a instruction, rather than an unrolled version.
1781fn determineSimdStoreStrategy(ty: Type, target: std.Target) SimdStoreStrategy {1791fn determineSimdStoreStrategy(ty: Type, mod: *const Module) SimdStoreStrategy {
1782 std.debug.assert(ty.zigTypeTag() == .Vector);1792 std.debug.assert(ty.zigTypeTag(mod) == .Vector);
1783 if (ty.bitSize(target) != 128) return .unrolled;1793 if (ty.bitSize(mod) != 128) return .unrolled;
1784 const hasFeature = std.Target.wasm.featureSetHas;1794 const hasFeature = std.Target.wasm.featureSetHas;
1795 const target = mod.getTarget();
1785 const features = target.cpu.features;1796 const features = target.cpu.features;
1786 if (hasFeature(features, .relaxed_simd) or hasFeature(features, .simd128)) {1797 if (hasFeature(features, .relaxed_simd) or hasFeature(features, .simd128)) {
1787 return .direct;1798 return .direct;
...@@ -2084,32 +2095,33 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2084,32 +2095,33 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2084 const operand = try func.resolveInst(un_op);2095 const operand = try func.resolveInst(un_op);
2085 const fn_info = func.decl.ty.fnInfo();2096 const fn_info = func.decl.ty.fnInfo();
2086 const ret_ty = fn_info.return_type;2097 const ret_ty = fn_info.return_type;
2098 const mod = func.bin_file.base.options.module.?;
20872099
2088 // result must be stored in the stack and we return a pointer2100 // result must be stored in the stack and we return a pointer
2089 // to the stack instead2101 // to the stack instead
2090 if (func.return_value != .none) {2102 if (func.return_value != .none) {
2091 try func.store(func.return_value, operand, ret_ty, 0);2103 try func.store(func.return_value, operand, ret_ty, 0);
2092 } else if (fn_info.cc == .C and ret_ty.hasRuntimeBitsIgnoreComptime()) {2104 } else if (fn_info.cc == .C and ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2093 switch (ret_ty.zigTypeTag()) {2105 switch (ret_ty.zigTypeTag(mod)) {
2094 // Aggregate types can be lowered as a singular value2106 // Aggregate types can be lowered as a singular value
2095 .Struct, .Union => {2107 .Struct, .Union => {
2096 const scalar_type = abi.scalarType(ret_ty, func.target);2108 const scalar_type = abi.scalarType(ret_ty, mod);
2097 try func.emitWValue(operand);2109 try func.emitWValue(operand);
2098 const opcode = buildOpcode(.{2110 const opcode = buildOpcode(.{
2099 .op = .load,2111 .op = .load,
2100 .width = @intCast(u8, scalar_type.abiSize(func.target) * 8),2112 .width = @intCast(u8, scalar_type.abiSize(mod) * 8),
2101 .signedness = if (scalar_type.isSignedInt()) .signed else .unsigned,2113 .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned,
2102 .valtype1 = typeToValtype(scalar_type, func.target),2114 .valtype1 = typeToValtype(scalar_type, mod),
2103 });2115 });
2104 try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{2116 try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{
2105 .offset = operand.offset(),2117 .offset = operand.offset(),
2106 .alignment = scalar_type.abiAlignment(func.target),2118 .alignment = scalar_type.abiAlignment(mod),
2107 });2119 });
2108 },2120 },
2109 else => try func.emitWValue(operand),2121 else => try func.emitWValue(operand),
2110 }2122 }
2111 } else {2123 } else {
2112 if (!ret_ty.hasRuntimeBitsIgnoreComptime() and ret_ty.isError()) {2124 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and ret_ty.isError(mod)) {
2113 try func.addImm32(0);2125 try func.addImm32(0);
2114 } else {2126 } else {
2115 try func.emitWValue(operand);2127 try func.emitWValue(operand);
...@@ -2123,14 +2135,15 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2123,14 +2135,15 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21232135
2124fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {2136fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2125 const child_type = func.air.typeOfIndex(inst).childType();2137 const child_type = func.air.typeOfIndex(inst).childType();
2138 const mod = func.bin_file.base.options.module.?;
21262139
2127 var result = result: {2140 var result = result: {
2128 if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime()) {2141 if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
2129 break :result try func.allocStack(Type.usize); // create pointer to void2142 break :result try func.allocStack(Type.usize); // create pointer to void
2130 }2143 }
21312144
2132 const fn_info = func.decl.ty.fnInfo();2145 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)) {
2134 break :result func.return_value;2147 break :result func.return_value;
2135 }2148 }
21362149
...@@ -2141,16 +2154,17 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2141,16 +2154,17 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2141}2154}
21422155
2143fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {2156fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2157 const mod = func.bin_file.base.options.module.?;
2144 const un_op = func.air.instructions.items(.data)[inst].un_op;2158 const un_op = func.air.instructions.items(.data)[inst].un_op;
2145 const operand = try func.resolveInst(un_op);2159 const operand = try func.resolveInst(un_op);
2146 const ret_ty = func.air.typeOf(un_op).childType();2160 const ret_ty = func.air.typeOf(un_op).childType();
21472161
2148 const fn_info = func.decl.ty.fnInfo();2162 const fn_info = func.decl.ty.fnInfo();
2149 if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {2163 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2150 if (ret_ty.isError()) {2164 if (ret_ty.isError(mod)) {
2151 try func.addImm32(0);2165 try func.addImm32(0);
2152 }2166 }
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)) {
2154 // leave on the stack2168 // leave on the stack
2155 _ = try func.load(operand, ret_ty, 0);2169 _ = try func.load(operand, ret_ty, 0);
2156 }2170 }
...@@ -2167,26 +2181,26 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2167,26 +2181,26 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2167 const args = @ptrCast([]const Air.Inst.Ref, func.air.extra[extra.end..][0..extra.data.args_len]);2181 const args = @ptrCast([]const Air.Inst.Ref, func.air.extra[extra.end..][0..extra.data.args_len]);
2168 const ty = func.air.typeOf(pl_op.operand);2182 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)) {
2171 .Fn => ty,2186 .Fn => ty,
2172 .Pointer => ty.childType(),2187 .Pointer => ty.childType(),
2173 else => unreachable,2188 else => unreachable,
2174 };2189 };
2175 const ret_ty = fn_ty.fnReturnType();2190 const ret_ty = fn_ty.fnReturnType();
2176 const fn_info = fn_ty.fnInfo();2191 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
2179 const callee: ?Decl.Index = blk: {2194 const callee: ?Decl.Index = blk: {
2180 const func_val = func.air.value(pl_op.operand) orelse break :blk null;2195 const func_val = func.air.value(pl_op.operand, mod) orelse break :blk null;
2181 const module = func.bin_file.base.options.module.?;
21822196
2183 if (func_val.castTag(.function)) |function| {2197 if (func_val.castTag(.function)) |function| {
2184 _ = try func.bin_file.getOrCreateAtomForDecl(function.data.owner_decl);2198 _ = try func.bin_file.getOrCreateAtomForDecl(function.data.owner_decl);
2185 break :blk function.data.owner_decl;2199 break :blk function.data.owner_decl;
2186 } else if (func_val.castTag(.extern_fn)) |extern_fn| {2200 } 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);
2188 const ext_info = ext_decl.ty.fnInfo();2202 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);
2190 defer func_type.deinit(func.gpa);2204 defer func_type.deinit(func.gpa);
2191 const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_fn.data.owner_decl);2205 const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_fn.data.owner_decl);
2192 const atom = func.bin_file.getAtomPtr(atom_index);2206 const atom = func.bin_file.getAtomPtr(atom_index);
...@@ -2215,7 +2229,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2215,7 +2229,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2215 const arg_val = try func.resolveInst(arg);2229 const arg_val = try func.resolveInst(arg);
22162230
2217 const arg_ty = func.air.typeOf(arg);2231 const arg_ty = func.air.typeOf(arg);
2218 if (!arg_ty.hasRuntimeBitsIgnoreComptime()) continue;2232 if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
22192233
2220 try func.lowerArg(fn_ty.fnInfo().cc, arg_ty, arg_val);2234 try func.lowerArg(fn_ty.fnInfo().cc, arg_ty, arg_val);
2221 }2235 }
...@@ -2226,11 +2240,11 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2226,11 +2240,11 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2226 } else {2240 } else {
2227 // in this case we call a function pointer2241 // in this case we call a function pointer
2228 // so load its value onto the stack2242 // so load its value onto the stack
2229 std.debug.assert(ty.zigTypeTag() == .Pointer);2243 std.debug.assert(ty.zigTypeTag(mod) == .Pointer);
2230 const operand = try func.resolveInst(pl_op.operand);2244 const operand = try func.resolveInst(pl_op.operand);
2231 try func.emitWValue(operand);2245 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);
2234 defer fn_type.deinit(func.gpa);2248 defer fn_type.deinit(func.gpa);
22352249
2236 const fn_type_index = try func.bin_file.putOrGetFuncType(fn_type);2250 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...@@ -2238,7 +2252,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2238 }2252 }
22392253
2240 const result_value = result_value: {2254 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)) {
2242 break :result_value WValue{ .none = {} };2256 break :result_value WValue{ .none = {} };
2243 } else if (ret_ty.isNoReturn()) {2257 } else if (ret_ty.isNoReturn()) {
2244 try func.addTag(.@"unreachable");2258 try func.addTag(.@"unreachable");
...@@ -2246,10 +2260,10 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2246,10 +2260,10 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2246 } else if (first_param_sret) {2260 } else if (first_param_sret) {
2247 break :result_value sret;2261 break :result_value sret;
2248 // TODO: Make this less fragile and optimize2262 // 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) {
2250 const result_local = try func.allocLocal(ret_ty);2264 const result_local = try func.allocLocal(ret_ty);
2251 try func.addLabel(.local_set, result_local.local.value);2265 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);
2253 const result = try func.allocStack(scalar_type);2267 const result = try func.allocStack(scalar_type);
2254 try func.store(result, result_local, scalar_type, 0);2268 try func.store(result, result_local, scalar_type, 0);
2255 break :result_value result;2269 break :result_value result;
...@@ -2272,6 +2286,7 @@ fn airAlloc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2272,6 +2286,7 @@ fn airAlloc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2272}2286}
22732287
2274fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {2288fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
2289 const mod = func.bin_file.base.options.module.?;
2275 if (safety) {2290 if (safety) {
2276 // TODO if the value is undef, write 0xaa bytes to dest2291 // TODO if the value is undef, write 0xaa bytes to dest
2277 } else {2292 } else {
...@@ -2290,17 +2305,13 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void...@@ -2290,17 +2305,13 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
2290 } else {2305 } else {
2291 // at this point we have a non-natural alignment, we must2306 // at this point we have a non-natural alignment, we must
2292 // load the value, and then shift+or the rhs into the result location.2307 // load the value, and then shift+or the rhs into the result location.
2293 var int_ty_payload: Type.Payload.Bits = .{2308 const int_elem_ty = try mod.intType(.unsigned, ptr_info.host_size * 8);
2294 .base = .{ .tag = .int_unsigned },
2295 .data = ptr_info.host_size * 8,
2296 };
2297 const int_elem_ty = Type.initPayload(&int_ty_payload.base);
22982309
2299 if (isByRef(int_elem_ty, func.target)) {2310 if (isByRef(int_elem_ty, mod)) {
2300 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});2311 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});
2301 }2312 }
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);
2304 mask <<= @intCast(u6, ptr_info.bit_offset);2315 mask <<= @intCast(u6, ptr_info.bit_offset);
2305 mask ^= ~@as(u64, 0);2316 mask ^= ~@as(u64, 0);
2306 const shift_val = if (ptr_info.host_size <= 4)2317 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...@@ -2329,11 +2340,12 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
23292340
2330fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void {2341fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void {
2331 assert(!(lhs != .stack and rhs == .stack));2342 assert(!(lhs != .stack and rhs == .stack));
2332 const abi_size = ty.abiSize(func.target);2343 const mod = func.bin_file.base.options.module.?;
2333 switch (ty.zigTypeTag()) {2344 const abi_size = ty.abiSize(mod);
2345 switch (ty.zigTypeTag(mod)) {
2334 .ErrorUnion => {2346 .ErrorUnion => {
2335 const pl_ty = ty.errorUnionPayload();2347 const pl_ty = ty.errorUnionPayload();
2336 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {2348 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2337 return func.store(lhs, rhs, Type.anyerror, 0);2349 return func.store(lhs, rhs, Type.anyerror, 0);
2338 }2350 }
23392351
...@@ -2341,26 +2353,26 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2341,26 +2353,26 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2341 return func.memcpy(lhs, rhs, .{ .imm32 = len });2353 return func.memcpy(lhs, rhs, .{ .imm32 = len });
2342 },2354 },
2343 .Optional => {2355 .Optional => {
2344 if (ty.isPtrLikeOptional()) {2356 if (ty.isPtrLikeOptional(mod)) {
2345 return func.store(lhs, rhs, Type.usize, 0);2357 return func.store(lhs, rhs, Type.usize, 0);
2346 }2358 }
2347 var buf: Type.Payload.ElemType = undefined;2359 var buf: Type.Payload.ElemType = undefined;
2348 const pl_ty = ty.optionalChild(&buf);2360 const pl_ty = ty.optionalChild(&buf);
2349 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {2361 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2350 return func.store(lhs, rhs, Type.u8, 0);2362 return func.store(lhs, rhs, Type.u8, 0);
2351 }2363 }
2352 if (pl_ty.zigTypeTag() == .ErrorSet) {2364 if (pl_ty.zigTypeTag(mod) == .ErrorSet) {
2353 return func.store(lhs, rhs, Type.anyerror, 0);2365 return func.store(lhs, rhs, Type.anyerror, 0);
2354 }2366 }
23552367
2356 const len = @intCast(u32, abi_size);2368 const len = @intCast(u32, abi_size);
2357 return func.memcpy(lhs, rhs, .{ .imm32 = len });2369 return func.memcpy(lhs, rhs, .{ .imm32 = len });
2358 },2370 },
2359 .Struct, .Array, .Union => if (isByRef(ty, func.target)) {2371 .Struct, .Array, .Union => if (isByRef(ty, mod)) {
2360 const len = @intCast(u32, abi_size);2372 const len = @intCast(u32, abi_size);
2361 return func.memcpy(lhs, rhs, .{ .imm32 = len });2373 return func.memcpy(lhs, rhs, .{ .imm32 = len });
2362 },2374 },
2363 .Vector => switch (determineSimdStoreStrategy(ty, func.target)) {2375 .Vector => switch (determineSimdStoreStrategy(ty, mod)) {
2364 .unrolled => {2376 .unrolled => {
2365 const len = @intCast(u32, abi_size);2377 const len = @intCast(u32, abi_size);
2366 return func.memcpy(lhs, rhs, .{ .imm32 = len });2378 return func.memcpy(lhs, rhs, .{ .imm32 = len });
...@@ -2374,7 +2386,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2374,7 +2386,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2374 try func.mir_extra.appendSlice(func.gpa, &[_]u32{2386 try func.mir_extra.appendSlice(func.gpa, &[_]u32{
2375 std.wasm.simdOpcode(.v128_store),2387 std.wasm.simdOpcode(.v128_store),
2376 offset + lhs.offset(),2388 offset + lhs.offset(),
2377 ty.abiAlignment(func.target),2389 ty.abiAlignment(mod),
2378 });2390 });
2379 return func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });2391 return func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
2380 },2392 },
...@@ -2404,7 +2416,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2404,7 +2416,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2404 try func.store(.{ .stack = {} }, msb, Type.u64, 8 + lhs.offset());2416 try func.store(.{ .stack = {} }, msb, Type.u64, 8 + lhs.offset());
2405 return;2417 return;
2406 } else if (abi_size > 16) {2418 } 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)) });
2408 },2420 },
2409 else => if (abi_size > 8) {2421 else => if (abi_size > 8) {
2410 return func.fail("TODO: `store` for type `{}` with abisize `{d}`", .{2422 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...@@ -2418,7 +2430,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2418 // into lhs, so we calculate that and emit that instead2430 // into lhs, so we calculate that and emit that instead
2419 try func.lowerToStack(rhs);2431 try func.lowerToStack(rhs);
24202432
2421 const valtype = typeToValtype(ty, func.target);2433 const valtype = typeToValtype(ty, mod);
2422 const opcode = buildOpcode(.{2434 const opcode = buildOpcode(.{
2423 .valtype1 = valtype,2435 .valtype1 = valtype,
2424 .width = @intCast(u8, abi_size * 8),2436 .width = @intCast(u8, abi_size * 8),
...@@ -2428,21 +2440,22 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2428,21 +2440,22 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2428 // store rhs value at stack pointer's location in memory2440 // store rhs value at stack pointer's location in memory
2429 try func.addMemArg(2441 try func.addMemArg(
2430 Mir.Inst.Tag.fromOpcode(opcode),2442 Mir.Inst.Tag.fromOpcode(opcode),
2431 .{ .offset = offset + lhs.offset(), .alignment = ty.abiAlignment(func.target) },2443 .{ .offset = offset + lhs.offset(), .alignment = ty.abiAlignment(mod) },
2432 );2444 );
2433}2445}
24342446
2435fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {2447fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2448 const mod = func.bin_file.base.options.module.?;
2436 const ty_op = func.air.instructions.items(.data)[inst].ty_op;2449 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
2437 const operand = try func.resolveInst(ty_op.operand);2450 const operand = try func.resolveInst(ty_op.operand);
2438 const ty = func.air.getRefType(ty_op.ty);2451 const ty = func.air.getRefType(ty_op.ty);
2439 const ptr_ty = func.air.typeOf(ty_op.operand);2452 const ptr_ty = func.air.typeOf(ty_op.operand);
2440 const ptr_info = ptr_ty.ptrInfo().data;2453 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
2444 const result = result: {2457 const result = result: {
2445 if (isByRef(ty, func.target)) {2458 if (isByRef(ty, mod)) {
2446 const new_local = try func.allocStack(ty);2459 const new_local = try func.allocStack(ty);
2447 try func.store(new_local, operand, ty, 0);2460 try func.store(new_local, operand, ty, 0);
2448 break :result new_local;2461 break :result new_local;
...@@ -2455,11 +2468,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2455,11 +2468,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
24552468
2456 // at this point we have a non-natural alignment, we must2469 // at this point we have a non-natural alignment, we must
2457 // shift the value to obtain the correct bit.2470 // shift the value to obtain the correct bit.
2458 var int_ty_payload: Type.Payload.Bits = .{2471 const int_elem_ty = try mod.intType(.unsigned, ptr_info.host_size * 8);
2459 .base = .{ .tag = .int_unsigned },
2460 .data = ptr_info.host_size * 8,
2461 };
2462 const int_elem_ty = Type.initPayload(&int_ty_payload.base);
2463 const shift_val = if (ptr_info.host_size <= 4)2472 const shift_val = if (ptr_info.host_size <= 4)
2464 WValue{ .imm32 = ptr_info.bit_offset }2473 WValue{ .imm32 = ptr_info.bit_offset }
2465 else if (ptr_info.host_size <= 8)2474 else if (ptr_info.host_size <= 8)
...@@ -2479,25 +2488,26 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2479,25 +2488,26 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2479/// Loads an operand from the linear memory section.2488/// Loads an operand from the linear memory section.
2480/// NOTE: Leaves the value on the stack.2489/// NOTE: Leaves the value on the stack.
2481fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValue {2490fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValue {
2491 const mod = func.bin_file.base.options.module.?;
2482 // load local's value from memory by its stack position2492 // load local's value from memory by its stack position
2483 try func.emitWValue(operand);2493 try func.emitWValue(operand);
24842494
2485 if (ty.zigTypeTag() == .Vector) {2495 if (ty.zigTypeTag(mod) == .Vector) {
2486 // TODO: Add helper functions for simd opcodes2496 // TODO: Add helper functions for simd opcodes
2487 const extra_index = @intCast(u32, func.mir_extra.items.len);2497 const extra_index = @intCast(u32, func.mir_extra.items.len);
2488 // stores as := opcode, offset, alignment (opcode::memarg)2498 // stores as := opcode, offset, alignment (opcode::memarg)
2489 try func.mir_extra.appendSlice(func.gpa, &[_]u32{2499 try func.mir_extra.appendSlice(func.gpa, &[_]u32{
2490 std.wasm.simdOpcode(.v128_load),2500 std.wasm.simdOpcode(.v128_load),
2491 offset + operand.offset(),2501 offset + operand.offset(),
2492 ty.abiAlignment(func.target),2502 ty.abiAlignment(mod),
2493 });2503 });
2494 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });2504 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
2495 return WValue{ .stack = {} };2505 return WValue{ .stack = {} };
2496 }2506 }
24972507
2498 const abi_size = @intCast(u8, ty.abiSize(func.target));2508 const abi_size = @intCast(u8, ty.abiSize(mod));
2499 const opcode = buildOpcode(.{2509 const opcode = buildOpcode(.{
2500 .valtype1 = typeToValtype(ty, func.target),2510 .valtype1 = typeToValtype(ty, mod),
2501 .width = abi_size * 8,2511 .width = abi_size * 8,
2502 .op = .load,2512 .op = .load,
2503 .signedness = .unsigned,2513 .signedness = .unsigned,
...@@ -2505,7 +2515,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu...@@ -2505,7 +2515,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
25052515
2506 try func.addMemArg(2516 try func.addMemArg(
2507 Mir.Inst.Tag.fromOpcode(opcode),2517 Mir.Inst.Tag.fromOpcode(opcode),
2508 .{ .offset = offset + operand.offset(), .alignment = ty.abiAlignment(func.target) },2518 .{ .offset = offset + operand.offset(), .alignment = ty.abiAlignment(mod) },
2509 );2519 );
25102520
2511 return WValue{ .stack = {} };2521 return WValue{ .stack = {} };
...@@ -2516,8 +2526,9 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2516,8 +2526,9 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2516 const arg = func.args[arg_index];2526 const arg = func.args[arg_index];
2517 const cc = func.decl.ty.fnInfo().cc;2527 const cc = func.decl.ty.fnInfo().cc;
2518 const arg_ty = func.air.typeOfIndex(inst);2528 const arg_ty = func.air.typeOfIndex(inst);
2529 const mod = func.bin_file.base.options.module.?;
2519 if (cc == .C) {2530 if (cc == .C) {
2520 const arg_classes = abi.classifyType(arg_ty, func.target);2531 const arg_classes = abi.classifyType(arg_ty, mod);
2521 for (arg_classes) |class| {2532 for (arg_classes) |class| {
2522 if (class != .none) {2533 if (class != .none) {
2523 func.arg_index += 1;2534 func.arg_index += 1;
...@@ -2527,7 +2538,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2527,7 +2538,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2527 // When we have an argument that's passed using more than a single parameter,2538 // When we have an argument that's passed using more than a single parameter,
2528 // we combine them into a single stack value2539 // we combine them into a single stack value
2529 if (arg_classes[0] == .direct and arg_classes[1] == .direct) {2540 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) {
2531 return func.fail(2542 return func.fail(
2532 "TODO: Implement C-ABI argument for type '{}'",2543 "TODO: Implement C-ABI argument for type '{}'",
2533 .{arg_ty.fmt(func.bin_file.base.options.module.?)},2544 .{arg_ty.fmt(func.bin_file.base.options.module.?)},
...@@ -2557,6 +2568,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2557,6 +2568,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2557}2568}
25582569
2559fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {2570fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2571 const mod = func.bin_file.base.options.module.?;
2560 const bin_op = func.air.instructions.items(.data)[inst].bin_op;2572 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
2561 const lhs = try func.resolveInst(bin_op.lhs);2573 const lhs = try func.resolveInst(bin_op.lhs);
2562 const rhs = try func.resolveInst(bin_op.rhs);2574 const rhs = try func.resolveInst(bin_op.rhs);
...@@ -2570,10 +2582,10 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -2570,10 +2582,10 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2570 // For big integers we can ignore this as we will call into compiler-rt which handles this.2582 // For big integers we can ignore this as we will call into compiler-rt which handles this.
2571 const result = switch (op) {2583 const result = switch (op) {
2572 .shr, .shl => res: {2584 .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 {
2574 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});2586 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});
2575 };2587 };
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))).?;
2577 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {2589 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {
2578 const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);2590 const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);
2579 break :blk try tmp.toLocal(func, lhs_ty);2591 break :blk try tmp.toLocal(func, lhs_ty);
...@@ -2593,6 +2605,7 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -2593,6 +2605,7 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2593/// Performs a binary operation on the given `WValue`'s2605/// Performs a binary operation on the given `WValue`'s
2594/// NOTE: THis leaves the value on top of the stack.2606/// NOTE: THis leaves the value on top of the stack.
2595fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {2607fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {
2608 const mod = func.bin_file.base.options.module.?;
2596 assert(!(lhs != .stack and rhs == .stack));2609 assert(!(lhs != .stack and rhs == .stack));
25972610
2598 if (ty.isAnyFloat()) {2611 if (ty.isAnyFloat()) {
...@@ -2600,8 +2613,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!...@@ -2600,8 +2613,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
2600 return func.floatOp(float_op, ty, &.{ lhs, rhs });2613 return func.floatOp(float_op, ty, &.{ lhs, rhs });
2601 }2614 }
26022615
2603 if (isByRef(ty, func.target)) {2616 if (isByRef(ty, mod)) {
2604 if (ty.zigTypeTag() == .Int) {2617 if (ty.zigTypeTag(mod) == .Int) {
2605 return func.binOpBigInt(lhs, rhs, ty, op);2618 return func.binOpBigInt(lhs, rhs, ty, op);
2606 } else {2619 } else {
2607 return func.fail(2620 return func.fail(
...@@ -2613,8 +2626,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!...@@ -2613,8 +2626,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
26132626
2614 const opcode: wasm.Opcode = buildOpcode(.{2627 const opcode: wasm.Opcode = buildOpcode(.{
2615 .op = op,2628 .op = op,
2616 .valtype1 = typeToValtype(ty, func.target),2629 .valtype1 = typeToValtype(ty, mod),
2617 .signedness = if (ty.isSignedInt()) .signed else .unsigned,2630 .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned,
2618 });2631 });
2619 try func.emitWValue(lhs);2632 try func.emitWValue(lhs);
2620 try func.emitWValue(rhs);2633 try func.emitWValue(rhs);
...@@ -2625,7 +2638,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!...@@ -2625,7 +2638,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
2625}2638}
26262639
2627fn binOpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {2640fn 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) {
2629 return func.fail("TODO: Implement binary operation for big integers larger than 128 bits", .{});2643 return func.fail("TODO: Implement binary operation for big integers larger than 128 bits", .{});
2630 }2644 }
26312645
...@@ -2763,7 +2777,8 @@ fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError...@@ -2763,7 +2777,8 @@ fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError
2763}2777}
27642778
2765fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) InnerError!WValue {2779fn 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) {
2767 return func.fail("TODO: Implement floatOps for vectors", .{});2782 return func.fail("TODO: Implement floatOps for vectors", .{});
2768 }2783 }
27692784
...@@ -2773,7 +2788,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In...@@ -2773,7 +2788,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In
2773 for (args) |operand| {2788 for (args) |operand| {
2774 try func.emitWValue(operand);2789 try func.emitWValue(operand);
2775 }2790 }
2776 const opcode = buildOpcode(.{ .op = op, .valtype1 = typeToValtype(ty, func.target) });2791 const opcode = buildOpcode(.{ .op = op, .valtype1 = typeToValtype(ty, mod) });
2777 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));2792 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
2778 return .stack;2793 return .stack;
2779 }2794 }
...@@ -2827,6 +2842,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In...@@ -2827,6 +2842,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In
2827}2842}
28282843
2829fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {2844fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2845 const mod = func.bin_file.base.options.module.?;
2830 const bin_op = func.air.instructions.items(.data)[inst].bin_op;2846 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
28312847
2832 const lhs = try func.resolveInst(bin_op.lhs);2848 const lhs = try func.resolveInst(bin_op.lhs);
...@@ -2834,7 +2850,7 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -2834,7 +2850,7 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2834 const lhs_ty = func.air.typeOf(bin_op.lhs);2850 const lhs_ty = func.air.typeOf(bin_op.lhs);
2835 const rhs_ty = func.air.typeOf(bin_op.rhs);2851 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) {
2838 return func.fail("TODO: Implement wrapping arithmetic for vectors", .{});2854 return func.fail("TODO: Implement wrapping arithmetic for vectors", .{});
2839 }2855 }
28402856
...@@ -2845,10 +2861,10 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -2845,10 +2861,10 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2845 // For big integers we can ignore this as we will call into compiler-rt which handles this.2861 // For big integers we can ignore this as we will call into compiler-rt which handles this.
2846 const result = switch (op) {2862 const result = switch (op) {
2847 .shr, .shl => res: {2863 .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 {
2849 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});2865 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});
2850 };2866 };
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))).?;
2852 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {2868 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {
2853 const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);2869 const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);
2854 break :blk try tmp.toLocal(func, lhs_ty);2870 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...@@ -2877,8 +2893,9 @@ fn wrapBinOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr
2877/// Asserts `Type` is <= 128 bits.2893/// Asserts `Type` is <= 128 bits.
2878/// NOTE: When the Type is <= 64 bits, leaves the value on top of the stack.2894/// NOTE: When the Type is <= 64 bits, leaves the value on top of the stack.
2879fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {2895fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
2880 assert(ty.abiSize(func.target) <= 16);2896 const mod = func.bin_file.base.options.module.?;
2881 const bitsize = @intCast(u16, ty.bitSize(func.target));2897 assert(ty.abiSize(mod) <= 16);
2898 const bitsize = @intCast(u16, ty.bitSize(mod));
2882 const wasm_bits = toWasmBits(bitsize) orelse {2899 const wasm_bits = toWasmBits(bitsize) orelse {
2883 return func.fail("TODO: Implement wrapOperand for bitsize '{d}'", .{bitsize});2900 return func.fail("TODO: Implement wrapOperand for bitsize '{d}'", .{bitsize});
2884 };2901 };
...@@ -2915,6 +2932,7 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {...@@ -2915,6 +2932,7 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
2915}2932}
29162933
2917fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue {2934fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue {
2935 const mod = func.bin_file.base.options.module.?;
2918 switch (ptr_val.tag()) {2936 switch (ptr_val.tag()) {
2919 .decl_ref_mut => {2937 .decl_ref_mut => {
2920 const decl_index = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;2938 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...@@ -2932,15 +2950,15 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue
2932 const field_ptr = ptr_val.castTag(.field_ptr).?.data;2950 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
2933 const parent_ty = field_ptr.container_ty;2951 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)) {
2936 .Struct => switch (parent_ty.containerLayout()) {2954 .Struct => switch (parent_ty.containerLayout()) {
2937 .Packed => parent_ty.packedStructFieldByteOffset(field_ptr.field_index, func.target),2955 .Packed => parent_ty.packedStructFieldByteOffset(field_ptr.field_index, mod),
2938 else => parent_ty.structFieldOffset(field_ptr.field_index, func.target),2956 else => parent_ty.structFieldOffset(field_ptr.field_index, mod),
2939 },2957 },
2940 .Union => switch (parent_ty.containerLayout()) {2958 .Union => switch (parent_ty.containerLayout()) {
2941 .Packed => 0,2959 .Packed => 0,
2942 else => blk: {2960 else => blk: {
2943 const layout: Module.Union.Layout = parent_ty.unionGetLayout(func.target);2961 const layout: Module.Union.Layout = parent_ty.unionGetLayout(mod);
2944 if (layout.payload_size == 0) break :blk 0;2962 if (layout.payload_size == 0) break :blk 0;
2945 if (layout.payload_align > layout.tag_align) break :blk 0;2963 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...@@ -2964,7 +2982,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue
2964 .elem_ptr => {2982 .elem_ptr => {
2965 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;2983 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2966 const index = elem_ptr.index;2984 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);
2968 return func.lowerParentPtr(elem_ptr.array_ptr, offset + @intCast(u32, elem_offset));2986 return func.lowerParentPtr(elem_ptr.array_ptr, offset + @intCast(u32, elem_offset));
2969 },2987 },
2970 .opt_payload_ptr => {2988 .opt_payload_ptr => {
...@@ -2976,9 +2994,9 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue...@@ -2976,9 +2994,9 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue
2976}2994}
29772995
2978fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.Index, offset: u32) InnerError!WValue {2996fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.Index, offset: u32) InnerError!WValue {
2979 const module = func.bin_file.base.options.module.?;2997 const mod = func.bin_file.base.options.module.?;
2980 const decl = module.declPtr(decl_index);2998 const decl = mod.declPtr(decl_index);
2981 module.markDeclAlive(decl);2999 mod.markDeclAlive(decl);
2982 var ptr_ty_payload: Type.Payload.ElemType = .{3000 var ptr_ty_payload: Type.Payload.ElemType = .{
2983 .base = .{ .tag = .single_mut_pointer },3001 .base = .{ .tag = .single_mut_pointer },
2984 .data = decl.ty,3002 .data = decl.ty,
...@@ -2992,18 +3010,18 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Ind...@@ -2992,18 +3010,18 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Ind
2992 return WValue{ .memory = try func.bin_file.lowerUnnamedConst(tv, decl_index) };3010 return WValue{ .memory = try func.bin_file.lowerUnnamedConst(tv, decl_index) };
2993 }3011 }
29943012
2995 const module = func.bin_file.base.options.module.?;3013 const mod = func.bin_file.base.options.module.?;
2996 const decl = module.declPtr(decl_index);3014 const decl = mod.declPtr(decl_index);
2997 if (decl.ty.zigTypeTag() != .Fn and !decl.ty.hasRuntimeBitsIgnoreComptime()) {3015 if (decl.ty.zigTypeTag(mod) != .Fn and !decl.ty.hasRuntimeBitsIgnoreComptime(mod)) {
2998 return WValue{ .imm32 = 0xaaaaaaaa };3016 return WValue{ .imm32 = 0xaaaaaaaa };
2999 }3017 }
30003018
3001 module.markDeclAlive(decl);3019 mod.markDeclAlive(decl);
3002 const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index);3020 const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index);
3003 const atom = func.bin_file.getAtom(atom_index);3021 const atom = func.bin_file.getAtom(atom_index);
30043022
3005 const target_sym_index = atom.sym_index;3023 const target_sym_index = atom.sym_index;
3006 if (decl.ty.zigTypeTag() == .Fn) {3024 if (decl.ty.zigTypeTag(mod) == .Fn) {
3007 try func.bin_file.addTableFunction(target_sym_index);3025 try func.bin_file.addTableFunction(target_sym_index);
3008 return WValue{ .function_index = target_sym_index };3026 return WValue{ .function_index = target_sym_index };
3009 } else if (offset == 0) {3027 } else if (offset == 0) {
...@@ -3041,31 +3059,31 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3041,31 +3059,31 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3041 const decl_index = decl_ref_mut.data.decl_index;3059 const decl_index = decl_ref_mut.data.decl_index;
3042 return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index, 0);3060 return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index, 0);
3043 }3061 }
3044 const target = func.target;3062 const mod = func.bin_file.base.options.module.?;
3045 switch (ty.zigTypeTag()) {3063 switch (ty.zigTypeTag(mod)) {
3046 .Void => return WValue{ .none = {} },3064 .Void => return WValue{ .none = {} },
3047 .Int => {3065 .Int => {
3048 const int_info = ty.intInfo(func.target);3066 const int_info = ty.intInfo(mod);
3049 switch (int_info.signedness) {3067 switch (int_info.signedness) {
3050 .signed => switch (int_info.bits) {3068 .signed => switch (int_info.bits) {
3051 0...32 => return WValue{ .imm32 = @intCast(u32, toTwosComplement(3069 0...32 => return WValue{ .imm32 = @intCast(u32, toTwosComplement(
3052 val.toSignedInt(target),3070 val.toSignedInt(mod),
3053 @intCast(u6, int_info.bits),3071 @intCast(u6, int_info.bits),
3054 )) },3072 )) },
3055 33...64 => return WValue{ .imm64 = toTwosComplement(3073 33...64 => return WValue{ .imm64 = toTwosComplement(
3056 val.toSignedInt(target),3074 val.toSignedInt(mod),
3057 @intCast(u7, int_info.bits),3075 @intCast(u7, int_info.bits),
3058 ) },3076 ) },
3059 else => unreachable,3077 else => unreachable,
3060 },3078 },
3061 .unsigned => switch (int_info.bits) {3079 .unsigned => switch (int_info.bits) {
3062 0...32 => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },3080 0...32 => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(mod)) },
3063 33...64 => return WValue{ .imm64 = val.toUnsignedInt(target) },3081 33...64 => return WValue{ .imm64 = val.toUnsignedInt(mod) },
3064 else => unreachable,3082 else => unreachable,
3065 },3083 },
3066 }3084 }
3067 },3085 },
3068 .Bool => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },3086 .Bool => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(mod)) },
3069 .Float => switch (ty.floatBits(func.target)) {3087 .Float => switch (ty.floatBits(func.target)) {
3070 16 => return WValue{ .imm32 = @bitCast(u16, val.toFloat(f16)) },3088 16 => return WValue{ .imm32 = @bitCast(u16, val.toFloat(f16)) },
3071 32 => return WValue{ .float32 = val.toFloat(f32) },3089 32 => return WValue{ .float32 = val.toFloat(f32) },
...@@ -3074,7 +3092,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3074,7 +3092,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3074 },3092 },
3075 .Pointer => switch (val.tag()) {3093 .Pointer => switch (val.tag()) {
3076 .field_ptr, .elem_ptr, .opt_payload_ptr => return func.lowerParentPtr(val, 0),3094 .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)) },
3078 .zero, .null_value => return WValue{ .imm32 = 0 },3096 .zero, .null_value => return WValue{ .imm32 = 0 },
3079 else => return func.fail("Wasm TODO: lowerConstant for other const pointer tag {}", .{val.tag()}),3097 else => return func.fail("Wasm TODO: lowerConstant for other const pointer tag {}", .{val.tag()}),
3080 },3098 },
...@@ -3100,8 +3118,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3100,8 +3118,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3100 else => return func.fail("TODO: lowerConstant for enum tag: {}", .{ty.tag()}),3118 else => return func.fail("TODO: lowerConstant for enum tag: {}", .{ty.tag()}),
3101 }3119 }
3102 } else {3120 } else {
3103 var int_tag_buffer: Type.Payload.Bits = undefined;3121 const int_tag_ty = ty.intTagType();
3104 const int_tag_ty = ty.intTagType(&int_tag_buffer);
3105 return func.lowerConstant(val, int_tag_ty);3122 return func.lowerConstant(val, int_tag_ty);
3106 }3123 }
3107 },3124 },
...@@ -3115,7 +3132,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3115,7 +3132,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3115 .ErrorUnion => {3132 .ErrorUnion => {
3116 const error_type = ty.errorUnionSet();3133 const error_type = ty.errorUnionSet();
3117 const payload_type = ty.errorUnionPayload();3134 const payload_type = ty.errorUnionPayload();
3118 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {3135 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
3119 // We use the error type directly as the type.3136 // We use the error type directly as the type.
3120 const is_pl = val.errorUnionIsPayload();3137 const is_pl = val.errorUnionIsPayload();
3121 const err_val = if (!is_pl) val else Value.initTag(.zero);3138 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 {...@@ -3123,12 +3140,12 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3123 }3140 }
3124 return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{});3141 return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{});
3125 },3142 },
3126 .Optional => if (ty.optionalReprIsPayload()) {3143 .Optional => if (ty.optionalReprIsPayload(mod)) {
3127 var buf: Type.Payload.ElemType = undefined;3144 var buf: Type.Payload.ElemType = undefined;
3128 const pl_ty = ty.optionalChild(&buf);3145 const pl_ty = ty.optionalChild(&buf);
3129 if (val.castTag(.opt_payload)) |payload| {3146 if (val.castTag(.opt_payload)) |payload| {
3130 return func.lowerConstant(payload.data, pl_ty);3147 return func.lowerConstant(payload.data, pl_ty);
3131 } else if (val.isNull()) {3148 } else if (val.isNull(mod)) {
3132 return WValue{ .imm32 = 0 };3149 return WValue{ .imm32 = 0 };
3133 } else {3150 } else {
3134 return func.lowerConstant(val, pl_ty);3151 return func.lowerConstant(val, pl_ty);
...@@ -3150,7 +3167,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3150,7 +3167,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3150 return func.lowerConstant(int_val, struct_obj.backing_int_ty);3167 return func.lowerConstant(int_val, struct_obj.backing_int_ty);
3151 },3168 },
3152 .Vector => {3169 .Vector => {
3153 assert(determineSimdStoreStrategy(ty, target) == .direct);3170 assert(determineSimdStoreStrategy(ty, mod) == .direct);
3154 var buf: [16]u8 = undefined;3171 var buf: [16]u8 = undefined;
3155 val.writeToMemory(ty, func.bin_file.base.options.module.?, &buf) catch unreachable;3172 val.writeToMemory(ty, func.bin_file.base.options.module.?, &buf) catch unreachable;
3156 return func.storeSimdImmd(buf);3173 return func.storeSimdImmd(buf);
...@@ -3176,9 +3193,10 @@ fn storeSimdImmd(func: *CodeGen, value: [16]u8) !WValue {...@@ -3176,9 +3193,10 @@ fn storeSimdImmd(func: *CodeGen, value: [16]u8) !WValue {
3176}3193}
31773194
3178fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {3195fn 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)) {
3180 .Bool, .ErrorSet => return WValue{ .imm32 = 0xaaaaaaaa },3198 .Bool, .ErrorSet => return WValue{ .imm32 = 0xaaaaaaaa },
3181 .Int, .Enum => switch (ty.intInfo(func.target).bits) {3199 .Int, .Enum => switch (ty.intInfo(mod).bits) {
3182 0...32 => return WValue{ .imm32 = 0xaaaaaaaa },3200 0...32 => return WValue{ .imm32 = 0xaaaaaaaa },
3183 33...64 => return WValue{ .imm64 = 0xaaaaaaaaaaaaaaaa },3201 33...64 => return WValue{ .imm64 = 0xaaaaaaaaaaaaaaaa },
3184 else => unreachable,3202 else => unreachable,
...@@ -3197,7 +3215,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -3197,7 +3215,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
3197 .Optional => {3215 .Optional => {
3198 var buf: Type.Payload.ElemType = undefined;3216 var buf: Type.Payload.ElemType = undefined;
3199 const pl_ty = ty.optionalChild(&buf);3217 const pl_ty = ty.optionalChild(&buf);
3200 if (ty.optionalReprIsPayload()) {3218 if (ty.optionalReprIsPayload(mod)) {
3201 return func.emitUndefined(pl_ty);3219 return func.emitUndefined(pl_ty);
3202 }3220 }
3203 return WValue{ .imm32 = 0xaaaaaaaa };3221 return WValue{ .imm32 = 0xaaaaaaaa };
...@@ -3210,7 +3228,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -3210,7 +3228,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
3210 assert(struct_obj.layout == .Packed);3228 assert(struct_obj.layout == .Packed);
3211 return func.emitUndefined(struct_obj.backing_int_ty);3229 return func.emitUndefined(struct_obj.backing_int_ty);
3212 },3230 },
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)}),
3214 }3232 }
3215}3233}
32163234
...@@ -3218,8 +3236,8 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -3218,8 +3236,8 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
3218/// It's illegal to provide a value with a type that cannot be represented3236/// It's illegal to provide a value with a type that cannot be represented
3219/// as an integer value.3237/// as an integer value.
3220fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {3238fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
3221 const target = func.target;3239 const mod = func.bin_file.base.options.module.?;
3222 switch (ty.zigTypeTag()) {3240 switch (ty.zigTypeTag(mod)) {
3223 .Enum => {3241 .Enum => {
3224 if (val.castTag(.enum_field_index)) |field_index| {3242 if (val.castTag(.enum_field_index)) |field_index| {
3225 switch (ty.tag()) {3243 switch (ty.tag()) {
...@@ -3239,35 +3257,35 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {...@@ -3239,35 +3257,35 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
3239 else => unreachable,3257 else => unreachable,
3240 }3258 }
3241 } else {3259 } else {
3242 var int_tag_buffer: Type.Payload.Bits = undefined;3260 const int_tag_ty = ty.intTagType();
3243 const int_tag_ty = ty.intTagType(&int_tag_buffer);
3244 return func.valueAsI32(val, int_tag_ty);3261 return func.valueAsI32(val, int_tag_ty);
3245 }3262 }
3246 },3263 },
3247 .Int => switch (ty.intInfo(func.target).signedness) {3264 .Int => switch (ty.intInfo(mod).signedness) {
3248 .signed => return @truncate(i32, val.toSignedInt(target)),3265 .signed => return @truncate(i32, val.toSignedInt(mod)),
3249 .unsigned => return @bitCast(i32, @truncate(u32, val.toUnsignedInt(target))),3266 .unsigned => return @bitCast(i32, @truncate(u32, val.toUnsignedInt(mod))),
3250 },3267 },
3251 .ErrorSet => {3268 .ErrorSet => {
3252 const kv = func.bin_file.base.options.module.?.getErrorValue(val.getError().?) catch unreachable; // passed invalid `Value` to function3269 const kv = func.bin_file.base.options.module.?.getErrorValue(val.getError().?) catch unreachable; // passed invalid `Value` to function
3253 return @bitCast(i32, kv.value);3270 return @bitCast(i32, kv.value);
3254 },3271 },
3255 .Bool => return @intCast(i32, val.toSignedInt(target)),3272 .Bool => return @intCast(i32, val.toSignedInt(mod)),
3256 .Pointer => return @intCast(i32, val.toSignedInt(target)),3273 .Pointer => return @intCast(i32, val.toSignedInt(mod)),
3257 else => unreachable, // Programmer called this function for an illegal type3274 else => unreachable, // Programmer called this function for an illegal type
3258 }3275 }
3259}3276}
32603277
3261fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3278fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3279 const mod = func.bin_file.base.options.module.?;
3262 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;3280 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
3263 const block_ty = func.air.getRefType(ty_pl.ty);3281 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);
3265 const extra = func.air.extraData(Air.Block, ty_pl.payload);3283 const extra = func.air.extraData(Air.Block, ty_pl.payload);
3266 const body = func.air.extra[extra.end..][0..extra.data.body_len];3284 const body = func.air.extra[extra.end..][0..extra.data.body_len];
32673285
3268 // if wasm_block_ty is non-empty, we create a register to store the temporary value3286 // if wasm_block_ty is non-empty, we create a register to store the temporary value
3269 const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: {3287 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;
3271 break :blk try func.ensureAllocLocal(ty); // make sure it's a clean local as it may never get overwritten3289 break :blk try func.ensureAllocLocal(ty); // make sure it's a clean local as it may never get overwritten
3272 } else WValue.none;3290 } else WValue.none;
32733291
...@@ -3379,16 +3397,17 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In...@@ -3379,16 +3397,17 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In
3379/// NOTE: This leaves the result on top of the stack, rather than a new local.3397/// NOTE: This leaves the result on top of the stack, rather than a new local.
3380fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOperator) InnerError!WValue {3398fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOperator) InnerError!WValue {
3381 assert(!(lhs != .stack and rhs == .stack));3399 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)) {
3383 var buf: Type.Payload.ElemType = undefined;3402 var buf: Type.Payload.ElemType = undefined;
3384 const payload_ty = ty.optionalChild(&buf);3403 const payload_ty = ty.optionalChild(&buf);
3385 if (payload_ty.hasRuntimeBitsIgnoreComptime()) {3404 if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3386 // When we hit this case, we must check the value of optionals3405 // When we hit this case, we must check the value of optionals
3387 // that are not pointers. This means first checking against non-null for3406 // that are not pointers. This means first checking against non-null for
3388 // both lhs and rhs, as well as checking the payload are matching of lhs and rhs3407 // both lhs and rhs, as well as checking the payload are matching of lhs and rhs
3389 return func.cmpOptionals(lhs, rhs, ty, op);3408 return func.cmpOptionals(lhs, rhs, ty, op);
3390 }3409 }
3391 } else if (isByRef(ty, func.target)) {3410 } else if (isByRef(ty, mod)) {
3392 return func.cmpBigInt(lhs, rhs, ty, op);3411 return func.cmpBigInt(lhs, rhs, ty, op);
3393 } else if (ty.isAnyFloat() and ty.floatBits(func.target) == 16) {3412 } else if (ty.isAnyFloat() and ty.floatBits(func.target) == 16) {
3394 return func.cmpFloat16(lhs, rhs, op);3413 return func.cmpFloat16(lhs, rhs, op);
...@@ -3401,13 +3420,13 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO...@@ -3401,13 +3420,13 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO
34013420
3402 const signedness: std.builtin.Signedness = blk: {3421 const signedness: std.builtin.Signedness = blk: {
3403 // by default we tell the operand type is unsigned (i.e. bools and enum values)3422 // 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
3406 // incase of an actual integer, we emit the correct signedness3425 // 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;
3408 };3427 };
3409 const opcode: wasm.Opcode = buildOpcode(.{3428 const opcode: wasm.Opcode = buildOpcode(.{
3410 .valtype1 = typeToValtype(ty, func.target),3429 .valtype1 = typeToValtype(ty, mod),
3411 .op = switch (op) {3430 .op = switch (op) {
3412 .lt => .lt,3431 .lt => .lt,
3413 .lte => .le,3432 .lte => .le,
...@@ -3464,11 +3483,12 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3464,11 +3483,12 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3464}3483}
34653484
3466fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3485fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3486 const mod = func.bin_file.base.options.module.?;
3467 const br = func.air.instructions.items(.data)[inst].br;3487 const br = func.air.instructions.items(.data)[inst].br;
3468 const block = func.blocks.get(br.block_inst).?;3488 const block = func.blocks.get(br.block_inst).?;
34693489
3470 // if operand has codegen bits we should break with a value3490 // 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)) {
3472 const operand = try func.resolveInst(br.operand);3492 const operand = try func.resolveInst(br.operand);
3473 try func.lowerToStack(operand);3493 try func.lowerToStack(operand);
34743494
...@@ -3490,16 +3510,17 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3490,16 +3510,17 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
34903510
3491 const operand = try func.resolveInst(ty_op.operand);3511 const operand = try func.resolveInst(ty_op.operand);
3492 const operand_ty = func.air.typeOf(ty_op.operand);3512 const operand_ty = func.air.typeOf(ty_op.operand);
3513 const mod = func.bin_file.base.options.module.?;
34933514
3494 const result = result: {3515 const result = result: {
3495 if (operand_ty.zigTypeTag() == .Bool) {3516 if (operand_ty.zigTypeTag(mod) == .Bool) {
3496 try func.emitWValue(operand);3517 try func.emitWValue(operand);
3497 try func.addTag(.i32_eqz);3518 try func.addTag(.i32_eqz);
3498 const not_tmp = try func.allocLocal(operand_ty);3519 const not_tmp = try func.allocLocal(operand_ty);
3499 try func.addLabel(.local_set, not_tmp.local.value);3520 try func.addLabel(.local_set, not_tmp.local.value);
3500 break :result not_tmp;3521 break :result not_tmp;
3501 } else {3522 } else {
3502 const operand_bits = operand_ty.intInfo(func.target).bits;3523 const operand_bits = operand_ty.intInfo(mod).bits;
3503 const wasm_bits = toWasmBits(operand_bits) orelse {3524 const wasm_bits = toWasmBits(operand_bits) orelse {
3504 return func.fail("TODO: Implement binary NOT for integer with bitsize '{d}'", .{operand_bits});3525 return func.fail("TODO: Implement binary NOT for integer with bitsize '{d}'", .{operand_bits});
3505 };3526 };
...@@ -3566,16 +3587,17 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3566,16 +3587,17 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3566}3587}
35673588
3568fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue {3589fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue {
3590 const mod = func.bin_file.base.options.module.?;
3569 // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction3591 // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction
3570 if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand;3592 if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand;
3571 if (wanted_ty.tag() == .f16 or given_ty.tag() == .f16) return operand;3593 if (wanted_ty.tag() == .f16 or given_ty.tag() == .f16) return operand;
3572 if (wanted_ty.bitSize(func.target) > 64) return operand;3594 if (wanted_ty.bitSize(mod) > 64) return operand;
3573 assert((wanted_ty.isInt() and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt()));3595 assert((wanted_ty.isInt(mod) and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt(mod)));
35743596
3575 const opcode = buildOpcode(.{3597 const opcode = buildOpcode(.{
3576 .op = .reinterpret,3598 .op = .reinterpret,
3577 .valtype1 = typeToValtype(wanted_ty, func.target),3599 .valtype1 = typeToValtype(wanted_ty, mod),
3578 .valtype2 = typeToValtype(given_ty, func.target),3600 .valtype2 = typeToValtype(given_ty, mod),
3579 });3601 });
3580 try func.emitWValue(operand);3602 try func.emitWValue(operand);
3581 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));3603 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
...@@ -3609,19 +3631,20 @@ fn structFieldPtr(...@@ -3609,19 +3631,20 @@ fn structFieldPtr(
3609 struct_ty: Type,3631 struct_ty: Type,
3610 index: u32,3632 index: u32,
3611) InnerError!WValue {3633) InnerError!WValue {
3634 const mod = func.bin_file.base.options.module.?;
3612 const result_ty = func.air.typeOfIndex(inst);3635 const result_ty = func.air.typeOfIndex(inst);
3613 const offset = switch (struct_ty.containerLayout()) {3636 const offset = switch (struct_ty.containerLayout()) {
3614 .Packed => switch (struct_ty.zigTypeTag()) {3637 .Packed => switch (struct_ty.zigTypeTag(mod)) {
3615 .Struct => offset: {3638 .Struct => offset: {
3616 if (result_ty.ptrInfo().data.host_size != 0) {3639 if (result_ty.ptrInfo().data.host_size != 0) {
3617 break :offset @as(u32, 0);3640 break :offset @as(u32, 0);
3618 }3641 }
3619 break :offset struct_ty.packedStructFieldByteOffset(index, func.target);3642 break :offset struct_ty.packedStructFieldByteOffset(index, mod);
3620 },3643 },
3621 .Union => 0,3644 .Union => 0,
3622 else => unreachable,3645 else => unreachable,
3623 },3646 },
3624 else => struct_ty.structFieldOffset(index, func.target),3647 else => struct_ty.structFieldOffset(index, mod),
3625 };3648 };
3626 // save a load and store when we can simply reuse the operand3649 // save a load and store when we can simply reuse the operand
3627 if (offset == 0) {3650 if (offset == 0) {
...@@ -3636,6 +3659,7 @@ fn structFieldPtr(...@@ -3636,6 +3659,7 @@ fn structFieldPtr(
3636}3659}
36373660
3638fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3661fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3662 const mod = func.bin_file.base.options.module.?;
3639 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;3663 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
3640 const struct_field = func.air.extraData(Air.StructField, ty_pl.payload).data;3664 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 {...@@ -3643,15 +3667,15 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3643 const operand = try func.resolveInst(struct_field.struct_operand);3667 const operand = try func.resolveInst(struct_field.struct_operand);
3644 const field_index = struct_field.field_index;3668 const field_index = struct_field.field_index;
3645 const field_ty = struct_ty.structFieldType(field_index);3669 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
3648 const result = switch (struct_ty.containerLayout()) {3672 const result = switch (struct_ty.containerLayout()) {
3649 .Packed => switch (struct_ty.zigTypeTag()) {3673 .Packed => switch (struct_ty.zigTypeTag(mod)) {
3650 .Struct => result: {3674 .Struct => result: {
3651 const struct_obj = struct_ty.castTag(.@"struct").?.data;3675 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);
3653 const backing_ty = struct_obj.backing_int_ty;3677 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 {
3655 return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{});3679 return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{});
3656 };3680 };
3657 const const_wvalue = if (wasm_bits == 32)3681 const const_wvalue = if (wasm_bits == 32)
...@@ -3667,25 +3691,17 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3667,25 +3691,17 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3667 else3691 else
3668 try func.binOp(operand, const_wvalue, backing_ty, .shr);3692 try func.binOp(operand, const_wvalue, backing_ty, .shr);
36693693
3670 if (field_ty.zigTypeTag() == .Float) {3694 if (field_ty.zigTypeTag(mod) == .Float) {
3671 var payload: Type.Payload.Bits = .{3695 const int_type = try mod.intType(.unsigned, @intCast(u16, field_ty.bitSize(mod)));
3672 .base = .{ .tag = .int_unsigned },
3673 .data = @intCast(u16, field_ty.bitSize(func.target)),
3674 };
3675 const int_type = Type.initPayload(&payload.base);
3676 const truncated = try func.trunc(shifted_value, int_type, backing_ty);3696 const truncated = try func.trunc(shifted_value, int_type, backing_ty);
3677 const bitcasted = try func.bitcast(field_ty, int_type, truncated);3697 const bitcasted = try func.bitcast(field_ty, int_type, truncated);
3678 break :result try bitcasted.toLocal(func, field_ty);3698 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) {
3680 // In this case we do not have to perform any transformations,3700 // In this case we do not have to perform any transformations,
3681 // we can simply reuse the operand.3701 // we can simply reuse the operand.
3682 break :result func.reuseOperand(struct_field.struct_operand, operand);3702 break :result func.reuseOperand(struct_field.struct_operand, operand);
3683 } else if (field_ty.isPtrAtRuntime()) {3703 } else if (field_ty.isPtrAtRuntime(mod)) {
3684 var payload: Type.Payload.Bits = .{3704 const int_type = try mod.intType(.unsigned, @intCast(u16, field_ty.bitSize(mod)));
3685 .base = .{ .tag = .int_unsigned },
3686 .data = @intCast(u16, field_ty.bitSize(func.target)),
3687 };
3688 const int_type = Type.initPayload(&payload.base);
3689 const truncated = try func.trunc(shifted_value, int_type, backing_ty);3705 const truncated = try func.trunc(shifted_value, int_type, backing_ty);
3690 break :result try truncated.toLocal(func, field_ty);3706 break :result try truncated.toLocal(func, field_ty);
3691 }3707 }
...@@ -3693,8 +3709,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3693,8 +3709,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3693 break :result try truncated.toLocal(func, field_ty);3709 break :result try truncated.toLocal(func, field_ty);
3694 },3710 },
3695 .Union => result: {3711 .Union => result: {
3696 if (isByRef(struct_ty, func.target)) {3712 if (isByRef(struct_ty, mod)) {
3697 if (!isByRef(field_ty, func.target)) {3713 if (!isByRef(field_ty, mod)) {
3698 const val = try func.load(operand, field_ty, 0);3714 const val = try func.load(operand, field_ty, 0);
3699 break :result try val.toLocal(func, field_ty);3715 break :result try val.toLocal(func, field_ty);
3700 } else {3716 } else {
...@@ -3704,26 +3720,14 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3704,26 +3720,14 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3704 }3720 }
3705 }3721 }
37063722
3707 var payload: Type.Payload.Bits = .{3723 const union_int_type = try mod.intType(.unsigned, @intCast(u16, struct_ty.bitSize(mod)));
3708 .base = .{ .tag = .int_unsigned },3724 if (field_ty.zigTypeTag(mod) == .Float) {
3709 .data = @intCast(u16, struct_ty.bitSize(func.target)),3725 const int_type = try mod.intType(.unsigned, @intCast(u16, field_ty.bitSize(mod)));
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);
3718 const truncated = try func.trunc(operand, int_type, union_int_type);3726 const truncated = try func.trunc(operand, int_type, union_int_type);
3719 const bitcasted = try func.bitcast(field_ty, int_type, truncated);3727 const bitcasted = try func.bitcast(field_ty, int_type, truncated);
3720 break :result try bitcasted.toLocal(func, field_ty);3728 break :result try bitcasted.toLocal(func, field_ty);
3721 } else if (field_ty.isPtrAtRuntime()) {3729 } else if (field_ty.isPtrAtRuntime(mod)) {
3722 var int_payload: Type.Payload.Bits = .{3730 const int_type = try mod.intType(.unsigned, @intCast(u16, field_ty.bitSize(mod)));
3723 .base = .{ .tag = .int_unsigned },
3724 .data = @intCast(u16, field_ty.bitSize(func.target)),
3725 };
3726 const int_type = Type.initPayload(&int_payload.base);
3727 const truncated = try func.trunc(operand, int_type, union_int_type);3731 const truncated = try func.trunc(operand, int_type, union_int_type);
3728 break :result try truncated.toLocal(func, field_ty);3732 break :result try truncated.toLocal(func, field_ty);
3729 }3733 }
...@@ -3733,11 +3737,10 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3733,11 +3737,10 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3733 else => unreachable,3737 else => unreachable,
3734 },3738 },
3735 else => result: {3739 else => result: {
3736 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, func.target)) orelse {3740 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, mod)) orelse {
3737 const module = func.bin_file.base.options.module.?;3741 return func.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(mod)});
3738 return func.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(module)});
3739 };3742 };
3740 if (isByRef(field_ty, func.target)) {3743 if (isByRef(field_ty, mod)) {
3741 switch (operand) {3744 switch (operand) {
3742 .stack_offset => |stack_offset| {3745 .stack_offset => |stack_offset| {
3743 break :result WValue{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } };3746 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 {...@@ -3754,6 +3757,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3754}3757}
37553758
3756fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3759fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3760 const mod = func.bin_file.base.options.module.?;
3757 // result type is always 'noreturn'3761 // result type is always 'noreturn'
3758 const blocktype = wasm.block_empty;3762 const blocktype = wasm.block_empty;
3759 const pl_op = func.air.instructions.items(.data)[inst].pl_op;3763 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 {...@@ -3787,7 +3791,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3787 errdefer func.gpa.free(values);3791 errdefer func.gpa.free(values);
37883792
3789 for (items, 0..) |ref, i| {3793 for (items, 0..) |ref, i| {
3790 const item_val = func.air.value(ref).?;3794 const item_val = func.air.value(ref, mod).?;
3791 const int_val = func.valueAsI32(item_val, target_ty);3795 const int_val = func.valueAsI32(item_val, target_ty);
3792 if (lowest_maybe == null or int_val < lowest_maybe.?) {3796 if (lowest_maybe == null or int_val < lowest_maybe.?) {
3793 lowest_maybe = int_val;3797 lowest_maybe = int_val;
...@@ -3810,7 +3814,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3810,7 +3814,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3810 // When the target is an integer size larger than u32, we have no way to use the value3814 // When the target is an integer size larger than u32, we have no way to use the value
3811 // as an index, therefore we also use an if/else-chain for those cases.3815 // as an index, therefore we also use an if/else-chain for those cases.
3812 // TODO: Benchmark this to find a proper value, LLVM seems to draw the line at '40~45'.3816 // 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
3815 const else_body = func.air.extra[extra_index..][0..switch_br.data.else_body_len];3819 const else_body = func.air.extra[extra_index..][0..switch_br.data.else_body_len];
3816 const has_else_body = else_body.len != 0;3820 const has_else_body = else_body.len != 0;
...@@ -3855,7 +3859,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3855,7 +3859,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3855 // for errors that are not present in any branch. This is fine as this default3859 // for errors that are not present in any branch. This is fine as this default
3856 // case will never be hit for those cases but we do save runtime cost and size3860 // case will never be hit for those cases but we do save runtime cost and size
3857 // by using a jump table for this instead of if-else chains.3861 // 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;
3859 };3863 };
3860 func.mir_extra.appendAssumeCapacity(idx);3864 func.mir_extra.appendAssumeCapacity(idx);
3861 } else if (has_else_body) {3865 } else if (has_else_body) {
...@@ -3866,10 +3870,10 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3866,10 +3870,10 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38663870
3867 const signedness: std.builtin.Signedness = blk: {3871 const signedness: std.builtin.Signedness = blk: {
3868 // by default we tell the operand type is unsigned (i.e. bools and enum values)3872 // 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
3871 // incase of an actual integer, we emit the correct signedness3875 // 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;
3873 };3877 };
38743878
3875 try func.branches.ensureUnusedCapacity(func.gpa, case_list.items.len + @boolToInt(has_else_body));3879 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 {...@@ -3882,7 +3886,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3882 const val = try func.lowerConstant(case.values[0].value, target_ty);3886 const val = try func.lowerConstant(case.values[0].value, target_ty);
3883 try func.emitWValue(val);3887 try func.emitWValue(val);
3884 const opcode = buildOpcode(.{3888 const opcode = buildOpcode(.{
3885 .valtype1 = typeToValtype(target_ty, func.target),3889 .valtype1 = typeToValtype(target_ty, mod),
3886 .op = .ne, // not equal, because we want to jump out of this block if it does not match the condition.3890 .op = .ne, // not equal, because we want to jump out of this block if it does not match the condition.
3887 .signedness = signedness,3891 .signedness = signedness,
3888 });3892 });
...@@ -3896,7 +3900,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3896,7 +3900,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3896 const val = try func.lowerConstant(value.value, target_ty);3900 const val = try func.lowerConstant(value.value, target_ty);
3897 try func.emitWValue(val);3901 try func.emitWValue(val);
3898 const opcode = buildOpcode(.{3902 const opcode = buildOpcode(.{
3899 .valtype1 = typeToValtype(target_ty, func.target),3903 .valtype1 = typeToValtype(target_ty, mod),
3900 .op = .eq,3904 .op = .eq,
3901 .signedness = signedness,3905 .signedness = signedness,
3902 });3906 });
...@@ -3933,6 +3937,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3933,6 +3937,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3933}3937}
39343938
3935fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!void {3939fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!void {
3940 const mod = func.bin_file.base.options.module.?;
3936 const un_op = func.air.instructions.items(.data)[inst].un_op;3941 const un_op = func.air.instructions.items(.data)[inst].un_op;
3937 const operand = try func.resolveInst(un_op);3942 const operand = try func.resolveInst(un_op);
3938 const err_union_ty = func.air.typeOf(un_op);3943 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...@@ -3948,10 +3953,10 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
3948 }3953 }
39493954
3950 try func.emitWValue(operand);3955 try func.emitWValue(operand);
3951 if (pl_ty.hasRuntimeBitsIgnoreComptime()) {3956 if (pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3952 try func.addMemArg(.i32_load16_u, .{3957 try func.addMemArg(.i32_load16_u, .{
3953 .offset = operand.offset() + @intCast(u32, errUnionErrorOffset(pl_ty, func.target)),3958 .offset = operand.offset() + @intCast(u32, errUnionErrorOffset(pl_ty, mod)),
3954 .alignment = Type.anyerror.abiAlignment(func.target),3959 .alignment = Type.anyerror.abiAlignment(mod),
3955 });3960 });
3956 }3961 }
39573962
...@@ -3967,6 +3972,7 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro...@@ -3967,6 +3972,7 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
3967}3972}
39683973
3969fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {3974fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
3975 const mod = func.bin_file.base.options.module.?;
3970 const ty_op = func.air.instructions.items(.data)[inst].ty_op;3976 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
39713977
3972 const operand = try func.resolveInst(ty_op.operand);3978 const operand = try func.resolveInst(ty_op.operand);
...@@ -3975,15 +3981,15 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo...@@ -3975,15 +3981,15 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
3975 const payload_ty = err_ty.errorUnionPayload();3981 const payload_ty = err_ty.errorUnionPayload();
39763982
3977 const result = result: {3983 const result = result: {
3978 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3984 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3979 if (op_is_ptr) {3985 if (op_is_ptr) {
3980 break :result func.reuseOperand(ty_op.operand, operand);3986 break :result func.reuseOperand(ty_op.operand, operand);
3981 }3987 }
3982 break :result WValue{ .none = {} };3988 break :result WValue{ .none = {} };
3983 }3989 }
39843990
3985 const pl_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, func.target));3991 const pl_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, mod));
3986 if (op_is_ptr or isByRef(payload_ty, func.target)) {3992 if (op_is_ptr or isByRef(payload_ty, mod)) {
3987 break :result try func.buildPointerOffset(operand, pl_offset, .new);3993 break :result try func.buildPointerOffset(operand, pl_offset, .new);
3988 }3994 }
39893995
...@@ -3994,6 +4000,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo...@@ -3994,6 +4000,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
3994}4000}
39954001
3996fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {4002fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
4003 const mod = func.bin_file.base.options.module.?;
3997 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4004 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
39984005
3999 const operand = try func.resolveInst(ty_op.operand);4006 const operand = try func.resolveInst(ty_op.operand);
...@@ -4006,17 +4013,18 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)...@@ -4006,17 +4013,18 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
4006 break :result WValue{ .imm32 = 0 };4013 break :result WValue{ .imm32 = 0 };
4007 }4014 }
40084015
4009 if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime()) {4016 if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4010 break :result func.reuseOperand(ty_op.operand, operand);4017 break :result func.reuseOperand(ty_op.operand, operand);
4011 }4018 }
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)));
4014 break :result try error_val.toLocal(func, Type.anyerror);4021 break :result try error_val.toLocal(func, Type.anyerror);
4015 };4022 };
4016 func.finishAir(inst, result, &.{ty_op.operand});4023 func.finishAir(inst, result, &.{ty_op.operand});
4017}4024}
40184025
4019fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4026fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4027 const mod = func.bin_file.base.options.module.?;
4020 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4028 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
40214029
4022 const operand = try func.resolveInst(ty_op.operand);4030 const operand = try func.resolveInst(ty_op.operand);
...@@ -4024,18 +4032,18 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void...@@ -4024,18 +4032,18 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void
40244032
4025 const pl_ty = func.air.typeOf(ty_op.operand);4033 const pl_ty = func.air.typeOf(ty_op.operand);
4026 const result = result: {4034 const result = result: {
4027 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {4035 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4028 break :result func.reuseOperand(ty_op.operand, operand);4036 break :result func.reuseOperand(ty_op.operand, operand);
4029 }4037 }
40304038
4031 const err_union = try func.allocStack(err_ty);4039 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);
4033 try func.store(payload_ptr, operand, pl_ty, 0);4041 try func.store(payload_ptr, operand, pl_ty, 0);
40344042
4035 // ensure we also write '0' to the error part, so any present stack value gets overwritten by it.4043 // ensure we also write '0' to the error part, so any present stack value gets overwritten by it.
4036 try func.emitWValue(err_union);4044 try func.emitWValue(err_union);
4037 try func.addImm32(0);4045 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));
4039 try func.addMemArg(.i32_store16, .{ .offset = err_union.offset() + err_val_offset, .alignment = 2 });4047 try func.addMemArg(.i32_store16, .{ .offset = err_union.offset() + err_val_offset, .alignment = 2 });
4040 break :result err_union;4048 break :result err_union;
4041 };4049 };
...@@ -4043,6 +4051,7 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void...@@ -4043,6 +4051,7 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void
4043}4051}
40444052
4045fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4053fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4054 const mod = func.bin_file.base.options.module.?;
4046 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4055 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
40474056
4048 const operand = try func.resolveInst(ty_op.operand);4057 const operand = try func.resolveInst(ty_op.operand);
...@@ -4050,17 +4059,17 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4050,17 +4059,17 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4050 const pl_ty = err_ty.errorUnionPayload();4059 const pl_ty = err_ty.errorUnionPayload();
40514060
4052 const result = result: {4061 const result = result: {
4053 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {4062 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4054 break :result func.reuseOperand(ty_op.operand, operand);4063 break :result func.reuseOperand(ty_op.operand, operand);
4055 }4064 }
40564065
4057 const err_union = try func.allocStack(err_ty);4066 const err_union = try func.allocStack(err_ty);
4058 // store error value4067 // 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
4061 // write 'undefined' to the payload4070 // write 'undefined' to the payload
4062 const payload_ptr = try func.buildPointerOffset(err_union, @intCast(u32, errUnionPayloadOffset(pl_ty, func.target)), .new);4071 const payload_ptr = try func.buildPointerOffset(err_union, @intCast(u32, errUnionPayloadOffset(pl_ty, mod)), .new);
4063 const len = @intCast(u32, err_ty.errorUnionPayload().abiSize(func.target));4072 const len = @intCast(u32, err_ty.errorUnionPayload().abiSize(mod));
4064 try func.memset(Type.u8, payload_ptr, .{ .imm32 = len }, .{ .imm32 = 0xaa });4073 try func.memset(Type.u8, payload_ptr, .{ .imm32 = len }, .{ .imm32 = 0xaa });
40654074
4066 break :result err_union;4075 break :result err_union;
...@@ -4074,15 +4083,16 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4074,15 +4083,16 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4074 const ty = func.air.getRefType(ty_op.ty);4083 const ty = func.air.getRefType(ty_op.ty);
4075 const operand = try func.resolveInst(ty_op.operand);4084 const operand = try func.resolveInst(ty_op.operand);
4076 const operand_ty = func.air.typeOf(ty_op.operand);4085 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) {
4078 return func.fail("todo Wasm intcast for vectors", .{});4088 return func.fail("todo Wasm intcast for vectors", .{});
4079 }4089 }
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) {
4081 return func.fail("todo Wasm intcast for bitsize > 128", .{});4091 return func.fail("todo Wasm intcast for bitsize > 128", .{});
4082 }4092 }
40834093
4084 const op_bits = toWasmBits(@intCast(u16, operand_ty.bitSize(func.target))).?;4094 const op_bits = toWasmBits(@intCast(u16, operand_ty.bitSize(mod))).?;
4085 const wanted_bits = toWasmBits(@intCast(u16, ty.bitSize(func.target))).?;4095 const wanted_bits = toWasmBits(@intCast(u16, ty.bitSize(mod))).?;
4086 const result = if (op_bits == wanted_bits)4096 const result = if (op_bits == wanted_bits)
4087 func.reuseOperand(ty_op.operand, operand)4097 func.reuseOperand(ty_op.operand, operand)
4088 else4098 else
...@@ -4096,8 +4106,9 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4096,8 +4106,9 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4096/// Asserts type's bitsize <= 1284106/// Asserts type's bitsize <= 128
4097/// NOTE: May leave the result on the top of the stack.4107/// NOTE: May leave the result on the top of the stack.
4098fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue {4108fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue {
4099 const given_bitsize = @intCast(u16, given.bitSize(func.target));4109 const mod = func.bin_file.base.options.module.?;
4100 const wanted_bitsize = @intCast(u16, wanted.bitSize(func.target));4110 const given_bitsize = @intCast(u16, given.bitSize(mod));
4111 const wanted_bitsize = @intCast(u16, wanted.bitSize(mod));
4101 assert(given_bitsize <= 128);4112 assert(given_bitsize <= 128);
4102 assert(wanted_bitsize <= 128);4113 assert(wanted_bitsize <= 128);
41034114
...@@ -4110,7 +4121,7 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro...@@ -4110,7 +4121,7 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
4110 try func.addTag(.i32_wrap_i64);4121 try func.addTag(.i32_wrap_i64);
4111 } else if (op_bits == 32 and wanted_bits > 32 and wanted_bits <= 64) {4122 } else if (op_bits == 32 and wanted_bits > 32 and wanted_bits <= 64) {
4112 try func.emitWValue(operand);4123 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);
4114 } else if (wanted_bits == 128) {4125 } else if (wanted_bits == 128) {
4115 // for 128bit integers we store the integer in the virtual stack, rather than a local4126 // for 128bit integers we store the integer in the virtual stack, rather than a local
4116 const stack_ptr = try func.allocStack(wanted);4127 const stack_ptr = try func.allocStack(wanted);
...@@ -4119,14 +4130,14 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro...@@ -4119,14 +4130,14 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
4119 // for 32 bit integers, we first coerce the value into a 64 bit integer before storing it4130 // for 32 bit integers, we first coerce the value into a 64 bit integer before storing it
4120 // meaning less store operations are required.4131 // meaning less store operations are required.
4121 const lhs = if (op_bits == 32) blk: {4132 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);
4123 } else operand;4134 } else operand;
41244135
4125 // store msb first4136 // store msb first
4126 try func.store(.{ .stack = {} }, lhs, Type.u64, 0 + stack_ptr.offset());4137 try func.store(.{ .stack = {} }, lhs, Type.u64, 0 + stack_ptr.offset());
41274138
4128 // For signed integers we shift msb by 63 (64bit integer - 1 sign bit) and store remaining value4139 // 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)) {
4130 try func.emitWValue(stack_ptr);4141 try func.emitWValue(stack_ptr);
4131 const shr = try func.binOp(lhs, .{ .imm64 = 63 }, Type.i64, .shr);4142 const shr = try func.binOp(lhs, .{ .imm64 = 63 }, Type.i64, .shr);
4132 try func.store(.{ .stack = {} }, shr, Type.u64, 8 + stack_ptr.offset());4143 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:...@@ -4154,16 +4165,16 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind:
4154/// For a given type and operand, checks if it's considered `null`.4165/// For a given type and operand, checks if it's considered `null`.
4155/// NOTE: Leaves the result on the stack4166/// NOTE: Leaves the result on the stack
4156fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcode) InnerError!WValue {4167fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcode) InnerError!WValue {
4168 const mod = func.bin_file.base.options.module.?;
4157 try func.emitWValue(operand);4169 try func.emitWValue(operand);
4158 var buf: Type.Payload.ElemType = undefined;4170 var buf: Type.Payload.ElemType = undefined;
4159 const payload_ty = optional_ty.optionalChild(&buf);4171 const payload_ty = optional_ty.optionalChild(&buf);
4160 if (!optional_ty.optionalReprIsPayload()) {4172 if (!optional_ty.optionalReprIsPayload(mod)) {
4161 // When payload is zero-bits, we can treat operand as a value, rather than4173 // When payload is zero-bits, we can treat operand as a value, rather than
4162 // a pointer to the stack value4174 // a pointer to the stack value
4163 if (payload_ty.hasRuntimeBitsIgnoreComptime()) {4175 if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4164 const offset = std.math.cast(u32, payload_ty.abiSize(func.target)) orelse {4176 const offset = std.math.cast(u32, payload_ty.abiSize(mod)) orelse {
4165 const module = func.bin_file.base.options.module.?;4177 return func.fail("Optional type {} too big to fit into stack frame", .{optional_ty.fmt(mod)});
4166 return func.fail("Optional type {} too big to fit into stack frame", .{optional_ty.fmt(module)});
4167 };4178 };
4168 try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 });4179 try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 });
4169 }4180 }
...@@ -4183,18 +4194,19 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod...@@ -4183,18 +4194,19 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod
4183}4194}
41844195
4185fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4196fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4197 const mod = func.bin_file.base.options.module.?;
4186 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4198 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
4187 const opt_ty = func.air.typeOf(ty_op.operand);4199 const opt_ty = func.air.typeOf(ty_op.operand);
4188 const payload_ty = func.air.typeOfIndex(inst);4200 const payload_ty = func.air.typeOfIndex(inst);
4189 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {4201 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4190 return func.finishAir(inst, .none, &.{ty_op.operand});4202 return func.finishAir(inst, .none, &.{ty_op.operand});
4191 }4203 }
41924204
4193 const result = result: {4205 const result = result: {
4194 const operand = try func.resolveInst(ty_op.operand);4206 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)) {
4198 break :result try func.buildPointerOffset(operand, 0, .new);4210 break :result try func.buildPointerOffset(operand, 0, .new);
4199 }4211 }
42004212
...@@ -4209,10 +4221,11 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4209,10 +4221,11 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4209 const operand = try func.resolveInst(ty_op.operand);4221 const operand = try func.resolveInst(ty_op.operand);
4210 const opt_ty = func.air.typeOf(ty_op.operand).childType();4222 const opt_ty = func.air.typeOf(ty_op.operand).childType();
42114223
4224 const mod = func.bin_file.base.options.module.?;
4212 const result = result: {4225 const result = result: {
4213 var buf: Type.Payload.ElemType = undefined;4226 var buf: Type.Payload.ElemType = undefined;
4214 const payload_ty = opt_ty.optionalChild(&buf);4227 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)) {
4216 break :result func.reuseOperand(ty_op.operand, operand);4229 break :result func.reuseOperand(ty_op.operand, operand);
4217 }4230 }
42184231
...@@ -4222,22 +4235,22 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4222,22 +4235,22 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4222}4235}
42234236
4224fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4237fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4238 const mod = func.bin_file.base.options.module.?;
4225 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4239 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
4226 const operand = try func.resolveInst(ty_op.operand);4240 const operand = try func.resolveInst(ty_op.operand);
4227 const opt_ty = func.air.typeOf(ty_op.operand).childType();4241 const opt_ty = func.air.typeOf(ty_op.operand).childType();
4228 var buf: Type.Payload.ElemType = undefined;4242 var buf: Type.Payload.ElemType = undefined;
4229 const payload_ty = opt_ty.optionalChild(&buf);4243 const payload_ty = opt_ty.optionalChild(&buf);
4230 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {4244 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4231 return func.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty.fmtDebug()});4245 return func.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty.fmtDebug()});
4232 }4246 }
42334247
4234 if (opt_ty.optionalReprIsPayload()) {4248 if (opt_ty.optionalReprIsPayload(mod)) {
4235 return func.finishAir(inst, operand, &.{ty_op.operand});4249 return func.finishAir(inst, operand, &.{ty_op.operand});
4236 }4250 }
42374251
4238 const offset = std.math.cast(u32, payload_ty.abiSize(func.target)) orelse {4252 const offset = std.math.cast(u32, payload_ty.abiSize(mod)) orelse {
4239 const module = func.bin_file.base.options.module.?;4253 return func.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(mod)});
4240 return func.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(module)});
4241 };4254 };
42424255
4243 try func.emitWValue(operand);4256 try func.emitWValue(operand);
...@@ -4251,9 +4264,10 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi...@@ -4251,9 +4264,10 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
4251fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4264fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4252 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4265 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
4253 const payload_ty = func.air.typeOf(ty_op.operand);4266 const payload_ty = func.air.typeOf(ty_op.operand);
4267 const mod = func.bin_file.base.options.module.?;
42544268
4255 const result = result: {4269 const result = result: {
4256 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {4270 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4257 const non_null_bit = try func.allocStack(Type.initTag(.u1));4271 const non_null_bit = try func.allocStack(Type.initTag(.u1));
4258 try func.emitWValue(non_null_bit);4272 try func.emitWValue(non_null_bit);
4259 try func.addImm32(1);4273 try func.addImm32(1);
...@@ -4263,12 +4277,11 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4263,12 +4277,11 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
42634277
4264 const operand = try func.resolveInst(ty_op.operand);4278 const operand = try func.resolveInst(ty_op.operand);
4265 const op_ty = func.air.typeOfIndex(inst);4279 const op_ty = func.air.typeOfIndex(inst);
4266 if (op_ty.optionalReprIsPayload()) {4280 if (op_ty.optionalReprIsPayload(mod)) {
4267 break :result func.reuseOperand(ty_op.operand, operand);4281 break :result func.reuseOperand(ty_op.operand, operand);
4268 }4282 }
4269 const offset = std.math.cast(u32, payload_ty.abiSize(func.target)) orelse {4283 const offset = std.math.cast(u32, payload_ty.abiSize(mod)) orelse {
4270 const module = func.bin_file.base.options.module.?;4284 return func.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(mod)});
4271 return func.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(module)});
4272 };4285 };
42734286
4274 // Create optional type, set the non-null bit, and store the operand inside the optional type4287 // 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 {...@@ -4314,7 +4327,8 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4314 const slice = try func.resolveInst(bin_op.lhs);4327 const slice = try func.resolveInst(bin_op.lhs);
4315 const index = try func.resolveInst(bin_op.rhs);4328 const index = try func.resolveInst(bin_op.rhs);
4316 const elem_ty = slice_ty.childType();4329 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
4319 // load pointer onto stack4333 // load pointer onto stack
4320 _ = try func.load(slice, Type.usize, 0);4334 _ = try func.load(slice, Type.usize, 0);
...@@ -4328,7 +4342,7 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4328,7 +4342,7 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4328 const result_ptr = try func.allocLocal(Type.usize);4342 const result_ptr = try func.allocLocal(Type.usize);
4329 try func.addLabel(.local_set, result_ptr.local.value);4343 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: {
4332 const elem_val = try func.load(result_ptr, elem_ty, 0);4346 const elem_val = try func.load(result_ptr, elem_ty, 0);
4333 break :result try elem_val.toLocal(func, elem_ty);4347 break :result try elem_val.toLocal(func, elem_ty);
4334 } else result_ptr;4348 } else result_ptr;
...@@ -4341,7 +4355,8 @@ fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4341,7 +4355,8 @@ fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4341 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;4355 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
43424356
4343 const elem_ty = func.air.getRefType(ty_pl.ty).childType();4357 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
4346 const slice = try func.resolveInst(bin_op.lhs);4361 const slice = try func.resolveInst(bin_op.lhs);
4347 const index = try func.resolveInst(bin_op.rhs);4362 const index = try func.resolveInst(bin_op.rhs);
...@@ -4389,13 +4404,14 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4389,13 +4404,14 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4389/// Truncates a given operand to a given type, discarding any overflown bits.4404/// Truncates a given operand to a given type, discarding any overflown bits.
4390/// NOTE: Resulting value is left on the stack.4405/// NOTE: Resulting value is left on the stack.
4391fn trunc(func: *CodeGen, operand: WValue, wanted_ty: Type, given_ty: Type) InnerError!WValue {4406fn 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));
4393 if (toWasmBits(given_bits) == null) {4409 if (toWasmBits(given_bits) == null) {
4394 return func.fail("TODO: Implement wasm integer truncation for integer bitsize: {d}", .{given_bits});4410 return func.fail("TODO: Implement wasm integer truncation for integer bitsize: {d}", .{given_bits});
4395 }4411 }
43964412
4397 var result = try func.intcast(operand, given_ty, wanted_ty);4413 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));
4399 const wasm_bits = toWasmBits(wanted_bits).?;4415 const wasm_bits = toWasmBits(wanted_bits).?;
4400 if (wasm_bits != wanted_bits) {4416 if (wasm_bits != wanted_bits) {
4401 result = try func.wrapOperand(result, wanted_ty);4417 result = try func.wrapOperand(result, wanted_ty);
...@@ -4412,6 +4428,7 @@ fn airBoolToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4412,6 +4428,7 @@ fn airBoolToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4412}4428}
44134429
4414fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4430fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4431 const mod = func.bin_file.base.options.module.?;
4415 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4432 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
44164433
4417 const operand = try func.resolveInst(ty_op.operand);4434 const operand = try func.resolveInst(ty_op.operand);
...@@ -4422,7 +4439,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4422,7 +4439,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4422 const slice_local = try func.allocStack(slice_ty);4439 const slice_local = try func.allocStack(slice_ty);
44234440
4424 // store the array ptr in the slice4441 // store the array ptr in the slice
4425 if (array_ty.hasRuntimeBitsIgnoreComptime()) {4442 if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4426 try func.store(slice_local, operand, Type.usize, 0);4443 try func.store(slice_local, operand, Type.usize, 0);
4427 }4444 }
44284445
...@@ -4454,7 +4471,8 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4454,7 +4471,8 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4454 const ptr = try func.resolveInst(bin_op.lhs);4471 const ptr = try func.resolveInst(bin_op.lhs);
4455 const index = try func.resolveInst(bin_op.rhs);4472 const index = try func.resolveInst(bin_op.rhs);
4456 const elem_ty = ptr_ty.childType();4473 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
4459 // load pointer onto the stack4477 // load pointer onto the stack
4460 if (ptr_ty.isSlice()) {4478 if (ptr_ty.isSlice()) {
...@@ -4472,7 +4490,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4472,7 +4490,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4472 const elem_result = val: {4490 const elem_result = val: {
4473 var result = try func.allocLocal(Type.usize);4491 var result = try func.allocLocal(Type.usize);
4474 try func.addLabel(.local_set, result.local.value);4492 try func.addLabel(.local_set, result.local.value);
4475 if (isByRef(elem_ty, func.target)) {4493 if (isByRef(elem_ty, mod)) {
4476 break :val result;4494 break :val result;
4477 }4495 }
4478 defer result.free(func); // only free if it's not returned like above4496 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 {...@@ -4489,7 +4507,8 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44894507
4490 const ptr_ty = func.air.typeOf(bin_op.lhs);4508 const ptr_ty = func.air.typeOf(bin_op.lhs);
4491 const elem_ty = func.air.getRefType(ty_pl.ty).childType();4509 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
4494 const ptr = try func.resolveInst(bin_op.lhs);4513 const ptr = try func.resolveInst(bin_op.lhs);
4495 const index = try func.resolveInst(bin_op.rhs);4514 const index = try func.resolveInst(bin_op.rhs);
...@@ -4513,6 +4532,7 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4513,6 +4532,7 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4513}4532}
45144533
4515fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {4534fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
4535 const mod = func.bin_file.base.options.module.?;
4516 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;4536 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
4517 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;4537 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 {...@@ -4524,13 +4544,13 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
4524 else => ptr_ty.childType(),4544 else => ptr_ty.childType(),
4525 };4545 };
45264546
4527 const valtype = typeToValtype(Type.usize, func.target);4547 const valtype = typeToValtype(Type.usize, mod);
4528 const mul_opcode = buildOpcode(.{ .valtype1 = valtype, .op = .mul });4548 const mul_opcode = buildOpcode(.{ .valtype1 = valtype, .op = .mul });
4529 const bin_opcode = buildOpcode(.{ .valtype1 = valtype, .op = op });4549 const bin_opcode = buildOpcode(.{ .valtype1 = valtype, .op = op });
45304550
4531 try func.lowerToStack(ptr);4551 try func.lowerToStack(ptr);
4532 try func.emitWValue(offset);4552 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))));
4534 try func.addTag(Mir.Inst.Tag.fromOpcode(mul_opcode));4554 try func.addTag(Mir.Inst.Tag.fromOpcode(mul_opcode));
4535 try func.addTag(Mir.Inst.Tag.fromOpcode(bin_opcode));4555 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...@@ -4572,7 +4592,8 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
4572/// this to wasm's memset instruction. When the feature is not present,4592/// this to wasm's memset instruction. When the feature is not present,
4573/// we implement it manually.4593/// we implement it manually.
4574fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue) InnerError!void {4594fn 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
4577 // When bulk_memory is enabled, we lower it to wasm's memset instruction.4598 // When bulk_memory is enabled, we lower it to wasm's memset instruction.
4578 // If not, we lower it ourselves.4599 // If not, we lower it ourselves.
...@@ -4666,24 +4687,25 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4666,24 +4687,25 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4666 const array = try func.resolveInst(bin_op.lhs);4687 const array = try func.resolveInst(bin_op.lhs);
4667 const index = try func.resolveInst(bin_op.rhs);4688 const index = try func.resolveInst(bin_op.rhs);
4668 const elem_ty = array_ty.childType();4689 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)) {
4672 try func.lowerToStack(array);4694 try func.lowerToStack(array);
4673 try func.emitWValue(index);4695 try func.emitWValue(index);
4674 try func.addImm32(@bitCast(i32, @intCast(u32, elem_size)));4696 try func.addImm32(@bitCast(i32, @intCast(u32, elem_size)));
4675 try func.addTag(.i32_mul);4697 try func.addTag(.i32_mul);
4676 try func.addTag(.i32_add);4698 try func.addTag(.i32_add);
4677 } else {4699 } else {
4678 std.debug.assert(array_ty.zigTypeTag() == .Vector);4700 std.debug.assert(array_ty.zigTypeTag(mod) == .Vector);
46794701
4680 switch (index) {4702 switch (index) {
4681 inline .imm32, .imm64 => |lane| {4703 inline .imm32, .imm64 => |lane| {
4682 const opcode: wasm.SimdOpcode = switch (elem_ty.bitSize(func.target)) {4704 const opcode: wasm.SimdOpcode = switch (elem_ty.bitSize(mod)) {
4683 8 => if (elem_ty.isSignedInt()) .i8x16_extract_lane_s else .i8x16_extract_lane_u,4705 8 => if (elem_ty.isSignedInt(mod)) .i8x16_extract_lane_s else .i8x16_extract_lane_u,
4684 16 => if (elem_ty.isSignedInt()) .i16x8_extract_lane_s else .i16x8_extract_lane_u,4706 16 => if (elem_ty.isSignedInt(mod)) .i16x8_extract_lane_s else .i16x8_extract_lane_u,
4685 32 => if (elem_ty.isInt()) .i32x4_extract_lane else .f32x4_extract_lane,4707 32 => if (elem_ty.isInt(mod)) .i32x4_extract_lane else .f32x4_extract_lane,
4686 64 => if (elem_ty.isInt()) .i64x2_extract_lane else .f64x2_extract_lane,4708 64 => if (elem_ty.isInt(mod)) .i64x2_extract_lane else .f64x2_extract_lane,
4687 else => unreachable,4709 else => unreachable,
4688 };4710 };
46894711
...@@ -4715,7 +4737,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4715,7 +4737,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4715 var result = try func.allocLocal(Type.usize);4737 var result = try func.allocLocal(Type.usize);
4716 try func.addLabel(.local_set, result.local.value);4738 try func.addLabel(.local_set, result.local.value);
47174739
4718 if (isByRef(elem_ty, func.target)) {4740 if (isByRef(elem_ty, mod)) {
4719 break :val result;4741 break :val result;
4720 }4742 }
4721 defer result.free(func); // only free if no longer needed and not returned like above4743 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 {...@@ -4733,17 +4755,18 @@ fn airFloatToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4733 const operand = try func.resolveInst(ty_op.operand);4755 const operand = try func.resolveInst(ty_op.operand);
4734 const dest_ty = func.air.typeOfIndex(inst);4756 const dest_ty = func.air.typeOfIndex(inst);
4735 const op_ty = func.air.typeOf(ty_op.operand);4757 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) {
4738 return func.fail("TODO: floatToInt for integers/floats with bitsize larger than 64 bits", .{});4761 return func.fail("TODO: floatToInt for integers/floats with bitsize larger than 64 bits", .{});
4739 }4762 }
47404763
4741 try func.emitWValue(operand);4764 try func.emitWValue(operand);
4742 const op = buildOpcode(.{4765 const op = buildOpcode(.{
4743 .op = .trunc,4766 .op = .trunc,
4744 .valtype1 = typeToValtype(dest_ty, func.target),4767 .valtype1 = typeToValtype(dest_ty, mod),
4745 .valtype2 = typeToValtype(op_ty, func.target),4768 .valtype2 = typeToValtype(op_ty, mod),
4746 .signedness = if (dest_ty.isSignedInt()) .signed else .unsigned,4769 .signedness = if (dest_ty.isSignedInt(mod)) .signed else .unsigned,
4747 });4770 });
4748 try func.addTag(Mir.Inst.Tag.fromOpcode(op));4771 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
4749 const wrapped = try func.wrapOperand(.{ .stack = {} }, dest_ty);4772 const wrapped = try func.wrapOperand(.{ .stack = {} }, dest_ty);
...@@ -4757,17 +4780,18 @@ fn airIntToFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4757,17 +4780,18 @@ fn airIntToFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4757 const operand = try func.resolveInst(ty_op.operand);4780 const operand = try func.resolveInst(ty_op.operand);
4758 const dest_ty = func.air.typeOfIndex(inst);4781 const dest_ty = func.air.typeOfIndex(inst);
4759 const op_ty = func.air.typeOf(ty_op.operand);4782 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) {
4762 return func.fail("TODO: intToFloat for integers/floats with bitsize larger than 64 bits", .{});4786 return func.fail("TODO: intToFloat for integers/floats with bitsize larger than 64 bits", .{});
4763 }4787 }
47644788
4765 try func.emitWValue(operand);4789 try func.emitWValue(operand);
4766 const op = buildOpcode(.{4790 const op = buildOpcode(.{
4767 .op = .convert,4791 .op = .convert,
4768 .valtype1 = typeToValtype(dest_ty, func.target),4792 .valtype1 = typeToValtype(dest_ty, mod),
4769 .valtype2 = typeToValtype(op_ty, func.target),4793 .valtype2 = typeToValtype(op_ty, mod),
4770 .signedness = if (op_ty.isSignedInt()) .signed else .unsigned,4794 .signedness = if (op_ty.isSignedInt(mod)) .signed else .unsigned,
4771 });4795 });
4772 try func.addTag(Mir.Inst.Tag.fromOpcode(op));4796 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
47734797
...@@ -4777,18 +4801,19 @@ fn airIntToFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4777,18 +4801,19 @@ fn airIntToFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4777}4801}
47784802
4779fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4803fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4804 const mod = func.bin_file.base.options.module.?;
4780 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4805 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
4781 const operand = try func.resolveInst(ty_op.operand);4806 const operand = try func.resolveInst(ty_op.operand);
4782 const ty = func.air.typeOfIndex(inst);4807 const ty = func.air.typeOfIndex(inst);
4783 const elem_ty = ty.childType();4808 const elem_ty = ty.childType();
47844809
4785 if (determineSimdStoreStrategy(ty, func.target) == .direct) blk: {4810 if (determineSimdStoreStrategy(ty, mod) == .direct) blk: {
4786 switch (operand) {4811 switch (operand) {
4787 // when the operand lives in the linear memory section, we can directly4812 // when the operand lives in the linear memory section, we can directly
4788 // load and splat the value at once. Meaning we do not first have to load4813 // load and splat the value at once. Meaning we do not first have to load
4789 // the scalar value onto the stack.4814 // the scalar value onto the stack.
4790 .stack_offset, .memory, .memory_offset => {4815 .stack_offset, .memory, .memory_offset => {
4791 const opcode = switch (elem_ty.bitSize(func.target)) {4816 const opcode = switch (elem_ty.bitSize(mod)) {
4792 8 => std.wasm.simdOpcode(.v128_load8_splat),4817 8 => std.wasm.simdOpcode(.v128_load8_splat),
4793 16 => std.wasm.simdOpcode(.v128_load16_splat),4818 16 => std.wasm.simdOpcode(.v128_load16_splat),
4794 32 => std.wasm.simdOpcode(.v128_load32_splat),4819 32 => std.wasm.simdOpcode(.v128_load32_splat),
...@@ -4803,18 +4828,18 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4803,18 +4828,18 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4803 try func.mir_extra.appendSlice(func.gpa, &[_]u32{4828 try func.mir_extra.appendSlice(func.gpa, &[_]u32{
4804 opcode,4829 opcode,
4805 operand.offset(),4830 operand.offset(),
4806 elem_ty.abiAlignment(func.target),4831 elem_ty.abiAlignment(mod),
4807 });4832 });
4808 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });4833 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
4809 try func.addLabel(.local_set, result.local.value);4834 try func.addLabel(.local_set, result.local.value);
4810 return func.finishAir(inst, result, &.{ty_op.operand});4835 return func.finishAir(inst, result, &.{ty_op.operand});
4811 },4836 },
4812 .local => {4837 .local => {
4813 const opcode = switch (elem_ty.bitSize(func.target)) {4838 const opcode = switch (elem_ty.bitSize(mod)) {
4814 8 => std.wasm.simdOpcode(.i8x16_splat),4839 8 => std.wasm.simdOpcode(.i8x16_splat),
4815 16 => std.wasm.simdOpcode(.i16x8_splat),4840 16 => std.wasm.simdOpcode(.i16x8_splat),
4816 32 => if (elem_ty.isInt()) std.wasm.simdOpcode(.i32x4_splat) else std.wasm.simdOpcode(.f32x4_splat),4841 32 => if (elem_ty.isInt(mod)) 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),4842 64 => if (elem_ty.isInt(mod)) std.wasm.simdOpcode(.i64x2_splat) else std.wasm.simdOpcode(.f64x2_splat),
4818 else => break :blk, // Cannot make use of simd-instructions4843 else => break :blk, // Cannot make use of simd-instructions
4819 };4844 };
4820 const result = try func.allocLocal(ty);4845 const result = try func.allocLocal(ty);
...@@ -4828,14 +4853,14 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4828,14 +4853,14 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4828 else => unreachable,4853 else => unreachable,
4829 }4854 }
4830 }4855 }
4831 const elem_size = elem_ty.bitSize(func.target);4856 const elem_size = elem_ty.bitSize(mod);
4832 const vector_len = @intCast(usize, ty.vectorLen());4857 const vector_len = @intCast(usize, ty.vectorLen());
4833 if ((!std.math.isPowerOfTwo(elem_size) or elem_size % 8 != 0) and vector_len > 1) {4858 if ((!std.math.isPowerOfTwo(elem_size) or elem_size % 8 != 0) and vector_len > 1) {
4834 return func.fail("TODO: WebAssembly `@splat` for arbitrary element bitsize {d}", .{elem_size});4859 return func.fail("TODO: WebAssembly `@splat` for arbitrary element bitsize {d}", .{elem_size});
4835 }4860 }
48364861
4837 const result = try func.allocStack(ty);4862 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));
4839 var index: usize = 0;4864 var index: usize = 0;
4840 var offset: u32 = 0;4865 var offset: u32 = 0;
4841 while (index < vector_len) : (index += 1) {4866 while (index < vector_len) : (index += 1) {
...@@ -4855,6 +4880,7 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4855,6 +4880,7 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4855}4880}
48564881
4857fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4882fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4883 const mod = func.bin_file.base.options.module.?;
4858 const inst_ty = func.air.typeOfIndex(inst);4884 const inst_ty = func.air.typeOfIndex(inst);
4859 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;4885 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
4860 const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data;4886 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 {...@@ -4865,16 +4891,15 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4865 const mask_len = extra.mask_len;4891 const mask_len = extra.mask_len;
48664892
4867 const child_ty = inst_ty.childType();4893 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.?;
4871 // TODO: One of them could be by ref; handle in loop4896 // 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)) {
4873 const result = try func.allocStack(inst_ty);4898 const result = try func.allocStack(inst_ty);
48744899
4875 for (0..mask_len) |index| {4900 for (0..mask_len) |index| {
4876 var buf: Value.ElemValueBuffer = undefined;4901 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
4879 try func.emitWValue(result);4904 try func.emitWValue(result);
48804905
...@@ -4895,7 +4920,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4895,7 +4920,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4895 var lanes = std.mem.asBytes(operands[1..]);4920 var lanes = std.mem.asBytes(operands[1..]);
4896 for (0..@intCast(usize, mask_len)) |index| {4921 for (0..@intCast(usize, mask_len)) |index| {
4897 var buf: Value.ElemValueBuffer = undefined;4922 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);
4899 const base_index = if (mask_elem >= 0)4924 const base_index = if (mask_elem >= 0)
4900 @intCast(u8, @intCast(i64, elem_size) * mask_elem)4925 @intCast(u8, @intCast(i64, elem_size) * mask_elem)
4901 else4926 else
...@@ -4930,13 +4955,14 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4930,13 +4955,14 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4930 const result_ty = func.air.typeOfIndex(inst);4955 const result_ty = func.air.typeOfIndex(inst);
4931 const len = @intCast(usize, result_ty.arrayLen());4956 const len = @intCast(usize, result_ty.arrayLen());
4932 const elements = @ptrCast([]const Air.Inst.Ref, func.air.extra[ty_pl.payload..][0..len]);4957 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
4934 const result: WValue = result_value: {4960 const result: WValue = result_value: {
4935 switch (result_ty.zigTypeTag()) {4961 switch (result_ty.zigTypeTag(mod)) {
4936 .Array => {4962 .Array => {
4937 const result = try func.allocStack(result_ty);4963 const result = try func.allocStack(result_ty);
4938 const elem_ty = result_ty.childType();4964 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));
4940 const sentinel = if (result_ty.sentinel()) |sent| blk: {4966 const sentinel = if (result_ty.sentinel()) |sent| blk: {
4941 break :blk try func.lowerConstant(sent, elem_ty);4967 break :blk try func.lowerConstant(sent, elem_ty);
4942 } else null;4968 } else null;
...@@ -4944,7 +4970,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4944,7 +4970,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4944 // When the element type is by reference, we must copy the entire4970 // When the element type is by reference, we must copy the entire
4945 // value. It is therefore safer to move the offset pointer and store4971 // value. It is therefore safer to move the offset pointer and store
4946 // each value individually, instead of using store offsets.4972 // each value individually, instead of using store offsets.
4947 if (isByRef(elem_ty, func.target)) {4973 if (isByRef(elem_ty, mod)) {
4948 // copy stack pointer into a temporary local, which is4974 // copy stack pointer into a temporary local, which is
4949 // moved for each element to store each value in the right position.4975 // moved for each element to store each value in the right position.
4950 const offset = try func.buildPointerOffset(result, 0, .new);4976 const offset = try func.buildPointerOffset(result, 0, .new);
...@@ -4974,7 +5000,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4974,7 +5000,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4974 },5000 },
4975 .Struct => switch (result_ty.containerLayout()) {5001 .Struct => switch (result_ty.containerLayout()) {
4976 .Packed => {5002 .Packed => {
4977 if (isByRef(result_ty, func.target)) {5003 if (isByRef(result_ty, mod)) {
4978 return func.fail("TODO: airAggregateInit for packed structs larger than 64 bits", .{});5004 return func.fail("TODO: airAggregateInit for packed structs larger than 64 bits", .{});
4979 }5005 }
4980 const struct_obj = result_ty.castTag(.@"struct").?.data;5006 const struct_obj = result_ty.castTag(.@"struct").?.data;
...@@ -4983,7 +5009,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4983,7 +5009,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
49835009
4984 // ensure the result is zero'd5010 // ensure the result is zero'd
4985 const result = try func.allocLocal(backing_type);5011 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)
4987 try func.addImm32(0)5013 try func.addImm32(0)
4988 else5014 else
4989 try func.addImm64(0);5015 try func.addImm64(0);
...@@ -4992,20 +5018,16 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4992,20 +5018,16 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4992 var current_bit: u16 = 0;5018 var current_bit: u16 = 0;
4993 for (elements, 0..) |elem, elem_index| {5019 for (elements, 0..) |elem, elem_index| {
4994 const field = fields[elem_index];5020 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)
4998 WValue{ .imm32 = current_bit }5024 WValue{ .imm32 = current_bit }
4999 else5025 else
5000 WValue{ .imm64 = current_bit };5026 WValue{ .imm64 = current_bit };
50015027
5002 const value = try func.resolveInst(elem);5028 const value = try func.resolveInst(elem);
5003 const value_bit_size = @intCast(u16, field.ty.bitSize(func.target));5029 const value_bit_size = @intCast(u16, field.ty.bitSize(mod));
5004 var int_ty_payload: Type.Payload.Bits = .{5030 const int_ty = try mod.intType(.unsigned, value_bit_size);
5005 .base = .{ .tag = .int_unsigned },
5006 .data = value_bit_size,
5007 };
5008 const int_ty = Type.initPayload(&int_ty_payload.base);
50095031
5010 // load our current result on stack so we can perform all transformations5032 // load our current result on stack so we can perform all transformations
5011 // using only stack values. Saving the cost of loads and stores.5033 // 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 {...@@ -5027,10 +5049,10 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5027 const result = try func.allocStack(result_ty);5049 const result = try func.allocStack(result_ty);
5028 const offset = try func.buildPointerOffset(result, 0, .new); // pointer to offset5050 const offset = try func.buildPointerOffset(result, 0, .new); // pointer to offset
5029 for (elements, 0..) |elem, elem_index| {5051 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
5032 const elem_ty = result_ty.structFieldType(elem_index);5054 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));
5034 const value = try func.resolveInst(elem);5056 const value = try func.resolveInst(elem);
5035 try func.store(offset, value, elem_ty, 0);5057 try func.store(offset, value, elem_ty, 0);
50365058
...@@ -5058,12 +5080,13 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5058,12 +5080,13 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5058}5080}
50595081
5060fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5082fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5083 const mod = func.bin_file.base.options.module.?;
5061 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;5084 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
5062 const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data;5085 const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data;
50635086
5064 const result = result: {5087 const result = result: {
5065 const union_ty = func.air.typeOfIndex(inst);5088 const union_ty = func.air.typeOfIndex(inst);
5066 const layout = union_ty.unionGetLayout(func.target);5089 const layout = union_ty.unionGetLayout(mod);
5067 const union_obj = union_ty.cast(Type.Payload.Union).?.data;5090 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
5068 const field = union_obj.fields.values()[extra.field_index];5091 const field = union_obj.fields.values()[extra.field_index];
5069 const field_name = union_obj.fields.keys()[extra.field_index];5092 const field_name = union_obj.fields.keys()[extra.field_index];
...@@ -5082,15 +5105,15 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5082,15 +5105,15 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5082 if (layout.tag_size == 0) {5105 if (layout.tag_size == 0) {
5083 break :result WValue{ .none = {} };5106 break :result WValue{ .none = {} };
5084 }5107 }
5085 assert(!isByRef(union_ty, func.target));5108 assert(!isByRef(union_ty, mod));
5086 break :result tag_int;5109 break :result tag_int;
5087 }5110 }
50885111
5089 if (isByRef(union_ty, func.target)) {5112 if (isByRef(union_ty, mod)) {
5090 const result_ptr = try func.allocStack(union_ty);5113 const result_ptr = try func.allocStack(union_ty);
5091 const payload = try func.resolveInst(extra.init);5114 const payload = try func.resolveInst(extra.init);
5092 if (layout.tag_align >= layout.payload_align) {5115 if (layout.tag_align >= layout.payload_align) {
5093 if (isByRef(field.ty, func.target)) {5116 if (isByRef(field.ty, mod)) {
5094 const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new);5117 const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new);
5095 try func.store(payload_ptr, payload, field.ty, 0);5118 try func.store(payload_ptr, payload, field.ty, 0);
5096 } else {5119 } else {
...@@ -5114,26 +5137,14 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5114,26 +5137,14 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5114 break :result result_ptr;5137 break :result result_ptr;
5115 } else {5138 } else {
5116 const operand = try func.resolveInst(extra.init);5139 const operand = try func.resolveInst(extra.init);
5117 var payload: Type.Payload.Bits = .{5140 const union_int_type = try mod.intType(.unsigned, @intCast(u16, union_ty.bitSize(mod)));
5118 .base = .{ .tag = .int_unsigned },5141 if (field.ty.zigTypeTag(mod) == .Float) {
5119 .data = @intCast(u16, union_ty.bitSize(func.target)),5142 const int_type = try mod.intType(.unsigned, @intCast(u16, field.ty.bitSize(mod)));
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);
5128 const bitcasted = try func.bitcast(field.ty, int_type, operand);5143 const bitcasted = try func.bitcast(field.ty, int_type, operand);
5129 const casted = try func.trunc(bitcasted, int_type, union_int_type);5144 const casted = try func.trunc(bitcasted, int_type, union_int_type);
5130 break :result try casted.toLocal(func, field.ty);5145 break :result try casted.toLocal(func, field.ty);
5131 } else if (field.ty.isPtrAtRuntime()) {5146 } else if (field.ty.isPtrAtRuntime(mod)) {
5132 var int_payload: Type.Payload.Bits = .{5147 const int_type = try mod.intType(.unsigned, @intCast(u16, field.ty.bitSize(mod)));
5133 .base = .{ .tag = .int_unsigned },
5134 .data = @intCast(u16, field.ty.bitSize(func.target)),
5135 };
5136 const int_type = Type.initPayload(&int_payload.base);
5137 const casted = try func.intcast(operand, int_type, union_int_type);5148 const casted = try func.intcast(operand, int_type, union_int_type);
5138 break :result try casted.toLocal(func, field.ty);5149 break :result try casted.toLocal(func, field.ty);
5139 }5150 }
...@@ -5171,7 +5182,8 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void {...@@ -5171,7 +5182,8 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void {
5171}5182}
51725183
5173fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {5184fn 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));
5175 assert(op == .eq or op == .neq);5187 assert(op == .eq or op == .neq);
5176 var buf: Type.Payload.ElemType = undefined;5188 var buf: Type.Payload.ElemType = undefined;
5177 const payload_ty = operand_ty.optionalChild(&buf);5189 const payload_ty = operand_ty.optionalChild(&buf);
...@@ -5189,7 +5201,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:...@@ -5189,7 +5201,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:
51895201
5190 _ = try func.load(lhs, payload_ty, 0);5202 _ = try func.load(lhs, payload_ty, 0);
5191 _ = try func.load(rhs, payload_ty, 0);5203 _ = 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) });
5193 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));5205 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
5194 try func.addLabel(.br_if, 0);5206 try func.addLabel(.br_if, 0);
51955207
...@@ -5207,10 +5219,11 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:...@@ -5207,10 +5219,11 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:
5207/// NOTE: Leaves the result of the comparison on top of the stack.5219/// NOTE: Leaves the result of the comparison on top of the stack.
5208/// TODO: Lower this to compiler_rt call when bitsize > 1285220/// TODO: Lower this to compiler_rt call when bitsize > 128
5209fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {5221fn 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);
5211 assert(!(lhs != .stack and rhs == .stack));5224 assert(!(lhs != .stack and rhs == .stack));
5212 if (operand_ty.bitSize(func.target) > 128) {5225 if (operand_ty.bitSize(mod) > 128) {
5213 return func.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.bitSize(func.target)});5226 return func.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.bitSize(mod)});
5214 }5227 }
52155228
5216 var lhs_high_bit = try (try func.load(lhs, Type.u64, 0)).toLocal(func, Type.u64);5229 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...@@ -5233,7 +5246,7 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std
5233 }5246 }
5234 },5247 },
5235 else => {5248 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;
5237 // leave those value on top of the stack for '.select'5250 // leave those value on top of the stack for '.select'
5238 const lhs_low_bit = try func.load(lhs, Type.u64, 8);5251 const lhs_low_bit = try func.load(lhs, Type.u64, 8);
5239 const rhs_low_bit = try func.load(rhs, Type.u64, 8);5252 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...@@ -5248,10 +5261,11 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std
5248}5261}
52495262
5250fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5263fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5264 const mod = func.bin_file.base.options.module.?;
5251 const bin_op = func.air.instructions.items(.data)[inst].bin_op;5265 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
5252 const un_ty = func.air.typeOf(bin_op.lhs).childType();5266 const un_ty = func.air.typeOf(bin_op.lhs).childType();
5253 const tag_ty = func.air.typeOf(bin_op.rhs);5267 const tag_ty = func.air.typeOf(bin_op.rhs);
5254 const layout = un_ty.unionGetLayout(func.target);5268 const layout = un_ty.unionGetLayout(mod);
5255 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });5269 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
52565270
5257 const union_ptr = try func.resolveInst(bin_op.lhs);5271 const union_ptr = try func.resolveInst(bin_op.lhs);
...@@ -5271,11 +5285,12 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5271,11 +5285,12 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5271}5285}
52725286
5273fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5287fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5288 const mod = func.bin_file.base.options.module.?;
5274 const ty_op = func.air.instructions.items(.data)[inst].ty_op;5289 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
52755290
5276 const un_ty = func.air.typeOf(ty_op.operand);5291 const un_ty = func.air.typeOf(ty_op.operand);
5277 const tag_ty = func.air.typeOfIndex(inst);5292 const tag_ty = func.air.typeOfIndex(inst);
5278 const layout = un_ty.unionGetLayout(func.target);5293 const layout = un_ty.unionGetLayout(mod);
5279 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ty_op.operand});5294 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ty_op.operand});
52805295
5281 const operand = try func.resolveInst(ty_op.operand);5296 const operand = try func.resolveInst(ty_op.operand);
...@@ -5375,6 +5390,7 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro...@@ -5375,6 +5390,7 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
5375}5390}
53765391
5377fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5392fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5393 const mod = func.bin_file.base.options.module.?;
5378 const ty_op = func.air.instructions.items(.data)[inst].ty_op;5394 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
53795395
5380 const err_set_ty = func.air.typeOf(ty_op.operand).childType();5396 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...@@ -5386,26 +5402,27 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
5386 operand,5402 operand,
5387 .{ .imm32 = 0 },5403 .{ .imm32 = 0 },
5388 Type.anyerror,5404 Type.anyerror,
5389 @intCast(u32, errUnionErrorOffset(payload_ty, func.target)),5405 @intCast(u32, errUnionErrorOffset(payload_ty, mod)),
5390 );5406 );
53915407
5392 const result = result: {5408 const result = result: {
5393 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {5409 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5394 break :result func.reuseOperand(ty_op.operand, operand);5410 break :result func.reuseOperand(ty_op.operand, operand);
5395 }5411 }
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);
5398 };5414 };
5399 func.finishAir(inst, result, &.{ty_op.operand});5415 func.finishAir(inst, result, &.{ty_op.operand});
5400}5416}
54015417
5402fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5418fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5419 const mod = func.bin_file.base.options.module.?;
5403 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;5420 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
5404 const extra = func.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;5421 const extra = func.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
54055422
5406 const field_ptr = try func.resolveInst(extra.field_ptr);5423 const field_ptr = try func.resolveInst(extra.field_ptr);
5407 const parent_ty = func.air.getRefType(ty_pl.ty).childType();5424 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
5410 const result = if (field_offset != 0) result: {5427 const result = if (field_offset != 0) result: {
5411 const base = try func.buildPointerOffset(field_ptr, 0, .new);5428 const base = try func.buildPointerOffset(field_ptr, 0, .new);
...@@ -5428,6 +5445,7 @@ fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue...@@ -5428,6 +5445,7 @@ fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue
5428}5445}
54295446
5430fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5447fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5448 const mod = func.bin_file.base.options.module.?;
5431 const bin_op = func.air.instructions.items(.data)[inst].bin_op;5449 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
5432 const dst = try func.resolveInst(bin_op.lhs);5450 const dst = try func.resolveInst(bin_op.lhs);
5433 const dst_ty = func.air.typeOf(bin_op.lhs);5451 const dst_ty = func.air.typeOf(bin_op.lhs);
...@@ -5437,16 +5455,16 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5437,16 +5455,16 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5437 const len = switch (dst_ty.ptrSize()) {5455 const len = switch (dst_ty.ptrSize()) {
5438 .Slice => blk: {5456 .Slice => blk: {
5439 const slice_len = try func.sliceLen(dst);5457 const slice_len = try func.sliceLen(dst);
5440 if (ptr_elem_ty.abiSize(func.target) != 1) {5458 if (ptr_elem_ty.abiSize(mod) != 1) {
5441 try func.emitWValue(slice_len);5459 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)) });
5443 try func.addTag(.i32_mul);5461 try func.addTag(.i32_mul);
5444 try func.addLabel(.local_set, slice_len.local.value);5462 try func.addLabel(.local_set, slice_len.local.value);
5445 }5463 }
5446 break :blk slice_len;5464 break :blk slice_len;
5447 },5465 },
5448 .One => @as(WValue, .{5466 .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)),
5450 }),5468 }),
5451 .C, .Many => unreachable,5469 .C, .Many => unreachable,
5452 };5470 };
...@@ -5472,12 +5490,13 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5472,12 +5490,13 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5472 const operand = try func.resolveInst(ty_op.operand);5490 const operand = try func.resolveInst(ty_op.operand);
5473 const op_ty = func.air.typeOf(ty_op.operand);5491 const op_ty = func.air.typeOf(ty_op.operand);
5474 const result_ty = func.air.typeOfIndex(inst);5492 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) {
5477 return func.fail("TODO: Implement @popCount for vectors", .{});5496 return func.fail("TODO: Implement @popCount for vectors", .{});
5478 }5497 }
54795498
5480 const int_info = op_ty.intInfo(func.target);5499 const int_info = op_ty.intInfo(mod);
5481 const bits = int_info.bits;5500 const bits = int_info.bits;
5482 const wasm_bits = toWasmBits(bits) orelse {5501 const wasm_bits = toWasmBits(bits) orelse {
5483 return func.fail("TODO: Implement @popCount for integers with bitsize '{d}'", .{bits});5502 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 {...@@ -5527,7 +5546,8 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5527 // to make a copy of the ptr+value but can point towards them directly.5546 // to make a copy of the ptr+value but can point towards them directly.
5528 const error_table_symbol = try func.bin_file.getErrorTableSymbol();5547 const error_table_symbol = try func.bin_file.getErrorTableSymbol();
5529 const name_ty = Type.initTag(.const_slice_u8_sentinel_0);5548 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
5532 const error_name_value: WValue = .{ .memory = error_table_symbol }; // emitting this will create a relocation5552 const error_name_value: WValue = .{ .memory = error_table_symbol }; // emitting this will create a relocation
5533 try func.emitWValue(error_name_value);5553 try func.emitWValue(error_name_value);
...@@ -5566,12 +5586,13 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro...@@ -5566,12 +5586,13 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
5566 const lhs_op = try func.resolveInst(extra.lhs);5586 const lhs_op = try func.resolveInst(extra.lhs);
5567 const rhs_op = try func.resolveInst(extra.rhs);5587 const rhs_op = try func.resolveInst(extra.rhs);
5568 const lhs_ty = func.air.typeOf(extra.lhs);5588 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) {
5571 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});5592 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
5572 }5593 }
55735594
5574 const int_info = lhs_ty.intInfo(func.target);5595 const int_info = lhs_ty.intInfo(mod);
5575 const is_signed = int_info.signedness == .signed;5596 const is_signed = int_info.signedness == .signed;
5576 const wasm_bits = toWasmBits(int_info.bits) orelse {5597 const wasm_bits = toWasmBits(int_info.bits) orelse {
5577 return func.fail("TODO: Implement {{add/sub}}_with_overflow for integer bitsize: {d}", .{int_info.bits});5598 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...@@ -5630,15 +5651,16 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
56305651
5631 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));5652 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));
5632 try func.store(result_ptr, result, lhs_ty, 0);5653 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));
5634 try func.store(result_ptr, overflow_local, Type.initTag(.u1), offset);5655 try func.store(result_ptr, overflow_local, Type.initTag(.u1), offset);
56355656
5636 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });5657 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
5637}5658}
56385659
5639fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, result_ty: Type, op: Op) InnerError!WValue {5660fn 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.?;
5640 assert(op == .add or op == .sub);5662 assert(op == .add or op == .sub);
5641 const int_info = ty.intInfo(func.target);5663 const int_info = ty.intInfo(mod);
5642 const is_signed = int_info.signedness == .signed;5664 const is_signed = int_info.signedness == .signed;
5643 if (int_info.bits != 128) {5665 if (int_info.bits != 128) {
5644 return func.fail("TODO: Implement @{{add/sub}}WithOverflow for integer bitsize '{d}'", .{int_info.bits});5666 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,...@@ -5701,6 +5723,7 @@ fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type,
5701}5723}
57025724
5703fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5725fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5726 const mod = func.bin_file.base.options.module.?;
5704 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;5727 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
5705 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;5728 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 {...@@ -5709,11 +5732,11 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5709 const lhs_ty = func.air.typeOf(extra.lhs);5732 const lhs_ty = func.air.typeOf(extra.lhs);
5710 const rhs_ty = func.air.typeOf(extra.rhs);5733 const rhs_ty = func.air.typeOf(extra.rhs);
57115734
5712 if (lhs_ty.zigTypeTag() == .Vector) {5735 if (lhs_ty.zigTypeTag(mod) == .Vector) {
5713 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});5736 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
5714 }5737 }
57155738
5716 const int_info = lhs_ty.intInfo(func.target);5739 const int_info = lhs_ty.intInfo(mod);
5717 const is_signed = int_info.signedness == .signed;5740 const is_signed = int_info.signedness == .signed;
5718 const wasm_bits = toWasmBits(int_info.bits) orelse {5741 const wasm_bits = toWasmBits(int_info.bits) orelse {
5719 return func.fail("TODO: Implement shl_with_overflow for integer bitsize: {d}", .{int_info.bits});5742 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 {...@@ -5721,7 +5744,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57215744
5722 // Ensure rhs is coerced to lhs as they must have the same WebAssembly types5745 // Ensure rhs is coerced to lhs as they must have the same WebAssembly types
5723 // before we can perform any binary operation.5746 // 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).?;
5725 const rhs_final = if (wasm_bits != rhs_wasm_bits) blk: {5748 const rhs_final = if (wasm_bits != rhs_wasm_bits) blk: {
5726 const rhs_casted = try func.intcast(rhs, rhs_ty, lhs_ty);5749 const rhs_casted = try func.intcast(rhs, rhs_ty, lhs_ty);
5727 break :blk try rhs_casted.toLocal(func, lhs_ty);5750 break :blk try rhs_casted.toLocal(func, lhs_ty);
...@@ -5750,7 +5773,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5750,7 +5773,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57505773
5751 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));5774 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));
5752 try func.store(result_ptr, result, lhs_ty, 0);5775 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));
5754 try func.store(result_ptr, overflow_local, Type.initTag(.u1), offset);5777 try func.store(result_ptr, overflow_local, Type.initTag(.u1), offset);
57555778
5756 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });5779 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
...@@ -5763,8 +5786,9 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5763,8 +5786,9 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5763 const lhs = try func.resolveInst(extra.lhs);5786 const lhs = try func.resolveInst(extra.lhs);
5764 const rhs = try func.resolveInst(extra.rhs);5787 const rhs = try func.resolveInst(extra.rhs);
5765 const lhs_ty = func.air.typeOf(extra.lhs);5788 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) {
5768 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});5792 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
5769 }5793 }
57705794
...@@ -5773,7 +5797,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5773,7 +5797,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5773 var overflow_bit = try func.ensureAllocLocal(Type.initTag(.u1));5797 var overflow_bit = try func.ensureAllocLocal(Type.initTag(.u1));
5774 defer overflow_bit.free(func);5798 defer overflow_bit.free(func);
57755799
5776 const int_info = lhs_ty.intInfo(func.target);5800 const int_info = lhs_ty.intInfo(mod);
5777 const wasm_bits = toWasmBits(int_info.bits) orelse {5801 const wasm_bits = toWasmBits(int_info.bits) orelse {
5778 return func.fail("TODO: Implement `@mulWithOverflow` for integer bitsize: {d}", .{int_info.bits});5802 return func.fail("TODO: Implement `@mulWithOverflow` for integer bitsize: {d}", .{int_info.bits});
5779 };5803 };
...@@ -5924,7 +5948,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5924,7 +5948,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
59245948
5925 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));5949 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));
5926 try func.store(result_ptr, bin_op_local, lhs_ty, 0);5950 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));
5928 try func.store(result_ptr, overflow_bit, Type.initTag(.u1), offset);5952 try func.store(result_ptr, overflow_bit, Type.initTag(.u1), offset);
59295953
5930 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });5954 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...@@ -5934,11 +5958,12 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: enum { max, min }) InnerE
5934 const bin_op = func.air.instructions.items(.data)[inst].bin_op;5958 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
59355959
5936 const ty = func.air.typeOfIndex(inst);5960 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) {
5938 return func.fail("TODO: `@maximum` and `@minimum` for vectors", .{});5963 return func.fail("TODO: `@maximum` and `@minimum` for vectors", .{});
5939 }5964 }
59405965
5941 if (ty.abiSize(func.target) > 16) {5966 if (ty.abiSize(mod) > 16) {
5942 return func.fail("TODO: `@maximum` and `@minimum` for types larger than 16 bytes", .{});5967 return func.fail("TODO: `@maximum` and `@minimum` for types larger than 16 bytes", .{});
5943 }5968 }
59445969
...@@ -5954,7 +5979,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: enum { max, min }) InnerE...@@ -5954,7 +5979,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: enum { max, min }) InnerE
5954 try func.addTag(.select);5979 try func.addTag(.select);
59555980
5956 // store result in local5981 // 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;
5958 const result = try func.allocLocal(result_ty);5983 const result = try func.allocLocal(result_ty);
5959 try func.addLabel(.local_set, result.local.value);5984 try func.addLabel(.local_set, result.local.value);
5960 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });5985 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
...@@ -5965,7 +5990,8 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5965,7 +5990,8 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5965 const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data;5990 const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data;
59665991
5967 const ty = func.air.typeOfIndex(inst);5992 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) {
5969 return func.fail("TODO: `@mulAdd` for vectors", .{});5995 return func.fail("TODO: `@mulAdd` for vectors", .{});
5970 }5996 }
59715997
...@@ -5998,12 +6024,13 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5998,12 +6024,13 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
59986024
5999 const ty = func.air.typeOf(ty_op.operand);6025 const ty = func.air.typeOf(ty_op.operand);
6000 const result_ty = func.air.typeOfIndex(inst);6026 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) {
6002 return func.fail("TODO: `@clz` for vectors", .{});6029 return func.fail("TODO: `@clz` for vectors", .{});
6003 }6030 }
60046031
6005 const operand = try func.resolveInst(ty_op.operand);6032 const operand = try func.resolveInst(ty_op.operand);
6006 const int_info = ty.intInfo(func.target);6033 const int_info = ty.intInfo(mod);
6007 const wasm_bits = toWasmBits(int_info.bits) orelse {6034 const wasm_bits = toWasmBits(int_info.bits) orelse {
6008 return func.fail("TODO: `@clz` for integers with bitsize '{d}'", .{int_info.bits});6035 return func.fail("TODO: `@clz` for integers with bitsize '{d}'", .{int_info.bits});
6009 };6036 };
...@@ -6051,12 +6078,13 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6051,12 +6078,13 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6051 const ty = func.air.typeOf(ty_op.operand);6078 const ty = func.air.typeOf(ty_op.operand);
6052 const result_ty = func.air.typeOfIndex(inst);6079 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) {
6055 return func.fail("TODO: `@ctz` for vectors", .{});6083 return func.fail("TODO: `@ctz` for vectors", .{});
6056 }6084 }
60576085
6058 const operand = try func.resolveInst(ty_op.operand);6086 const operand = try func.resolveInst(ty_op.operand);
6059 const int_info = ty.intInfo(func.target);6087 const int_info = ty.intInfo(mod);
6060 const wasm_bits = toWasmBits(int_info.bits) orelse {6088 const wasm_bits = toWasmBits(int_info.bits) orelse {
6061 return func.fail("TODO: `@clz` for integers with bitsize '{d}'", .{int_info.bits});6089 return func.fail("TODO: `@clz` for integers with bitsize '{d}'", .{int_info.bits});
6062 };6090 };
...@@ -6174,12 +6202,13 @@ fn lowerTry(...@@ -6174,12 +6202,13 @@ fn lowerTry(
6174 err_union_ty: Type,6202 err_union_ty: Type,
6175 operand_is_ptr: bool,6203 operand_is_ptr: bool,
6176) InnerError!WValue {6204) InnerError!WValue {
6205 const mod = func.bin_file.base.options.module.?;
6177 if (operand_is_ptr) {6206 if (operand_is_ptr) {
6178 return func.fail("TODO: lowerTry for pointers", .{});6207 return func.fail("TODO: lowerTry for pointers", .{});
6179 }6208 }
61806209
6181 const pl_ty = err_union_ty.errorUnionPayload();6210 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
6184 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {6213 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
6185 // Block we can jump out of when error is not set6214 // Block we can jump out of when error is not set
...@@ -6188,10 +6217,10 @@ fn lowerTry(...@@ -6188,10 +6217,10 @@ fn lowerTry(
6188 // check if the error tag is set for the error union.6217 // check if the error tag is set for the error union.
6189 try func.emitWValue(err_union);6218 try func.emitWValue(err_union);
6190 if (pl_has_bits) {6219 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));
6192 try func.addMemArg(.i32_load16_u, .{6221 try func.addMemArg(.i32_load16_u, .{
6193 .offset = err_union.offset() + err_offset,6222 .offset = err_union.offset() + err_offset,
6194 .alignment = Type.anyerror.abiAlignment(func.target),6223 .alignment = Type.anyerror.abiAlignment(mod),
6195 });6224 });
6196 }6225 }
6197 try func.addTag(.i32_eqz);6226 try func.addTag(.i32_eqz);
...@@ -6213,8 +6242,8 @@ fn lowerTry(...@@ -6213,8 +6242,8 @@ fn lowerTry(
6213 return WValue{ .none = {} };6242 return WValue{ .none = {} };
6214 }6243 }
62156244
6216 const pl_offset = @intCast(u32, errUnionPayloadOffset(pl_ty, func.target));6245 const pl_offset = @intCast(u32, errUnionPayloadOffset(pl_ty, mod));
6217 if (isByRef(pl_ty, func.target)) {6246 if (isByRef(pl_ty, mod)) {
6218 return buildPointerOffset(func, err_union, pl_offset, .new);6247 return buildPointerOffset(func, err_union, pl_offset, .new);
6219 }6248 }
6220 const payload = try func.load(err_union, pl_ty, pl_offset);6249 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 {...@@ -6226,11 +6255,12 @@ fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
62266255
6227 const ty = func.air.typeOfIndex(inst);6256 const ty = func.air.typeOfIndex(inst);
6228 const operand = try func.resolveInst(ty_op.operand);6257 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) {
6231 return func.fail("TODO: @byteSwap for vectors", .{});6261 return func.fail("TODO: @byteSwap for vectors", .{});
6232 }6262 }
6233 const int_info = ty.intInfo(func.target);6263 const int_info = ty.intInfo(mod);
62346264
6235 // bytes are no-op6265 // bytes are no-op
6236 if (int_info.bits == 8) {6266 if (int_info.bits == 8) {
...@@ -6292,13 +6322,14 @@ fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6292,13 +6322,14 @@ fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6292}6322}
62936323
6294fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6324fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6325 const mod = func.bin_file.base.options.module.?;
6295 const bin_op = func.air.instructions.items(.data)[inst].bin_op;6326 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
62966327
6297 const ty = func.air.typeOfIndex(inst);6328 const ty = func.air.typeOfIndex(inst);
6298 const lhs = try func.resolveInst(bin_op.lhs);6329 const lhs = try func.resolveInst(bin_op.lhs);
6299 const rhs = try func.resolveInst(bin_op.rhs);6330 const rhs = try func.resolveInst(bin_op.rhs);
63006331
6301 const result = if (ty.isSignedInt())6332 const result = if (ty.isSignedInt(mod))
6302 try func.divSigned(lhs, rhs, ty)6333 try func.divSigned(lhs, rhs, ty)
6303 else6334 else
6304 try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);6335 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 {...@@ -6306,13 +6337,14 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6306}6337}
63076338
6308fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6339fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6340 const mod = func.bin_file.base.options.module.?;
6309 const bin_op = func.air.instructions.items(.data)[inst].bin_op;6341 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
63106342
6311 const ty = func.air.typeOfIndex(inst);6343 const ty = func.air.typeOfIndex(inst);
6312 const lhs = try func.resolveInst(bin_op.lhs);6344 const lhs = try func.resolveInst(bin_op.lhs);
6313 const rhs = try func.resolveInst(bin_op.rhs);6345 const rhs = try func.resolveInst(bin_op.rhs);
63146346
6315 const div_result = if (ty.isSignedInt())6347 const div_result = if (ty.isSignedInt(mod))
6316 try func.divSigned(lhs, rhs, ty)6348 try func.divSigned(lhs, rhs, ty)
6317 else6349 else
6318 try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);6350 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 {...@@ -6328,15 +6360,16 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6328fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6360fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6329 const bin_op = func.air.instructions.items(.data)[inst].bin_op;6361 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
63306362
6363 const mod = func.bin_file.base.options.module.?;
6331 const ty = func.air.typeOfIndex(inst);6364 const ty = func.air.typeOfIndex(inst);
6332 const lhs = try func.resolveInst(bin_op.lhs);6365 const lhs = try func.resolveInst(bin_op.lhs);
6333 const rhs = try func.resolveInst(bin_op.rhs);6366 const rhs = try func.resolveInst(bin_op.rhs);
63346367
6335 if (ty.isUnsignedInt()) {6368 if (ty.isUnsignedInt(mod)) {
6336 const result = try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);6369 const result = try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);
6337 return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });6370 return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
6338 } else if (ty.isSignedInt()) {6371 } else if (ty.isSignedInt(mod)) {
6339 const int_bits = ty.intInfo(func.target).bits;6372 const int_bits = ty.intInfo(mod).bits;
6340 const wasm_bits = toWasmBits(int_bits) orelse {6373 const wasm_bits = toWasmBits(int_bits) orelse {
6341 return func.fail("TODO: `@divFloor` for signed integers larger than '{d}' bits", .{int_bits});6374 return func.fail("TODO: `@divFloor` for signed integers larger than '{d}' bits", .{int_bits});
6342 };6375 };
...@@ -6414,7 +6447,8 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6414,7 +6447,8 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6414}6447}
64156448
6416fn divSigned(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type) InnerError!WValue {6449fn 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;
6418 const wasm_bits = toWasmBits(int_bits) orelse {6452 const wasm_bits = toWasmBits(int_bits) orelse {
6419 return func.fail("TODO: Implement signed division for integers with bitsize '{d}'", .{int_bits});6453 return func.fail("TODO: Implement signed division for integers with bitsize '{d}'", .{int_bits});
6420 };6454 };
...@@ -6441,7 +6475,8 @@ fn divSigned(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type) InnerError!WVal...@@ -6441,7 +6475,8 @@ fn divSigned(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type) InnerError!WVal
6441/// Retrieves the absolute value of a signed integer6475/// Retrieves the absolute value of a signed integer
6442/// NOTE: Leaves the result value on the stack.6476/// NOTE: Leaves the result value on the stack.
6443fn signAbsValue(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {6477fn 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;
6445 const wasm_bits = toWasmBits(int_bits) orelse {6480 const wasm_bits = toWasmBits(int_bits) orelse {
6446 return func.fail("TODO: signAbsValue for signed integers larger than '{d}' bits", .{int_bits});6481 return func.fail("TODO: signAbsValue for signed integers larger than '{d}' bits", .{int_bits});
6447 };6482 };
...@@ -6476,11 +6511,12 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -6476,11 +6511,12 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
6476 assert(op == .add or op == .sub);6511 assert(op == .add or op == .sub);
6477 const bin_op = func.air.instructions.items(.data)[inst].bin_op;6512 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
64786513
6514 const mod = func.bin_file.base.options.module.?;
6479 const ty = func.air.typeOfIndex(inst);6515 const ty = func.air.typeOfIndex(inst);
6480 const lhs = try func.resolveInst(bin_op.lhs);6516 const lhs = try func.resolveInst(bin_op.lhs);
6481 const rhs = try func.resolveInst(bin_op.rhs);6517 const rhs = try func.resolveInst(bin_op.rhs);
64826518
6483 const int_info = ty.intInfo(func.target);6519 const int_info = ty.intInfo(mod);
6484 const is_signed = int_info.signedness == .signed;6520 const is_signed = int_info.signedness == .signed;
64856521
6486 if (int_info.bits > 64) {6522 if (int_info.bits > 64) {
...@@ -6523,7 +6559,8 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -6523,7 +6559,8 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
6523}6559}
65246560
6525fn signedSat(func: *CodeGen, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op: Op) InnerError!WValue {6561fn 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);
6527 const wasm_bits = toWasmBits(int_info.bits).?;6564 const wasm_bits = toWasmBits(int_info.bits).?;
6528 const is_wasm_bits = wasm_bits == int_info.bits;6565 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,...@@ -6588,8 +6625,9 @@ fn signedSat(func: *CodeGen, lhs_operand: WValue, rhs_operand: WValue, ty: Type,
6588fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6625fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6589 const bin_op = func.air.instructions.items(.data)[inst].bin_op;6626 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
65906627
6628 const mod = func.bin_file.base.options.module.?;
6591 const ty = func.air.typeOfIndex(inst);6629 const ty = func.air.typeOfIndex(inst);
6592 const int_info = ty.intInfo(func.target);6630 const int_info = ty.intInfo(mod);
6593 const is_signed = int_info.signedness == .signed;6631 const is_signed = int_info.signedness == .signed;
6594 if (int_info.bits > 64) {6632 if (int_info.bits > 64) {
6595 return func.fail("TODO: Saturating shifting left for integers with bitsize '{d}'", .{int_info.bits});6633 return func.fail("TODO: Saturating shifting left for integers with bitsize '{d}'", .{int_info.bits});
...@@ -6707,12 +6745,13 @@ fn callIntrinsic(...@@ -6707,12 +6745,13 @@ fn callIntrinsic(
6707 };6745 };
67086746
6709 // Always pass over C-ABI6747 // 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);
6711 defer func_type.deinit(func.gpa);6750 defer func_type.deinit(func.gpa);
6712 const func_type_index = try func.bin_file.putOrGetFuncType(func_type);6751 const func_type_index = try func.bin_file.putOrGetFuncType(func_type);
6713 try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index);6752 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);
6716 // if we want return as first param, we allocate a pointer to stack,6755 // if we want return as first param, we allocate a pointer to stack,
6717 // and emit it as our first argument6756 // and emit it as our first argument
6718 const sret = if (want_sret_param) blk: {6757 const sret = if (want_sret_param) blk: {
...@@ -6724,14 +6763,14 @@ fn callIntrinsic(...@@ -6724,14 +6763,14 @@ fn callIntrinsic(
6724 // Lower all arguments to the stack before we call our function6763 // Lower all arguments to the stack before we call our function
6725 for (args, 0..) |arg, arg_i| {6764 for (args, 0..) |arg, arg_i| {
6726 assert(!(want_sret_param and arg == .stack));6765 assert(!(want_sret_param and arg == .stack));
6727 assert(param_types[arg_i].hasRuntimeBitsIgnoreComptime());6766 assert(param_types[arg_i].hasRuntimeBitsIgnoreComptime(mod));
6728 try func.lowerArg(.C, param_types[arg_i], arg);6767 try func.lowerArg(.C, param_types[arg_i], arg);
6729 }6768 }
67306769
6731 // Actually call our intrinsic6770 // Actually call our intrinsic
6732 try func.addLabel(.call, symbol_index);6771 try func.addLabel(.call, symbol_index);
67336772
6734 if (!return_type.hasRuntimeBitsIgnoreComptime()) {6773 if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) {
6735 return WValue.none;6774 return WValue.none;
6736 } else if (return_type.isNoReturn()) {6775 } else if (return_type.isNoReturn()) {
6737 try func.addTag(.@"unreachable");6776 try func.addTag(.@"unreachable");
...@@ -6759,15 +6798,15 @@ fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6759,15 +6798,15 @@ fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6759}6798}
67606799
6761fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {6800fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
6801 const mod = func.bin_file.base.options.module.?;
6762 const enum_decl_index = enum_ty.getOwnerDecl();6802 const enum_decl_index = enum_ty.getOwnerDecl();
6763 const module = func.bin_file.base.options.module.?;
67646803
6765 var arena_allocator = std.heap.ArenaAllocator.init(func.gpa);6804 var arena_allocator = std.heap.ArenaAllocator.init(func.gpa);
6766 defer arena_allocator.deinit();6805 defer arena_allocator.deinit();
6767 const arena = arena_allocator.allocator();6806 const arena = arena_allocator.allocator();
67686807
6769 const fqn = try module.declPtr(enum_decl_index).getFullyQualifiedName(module);6808 const fqn = try mod.declPtr(enum_decl_index).getFullyQualifiedName(mod);
6770 defer module.gpa.free(fqn);6809 defer mod.gpa.free(fqn);
6771 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});6810 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
67726811
6773 // check if we already generated code for this.6812 // check if we already generated code for this.
...@@ -6775,10 +6814,9 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -6775,10 +6814,9 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
6775 return loc.index;6814 return loc.index;
6776 }6815 }
67776816
6778 var int_tag_type_buffer: Type.Payload.Bits = undefined;6817 const int_tag_ty = enum_ty.intTagType();
6779 const int_tag_ty = enum_ty.intTagType(&int_tag_type_buffer);
67806818
6781 if (int_tag_ty.bitSize(func.target) > 64) {6819 if (int_tag_ty.bitSize(mod) > 64) {
6782 return func.fail("TODO: Implement @tagName for enums with tag size larger than 64 bits", .{});6820 return func.fail("TODO: Implement @tagName for enums with tag size larger than 64 bits", .{});
6783 }6821 }
67846822
...@@ -6806,9 +6844,9 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -6806,9 +6844,9 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
6806 .data = @intCast(u64, tag_name.len),6844 .data = @intCast(u64, tag_name.len),
6807 };6845 };
6808 const name_ty = Type.initPayload(&name_ty_payload.base);6846 const name_ty = Type.initPayload(&name_ty_payload.base);
6809 const string_bytes = &module.string_literal_bytes;6847 const string_bytes = &mod.string_literal_bytes;
6810 try string_bytes.ensureUnusedCapacity(module.gpa, tag_name.len);6848 try string_bytes.ensureUnusedCapacity(mod.gpa, tag_name.len);
6811 const gop = try module.string_literal_table.getOrPutContextAdapted(module.gpa, tag_name, Module.StringLiteralAdapter{6849 const gop = try mod.string_literal_table.getOrPutContextAdapted(mod.gpa, tag_name, Module.StringLiteralAdapter{
6812 .bytes = string_bytes,6850 .bytes = string_bytes,
6813 }, Module.StringLiteralContext{6851 }, Module.StringLiteralContext{
6814 .bytes = string_bytes,6852 .bytes = string_bytes,
...@@ -6929,7 +6967,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -6929,7 +6967,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
6929 try writer.writeByte(std.wasm.opcode(.end));6967 try writer.writeByte(std.wasm.opcode(.end));
69306968
6931 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);6969 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);
6933 return func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);6971 return func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);
6934}6972}
69356973
...@@ -6944,11 +6982,11 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6944,11 +6982,11 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6944 var values = try std.ArrayList(u32).initCapacity(func.gpa, names.len);6982 var values = try std.ArrayList(u32).initCapacity(func.gpa, names.len);
6945 defer values.deinit();6983 defer values.deinit();
69466984
6947 const module = func.bin_file.base.options.module.?;6985 const mod = func.bin_file.base.options.module.?;
6948 var lowest: ?u32 = null;6986 var lowest: ?u32 = null;
6949 var highest: ?u32 = null;6987 var highest: ?u32 = null;
6950 for (names) |name| {6988 for (names) |name| {
6951 const err_int = module.global_error_set.get(name).?;6989 const err_int = mod.global_error_set.get(name).?;
6952 if (lowest) |*l| {6990 if (lowest) |*l| {
6953 if (err_int < l.*) {6991 if (err_int < l.*) {
6954 l.* = err_int;6992 l.* = err_int;
...@@ -7019,6 +7057,7 @@ inline fn useAtomicFeature(func: *const CodeGen) bool {...@@ -7019,6 +7057,7 @@ inline fn useAtomicFeature(func: *const CodeGen) bool {
7019}7057}
70207058
7021fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {7059fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7060 const mod = func.bin_file.base.options.module.?;
7022 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;7061 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
7023 const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data;7062 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 {...@@ -7037,7 +7076,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7037 try func.emitWValue(ptr_operand);7076 try func.emitWValue(ptr_operand);
7038 try func.lowerToStack(expected_val);7077 try func.lowerToStack(expected_val);
7039 try func.lowerToStack(new_val);7078 try func.lowerToStack(new_val);
7040 try func.addAtomicMemArg(switch (ty.abiSize(func.target)) {7079 try func.addAtomicMemArg(switch (ty.abiSize(mod)) {
7041 1 => .i32_atomic_rmw8_cmpxchg_u,7080 1 => .i32_atomic_rmw8_cmpxchg_u,
7042 2 => .i32_atomic_rmw16_cmpxchg_u,7081 2 => .i32_atomic_rmw16_cmpxchg_u,
7043 4 => .i32_atomic_rmw_cmpxchg,7082 4 => .i32_atomic_rmw_cmpxchg,
...@@ -7045,14 +7084,14 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7045,14 +7084,14 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7045 else => |size| return func.fail("TODO: implement `@cmpxchg` for types with abi size '{d}'", .{size}),7084 else => |size| return func.fail("TODO: implement `@cmpxchg` for types with abi size '{d}'", .{size}),
7046 }, .{7085 }, .{
7047 .offset = ptr_operand.offset(),7086 .offset = ptr_operand.offset(),
7048 .alignment = ty.abiAlignment(func.target),7087 .alignment = ty.abiAlignment(mod),
7049 });7088 });
7050 try func.addLabel(.local_tee, val_local.local.value);7089 try func.addLabel(.local_tee, val_local.local.value);
7051 _ = try func.cmp(.stack, expected_val, ty, .eq);7090 _ = try func.cmp(.stack, expected_val, ty, .eq);
7052 try func.addLabel(.local_set, cmp_result.local.value);7091 try func.addLabel(.local_set, cmp_result.local.value);
7053 break :val val_local;7092 break :val val_local;
7054 } else val: {7093 } else val: {
7055 if (ty.abiSize(func.target) > 8) {7094 if (ty.abiSize(mod) > 8) {
7056 return func.fail("TODO: Implement `@cmpxchg` for types larger than abi size of 8 bytes", .{});7095 return func.fail("TODO: Implement `@cmpxchg` for types larger than abi size of 8 bytes", .{});
7057 }7096 }
7058 const ptr_val = try WValue.toLocal(try func.load(ptr_operand, ty, 0), func, ty);7097 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 {...@@ -7068,7 +7107,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7068 break :val ptr_val;7107 break :val ptr_val;
7069 };7108 };
70707109
7071 const result_ptr = if (isByRef(result_ty, func.target)) val: {7110 const result_ptr = if (isByRef(result_ty, mod)) val: {
7072 try func.emitWValue(cmp_result);7111 try func.emitWValue(cmp_result);
7073 try func.addImm32(-1);7112 try func.addImm32(-1);
7074 try func.addTag(.i32_xor);7113 try func.addTag(.i32_xor);
...@@ -7076,7 +7115,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7076,7 +7115,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7076 try func.addTag(.i32_and);7115 try func.addTag(.i32_and);
7077 const and_result = try WValue.toLocal(.stack, func, Type.bool);7116 const and_result = try WValue.toLocal(.stack, func, Type.bool);
7078 const result_ptr = try func.allocStack(result_ty);7117 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)));
7080 try func.store(result_ptr, ptr_val, ty, 0);7119 try func.store(result_ptr, ptr_val, ty, 0);
7081 break :val result_ptr;7120 break :val result_ptr;
7082 } else val: {7121 } else val: {
...@@ -7091,12 +7130,13 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7091,12 +7130,13 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7091}7130}
70927131
7093fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {7132fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7133 const mod = func.bin_file.base.options.module.?;
7094 const atomic_load = func.air.instructions.items(.data)[inst].atomic_load;7134 const atomic_load = func.air.instructions.items(.data)[inst].atomic_load;
7095 const ptr = try func.resolveInst(atomic_load.ptr);7135 const ptr = try func.resolveInst(atomic_load.ptr);
7096 const ty = func.air.typeOfIndex(inst);7136 const ty = func.air.typeOfIndex(inst);
70977137
7098 if (func.useAtomicFeature()) {7138 if (func.useAtomicFeature()) {
7099 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(func.target)) {7139 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) {
7100 1 => .i32_atomic_load8_u,7140 1 => .i32_atomic_load8_u,
7101 2 => .i32_atomic_load16_u,7141 2 => .i32_atomic_load16_u,
7102 4 => .i32_atomic_load,7142 4 => .i32_atomic_load,
...@@ -7106,7 +7146,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7106,7 +7146,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7106 try func.emitWValue(ptr);7146 try func.emitWValue(ptr);
7107 try func.addAtomicMemArg(tag, .{7147 try func.addAtomicMemArg(tag, .{
7108 .offset = ptr.offset(),7148 .offset = ptr.offset(),
7109 .alignment = ty.abiAlignment(func.target),7149 .alignment = ty.abiAlignment(mod),
7110 });7150 });
7111 } else {7151 } else {
7112 _ = try func.load(ptr, ty, 0);7152 _ = try func.load(ptr, ty, 0);
...@@ -7117,6 +7157,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7117,6 +7157,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7117}7157}
71187158
7119fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {7159fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7160 const mod = func.bin_file.base.options.module.?;
7120 const pl_op = func.air.instructions.items(.data)[inst].pl_op;7161 const pl_op = func.air.instructions.items(.data)[inst].pl_op;
7121 const extra = func.air.extraData(Air.AtomicRmw, pl_op.payload).data;7162 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 {...@@ -7140,7 +7181,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7140 try func.emitWValue(ptr);7181 try func.emitWValue(ptr);
7141 try func.emitWValue(value);7182 try func.emitWValue(value);
7142 if (op == .Nand) {7183 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
7145 const and_res = try func.binOp(value, operand, ty, .@"and");7186 const and_res = try func.binOp(value, operand, ty, .@"and");
7146 if (wasm_bits == 32)7187 if (wasm_bits == 32)
...@@ -7157,7 +7198,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7157,7 +7198,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7157 try func.addTag(.select);7198 try func.addTag(.select);
7158 }7199 }
7159 try func.addAtomicMemArg(7200 try func.addAtomicMemArg(
7160 switch (ty.abiSize(func.target)) {7201 switch (ty.abiSize(mod)) {
7161 1 => .i32_atomic_rmw8_cmpxchg_u,7202 1 => .i32_atomic_rmw8_cmpxchg_u,
7162 2 => .i32_atomic_rmw16_cmpxchg_u,7203 2 => .i32_atomic_rmw16_cmpxchg_u,
7163 4 => .i32_atomic_rmw_cmpxchg,7204 4 => .i32_atomic_rmw_cmpxchg,
...@@ -7166,7 +7207,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7166,7 +7207,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7166 },7207 },
7167 .{7208 .{
7168 .offset = ptr.offset(),7209 .offset = ptr.offset(),
7169 .alignment = ty.abiAlignment(func.target),7210 .alignment = ty.abiAlignment(mod),
7170 },7211 },
7171 );7212 );
7172 const select_res = try func.allocLocal(ty);7213 const select_res = try func.allocLocal(ty);
...@@ -7185,7 +7226,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7185,7 +7226,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7185 else => {7226 else => {
7186 try func.emitWValue(ptr);7227 try func.emitWValue(ptr);
7187 try func.emitWValue(operand);7228 try func.emitWValue(operand);
7188 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(func.target)) {7229 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) {
7189 1 => switch (op) {7230 1 => switch (op) {
7190 .Xchg => .i32_atomic_rmw8_xchg_u,7231 .Xchg => .i32_atomic_rmw8_xchg_u,
7191 .Add => .i32_atomic_rmw8_add_u,7232 .Add => .i32_atomic_rmw8_add_u,
...@@ -7226,7 +7267,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7226,7 +7267,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7226 };7267 };
7227 try func.addAtomicMemArg(tag, .{7268 try func.addAtomicMemArg(tag, .{
7228 .offset = ptr.offset(),7269 .offset = ptr.offset(),
7229 .alignment = ty.abiAlignment(func.target),7270 .alignment = ty.abiAlignment(mod),
7230 });7271 });
7231 const result = try WValue.toLocal(.stack, func, ty);7272 const result = try WValue.toLocal(.stack, func, ty);
7232 return func.finishAir(inst, result, &.{ pl_op.operand, extra.operand });7273 return func.finishAir(inst, result, &.{ pl_op.operand, extra.operand });
...@@ -7255,7 +7296,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7255,7 +7296,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7255 .Xor => .xor,7296 .Xor => .xor,
7256 else => unreachable,7297 else => unreachable,
7257 });7298 });
7258 if (ty.isInt() and (op == .Add or op == .Sub)) {7299 if (ty.isInt(mod) and (op == .Add or op == .Sub)) {
7259 _ = try func.wrapOperand(.stack, ty);7300 _ = try func.wrapOperand(.stack, ty);
7260 }7301 }
7261 try func.store(.stack, .stack, ty, ptr.offset());7302 try func.store(.stack, .stack, ty, ptr.offset());
...@@ -7271,7 +7312,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7271,7 +7312,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7271 try func.store(.stack, .stack, ty, ptr.offset());7312 try func.store(.stack, .stack, ty, ptr.offset());
7272 },7313 },
7273 .Nand => {7314 .Nand => {
7274 const wasm_bits = toWasmBits(@intCast(u16, ty.bitSize(func.target))).?;7315 const wasm_bits = toWasmBits(@intCast(u16, ty.bitSize(mod))).?;
72757316
7276 try func.emitWValue(ptr);7317 try func.emitWValue(ptr);
7277 const and_res = try func.binOp(result, operand, ty, .@"and");7318 const and_res = try func.binOp(result, operand, ty, .@"and");
...@@ -7302,6 +7343,7 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7302,6 +7343,7 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7302}7343}
73037344
7304fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {7345fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7346 const mod = func.bin_file.base.options.module.?;
7305 const bin_op = func.air.instructions.items(.data)[inst].bin_op;7347 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
73067348
7307 const ptr = try func.resolveInst(bin_op.lhs);7349 const ptr = try func.resolveInst(bin_op.lhs);
...@@ -7310,7 +7352,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7310,7 +7352,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7310 const ty = ptr_ty.childType();7352 const ty = ptr_ty.childType();
73117353
7312 if (func.useAtomicFeature()) {7354 if (func.useAtomicFeature()) {
7313 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(func.target)) {7355 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) {
7314 1 => .i32_atomic_store8,7356 1 => .i32_atomic_store8,
7315 2 => .i32_atomic_store16,7357 2 => .i32_atomic_store16,
7316 4 => .i32_atomic_store,7358 4 => .i32_atomic_store,
...@@ -7321,7 +7363,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7321,7 +7363,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7321 try func.lowerToStack(operand);7363 try func.lowerToStack(operand);
7322 try func.addAtomicMemArg(tag, .{7364 try func.addAtomicMemArg(tag, .{
7323 .offset = ptr.offset(),7365 .offset = ptr.offset(),
7324 .alignment = ty.abiAlignment(func.target),7366 .alignment = ty.abiAlignment(mod),
7325 });7367 });
7326 } else {7368 } else {
7327 try func.store(ptr, operand, ty, 0);7369 try func.store(ptr, operand, ty, 0);
src/arch/wasm/abi.zig+22-19
...@@ -5,9 +5,11 @@...@@ -5,9 +5,11 @@
5//! Note: Above mentioned document is not an official specification, therefore called a convention.5//! Note: Above mentioned document is not an official specification, therefore called a convention.
66
7const std = @import("std");7const std = @import("std");
8const Type = @import("../../type.zig").Type;
9const Target = std.Target;8const Target = std.Target;
109
10const Type = @import("../../type.zig").Type;
11const Module = @import("../../Module.zig");
12
11/// Defines how to pass a type as part of a function signature,13/// Defines how to pass a type as part of a function signature,
12/// both for parameters as well as return values.14/// both for parameters as well as return values.
13pub const Class = enum { direct, indirect, none };15pub const Class = enum { direct, indirect, none };
...@@ -19,12 +21,13 @@ const direct: [2]Class = .{ .direct, .none };...@@ -19,12 +21,13 @@ const direct: [2]Class = .{ .direct, .none };
19/// Classifies a given Zig type to determine how they must be passed21/// Classifies a given Zig type to determine how they must be passed
20/// or returned as value within a wasm function.22/// or returned as value within a wasm function.
21/// When all elements result in `.none`, no value must be passed in or returned.23/// When all elements result in `.none`, no value must be passed in or returned.
22pub fn classifyType(ty: Type, target: Target) [2]Class {24pub fn classifyType(ty: Type, mod: *const Module) [2]Class {
23 if (!ty.hasRuntimeBitsIgnoreComptime()) return none;25 const target = mod.getTarget();
24 switch (ty.zigTypeTag()) {26 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return none;
27 switch (ty.zigTypeTag(mod)) {
25 .Struct => {28 .Struct => {
26 if (ty.containerLayout() == .Packed) {29 if (ty.containerLayout() == .Packed) {
27 if (ty.bitSize(target) <= 64) return direct;30 if (ty.bitSize(mod) <= 64) return direct;
28 return .{ .direct, .direct };31 return .{ .direct, .direct };
29 }32 }
30 // When the struct type is non-scalar33 // When the struct type is non-scalar
...@@ -32,14 +35,14 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {...@@ -32,14 +35,14 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {
32 // When the struct's alignment is non-natural35 // When the struct's alignment is non-natural
33 const field = ty.structFields().values()[0];36 const field = ty.structFields().values()[0];
34 if (field.abi_align != 0) {37 if (field.abi_align != 0) {
35 if (field.abi_align > field.ty.abiAlignment(target)) {38 if (field.abi_align > field.ty.abiAlignment(mod)) {
36 return memory;39 return memory;
37 }40 }
38 }41 }
39 return classifyType(field.ty, target);42 return classifyType(field.ty, mod);
40 },43 },
41 .Int, .Enum, .ErrorSet, .Vector => {44 .Int, .Enum, .ErrorSet, .Vector => {
42 const int_bits = ty.intInfo(target).bits;45 const int_bits = ty.intInfo(mod).bits;
43 if (int_bits <= 64) return direct;46 if (int_bits <= 64) return direct;
44 if (int_bits <= 128) return .{ .direct, .direct };47 if (int_bits <= 128) return .{ .direct, .direct };
45 return memory;48 return memory;
...@@ -53,7 +56,7 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {...@@ -53,7 +56,7 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {
53 .Bool => return direct,56 .Bool => return direct,
54 .Array => return memory,57 .Array => return memory,
55 .Optional => {58 .Optional => {
56 std.debug.assert(ty.isPtrLikeOptional());59 std.debug.assert(ty.isPtrLikeOptional(mod));
57 return direct;60 return direct;
58 },61 },
59 .Pointer => {62 .Pointer => {
...@@ -62,13 +65,13 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {...@@ -62,13 +65,13 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {
62 },65 },
63 .Union => {66 .Union => {
64 if (ty.containerLayout() == .Packed) {67 if (ty.containerLayout() == .Packed) {
65 if (ty.bitSize(target) <= 64) return direct;68 if (ty.bitSize(mod) <= 64) return direct;
66 return .{ .direct, .direct };69 return .{ .direct, .direct };
67 }70 }
68 const layout = ty.unionGetLayout(target);71 const layout = ty.unionGetLayout(mod);
69 std.debug.assert(layout.tag_size == 0);72 std.debug.assert(layout.tag_size == 0);
70 if (ty.unionFields().count() > 1) return memory;73 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);
72 },75 },
73 .ErrorUnion,76 .ErrorUnion,
74 .Frame,77 .Frame,
...@@ -90,29 +93,29 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {...@@ -90,29 +93,29 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {
90/// Returns the scalar type a given type can represent.93/// Returns the scalar type a given type can represent.
91/// Asserts given type can be represented as scalar, such as94/// Asserts given type can be represented as scalar, such as
92/// a struct with a single scalar field.95/// a struct with a single scalar field.
93pub fn scalarType(ty: Type, target: std.Target) Type {96pub fn scalarType(ty: Type, mod: *const Module) Type {
94 switch (ty.zigTypeTag()) {97 switch (ty.zigTypeTag(mod)) {
95 .Struct => {98 .Struct => {
96 switch (ty.containerLayout()) {99 switch (ty.containerLayout()) {
97 .Packed => {100 .Packed => {
98 const struct_obj = ty.castTag(.@"struct").?.data;101 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);
100 },103 },
101 else => {104 else => {
102 std.debug.assert(ty.structFieldCount() == 1);105 std.debug.assert(ty.structFieldCount() == 1);
103 return scalarType(ty.structFieldType(0), target);106 return scalarType(ty.structFieldType(0), mod);
104 },107 },
105 }108 }
106 },109 },
107 .Union => {110 .Union => {
108 if (ty.containerLayout() != .Packed) {111 if (ty.containerLayout() != .Packed) {
109 const layout = ty.unionGetLayout(target);112 const layout = ty.unionGetLayout(mod);
110 if (layout.payload_size == 0 and layout.tag_size != 0) {113 if (layout.payload_size == 0 and layout.tag_size != 0) {
111 return scalarType(ty.unionTagTypeSafety().?, target);114 return scalarType(ty.unionTagTypeSafety().?, mod);
112 }115 }
113 std.debug.assert(ty.unionFields().count() == 1);116 std.debug.assert(ty.unionFields().count() == 1);
114 }117 }
115 return scalarType(ty.unionFields().values()[0].ty, target);118 return scalarType(ty.unionFields().values()[0].ty, mod);
116 },119 },
117 else => return ty,120 else => return ty,
118 }121 }
src/arch/x86_64/CodeGen.zig+407-367
...@@ -605,14 +605,14 @@ const FrameAlloc = struct {...@@ -605,14 +605,14 @@ const FrameAlloc = struct {
605 .ref_count = 0,605 .ref_count = 0,
606 };606 };
607 }607 }
608 fn initType(ty: Type, target: Target) FrameAlloc {608 fn initType(ty: Type, mod: *const Module) FrameAlloc {
609 return init(.{ .size = ty.abiSize(target), .alignment = ty.abiAlignment(target) });609 return init(.{ .size = ty.abiSize(mod), .alignment = ty.abiAlignment(mod) });
610 }610 }
611};611};
612612
613const StackAllocation = struct {613const StackAllocation = struct {
614 inst: ?Air.Inst.Index,614 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)
616 size: u32,616 size: u32,
617};617};
618618
...@@ -714,12 +714,12 @@ pub fn generate(...@@ -714,12 +714,12 @@ pub fn generate(
714 function.args = call_info.args;714 function.args = call_info.args;
715 function.ret_mcv = call_info.return_value;715 function.ret_mcv = call_info.return_value;
716 function.frame_allocs.set(@enumToInt(FrameIndex.ret_addr), FrameAlloc.init(.{716 function.frame_allocs.set(@enumToInt(FrameIndex.ret_addr), FrameAlloc.init(.{
717 .size = Type.usize.abiSize(function.target.*),717 .size = Type.usize.abiSize(mod),
718 .alignment = @min(Type.usize.abiAlignment(function.target.*), call_info.stack_align),718 .alignment = @min(Type.usize.abiAlignment(mod), call_info.stack_align),
719 }));719 }));
720 function.frame_allocs.set(@enumToInt(FrameIndex.base_ptr), FrameAlloc.init(.{720 function.frame_allocs.set(@enumToInt(FrameIndex.base_ptr), FrameAlloc.init(.{
721 .size = Type.usize.abiSize(function.target.*),721 .size = Type.usize.abiSize(mod),
722 .alignment = @min(Type.usize.abiAlignment(function.target.*) * 2, call_info.stack_align),722 .alignment = @min(Type.usize.abiAlignment(mod) * 2, call_info.stack_align),
723 }));723 }));
724 function.frame_allocs.set(724 function.frame_allocs.set(
725 @enumToInt(FrameIndex.args_frame),725 @enumToInt(FrameIndex.args_frame),
...@@ -1565,6 +1565,7 @@ fn asmMemoryRegisterImmediate(...@@ -1565,6 +1565,7 @@ fn asmMemoryRegisterImmediate(
1565}1565}
15661566
1567fn gen(self: *Self) InnerError!void {1567fn gen(self: *Self) InnerError!void {
1568 const mod = self.bin_file.options.module.?;
1568 const cc = self.fn_type.fnCallingConvention();1569 const cc = self.fn_type.fnCallingConvention();
1569 if (cc != .Naked) {1570 if (cc != .Naked) {
1570 try self.asmRegister(.{ ._, .push }, .rbp);1571 try self.asmRegister(.{ ._, .push }, .rbp);
...@@ -1582,7 +1583,7 @@ fn gen(self: *Self) InnerError!void {...@@ -1582,7 +1583,7 @@ fn gen(self: *Self) InnerError!void {
1582 // register which the callee is free to clobber. Therefore, we purposely1583 // register which the callee is free to clobber. Therefore, we purposely
1583 // spill it to stack immediately.1584 // spill it to stack immediately.
1584 const frame_index =1585 const frame_index =
1585 try self.allocFrameIndex(FrameAlloc.initType(Type.usize, self.target.*));1586 try self.allocFrameIndex(FrameAlloc.initType(Type.usize, mod));
1586 try self.genSetMem(1587 try self.genSetMem(
1587 .{ .frame = frame_index },1588 .{ .frame = frame_index },
1588 0,1589 0,
...@@ -1999,7 +2000,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -1999,7 +2000,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
1999}2000}
20002001
2001fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {2002fn 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)) {
2003 .Enum => {2005 .Enum => {
2004 const enum_ty = lazy_sym.ty;2006 const enum_ty = lazy_sym.ty;
2005 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(self.bin_file.options.module.?)});2007 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...@@ -2127,8 +2129,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
2127 tomb_bits >>= 1;2129 tomb_bits >>= 1;
2128 if (!dies) continue;2130 if (!dies) continue;
2129 const op_int = @enumToInt(op);2131 const op_int = @enumToInt(op);
2130 if (op_int < Air.Inst.Ref.typed_value_map.len) continue;2132 if (op_int < Air.ref_start_index) continue;
2131 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);2133 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
2132 self.processDeath(op_index);2134 self.processDeath(op_index);
2133 }2135 }
2134 self.finishAirResult(inst, result);2136 self.finishAirResult(inst, result);
...@@ -2252,14 +2254,14 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {...@@ -2252,14 +2254,14 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {
22522254
2253/// Use a pointer instruction as the basis for allocating stack memory.2255/// Use a pointer instruction as the basis for allocating stack memory.
2254fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {2256fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {
2257 const mod = self.bin_file.options.module.?;
2255 const ptr_ty = self.air.typeOfIndex(inst);2258 const ptr_ty = self.air.typeOfIndex(inst);
2256 const val_ty = ptr_ty.childType();2259 const val_ty = ptr_ty.childType();
2257 return self.allocFrameIndex(FrameAlloc.init(.{2260 return self.allocFrameIndex(FrameAlloc.init(.{
2258 .size = math.cast(u32, val_ty.abiSize(self.target.*)) orelse {2261 .size = math.cast(u32, val_ty.abiSize(mod)) orelse {
2259 const mod = self.bin_file.options.module.?;
2260 return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(mod)});2262 return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(mod)});
2261 },2263 },
2262 .alignment = @max(ptr_ty.ptrAlignment(self.target.*), 1),2264 .alignment = @max(ptr_ty.ptrAlignment(mod), 1),
2263 }));2265 }));
2264}2266}
22652267
...@@ -2272,19 +2274,19 @@ fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue {...@@ -2272,19 +2274,19 @@ fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue {
2272}2274}
22732275
2274fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue {2276fn 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 {2277 const mod = self.bin_file.options.module.?;
2276 const mod = self.bin_file.options.module.?;2278 const abi_size = math.cast(u32, ty.abiSize(mod)) orelse {
2277 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});2279 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});
2278 };2280 };
22792281
2280 if (reg_ok) need_mem: {2282 if (reg_ok) need_mem: {
2281 if (abi_size <= @as(u32, switch (ty.zigTypeTag()) {2283 if (abi_size <= @as(u32, switch (ty.zigTypeTag(mod)) {
2282 .Float => switch (ty.floatBits(self.target.*)) {2284 .Float => switch (ty.floatBits(self.target.*)) {
2283 16, 32, 64, 128 => 16,2285 16, 32, 64, 128 => 16,
2284 80 => break :need_mem,2286 80 => break :need_mem,
2285 else => unreachable,2287 else => unreachable,
2286 },2288 },
2287 .Vector => switch (ty.childType().zigTypeTag()) {2289 .Vector => switch (ty.childType().zigTypeTag(mod)) {
2288 .Float => switch (ty.childType().floatBits(self.target.*)) {2290 .Float => switch (ty.childType().floatBits(self.target.*)) {
2289 16, 32, 64, 128 => if (self.hasFeature(.avx)) 32 else 16,2291 16, 32, 64, 128 => if (self.hasFeature(.avx)) 32 else 16,
2290 80 => break :need_mem,2292 80 => break :need_mem,
...@@ -2294,18 +2296,18 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b...@@ -2294,18 +2296,18 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b
2294 },2296 },
2295 else => 8,2297 else => 8,
2296 })) {2298 })) {
2297 if (self.register_manager.tryAllocReg(inst, regClassForType(ty))) |reg| {2299 if (self.register_manager.tryAllocReg(inst, regClassForType(ty, mod))) |reg| {
2298 return MCValue{ .register = registerAlias(reg, abi_size) };2300 return MCValue{ .register = registerAlias(reg, abi_size) };
2299 }2301 }
2300 }2302 }
2301 }2303 }
23022304
2303 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(ty, self.target.*));2305 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(ty, mod));
2304 return .{ .load_frame = .{ .index = frame_index } };2306 return .{ .load_frame = .{ .index = frame_index } };
2305}2307}
23062308
2307fn regClassForType(ty: Type) RegisterManager.RegisterBitSet {2309fn regClassForType(ty: Type, mod: *const Module) RegisterManager.RegisterBitSet {
2308 return switch (ty.zigTypeTag()) {2310 return switch (ty.zigTypeTag(mod)) {
2309 .Float, .Vector => sse,2311 .Float, .Vector => sse,
2310 else => gp,2312 else => gp,
2311 };2313 };
...@@ -2449,7 +2451,8 @@ pub fn spillRegisters(self: *Self, registers: []const Register) !void {...@@ -2449,7 +2451,8 @@ pub fn spillRegisters(self: *Self, registers: []const Register) !void {
2449/// allocated. A second call to `copyToTmpRegister` may return the same register.2451/// allocated. A second call to `copyToTmpRegister` may return the same register.
2450/// This can have a side effect of spilling instructions to the stack to free up a register.2452/// This can have a side effect of spilling instructions to the stack to free up a register.
2451fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register {2453fn 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));
2453 try self.genSetReg(reg, ty, mcv);2456 try self.genSetReg(reg, ty, mcv);
2454 return reg;2457 return reg;
2455}2458}
...@@ -2464,7 +2467,8 @@ fn copyToRegisterWithInstTracking(...@@ -2464,7 +2467,8 @@ fn copyToRegisterWithInstTracking(
2464 ty: Type,2467 ty: Type,
2465 mcv: MCValue,2468 mcv: MCValue,
2466) !MCValue {2469) !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));
2468 try self.genSetReg(reg, ty, mcv);2472 try self.genSetReg(reg, ty, mcv);
2469 return MCValue{ .register = reg };2473 return MCValue{ .register = reg };
2470}2474}
...@@ -2618,14 +2622,15 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {...@@ -2618,14 +2622,15 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
2618}2622}
26192623
2620fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {2624fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
2625 const mod = self.bin_file.options.module.?;
2621 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2626 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2622 const result: MCValue = result: {2627 const result: MCValue = result: {
2623 const src_ty = self.air.typeOf(ty_op.operand);2628 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
2626 const dst_ty = self.air.typeOfIndex(inst);2631 const dst_ty = self.air.typeOfIndex(inst);
2627 const dst_int_info = dst_ty.intInfo(self.target.*);2632 const dst_int_info = dst_ty.intInfo(mod);
2628 const abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));2633 const abi_size = @intCast(u32, dst_ty.abiSize(mod));
26292634
2630 const min_ty = if (dst_int_info.bits < src_int_info.bits) dst_ty else src_ty;2635 const min_ty = if (dst_int_info.bits < src_int_info.bits) dst_ty else src_ty;
2631 const extend = switch (src_int_info.signedness) {2636 const extend = switch (src_int_info.signedness) {
...@@ -2670,14 +2675,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -2670,14 +2675,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
26702675
2671 const high_bits = src_int_info.bits % 64;2676 const high_bits = src_int_info.bits % 64;
2672 if (high_bits > 0) {2677 if (high_bits > 0) {
2673 var high_pl = Type.Payload.Bits{2678 const high_ty = try mod.intType(extend, high_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);
2681 try self.truncateRegister(high_ty, high_reg);2679 try self.truncateRegister(high_ty, high_reg);
2682 try self.genCopy(Type.usize, high_mcv, .{ .register = high_reg });2680 try self.genCopy(Type.usize, high_mcv, .{ .register = high_reg });
2683 }2681 }
...@@ -2706,12 +2704,13 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -2706,12 +2704,13 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
2706}2704}
27072705
2708fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {2706fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
2707 const mod = self.bin_file.options.module.?;
2709 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2708 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
27102709
2711 const dst_ty = self.air.typeOfIndex(inst);2710 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));
2713 const src_ty = self.air.typeOf(ty_op.operand);2712 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
2716 const result = result: {2715 const result = result: {
2717 const src_mcv = try self.resolveInst(ty_op.operand);2716 const src_mcv = try self.resolveInst(ty_op.operand);
...@@ -2724,10 +2723,10 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -2724,10 +2723,10 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
2724 else2723 else
2725 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);2724 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
27262725
2727 if (dst_ty.zigTypeTag() == .Vector) {2726 if (dst_ty.zigTypeTag(mod) == .Vector) {
2728 assert(src_ty.zigTypeTag() == .Vector and dst_ty.vectorLen() == src_ty.vectorLen());2727 assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen() == src_ty.vectorLen());
2729 const dst_info = dst_ty.childType().intInfo(self.target.*);2728 const dst_info = dst_ty.childType().intInfo(mod);
2730 const src_info = src_ty.childType().intInfo(self.target.*);2729 const src_info = src_ty.childType().intInfo(mod);
2731 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (dst_info.bits) {2730 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (dst_info.bits) {
2732 8 => switch (src_info.bits) {2731 8 => switch (src_info.bits) {
2733 16 => switch (dst_ty.vectorLen()) {2732 16 => switch (dst_ty.vectorLen()) {
...@@ -2775,7 +2774,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -2775,7 +2774,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
2775 },2774 },
2776 };2775 };
2777 const full_ty = Type.initPayload(&full_pl.base);2776 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
2780 const splat_mcv = try self.genTypedValue(.{ .ty = full_ty, .val = splat_val });2779 const splat_mcv = try self.genTypedValue(.{ .ty = full_ty, .val = splat_val });
2781 const splat_addr_mcv: MCValue = switch (splat_mcv) {2780 const splat_addr_mcv: MCValue = switch (splat_mcv) {
...@@ -2831,6 +2830,7 @@ fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -2831,6 +2830,7 @@ fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {
2831}2830}
28322831
2833fn airSlice(self: *Self, inst: Air.Inst.Index) !void {2832fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
2833 const mod = self.bin_file.options.module.?;
2834 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2834 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2835 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;2835 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 {...@@ -2840,11 +2840,11 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
2840 const len = try self.resolveInst(bin_op.rhs);2840 const len = try self.resolveInst(bin_op.rhs);
2841 const len_ty = self.air.typeOf(bin_op.rhs);2841 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));
2844 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);2844 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);
2845 try self.genSetMem(2845 try self.genSetMem(
2846 .{ .frame = frame_index },2846 .{ .frame = frame_index },
2847 @intCast(i32, ptr_ty.abiSize(self.target.*)),2847 @intCast(i32, ptr_ty.abiSize(mod)),
2848 len_ty,2848 len_ty,
2849 len,2849 len,
2850 );2850 );
...@@ -2873,23 +2873,24 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void...@@ -2873,23 +2873,24 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
2873}2873}
28742874
2875fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {2875fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
2876 const mod = self.bin_file.options.module.?;
2876 const air_tag = self.air.instructions.items(.tag);2877 const air_tag = self.air.instructions.items(.tag);
2877 const air_data = self.air.instructions.items(.data);2878 const air_data = self.air.instructions.items(.data);
28782879
2879 const dst_ty = self.air.typeOf(dst_air);2880 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);
2881 if (Air.refToIndex(dst_air)) |inst| {2882 if (Air.refToIndex(dst_air)) |inst| {
2882 switch (air_tag[inst]) {2883 switch (air_tag[inst]) {
2883 .constant => {2884 .constant => {
2884 const src_val = self.air.values[air_data[inst].ty_pl.payload];2885 const src_val = self.air.values[air_data[inst].ty_pl.payload];
2885 var space: Value.BigIntSpace = undefined;2886 var space: Value.BigIntSpace = undefined;
2886 const src_int = src_val.toBigInt(&space, self.target.*);2887 const src_int = src_val.toBigInt(&space, mod);
2887 return @intCast(u16, src_int.bitCountTwosComp()) +2888 return @intCast(u16, src_int.bitCountTwosComp()) +
2888 @boolToInt(src_int.positive and dst_info.signedness == .signed);2889 @boolToInt(src_int.positive and dst_info.signedness == .signed);
2889 },2890 },
2890 .intcast => {2891 .intcast => {
2891 const src_ty = self.air.typeOf(air_data[inst].ty_op.operand);2892 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);
2893 return @min(switch (src_info.signedness) {2894 return @min(switch (src_info.signedness) {
2894 .signed => switch (dst_info.signedness) {2895 .signed => switch (dst_info.signedness) {
2895 .signed => src_info.bits,2896 .signed => src_info.bits,
...@@ -2908,20 +2909,18 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {...@@ -2908,20 +2909,18 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
2908}2909}
29092910
2910fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {2911fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
2912 const mod = self.bin_file.options.module.?;
2911 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2913 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2912 const result = result: {2914 const result = result: {
2913 const tag = self.air.instructions.items(.tag)[inst];2915 const tag = self.air.instructions.items(.tag)[inst];
2914 const dst_ty = self.air.typeOfIndex(inst);2916 const dst_ty = self.air.typeOfIndex(inst);
2915 switch (dst_ty.zigTypeTag()) {2917 switch (dst_ty.zigTypeTag(mod)) {
2916 .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs),2918 .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs),
2917 else => {},2919 else => {},
2918 }2920 }
29192921
2920 const dst_info = dst_ty.intInfo(self.target.*);2922 const dst_info = dst_ty.intInfo(mod);
2921 var src_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dst_info.signedness) {2923 const src_ty = try mod.intType(dst_info.signedness, switch (tag) {
2922 .signed => .int_signed,
2923 .unsigned => .int_unsigned,
2924 } }, .data = switch (tag) {
2925 else => unreachable,2924 else => unreachable,
2926 .mul, .mulwrap => math.max3(2925 .mul, .mulwrap => math.max3(
2927 self.activeIntBits(bin_op.lhs),2926 self.activeIntBits(bin_op.lhs),
...@@ -2929,8 +2928,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -2929,8 +2928,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
2929 dst_info.bits / 2,2928 dst_info.bits / 2,
2930 ),2929 ),
2931 .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_info.bits,2930 .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_info.bits,
2932 } };2931 });
2933 const src_ty = Type.initPayload(&src_pl.base);
29342932
2935 try self.spillEflagsIfOccupied();2933 try self.spillEflagsIfOccupied();
2936 try self.spillRegisters(&.{ .rax, .rdx });2934 try self.spillRegisters(&.{ .rax, .rdx });
...@@ -2942,6 +2940,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -2942,6 +2940,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
2942}2940}
29432941
2944fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {2942fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
2943 const mod = self.bin_file.options.module.?;
2945 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2944 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2946 const ty = self.air.typeOf(bin_op.lhs);2945 const ty = self.air.typeOf(bin_op.lhs);
29472946
...@@ -2968,7 +2967,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -2968,7 +2967,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
29682967
2969 const reg_bits = self.regBitSize(ty);2968 const reg_bits = self.regBitSize(ty);
2970 const reg_extra_bits = self.regExtraBits(ty);2969 const reg_extra_bits = self.regExtraBits(ty);
2971 const cc: Condition = if (ty.isSignedInt()) cc: {2970 const cc: Condition = if (ty.isSignedInt(mod)) cc: {
2972 if (reg_extra_bits > 0) {2971 if (reg_extra_bits > 0) {
2973 try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits });2972 try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits });
2974 }2973 }
...@@ -2994,7 +2993,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -2994,7 +2993,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
2994 break :cc .o;2993 break :cc .o;
2995 } else cc: {2994 } else cc: {
2996 try self.genSetReg(limit_reg, ty, .{2995 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)),
2998 });2997 });
29992998
3000 try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv);2999 try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv);
...@@ -3005,14 +3004,14 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3005,14 +3004,14 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
3005 break :cc .c;3004 break :cc .c;
3006 };3005 };
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);
3009 try self.asmCmovccRegisterRegister(3008 try self.asmCmovccRegisterRegister(
3010 registerAlias(dst_reg, cmov_abi_size),3009 registerAlias(dst_reg, cmov_abi_size),
3011 registerAlias(limit_reg, cmov_abi_size),3010 registerAlias(limit_reg, cmov_abi_size),
3012 cc,3011 cc,
3013 );3012 );
30143013
3015 if (reg_extra_bits > 0 and ty.isSignedInt()) {3014 if (reg_extra_bits > 0 and ty.isSignedInt(mod)) {
3016 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits });3015 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits });
3017 }3016 }
30183017
...@@ -3020,6 +3019,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3020,6 +3019,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
3020}3019}
30213020
3022fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {3021fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
3022 const mod = self.bin_file.options.module.?;
3023 const bin_op = self.air.instructions.items(.data)[inst].bin_op;3023 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
3024 const ty = self.air.typeOf(bin_op.lhs);3024 const ty = self.air.typeOf(bin_op.lhs);
30253025
...@@ -3046,7 +3046,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3046,7 +3046,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
30463046
3047 const reg_bits = self.regBitSize(ty);3047 const reg_bits = self.regBitSize(ty);
3048 const reg_extra_bits = self.regExtraBits(ty);3048 const reg_extra_bits = self.regExtraBits(ty);
3049 const cc: Condition = if (ty.isSignedInt()) cc: {3049 const cc: Condition = if (ty.isSignedInt(mod)) cc: {
3050 if (reg_extra_bits > 0) {3050 if (reg_extra_bits > 0) {
3051 try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits });3051 try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits });
3052 }3052 }
...@@ -3076,14 +3076,14 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3076,14 +3076,14 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
3076 break :cc .c;3076 break :cc .c;
3077 };3077 };
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);
3080 try self.asmCmovccRegisterRegister(3080 try self.asmCmovccRegisterRegister(
3081 registerAlias(dst_reg, cmov_abi_size),3081 registerAlias(dst_reg, cmov_abi_size),
3082 registerAlias(limit_reg, cmov_abi_size),3082 registerAlias(limit_reg, cmov_abi_size),
3083 cc,3083 cc,
3084 );3084 );
30853085
3086 if (reg_extra_bits > 0 and ty.isSignedInt()) {3086 if (reg_extra_bits > 0 and ty.isSignedInt(mod)) {
3087 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits });3087 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits });
3088 }3088 }
30893089
...@@ -3091,6 +3091,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3091,6 +3091,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
3091}3091}
30923092
3093fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {3093fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
3094 const mod = self.bin_file.options.module.?;
3094 const bin_op = self.air.instructions.items(.data)[inst].bin_op;3095 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
3095 const ty = self.air.typeOf(bin_op.lhs);3096 const ty = self.air.typeOf(bin_op.lhs);
30963097
...@@ -3118,7 +3119,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3118,7 +3119,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
3118 defer self.register_manager.unlockReg(limit_lock);3119 defer self.register_manager.unlockReg(limit_lock);
31193120
3120 const reg_bits = self.regBitSize(ty);3121 const reg_bits = self.regBitSize(ty);
3121 const cc: Condition = if (ty.isSignedInt()) cc: {3122 const cc: Condition = if (ty.isSignedInt(mod)) cc: {
3122 try self.genSetReg(limit_reg, ty, lhs_mcv);3123 try self.genSetReg(limit_reg, ty, lhs_mcv);
3123 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv);3124 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv);
3124 try self.genShiftBinOpMir(.{ ._, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 });3125 try self.genShiftBinOpMir(.{ ._, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 });
...@@ -3134,7 +3135,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3134,7 +3135,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
3134 };3135 };
31353136
3136 const dst_mcv = try self.genMulDivBinOp(.mul, inst, ty, ty, lhs_mcv, rhs_mcv);3137 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);
3138 try self.asmCmovccRegisterRegister(3139 try self.asmCmovccRegisterRegister(
3139 registerAlias(dst_mcv.register, cmov_abi_size),3140 registerAlias(dst_mcv.register, cmov_abi_size),
3140 registerAlias(limit_reg, cmov_abi_size),3141 registerAlias(limit_reg, cmov_abi_size),
...@@ -3145,12 +3146,13 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3145,12 +3146,13 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
3145}3146}
31463147
3147fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {3148fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3149 const mod = self.bin_file.options.module.?;
3148 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;3150 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3149 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;3151 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
3150 const result: MCValue = result: {3152 const result: MCValue = result: {
3151 const tag = self.air.instructions.items(.tag)[inst];3153 const tag = self.air.instructions.items(.tag)[inst];
3152 const ty = self.air.typeOf(bin_op.lhs);3154 const ty = self.air.typeOf(bin_op.lhs);
3153 switch (ty.zigTypeTag()) {3155 switch (ty.zigTypeTag(mod)) {
3154 .Vector => return self.fail("TODO implement add/sub with overflow for Vector type", .{}),3156 .Vector => return self.fail("TODO implement add/sub with overflow for Vector type", .{}),
3155 .Int => {3157 .Int => {
3156 try self.spillEflagsIfOccupied();3158 try self.spillEflagsIfOccupied();
...@@ -3160,7 +3162,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3160,7 +3162,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3160 .sub_with_overflow => .sub,3162 .sub_with_overflow => .sub,
3161 else => unreachable,3163 else => unreachable,
3162 }, bin_op.lhs, bin_op.rhs);3164 }, bin_op.lhs, bin_op.rhs);
3163 const int_info = ty.intInfo(self.target.*);3165 const int_info = ty.intInfo(mod);
3164 const cc: Condition = switch (int_info.signedness) {3166 const cc: Condition = switch (int_info.signedness) {
3165 .unsigned => .c,3167 .unsigned => .c,
3166 .signed => .o,3168 .signed => .o,
...@@ -3177,16 +3179,16 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3177,16 +3179,16 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3177 }3179 }
31783180
3179 const frame_index =3181 const frame_index =
3180 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, self.target.*));3182 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
3181 try self.genSetMem(3183 try self.genSetMem(
3182 .{ .frame = frame_index },3184 .{ .frame = frame_index },
3183 @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)),3185 @intCast(i32, tuple_ty.structFieldOffset(1, mod)),
3184 Type.u1,3186 Type.u1,
3185 .{ .eflags = cc },3187 .{ .eflags = cc },
3186 );3188 );
3187 try self.genSetMem(3189 try self.genSetMem(
3188 .{ .frame = frame_index },3190 .{ .frame = frame_index },
3189 @intCast(i32, tuple_ty.structFieldOffset(0, self.target.*)),3191 @intCast(i32, tuple_ty.structFieldOffset(0, mod)),
3190 ty,3192 ty,
3191 partial_mcv,3193 partial_mcv,
3192 );3194 );
...@@ -3194,7 +3196,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3194,7 +3196,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3194 }3196 }
31953197
3196 const frame_index =3198 const frame_index =
3197 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, self.target.*));3199 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
3198 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);3200 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);
3199 break :result .{ .load_frame = .{ .index = frame_index } };3201 break :result .{ .load_frame = .{ .index = frame_index } };
3200 },3202 },
...@@ -3205,12 +3207,13 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3205,12 +3207,13 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3205}3207}
32063208
3207fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {3209fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3210 const mod = self.bin_file.options.module.?;
3208 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;3211 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3209 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;3212 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
3210 const result: MCValue = result: {3213 const result: MCValue = result: {
3211 const lhs_ty = self.air.typeOf(bin_op.lhs);3214 const lhs_ty = self.air.typeOf(bin_op.lhs);
3212 const rhs_ty = self.air.typeOf(bin_op.rhs);3215 const rhs_ty = self.air.typeOf(bin_op.rhs);
3213 switch (lhs_ty.zigTypeTag()) {3216 switch (lhs_ty.zigTypeTag(mod)) {
3214 .Vector => return self.fail("TODO implement shl with overflow for Vector type", .{}),3217 .Vector => return self.fail("TODO implement shl with overflow for Vector type", .{}),
3215 .Int => {3218 .Int => {
3216 try self.spillEflagsIfOccupied();3219 try self.spillEflagsIfOccupied();
...@@ -3219,7 +3222,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3219,7 +3222,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3219 const lhs = try self.resolveInst(bin_op.lhs);3222 const lhs = try self.resolveInst(bin_op.lhs);
3220 const rhs = try self.resolveInst(bin_op.rhs);3223 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
3224 const partial_mcv = try self.genShiftBinOp(.shl, null, lhs, rhs, lhs_ty, rhs_ty);3227 const partial_mcv = try self.genShiftBinOp(.shl, null, lhs, rhs, lhs_ty, rhs_ty);
3225 const partial_lock = switch (partial_mcv) {3228 const partial_lock = switch (partial_mcv) {
...@@ -3249,16 +3252,16 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3249,16 +3252,16 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3249 }3252 }
32503253
3251 const frame_index =3254 const frame_index =
3252 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, self.target.*));3255 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
3253 try self.genSetMem(3256 try self.genSetMem(
3254 .{ .frame = frame_index },3257 .{ .frame = frame_index },
3255 @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)),3258 @intCast(i32, tuple_ty.structFieldOffset(1, mod)),
3256 tuple_ty.structFieldType(1),3259 tuple_ty.structFieldType(1),
3257 .{ .eflags = cc },3260 .{ .eflags = cc },
3258 );3261 );
3259 try self.genSetMem(3262 try self.genSetMem(
3260 .{ .frame = frame_index },3263 .{ .frame = frame_index },
3261 @intCast(i32, tuple_ty.structFieldOffset(0, self.target.*)),3264 @intCast(i32, tuple_ty.structFieldOffset(0, mod)),
3262 tuple_ty.structFieldType(0),3265 tuple_ty.structFieldType(0),
3263 partial_mcv,3266 partial_mcv,
3264 );3267 );
...@@ -3266,7 +3269,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3266,7 +3269,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3266 }3269 }
32673270
3268 const frame_index =3271 const frame_index =
3269 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, self.target.*));3272 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
3270 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);3273 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);
3271 break :result .{ .load_frame = .{ .index = frame_index } };3274 break :result .{ .load_frame = .{ .index = frame_index } };
3272 },3275 },
...@@ -3283,6 +3286,7 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -3283,6 +3286,7 @@ fn genSetFrameTruncatedOverflowCompare(
3283 src_mcv: MCValue,3286 src_mcv: MCValue,
3284 overflow_cc: ?Condition,3287 overflow_cc: ?Condition,
3285) !void {3288) !void {
3289 const mod = self.bin_file.options.module.?;
3286 const src_lock = switch (src_mcv) {3290 const src_lock = switch (src_mcv) {
3287 .register => |reg| self.register_manager.lockReg(reg),3291 .register => |reg| self.register_manager.lockReg(reg),
3288 else => null,3292 else => null,
...@@ -3290,22 +3294,12 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -3290,22 +3294,12 @@ fn genSetFrameTruncatedOverflowCompare(
3290 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);3294 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
32913295
3292 const ty = tuple_ty.structFieldType(0);3296 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{3299 const hi_limb_bits = (int_info.bits - 1) % 64 + 1;
3296 .base = .{ .tag = switch (int_info.signedness) {3300 const hi_limb_ty = try mod.intType(int_info.signedness, hi_limb_bits);
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);
33033301
3304 var rest_pl = Type.Payload.Bits{3302 const rest_ty = try mod.intType(.unsigned, int_info.bits - hi_limb_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);
33093303
3310 const temp_regs = try self.register_manager.allocRegs(3, .{ null, null, null }, gp);3304 const temp_regs = try self.register_manager.allocRegs(3, .{ null, null, null }, gp);
3311 const temp_locks = self.register_manager.lockRegsAssumeUnused(3, temp_regs);3305 const temp_locks = self.register_manager.lockRegsAssumeUnused(3, temp_regs);
...@@ -3335,7 +3329,7 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -3335,7 +3329,7 @@ fn genSetFrameTruncatedOverflowCompare(
3335 );3329 );
3336 }3330 }
33373331
3338 const payload_off = @intCast(i32, tuple_ty.structFieldOffset(0, self.target.*));3332 const payload_off = @intCast(i32, tuple_ty.structFieldOffset(0, mod));
3339 if (hi_limb_off > 0) try self.genSetMem(.{ .frame = frame_index }, payload_off, rest_ty, src_mcv);3333 if (hi_limb_off > 0) try self.genSetMem(.{ .frame = frame_index }, payload_off, rest_ty, src_mcv);
3340 try self.genSetMem(3334 try self.genSetMem(
3341 .{ .frame = frame_index },3335 .{ .frame = frame_index },
...@@ -3345,23 +3339,24 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -3345,23 +3339,24 @@ fn genSetFrameTruncatedOverflowCompare(
3345 );3339 );
3346 try self.genSetMem(3340 try self.genSetMem(
3347 .{ .frame = frame_index },3341 .{ .frame = frame_index },
3348 @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)),3342 @intCast(i32, tuple_ty.structFieldOffset(1, mod)),
3349 tuple_ty.structFieldType(1),3343 tuple_ty.structFieldType(1),
3350 if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne },3344 if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne },
3351 );3345 );
3352}3346}
33533347
3354fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {3348fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3349 const mod = self.bin_file.options.module.?;
3355 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;3350 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3356 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;3351 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
3357 const dst_ty = self.air.typeOf(bin_op.lhs);3352 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)) {
3359 .Vector => return self.fail("TODO implement mul_with_overflow for Vector type", .{}),3354 .Vector => return self.fail("TODO implement mul_with_overflow for Vector type", .{}),
3360 .Int => result: {3355 .Int => result: {
3361 try self.spillEflagsIfOccupied();3356 try self.spillEflagsIfOccupied();
3362 try self.spillRegisters(&.{ .rax, .rdx });3357 try self.spillRegisters(&.{ .rax, .rdx });
33633358
3364 const dst_info = dst_ty.intInfo(self.target.*);3359 const dst_info = dst_ty.intInfo(mod);
3365 const cc: Condition = switch (dst_info.signedness) {3360 const cc: Condition = switch (dst_info.signedness) {
3366 .unsigned => .c,3361 .unsigned => .c,
3367 .signed => .o,3362 .signed => .o,
...@@ -3369,11 +3364,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3369,11 +3364,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
33693364
3370 const lhs_active_bits = self.activeIntBits(bin_op.lhs);3365 const lhs_active_bits = self.activeIntBits(bin_op.lhs);
3371 const rhs_active_bits = self.activeIntBits(bin_op.rhs);3366 const rhs_active_bits = self.activeIntBits(bin_op.rhs);
3372 var src_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dst_info.signedness) {3367 const src_bits = math.max3(lhs_active_bits, rhs_active_bits, dst_info.bits / 2);
3373 .signed => .int_signed,3368 const src_ty = try mod.intType(dst_info.signedness, src_bits);
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);
33773369
3378 const lhs = try self.resolveInst(bin_op.lhs);3370 const lhs = try self.resolveInst(bin_op.lhs);
3379 const rhs = try self.resolveInst(bin_op.rhs);3371 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -3391,26 +3383,26 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3391,26 +3383,26 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3391 break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } };3383 break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } };
3392 } else {3384 } else {
3393 const frame_index =3385 const frame_index =
3394 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, self.target.*));3386 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
3395 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);3387 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);
3396 break :result .{ .load_frame = .{ .index = frame_index } };3388 break :result .{ .load_frame = .{ .index = frame_index } };
3397 },3389 },
3398 else => {3390 else => {
3399 // For now, this is the only supported multiply that doesn't fit in a register.3391 // 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
3402 const frame_index =3394 const frame_index =
3403 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, self.target.*));3395 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
3404 if (dst_info.bits >= lhs_active_bits + rhs_active_bits) {3396 if (dst_info.bits >= lhs_active_bits + rhs_active_bits) {
3405 try self.genSetMem(3397 try self.genSetMem(
3406 .{ .frame = frame_index },3398 .{ .frame = frame_index },
3407 @intCast(i32, tuple_ty.structFieldOffset(0, self.target.*)),3399 @intCast(i32, tuple_ty.structFieldOffset(0, mod)),
3408 tuple_ty.structFieldType(0),3400 tuple_ty.structFieldType(0),
3409 partial_mcv,3401 partial_mcv,
3410 );3402 );
3411 try self.genSetMem(3403 try self.genSetMem(
3412 .{ .frame = frame_index },3404 .{ .frame = frame_index },
3413 @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)),3405 @intCast(i32, tuple_ty.structFieldOffset(1, mod)),
3414 tuple_ty.structFieldType(1),3406 tuple_ty.structFieldType(1),
3415 .{ .immediate = 0 }, // cc being set is impossible3407 .{ .immediate = 0 }, // cc being set is impossible
3416 );3408 );
...@@ -3433,7 +3425,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3433,7 +3425,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3433/// Clobbers .rax and .rdx registers.3425/// Clobbers .rax and .rdx registers.
3434/// Quotient is saved in .rax and remainder in .rdx.3426/// Quotient is saved in .rax and remainder in .rdx.
3435fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void {3427fn 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));
3437 if (abi_size > 8) {3430 if (abi_size > 8) {
3438 return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{});3431 return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{});
3439 }3432 }
...@@ -3472,8 +3465,9 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue...@@ -3472,8 +3465,9 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue
3472/// Always returns a register.3465/// Always returns a register.
3473/// Clobbers .rax and .rdx registers.3466/// Clobbers .rax and .rdx registers.
3474fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue {3467fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue {
3475 const abi_size = @intCast(u32, ty.abiSize(self.target.*));3468 const mod = self.bin_file.options.module.?;
3476 const int_info = ty.intInfo(self.target.*);3469 const abi_size = @intCast(u32, ty.abiSize(mod));
3470 const int_info = ty.intInfo(mod);
3477 const dividend: Register = switch (lhs) {3471 const dividend: Register = switch (lhs) {
3478 .register => |reg| reg,3472 .register => |reg| reg,
3479 else => try self.copyToTmpRegister(ty, lhs),3473 else => try self.copyToTmpRegister(ty, lhs),
...@@ -3585,6 +3579,7 @@ fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3585,6 +3579,7 @@ fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
3585}3579}
35863580
3587fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {3581fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3582 const mod = self.bin_file.options.module.?;
3588 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3583 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3589 const result = result: {3584 const result = result: {
3590 const dst_ty = self.air.typeOfIndex(inst);3585 const dst_ty = self.air.typeOfIndex(inst);
...@@ -3592,7 +3587,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3592,7 +3587,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3592 const opt_ty = src_ty.childType();3587 const opt_ty = src_ty.childType();
3593 const src_mcv = try self.resolveInst(ty_op.operand);3588 const src_mcv = try self.resolveInst(ty_op.operand);
35943589
3595 if (opt_ty.optionalReprIsPayload()) {3590 if (opt_ty.optionalReprIsPayload(mod)) {
3596 break :result if (self.liveness.isUnused(inst))3591 break :result if (self.liveness.isUnused(inst))
3597 .unreach3592 .unreach
3598 else if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))3593 else if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
...@@ -3610,7 +3605,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3610,7 +3605,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3610 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);3605 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
36113606
3612 const pl_ty = dst_ty.childType();3607 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));
3614 try self.genSetMem(.{ .reg = dst_mcv.getReg().? }, pl_abi_size, Type.bool, .{ .immediate = 1 });3609 try self.genSetMem(.{ .reg = dst_mcv.getReg().? }, pl_abi_size, Type.bool, .{ .immediate = 1 });
3615 break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv;3610 break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv;
3616 };3611 };
...@@ -3618,6 +3613,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3618,6 +3613,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3618}3613}
36193614
3620fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {3615fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3616 const mod = self.bin_file.options.module.?;
3621 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3617 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3622 const err_union_ty = self.air.typeOf(ty_op.operand);3618 const err_union_ty = self.air.typeOf(ty_op.operand);
3623 const err_ty = err_union_ty.errorUnionSet();3619 const err_ty = err_union_ty.errorUnionSet();
...@@ -3629,11 +3625,11 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3629,11 +3625,11 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3629 break :result MCValue{ .immediate = 0 };3625 break :result MCValue{ .immediate = 0 };
3630 }3626 }
36313627
3632 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3628 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3633 break :result operand;3629 break :result operand;
3634 }3630 }
36353631
3636 const err_off = errUnionErrorOffset(payload_ty, self.target.*);3632 const err_off = errUnionErrorOffset(payload_ty, mod);
3637 switch (operand) {3633 switch (operand) {
3638 .register => |reg| {3634 .register => |reg| {
3639 // TODO reuse operand3635 // TODO reuse operand
...@@ -3678,12 +3674,13 @@ fn genUnwrapErrorUnionPayloadMir(...@@ -3678,12 +3674,13 @@ fn genUnwrapErrorUnionPayloadMir(
3678 err_union_ty: Type,3674 err_union_ty: Type,
3679 err_union: MCValue,3675 err_union: MCValue,
3680) !MCValue {3676) !MCValue {
3677 const mod = self.bin_file.options.module.?;
3681 const payload_ty = err_union_ty.errorUnionPayload();3678 const payload_ty = err_union_ty.errorUnionPayload();
36823679
3683 const result: MCValue = result: {3680 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);
3687 switch (err_union) {3684 switch (err_union) {
3688 .load_frame => |frame_addr| break :result .{ .load_frame = .{3685 .load_frame => |frame_addr| break :result .{ .load_frame = .{
3689 .index = frame_addr.index,3686 .index = frame_addr.index,
...@@ -3720,6 +3717,7 @@ fn genUnwrapErrorUnionPayloadMir(...@@ -3720,6 +3717,7 @@ fn genUnwrapErrorUnionPayloadMir(
37203717
3721// *(E!T) -> E3718// *(E!T) -> E
3722fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {3719fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
3720 const mod = self.bin_file.options.module.?;
3723 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3721 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
37243722
3725 const src_ty = self.air.typeOf(ty_op.operand);3723 const src_ty = self.air.typeOf(ty_op.operand);
...@@ -3739,8 +3737,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3739,8 +3737,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
3739 const eu_ty = src_ty.childType();3737 const eu_ty = src_ty.childType();
3740 const pl_ty = eu_ty.errorUnionPayload();3738 const pl_ty = eu_ty.errorUnionPayload();
3741 const err_ty = eu_ty.errorUnionSet();3739 const err_ty = eu_ty.errorUnionSet();
3742 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*));3740 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));
3743 const err_abi_size = @intCast(u32, err_ty.abiSize(self.target.*));3741 const err_abi_size = @intCast(u32, err_ty.abiSize(mod));
3744 try self.asmRegisterMemory(3742 try self.asmRegisterMemory(
3745 .{ ._, .mov },3743 .{ ._, .mov },
3746 registerAlias(dst_reg, err_abi_size),3744 registerAlias(dst_reg, err_abi_size),
...@@ -3755,6 +3753,7 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3755,6 +3753,7 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
37553753
3756// *(E!T) -> *T3754// *(E!T) -> *T
3757fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {3755fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
3756 const mod = self.bin_file.options.module.?;
3758 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3757 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
37593758
3760 const src_ty = self.air.typeOf(ty_op.operand);3759 const src_ty = self.air.typeOf(ty_op.operand);
...@@ -3777,8 +3776,8 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3777,8 +3776,8 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
37773776
3778 const eu_ty = src_ty.childType();3777 const eu_ty = src_ty.childType();
3779 const pl_ty = eu_ty.errorUnionPayload();3778 const pl_ty = eu_ty.errorUnionPayload();
3780 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, self.target.*));3779 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, mod));
3781 const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));3780 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));
3782 try self.asmRegisterMemory(3781 try self.asmRegisterMemory(
3783 .{ ._, .lea },3782 .{ ._, .lea },
3784 registerAlias(dst_reg, dst_abi_size),3783 registerAlias(dst_reg, dst_abi_size),
...@@ -3789,6 +3788,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3789,6 +3788,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
3789}3788}
37903789
3791fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {3790fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3791 const mod = self.bin_file.options.module.?;
3792 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3792 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3793 const result: MCValue = result: {3793 const result: MCValue = result: {
3794 const src_ty = self.air.typeOf(ty_op.operand);3794 const src_ty = self.air.typeOf(ty_op.operand);
...@@ -3803,8 +3803,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3803,8 +3803,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3803 const eu_ty = src_ty.childType();3803 const eu_ty = src_ty.childType();
3804 const pl_ty = eu_ty.errorUnionPayload();3804 const pl_ty = eu_ty.errorUnionPayload();
3805 const err_ty = eu_ty.errorUnionSet();3805 const err_ty = eu_ty.errorUnionSet();
3806 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*));3806 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));
3807 const err_abi_size = @intCast(u32, err_ty.abiSize(self.target.*));3807 const err_abi_size = @intCast(u32, err_ty.abiSize(mod));
3808 try self.asmMemoryImmediate(3808 try self.asmMemoryImmediate(
3809 .{ ._, .mov },3809 .{ ._, .mov },
3810 Memory.sib(Memory.PtrSize.fromSize(err_abi_size), .{3810 Memory.sib(Memory.PtrSize.fromSize(err_abi_size), .{
...@@ -3824,8 +3824,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3824,8 +3824,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3824 const dst_lock = self.register_manager.lockReg(dst_reg);3824 const dst_lock = self.register_manager.lockReg(dst_reg);
3825 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);3825 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
38263826
3827 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, self.target.*));3827 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, mod));
3828 const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));3828 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));
3829 try self.asmRegisterMemory(3829 try self.asmRegisterMemory(
3830 .{ ._, .lea },3830 .{ ._, .lea },
3831 registerAlias(dst_reg, dst_abi_size),3831 registerAlias(dst_reg, dst_abi_size),
...@@ -3853,14 +3853,15 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {...@@ -3853,14 +3853,15 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
3853}3853}
38543854
3855fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {3855fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3856 const mod = self.bin_file.options.module.?;
3856 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3857 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3857 const result: MCValue = result: {3858 const result: MCValue = result: {
3858 const pl_ty = self.air.typeOf(ty_op.operand);3859 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
3861 const opt_ty = self.air.typeOfIndex(inst);3862 const opt_ty = self.air.typeOfIndex(inst);
3862 const pl_mcv = try self.resolveInst(ty_op.operand);3863 const pl_mcv = try self.resolveInst(ty_op.operand);
3863 const same_repr = opt_ty.optionalReprIsPayload();3864 const same_repr = opt_ty.optionalReprIsPayload(mod);
3864 if (same_repr and self.reuseOperand(inst, ty_op.operand, 0, pl_mcv)) break :result pl_mcv;3865 if (same_repr and self.reuseOperand(inst, ty_op.operand, 0, pl_mcv)) break :result pl_mcv;
38653866
3866 const pl_lock: ?RegisterLock = switch (pl_mcv) {3867 const pl_lock: ?RegisterLock = switch (pl_mcv) {
...@@ -3873,7 +3874,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -3873,7 +3874,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3873 try self.genCopy(pl_ty, opt_mcv, pl_mcv);3874 try self.genCopy(pl_ty, opt_mcv, pl_mcv);
38743875
3875 if (!same_repr) {3876 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));
3877 switch (opt_mcv) {3878 switch (opt_mcv) {
3878 else => unreachable,3879 else => unreachable,
38793880
...@@ -3900,6 +3901,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -3900,6 +3901,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
39003901
3901/// T to E!T3902/// T to E!T
3902fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {3903fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3904 const mod = self.bin_file.options.module.?;
3903 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3905 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39043906
3905 const eu_ty = self.air.getRefType(ty_op.ty);3907 const eu_ty = self.air.getRefType(ty_op.ty);
...@@ -3908,11 +3910,11 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -3908,11 +3910,11 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3908 const operand = try self.resolveInst(ty_op.operand);3910 const operand = try self.resolveInst(ty_op.operand);
39093911
3910 const result: MCValue = result: {3912 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.*));3915 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(eu_ty, mod));
3914 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, self.target.*));3916 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, mod));
3915 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*));3917 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));
3916 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand);3918 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand);
3917 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 });3919 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 });
3918 break :result .{ .load_frame = .{ .index = frame_index } };3920 break :result .{ .load_frame = .{ .index = frame_index } };
...@@ -3922,6 +3924,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -3922,6 +3924,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
39223924
3923/// E to E!T3925/// E to E!T
3924fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {3926fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3927 const mod = self.bin_file.options.module.?;
3925 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3928 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39263929
3927 const eu_ty = self.air.getRefType(ty_op.ty);3930 const eu_ty = self.air.getRefType(ty_op.ty);
...@@ -3929,11 +3932,11 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3929,11 +3932,11 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3929 const err_ty = eu_ty.errorUnionSet();3932 const err_ty = eu_ty.errorUnionSet();
39303933
3931 const result: MCValue = result: {3934 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.*));3937 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(eu_ty, mod));
3935 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, self.target.*));3938 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, mod));
3936 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*));3939 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));
3937 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef);3940 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef);
3938 const operand = try self.resolveInst(ty_op.operand);3941 const operand = try self.resolveInst(ty_op.operand);
3939 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand);3942 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand);
...@@ -3974,6 +3977,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -3974,6 +3977,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
3974}3977}
39753978
3976fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {3979fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
3980 const mod = self.bin_file.options.module.?;
3977 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3981 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39783982
3979 const src_ty = self.air.typeOf(ty_op.operand);3983 const src_ty = self.air.typeOf(ty_op.operand);
...@@ -3994,7 +3998,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3994,7 +3998,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
3994 const dst_lock = self.register_manager.lockReg(dst_reg);3998 const dst_lock = self.register_manager.lockReg(dst_reg);
3995 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);3999 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));
3998 try self.asmRegisterMemory(4002 try self.asmRegisterMemory(
3999 .{ ._, .lea },4003 .{ ._, .lea },
4000 registerAlias(dst_reg, dst_abi_size),4004 registerAlias(dst_reg, dst_abi_size),
...@@ -4041,6 +4045,7 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi...@@ -4041,6 +4045,7 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi
4041}4045}
40424046
4043fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {4047fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
4048 const mod = self.bin_file.options.module.?;
4044 const slice_ty = self.air.typeOf(lhs);4049 const slice_ty = self.air.typeOf(lhs);
4045 const slice_mcv = try self.resolveInst(lhs);4050 const slice_mcv = try self.resolveInst(lhs);
4046 const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) {4051 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 {...@@ -4050,7 +4055,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
4050 defer if (slice_mcv_lock) |lock| self.register_manager.unlockReg(lock);4055 defer if (slice_mcv_lock) |lock| self.register_manager.unlockReg(lock);
40514056
4052 const elem_ty = slice_ty.childType();4057 const elem_ty = slice_ty.childType();
4053 const elem_size = elem_ty.abiSize(self.target.*);4058 const elem_size = elem_ty.abiSize(mod);
4054 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4059 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4055 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);4060 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
40564061
...@@ -4097,6 +4102,7 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4097,6 +4102,7 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
4097}4102}
40984103
4099fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {4104fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
4105 const mod = self.bin_file.options.module.?;
4100 const bin_op = self.air.instructions.items(.data)[inst].bin_op;4106 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
41014107
4102 const array_ty = self.air.typeOf(bin_op.lhs);4108 const array_ty = self.air.typeOf(bin_op.lhs);
...@@ -4108,7 +4114,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4108,7 +4114,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
4108 defer if (array_lock) |lock| self.register_manager.unlockReg(lock);4114 defer if (array_lock) |lock| self.register_manager.unlockReg(lock);
41094115
4110 const elem_ty = array_ty.childType();4116 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
4113 const index_ty = self.air.typeOf(bin_op.rhs);4119 const index_ty = self.air.typeOf(bin_op.rhs);
4114 const index = try self.resolveInst(bin_op.rhs);4120 const index = try self.resolveInst(bin_op.rhs);
...@@ -4125,7 +4131,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4125,7 +4131,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
4125 const addr_reg = try self.register_manager.allocReg(null, gp);4131 const addr_reg = try self.register_manager.allocReg(null, gp);
4126 switch (array) {4132 switch (array) {
4127 .register => {4133 .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));
4129 try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array);4135 try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array);
4130 try self.asmRegisterMemory(4136 try self.asmRegisterMemory(
4131 .{ ._, .lea },4137 .{ ._, .lea },
...@@ -4162,14 +4168,15 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4162,14 +4168,15 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
4162}4168}
41634169
4164fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {4170fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
4171 const mod = self.bin_file.options.module.?;
4165 const bin_op = self.air.instructions.items(.data)[inst].bin_op;4172 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
4166 const ptr_ty = self.air.typeOf(bin_op.lhs);4173 const ptr_ty = self.air.typeOf(bin_op.lhs);
41674174
4168 // this is identical to the `airPtrElemPtr` codegen expect here an4175 // this is identical to the `airPtrElemPtr` codegen expect here an
4169 // additional `mov` is needed at the end to get the actual value4176 // additional `mov` is needed at the end to get the actual value
41704177
4171 const elem_ty = ptr_ty.elemType2();4178 const elem_ty = ptr_ty.elemType2(mod);
4172 const elem_abi_size = @intCast(u32, elem_ty.abiSize(self.target.*));4179 const elem_abi_size = @intCast(u32, elem_ty.abiSize(mod));
4173 const index_ty = self.air.typeOf(bin_op.rhs);4180 const index_ty = self.air.typeOf(bin_op.rhs);
4174 const index_mcv = try self.resolveInst(bin_op.rhs);4181 const index_mcv = try self.resolveInst(bin_op.rhs);
4175 const index_lock = switch (index_mcv) {4182 const index_lock = switch (index_mcv) {
...@@ -4207,6 +4214,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4207,6 +4214,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
4207}4214}
42084215
4209fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {4216fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
4217 const mod = self.bin_file.options.module.?;
4210 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;4218 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
4211 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;4219 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 {...@@ -4218,8 +4226,8 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
4218 };4226 };
4219 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);4227 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);
42204228
4221 const elem_ty = ptr_ty.elemType2();4229 const elem_ty = ptr_ty.elemType2(mod);
4222 const elem_abi_size = elem_ty.abiSize(self.target.*);4230 const elem_abi_size = elem_ty.abiSize(mod);
4223 const index_ty = self.air.typeOf(extra.rhs);4231 const index_ty = self.air.typeOf(extra.rhs);
4224 const index = try self.resolveInst(extra.rhs);4232 const index = try self.resolveInst(extra.rhs);
4225 const index_lock: ?RegisterLock = switch (index) {4233 const index_lock: ?RegisterLock = switch (index) {
...@@ -4239,11 +4247,12 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4239,11 +4247,12 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
4239}4247}
42404248
4241fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {4249fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
4250 const mod = self.bin_file.options.module.?;
4242 const bin_op = self.air.instructions.items(.data)[inst].bin_op;4251 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
4243 const ptr_union_ty = self.air.typeOf(bin_op.lhs);4252 const ptr_union_ty = self.air.typeOf(bin_op.lhs);
4244 const union_ty = ptr_union_ty.childType();4253 const union_ty = ptr_union_ty.childType();
4245 const tag_ty = self.air.typeOf(bin_op.rhs);4254 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
4248 if (layout.tag_size == 0) {4257 if (layout.tag_size == 0) {
4249 return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none });4258 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 {...@@ -4284,11 +4293,12 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
4284}4293}
42854294
4286fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {4295fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
4296 const mod = self.bin_file.options.module.?;
4287 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4297 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
42884298
4289 const tag_ty = self.air.typeOfIndex(inst);4299 const tag_ty = self.air.typeOfIndex(inst);
4290 const union_ty = self.air.typeOf(ty_op.operand);4300 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
4293 if (layout.tag_size == 0) {4303 if (layout.tag_size == 0) {
4294 return self.finishAir(inst, .none, .{ ty_op.operand, .none, .none });4304 return self.finishAir(inst, .none, .{ ty_op.operand, .none, .none });
...@@ -4302,7 +4312,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {...@@ -4302,7 +4312,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
4302 };4312 };
4303 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);4313 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);
4306 const dst_mcv: MCValue = blk: {4316 const dst_mcv: MCValue = blk: {
4307 switch (operand) {4317 switch (operand) {
4308 .load_frame => |frame_addr| {4318 .load_frame => |frame_addr| {
...@@ -4337,6 +4347,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {...@@ -4337,6 +4347,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
4337}4347}
43384348
4339fn airClz(self: *Self, inst: Air.Inst.Index) !void {4349fn airClz(self: *Self, inst: Air.Inst.Index) !void {
4350 const mod = self.bin_file.options.module.?;
4340 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4351 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
4341 const result = result: {4352 const result = result: {
4342 const dst_ty = self.air.typeOfIndex(inst);4353 const dst_ty = self.air.typeOfIndex(inst);
...@@ -4358,7 +4369,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4358,7 +4369,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
4358 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);4369 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
4359 defer self.register_manager.unlockReg(dst_lock);4370 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);
4362 if (self.hasFeature(.lzcnt)) {4373 if (self.hasFeature(.lzcnt)) {
4363 if (src_bits <= 8) {4374 if (src_bits <= 8) {
4364 const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv);4375 const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv);
...@@ -4405,7 +4416,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4405,7 +4416,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
4405 }4416 }
44064417
4407 if (src_bits > 64)4418 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)});
4409 if (math.isPowerOfTwo(src_bits)) {4420 if (math.isPowerOfTwo(src_bits)) {
4410 const imm_reg = try self.copyToTmpRegister(dst_ty, .{4421 const imm_reg = try self.copyToTmpRegister(dst_ty, .{
4411 .immediate = src_bits ^ (src_bits - 1),4422 .immediate = src_bits ^ (src_bits - 1),
...@@ -4422,7 +4433,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4422,7 +4433,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
4422 try self.genBinOpMir(.{ ._, .bsr }, Type.u16, dst_mcv, .{ .register = wide_reg });4433 try self.genBinOpMir(.{ ._, .bsr }, Type.u16, dst_mcv, .{ .register = wide_reg });
4423 } else try self.genBinOpMir(.{ ._, .bsr }, src_ty, dst_mcv, mat_src_mcv);4434 } 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);
4426 try self.asmCmovccRegisterRegister(4437 try self.asmCmovccRegisterRegister(
4427 registerAlias(dst_reg, cmov_abi_size),4438 registerAlias(dst_reg, cmov_abi_size),
4428 registerAlias(imm_reg, cmov_abi_size),4439 registerAlias(imm_reg, cmov_abi_size),
...@@ -4449,7 +4460,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4449,7 +4460,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
4449 .{ .register = wide_reg },4460 .{ .register = wide_reg },
4450 );4461 );
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);
4453 try self.asmCmovccRegisterRegister(4464 try self.asmCmovccRegisterRegister(
4454 registerAlias(imm_reg, cmov_abi_size),4465 registerAlias(imm_reg, cmov_abi_size),
4455 registerAlias(dst_reg, cmov_abi_size),4466 registerAlias(dst_reg, cmov_abi_size),
...@@ -4465,11 +4476,12 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4465,11 +4476,12 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
4465}4476}
44664477
4467fn airCtz(self: *Self, inst: Air.Inst.Index) !void {4478fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
4479 const mod = self.bin_file.options.module.?;
4468 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4480 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
4469 const result = result: {4481 const result = result: {
4470 const dst_ty = self.air.typeOfIndex(inst);4482 const dst_ty = self.air.typeOfIndex(inst);
4471 const src_ty = self.air.typeOf(ty_op.operand);4483 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
4474 const src_mcv = try self.resolveInst(ty_op.operand);4486 const src_mcv = try self.resolveInst(ty_op.operand);
4475 const mat_src_mcv = switch (src_mcv) {4487 const mat_src_mcv = switch (src_mcv) {
...@@ -4548,7 +4560,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4548,7 +4560,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
4548 try self.genBinOpMir(.{ ._, .bsf }, Type.u16, dst_mcv, .{ .register = wide_reg });4560 try self.genBinOpMir(.{ ._, .bsf }, Type.u16, dst_mcv, .{ .register = wide_reg });
4549 } else try self.genBinOpMir(.{ ._, .bsf }, src_ty, dst_mcv, mat_src_mcv);4561 } 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);
4552 try self.asmCmovccRegisterRegister(4564 try self.asmCmovccRegisterRegister(
4553 registerAlias(dst_reg, cmov_abi_size),4565 registerAlias(dst_reg, cmov_abi_size),
4554 registerAlias(width_reg, cmov_abi_size),4566 registerAlias(width_reg, cmov_abi_size),
...@@ -4560,10 +4572,11 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4560,10 +4572,11 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
4560}4572}
45614573
4562fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {4574fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
4575 const mod = self.bin_file.options.module.?;
4563 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4576 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
4564 const result: MCValue = result: {4577 const result: MCValue = result: {
4565 const src_ty = self.air.typeOf(ty_op.operand);4578 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));
4567 const src_mcv = try self.resolveInst(ty_op.operand);4580 const src_mcv = try self.resolveInst(ty_op.operand);
45684581
4569 if (self.hasFeature(.popcnt)) {4582 if (self.hasFeature(.popcnt)) {
...@@ -4729,6 +4742,7 @@ fn byteSwap(self: *Self, inst: Air.Inst.Index, src_ty: Type, src_mcv: MCValue, m...@@ -4729,6 +4742,7 @@ fn byteSwap(self: *Self, inst: Air.Inst.Index, src_ty: Type, src_mcv: MCValue, m
4729}4742}
47304743
4731fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {4744fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
4745 const mod = self.bin_file.options.module.?;
4732 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4746 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
47334747
4734 const src_ty = self.air.typeOf(ty_op.operand);4748 const src_ty = self.air.typeOf(ty_op.operand);
...@@ -4738,7 +4752,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {...@@ -4738,7 +4752,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
4738 switch (self.regExtraBits(src_ty)) {4752 switch (self.regExtraBits(src_ty)) {
4739 0 => {},4753 0 => {},
4740 else => |extra| try self.genBinOpMir(4754 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 },
4742 src_ty,4756 src_ty,
4743 dst_mcv,4757 dst_mcv,
4744 .{ .immediate = extra },4758 .{ .immediate = extra },
...@@ -4749,10 +4763,11 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {...@@ -4749,10 +4763,11 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
4749}4763}
47504764
4751fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {4765fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
4766 const mod = self.bin_file.options.module.?;
4752 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4767 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
47534768
4754 const src_ty = self.air.typeOf(ty_op.operand);4769 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));
4756 const src_mcv = try self.resolveInst(ty_op.operand);4771 const src_mcv = try self.resolveInst(ty_op.operand);
47574772
4758 const dst_mcv = try self.byteSwap(inst, src_ty, src_mcv, false);4773 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 {...@@ -4847,7 +4862,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
4847 switch (self.regExtraBits(src_ty)) {4862 switch (self.regExtraBits(src_ty)) {
4848 0 => {},4863 0 => {},
4849 else => |extra| try self.genBinOpMir(4864 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 },
4851 src_ty,4866 src_ty,
4852 dst_mcv,4867 dst_mcv,
4853 .{ .immediate = extra },4868 .{ .immediate = extra },
...@@ -4858,17 +4873,18 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {...@@ -4858,17 +4873,18 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
4858}4873}
48594874
4860fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {4875fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
4876 const mod = self.bin_file.options.module.?;
4861 const tag = self.air.instructions.items(.tag)[inst];4877 const tag = self.air.instructions.items(.tag)[inst];
4862 const un_op = self.air.instructions.items(.data)[inst].un_op;4878 const un_op = self.air.instructions.items(.data)[inst].un_op;
4863 const ty = self.air.typeOf(un_op);4879 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)) {
4865 1...16 => 16,4881 1...16 => 16,
4866 17...32 => 32,4882 17...32 => 32,
4867 else => return self.fail("TODO implement airFloatSign for {}", .{4883 else => return self.fail("TODO implement airFloatSign for {}", .{
4868 ty.fmt(self.bin_file.options.module.?),4884 ty.fmt(self.bin_file.options.module.?),
4869 }),4885 }),
4870 };4886 };
4871 const scalar_bits = ty.scalarType().floatBits(self.target.*);4887 const scalar_bits = ty.scalarType(mod).floatBits(self.target.*);
48724888
4873 const src_mcv = try self.resolveInst(un_op);4889 const src_mcv = try self.resolveInst(un_op);
4874 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;4890 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 {...@@ -4905,21 +4921,17 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
4905 var stack align(@alignOf(ExpectedContents)) =4921 var stack align(@alignOf(ExpectedContents)) =
4906 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());4922 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 };
4912 var vec_pl = Type.Payload.Array{4924 var vec_pl = Type.Payload.Array{
4913 .base = .{ .tag = .vector },4925 .base = .{ .tag = .vector },
4914 .data = .{4926 .data = .{
4915 .len = @divExact(abi_size * 8, scalar_bits),4927 .len = @divExact(abi_size * 8, scalar_bits),
4916 .elem_type = Type.initPayload(&int_pl.base),4928 .elem_type = try mod.intType(.signed, scalar_bits),
4917 },4929 },
4918 };4930 };
4919 const vec_ty = Type.initPayload(&vec_pl.base);4931 const vec_ty = Type.initPayload(&vec_pl.base);
4920 const sign_val = switch (tag) {4932 const sign_val = switch (tag) {
4921 .neg => try vec_ty.minInt(stack.get(), self.target.*),4933 .neg => try vec_ty.minInt(stack.get(), mod),
4922 .fabs => try vec_ty.maxInt(stack.get(), self.target.*),4934 .fabs => try vec_ty.maxInt(stack.get(), mod),
4923 else => unreachable,4935 else => unreachable,
4924 };4936 };
49254937
...@@ -5008,17 +5020,18 @@ fn airRound(self: *Self, inst: Air.Inst.Index, mode: u4) !void {...@@ -5008,17 +5020,18 @@ fn airRound(self: *Self, inst: Air.Inst.Index, mode: u4) !void {
5008}5020}
50095021
5010fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4) !void {5022fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4) !void {
5023 const mod = self.bin_file.options.module.?;
5011 if (!self.hasFeature(.sse4_1))5024 if (!self.hasFeature(.sse4_1))
5012 return self.fail("TODO implement genRound without sse4_1 feature", .{});5025 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)) {
5015 .Float => switch (ty.floatBits(self.target.*)) {5028 .Float => switch (ty.floatBits(self.target.*)) {
5016 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },5029 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },
5017 64 => if (self.hasFeature(.avx)) .{ .v_sd, .round } else .{ ._sd, .round },5030 64 => if (self.hasFeature(.avx)) .{ .v_sd, .round } else .{ ._sd, .round },
5018 16, 80, 128 => null,5031 16, 80, 128 => null,
5019 else => unreachable,5032 else => unreachable,
5020 },5033 },
5021 .Vector => switch (ty.childType().zigTypeTag()) {5034 .Vector => switch (ty.childType().zigTypeTag(mod)) {
5022 .Float => switch (ty.childType().floatBits(self.target.*)) {5035 .Float => switch (ty.childType().floatBits(self.target.*)) {
5023 32 => switch (ty.vectorLen()) {5036 32 => switch (ty.vectorLen()) {
5024 1 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },5037 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...@@ -5041,7 +5054,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4
5041 })) |tag| tag else return self.fail("TODO implement genRound for {}", .{5054 })) |tag| tag else return self.fail("TODO implement genRound for {}", .{
5042 ty.fmt(self.bin_file.options.module.?),5055 ty.fmt(self.bin_file.options.module.?),
5043 });5056 });
5044 const abi_size = @intCast(u32, ty.abiSize(self.target.*));5057 const abi_size = @intCast(u32, ty.abiSize(mod));
5045 const dst_alias = registerAlias(dst_reg, abi_size);5058 const dst_alias = registerAlias(dst_reg, abi_size);
5046 switch (mir_tag[0]) {5059 switch (mir_tag[0]) {
5047 .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate(5060 .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...@@ -5078,9 +5091,10 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4
5078}5091}
50795092
5080fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {5093fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
5094 const mod = self.bin_file.options.module.?;
5081 const un_op = self.air.instructions.items(.data)[inst].un_op;5095 const un_op = self.air.instructions.items(.data)[inst].un_op;
5082 const ty = self.air.typeOf(un_op);5096 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
5085 const src_mcv = try self.resolveInst(un_op);5099 const src_mcv = try self.resolveInst(un_op);
5086 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv))5100 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 {...@@ -5092,7 +5106,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
5092 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);5106 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
50935107
5094 const result: MCValue = result: {5108 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)) {
5096 .Float => switch (ty.floatBits(self.target.*)) {5110 .Float => switch (ty.floatBits(self.target.*)) {
5097 16 => if (self.hasFeature(.f16c)) {5111 16 => if (self.hasFeature(.f16c)) {
5098 const mat_src_reg = if (src_mcv.isRegister())5112 const mat_src_reg = if (src_mcv.isRegister())
...@@ -5114,7 +5128,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {...@@ -5114,7 +5128,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
5114 80, 128 => null,5128 80, 128 => null,
5115 else => unreachable,5129 else => unreachable,
5116 },5130 },
5117 .Vector => switch (ty.childType().zigTypeTag()) {5131 .Vector => switch (ty.childType().zigTypeTag(mod)) {
5118 .Float => switch (ty.childType().floatBits(self.target.*)) {5132 .Float => switch (ty.childType().floatBits(self.target.*)) {
5119 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen()) {5133 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen()) {
5120 1 => {5134 1 => {
...@@ -5186,7 +5200,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {...@@ -5186,7 +5200,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
5186 },5200 },
5187 else => unreachable,5201 else => unreachable,
5188 })) |tag| tag else return self.fail("TODO implement airSqrt for {}", .{5202 })) |tag| tag else return self.fail("TODO implement airSqrt for {}", .{
5189 ty.fmt(self.bin_file.options.module.?),5203 ty.fmt(mod),
5190 });5204 });
5191 switch (mir_tag[0]) {5205 switch (mir_tag[0]) {
5192 .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory(5206 .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory(
...@@ -5274,10 +5288,11 @@ fn reuseOperandAdvanced(...@@ -5274,10 +5288,11 @@ fn reuseOperandAdvanced(
5274}5288}
52755289
5276fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void {5290fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void {
5291 const mod = self.bin_file.options.module.?;
5277 const ptr_info = ptr_ty.ptrInfo().data;5292 const ptr_info = ptr_ty.ptrInfo().data;
52785293
5279 const val_ty = ptr_info.pointee_type;5294 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));
5281 const limb_abi_size: u32 = @min(val_abi_size, 8);5296 const limb_abi_size: u32 = @min(val_abi_size, 8);
5282 const limb_abi_bits = limb_abi_size * 8;5297 const limb_abi_bits = limb_abi_size * 8;
5283 const val_byte_off = @intCast(i32, ptr_info.bit_offset / limb_abi_bits * limb_abi_size);5298 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...@@ -5382,20 +5397,21 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro
5382}5397}
53835398
5384fn airLoad(self: *Self, inst: Air.Inst.Index) !void {5399fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
5400 const mod = self.bin_file.options.module.?;
5385 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5401 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5386 const elem_ty = self.air.typeOfIndex(inst);5402 const elem_ty = self.air.typeOfIndex(inst);
5387 const result: MCValue = result: {5403 const result: MCValue = result: {
5388 if (!elem_ty.hasRuntimeBitsIgnoreComptime()) break :result .none;5404 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
53895405
5390 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });5406 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });
5391 const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx });5407 const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx });
5392 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);5408 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
53935409
5394 const ptr_ty = self.air.typeOf(ty_op.operand);5410 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);5413 const elem_rc = regClassForType(elem_ty, mod);
5398 const ptr_rc = regClassForType(ptr_ty);5414 const ptr_rc = regClassForType(ptr_ty, mod);
53995415
5400 const ptr_mcv = try self.resolveInst(ty_op.operand);5416 const ptr_mcv = try self.resolveInst(ty_op.operand);
5401 const dst_mcv = if (elem_size <= 8 and elem_rc.supersetOf(ptr_rc) and5417 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 {...@@ -5416,13 +5432,14 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
5416}5432}
54175433
5418fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void {5434fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void {
5435 const mod = self.bin_file.options.module.?;
5419 const ptr_info = ptr_ty.ptrInfo().data;5436 const ptr_info = ptr_ty.ptrInfo().data;
5420 const src_ty = ptr_ty.childType();5437 const src_ty = ptr_ty.childType();
54215438
5422 const limb_abi_size: u16 = @min(ptr_info.host_size, 8);5439 const limb_abi_size: u16 = @min(ptr_info.host_size, 8);
5423 const limb_abi_bits = limb_abi_size * 8;5440 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);
5426 const src_byte_off = @intCast(i32, ptr_info.bit_offset / limb_abi_bits * limb_abi_size);5443 const src_byte_off = @intCast(i32, ptr_info.bit_offset / limb_abi_bits * limb_abi_size);
5427 const src_bit_off = ptr_info.bit_offset % limb_abi_bits;5444 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 {...@@ -5555,14 +5572,15 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
5555}5572}
55565573
5557fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {5574fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
5575 const mod = self.bin_file.options.module.?;
5558 const ptr_field_ty = self.air.typeOfIndex(inst);5576 const ptr_field_ty = self.air.typeOfIndex(inst);
5559 const ptr_container_ty = self.air.typeOf(operand);5577 const ptr_container_ty = self.air.typeOf(operand);
5560 const container_ty = ptr_container_ty.childType();5578 const container_ty = ptr_container_ty.childType();
5561 const field_offset = @intCast(i32, switch (container_ty.containerLayout()) {5579 const field_offset = @intCast(i32, switch (container_ty.containerLayout()) {
5562 .Auto, .Extern => container_ty.structFieldOffset(index, self.target.*),5580 .Auto, .Extern => container_ty.structFieldOffset(index, mod),
5563 .Packed => if (container_ty.zigTypeTag() == .Struct and5581 .Packed => if (container_ty.zigTypeTag(mod) == .Struct and
5564 ptr_field_ty.ptrInfo().data.host_size == 0)5582 ptr_field_ty.ptrInfo().data.host_size == 0)
5565 container_ty.packedStructFieldByteOffset(index, self.target.*)5583 container_ty.packedStructFieldByteOffset(index, mod)
5566 else5584 else
5567 0,5585 0,
5568 });5586 });
...@@ -5577,6 +5595,7 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32...@@ -5577,6 +5595,7 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32
5577}5595}
55785596
5579fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {5597fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
5598 const mod = self.bin_file.options.module.?;
5580 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5599 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5581 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;5600 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
5582 const result: MCValue = result: {5601 const result: MCValue = result: {
...@@ -5584,17 +5603,17 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5584,17 +5603,17 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
5584 const index = extra.field_index;5603 const index = extra.field_index;
55855604
5586 const container_ty = self.air.typeOf(operand);5605 const container_ty = self.air.typeOf(operand);
5587 const container_rc = regClassForType(container_ty);5606 const container_rc = regClassForType(container_ty, mod);
5588 const field_ty = container_ty.structFieldType(index);5607 const field_ty = container_ty.structFieldType(index);
5589 if (!field_ty.hasRuntimeBitsIgnoreComptime()) break :result .none;5608 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
5590 const field_rc = regClassForType(field_ty);5609 const field_rc = regClassForType(field_ty, mod);
5591 const field_is_gp = field_rc.supersetOf(gp);5610 const field_is_gp = field_rc.supersetOf(gp);
55925611
5593 const src_mcv = try self.resolveInst(operand);5612 const src_mcv = try self.resolveInst(operand);
5594 const field_off = switch (container_ty.containerLayout()) {5613 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),
5596 .Packed => if (container_ty.castTag(.@"struct")) |struct_obj|5615 .Packed => if (container_ty.castTag(.@"struct")) |struct_obj|
5597 struct_obj.data.packedFieldBitOffset(self.target.*, index)5616 struct_obj.data.packedFieldBitOffset(mod, index)
5598 else5617 else
5599 0,5618 0,
5600 };5619 };
...@@ -5611,7 +5630,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5611,7 +5630,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
5611 break :result dst_mcv;5630 break :result dst_mcv;
5612 }5631 }
56135632
5614 const field_abi_size = @intCast(u32, field_ty.abiSize(self.target.*));5633 const field_abi_size = @intCast(u32, field_ty.abiSize(mod));
5615 const limb_abi_size: u32 = @min(field_abi_size, 8);5634 const limb_abi_size: u32 = @min(field_abi_size, 8);
5616 const limb_abi_bits = limb_abi_size * 8;5635 const limb_abi_bits = limb_abi_size * 8;
5617 const field_byte_off = @intCast(i32, field_off / limb_abi_bits * limb_abi_size);5636 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 {...@@ -5733,12 +5752,13 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
5733}5752}
57345753
5735fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {5754fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
5755 const mod = self.bin_file.options.module.?;
5736 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5756 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5737 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;5757 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
57385758
5739 const inst_ty = self.air.typeOfIndex(inst);5759 const inst_ty = self.air.typeOfIndex(inst);
5740 const parent_ty = inst_ty.childType();5760 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
5743 const src_mcv = try self.resolveInst(extra.field_ptr);5763 const src_mcv = try self.resolveInst(extra.field_ptr);
5744 const dst_mcv = if (src_mcv.isRegisterOffset() and5764 const dst_mcv = if (src_mcv.isRegisterOffset() and
...@@ -5751,9 +5771,10 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5751,9 +5771,10 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
5751}5771}
57525772
5753fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue {5773fn 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.?;
5754 const src_ty = self.air.typeOf(src_air);5775 const src_ty = self.air.typeOf(src_air);
5755 const src_mcv = try self.resolveInst(src_air);5776 const src_mcv = try self.resolveInst(src_air);
5756 if (src_ty.zigTypeTag() == .Vector) {5777 if (src_ty.zigTypeTag(mod) == .Vector) {
5757 return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)});5778 return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)});
5758 }5779 }
57595780
...@@ -5786,28 +5807,22 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:...@@ -5786,28 +5807,22 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
57865807
5787 switch (tag) {5808 switch (tag) {
5788 .not => {5809 .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));
5790 const int_info = if (src_ty.tag() == .bool)5811 const int_info = if (src_ty.tag() == .bool)
5791 std.builtin.Type.Int{ .signedness = .unsigned, .bits = 1 }5812 std.builtin.Type.Int{ .signedness = .unsigned, .bits = 1 }
5792 else5813 else
5793 src_ty.intInfo(self.target.*);5814 src_ty.intInfo(mod);
5794 var byte_off: i32 = 0;5815 var byte_off: i32 = 0;
5795 while (byte_off * 8 < int_info.bits) : (byte_off += limb_abi_size) {5816 while (byte_off * 8 < int_info.bits) : (byte_off += limb_abi_size) {
5796 var limb_pl = Type.Payload.Bits{5817 const limb_bits = @intCast(u16, @min(int_info.bits - byte_off * 8, limb_abi_size * 8));
5797 .base = .{ .tag = switch (int_info.signedness) {5818 const limb_ty = try mod.intType(int_info.signedness, limb_bits);
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);
5804 const limb_mcv = switch (byte_off) {5819 const limb_mcv = switch (byte_off) {
5805 0 => dst_mcv,5820 0 => dst_mcv,
5806 else => dst_mcv.address().offset(byte_off).deref(),5821 else => dst_mcv.address().offset(byte_off).deref(),
5807 };5822 };
58085823
5809 if (limb_pl.base.tag == .int_unsigned and self.regExtraBits(limb_ty) > 0) {5824 if (int_info.signedness == .unsigned and self.regExtraBits(limb_ty) > 0) {
5810 const mask = @as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - limb_pl.data);5825 const mask = @as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - limb_bits);
5811 try self.genBinOpMir(.{ ._, .xor }, limb_ty, limb_mcv, .{ .immediate = mask });5826 try self.genBinOpMir(.{ ._, .xor }, limb_ty, limb_mcv, .{ .immediate = mask });
5812 } else try self.genUnOpMir(.{ ._, .not }, limb_ty, limb_mcv);5827 } else try self.genUnOpMir(.{ ._, .not }, limb_ty, limb_mcv);
5813 }5828 }
...@@ -5819,7 +5834,8 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:...@@ -5819,7 +5834,8 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
5819}5834}
58205835
5821fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void {5836fn 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));
5823 if (abi_size > 8) return self.fail("TODO implement {} for {}", .{5839 if (abi_size > 8) return self.fail("TODO implement {} for {}", .{
5824 mir_tag,5840 mir_tag,
5825 dst_ty.fmt(self.bin_file.options.module.?),5841 dst_ty.fmt(self.bin_file.options.module.?),
...@@ -5866,6 +5882,7 @@ fn genShiftBinOpMir(...@@ -5866,6 +5882,7 @@ fn genShiftBinOpMir(
5866 lhs_mcv: MCValue,5882 lhs_mcv: MCValue,
5867 shift_mcv: MCValue,5883 shift_mcv: MCValue,
5868) !void {5884) !void {
5885 const mod = self.bin_file.options.module.?;
5869 const rhs_mcv: MCValue = rhs: {5886 const rhs_mcv: MCValue = rhs: {
5870 switch (shift_mcv) {5887 switch (shift_mcv) {
5871 .immediate => |imm| switch (imm) {5888 .immediate => |imm| switch (imm) {
...@@ -5880,7 +5897,7 @@ fn genShiftBinOpMir(...@@ -5880,7 +5897,7 @@ fn genShiftBinOpMir(
5880 break :rhs .{ .register = .rcx };5897 break :rhs .{ .register = .rcx };
5881 };5898 };
58825899
5883 const abi_size = @intCast(u32, ty.abiSize(self.target.*));5900 const abi_size = @intCast(u32, ty.abiSize(mod));
5884 if (abi_size <= 8) {5901 if (abi_size <= 8) {
5885 switch (lhs_mcv) {5902 switch (lhs_mcv) {
5886 .register => |lhs_reg| switch (rhs_mcv) {5903 .register => |lhs_reg| switch (rhs_mcv) {
...@@ -6099,13 +6116,14 @@ fn genShiftBinOp(...@@ -6099,13 +6116,14 @@ fn genShiftBinOp(
6099 lhs_ty: Type,6116 lhs_ty: Type,
6100 rhs_ty: Type,6117 rhs_ty: Type,
6101) !MCValue {6118) !MCValue {
6102 if (lhs_ty.zigTypeTag() == .Vector) {6119 const mod = self.bin_file.options.module.?;
6120 if (lhs_ty.zigTypeTag(mod) == .Vector) {
6103 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});6121 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});
6104 }6122 }
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);
6109 if (lhs_abi_size > 16) {6127 if (lhs_abi_size > 16) {
6110 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});6128 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});
6111 }6129 }
...@@ -6136,7 +6154,7 @@ fn genShiftBinOp(...@@ -6136,7 +6154,7 @@ fn genShiftBinOp(
6136 break :dst dst_mcv;6154 break :dst dst_mcv;
6137 };6155 };
61386156
6139 const signedness = lhs_ty.intInfo(self.target.*).signedness;6157 const signedness = lhs_ty.intInfo(mod).signedness;
6140 try self.genShiftBinOpMir(switch (air_tag) {6158 try self.genShiftBinOpMir(switch (air_tag) {
6141 .shl, .shl_exact => switch (signedness) {6159 .shl, .shl_exact => switch (signedness) {
6142 .signed => .{ ._l, .sa },6160 .signed => .{ ._l, .sa },
...@@ -6163,11 +6181,12 @@ fn genMulDivBinOp(...@@ -6163,11 +6181,12 @@ fn genMulDivBinOp(
6163 lhs: MCValue,6181 lhs: MCValue,
6164 rhs: MCValue,6182 rhs: MCValue,
6165) !MCValue {6183) !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) {
6167 return self.fail("TODO implement genMulDivBinOp for {}", .{dst_ty.fmtDebug()});6186 return self.fail("TODO implement genMulDivBinOp for {}", .{dst_ty.fmtDebug()});
6168 }6187 }
6169 const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));6188 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));
6170 const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*));6189 const src_abi_size = @intCast(u32, src_ty.abiSize(mod));
6171 if (switch (tag) {6190 if (switch (tag) {
6172 else => unreachable,6191 else => unreachable,
6173 .mul, .mulwrap => dst_abi_size != src_abi_size and dst_abi_size != src_abi_size * 2,6192 .mul, .mulwrap => dst_abi_size != src_abi_size and dst_abi_size != src_abi_size * 2,
...@@ -6184,7 +6203,7 @@ fn genMulDivBinOp(...@@ -6184,7 +6203,7 @@ fn genMulDivBinOp(
6184 const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx });6203 const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx });
6185 defer for (reg_locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock);6204 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;
6188 switch (tag) {6207 switch (tag) {
6189 .mul,6208 .mul,
6190 .mulwrap,6209 .mulwrap,
...@@ -6338,13 +6357,14 @@ fn genBinOp(...@@ -6338,13 +6357,14 @@ fn genBinOp(
6338 lhs_air: Air.Inst.Ref,6357 lhs_air: Air.Inst.Ref,
6339 rhs_air: Air.Inst.Ref,6358 rhs_air: Air.Inst.Ref,
6340) !MCValue {6359) !MCValue {
6360 const mod = self.bin_file.options.module.?;
6341 const lhs_ty = self.air.typeOf(lhs_air);6361 const lhs_ty = self.air.typeOf(lhs_air);
6342 const rhs_ty = self.air.typeOf(rhs_air);6362 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
6345 const maybe_mask_reg = switch (air_tag) {6365 const maybe_mask_reg = switch (air_tag) {
6346 else => null,6366 else => null,
6347 .max, .min => if (lhs_ty.scalarType().isRuntimeFloat()) registerAlias(6367 .max, .min => if (lhs_ty.scalarType(mod).isRuntimeFloat()) registerAlias(
6348 if (!self.hasFeature(.avx) and self.hasFeature(.sse4_1)) mask: {6368 if (!self.hasFeature(.avx) and self.hasFeature(.sse4_1)) mask: {
6349 try self.register_manager.getReg(.xmm0, null);6369 try self.register_manager.getReg(.xmm0, null);
6350 break :mask .xmm0;6370 break :mask .xmm0;
...@@ -6384,7 +6404,7 @@ fn genBinOp(...@@ -6384,7 +6404,7 @@ fn genBinOp(
63846404
6385 else => false,6405 else => false,
6386 };6406 };
6387 const vec_op = switch (lhs_ty.zigTypeTag()) {6407 const vec_op = switch (lhs_ty.zigTypeTag(mod)) {
6388 else => false,6408 else => false,
6389 .Float, .Vector => true,6409 .Float, .Vector => true,
6390 };6410 };
...@@ -6456,7 +6476,7 @@ fn genBinOp(...@@ -6456,7 +6476,7 @@ fn genBinOp(
6456 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);6476 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
6457 defer self.register_manager.unlockReg(tmp_lock);6477 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);
6460 try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size });6480 try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size });
6461 try self.genBinOpMir(6481 try self.genBinOpMir(
6462 switch (air_tag) {6482 switch (air_tag) {
...@@ -6506,7 +6526,7 @@ fn genBinOp(...@@ -6506,7 +6526,7 @@ fn genBinOp(
65066526
6507 try self.genBinOpMir(.{ ._, .cmp }, lhs_ty, dst_mcv, mat_src_mcv);6527 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);
6510 const cc: Condition = switch (int_info.signedness) {6530 const cc: Condition = switch (int_info.signedness) {
6511 .unsigned => switch (air_tag) {6531 .unsigned => switch (air_tag) {
6512 .min => .a,6532 .min => .a,
...@@ -6520,7 +6540,7 @@ fn genBinOp(...@@ -6520,7 +6540,7 @@ fn genBinOp(
6520 },6540 },
6521 };6541 };
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);
6524 const tmp_reg = switch (dst_mcv) {6544 const tmp_reg = switch (dst_mcv) {
6525 .register => |reg| reg,6545 .register => |reg| reg,
6526 else => try self.copyToTmpRegister(lhs_ty, dst_mcv),6546 else => try self.copyToTmpRegister(lhs_ty, dst_mcv),
...@@ -6581,7 +6601,7 @@ fn genBinOp(...@@ -6581,7 +6601,7 @@ fn genBinOp(
6581 }6601 }
65826602
6583 const dst_reg = registerAlias(dst_mcv.getReg().?, abi_size);6603 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)) {
6585 else => unreachable,6605 else => unreachable,
6586 .Float => switch (lhs_ty.floatBits(self.target.*)) {6606 .Float => switch (lhs_ty.floatBits(self.target.*)) {
6587 16 => if (self.hasFeature(.f16c)) {6607 16 => if (self.hasFeature(.f16c)) {
...@@ -6657,9 +6677,9 @@ fn genBinOp(...@@ -6657,9 +6677,9 @@ fn genBinOp(
6657 80, 128 => null,6677 80, 128 => null,
6658 else => unreachable,6678 else => unreachable,
6659 },6679 },
6660 .Vector => switch (lhs_ty.childType().zigTypeTag()) {6680 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
6661 else => null,6681 else => null,
6662 .Int => switch (lhs_ty.childType().intInfo(self.target.*).bits) {6682 .Int => switch (lhs_ty.childType().intInfo(mod).bits) {
6663 8 => switch (lhs_ty.vectorLen()) {6683 8 => switch (lhs_ty.vectorLen()) {
6664 1...16 => switch (air_tag) {6684 1...16 => switch (air_tag) {
6665 .add,6685 .add,
...@@ -6671,7 +6691,7 @@ fn genBinOp(...@@ -6671,7 +6691,7 @@ fn genBinOp(
6671 .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" },6691 .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" },
6672 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },6692 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
6673 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },6693 .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) {
6675 .signed => if (self.hasFeature(.avx))6695 .signed => if (self.hasFeature(.avx))
6676 .{ .vp_b, .mins }6696 .{ .vp_b, .mins }
6677 else if (self.hasFeature(.sse4_1))6697 else if (self.hasFeature(.sse4_1))
...@@ -6685,7 +6705,7 @@ fn genBinOp(...@@ -6685,7 +6705,7 @@ fn genBinOp(
6685 else6705 else
6686 null,6706 null,
6687 },6707 },
6688 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {6708 .max => switch (lhs_ty.childType().intInfo(mod).signedness) {
6689 .signed => if (self.hasFeature(.avx))6709 .signed => if (self.hasFeature(.avx))
6690 .{ .vp_b, .maxs }6710 .{ .vp_b, .maxs }
6691 else if (self.hasFeature(.sse4_1))6711 else if (self.hasFeature(.sse4_1))
...@@ -6711,11 +6731,11 @@ fn genBinOp(...@@ -6711,11 +6731,11 @@ fn genBinOp(
6711 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,6731 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
6712 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,6732 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
6713 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,6733 .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) {
6715 .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .mins } else null,6735 .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .mins } else null,
6716 .unsigned => if (self.hasFeature(.avx)) .{ .vp_b, .minu } else null,6736 .unsigned => if (self.hasFeature(.avx)) .{ .vp_b, .minu } else null,
6717 },6737 },
6718 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {6738 .max => switch (lhs_ty.childType().intInfo(mod).signedness) {
6719 .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .maxs } else null,6739 .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .maxs } else null,
6720 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_b, .maxu } else null,6740 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_b, .maxu } else null,
6721 },6741 },
...@@ -6737,7 +6757,7 @@ fn genBinOp(...@@ -6737,7 +6757,7 @@ fn genBinOp(
6737 .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" },6757 .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" },
6738 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },6758 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
6739 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },6759 .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) {
6741 .signed => if (self.hasFeature(.avx))6761 .signed => if (self.hasFeature(.avx))
6742 .{ .vp_w, .mins }6762 .{ .vp_w, .mins }
6743 else6763 else
...@@ -6747,7 +6767,7 @@ fn genBinOp(...@@ -6747,7 +6767,7 @@ fn genBinOp(
6747 else6767 else
6748 .{ .p_w, .minu },6768 .{ .p_w, .minu },
6749 },6769 },
6750 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {6770 .max => switch (lhs_ty.childType().intInfo(mod).signedness) {
6751 .signed => if (self.hasFeature(.avx))6771 .signed => if (self.hasFeature(.avx))
6752 .{ .vp_w, .maxs }6772 .{ .vp_w, .maxs }
6753 else6773 else
...@@ -6772,11 +6792,11 @@ fn genBinOp(...@@ -6772,11 +6792,11 @@ fn genBinOp(
6772 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,6792 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
6773 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,6793 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
6774 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,6794 .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) {
6776 .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .mins } else null,6796 .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .mins } else null,
6777 .unsigned => if (self.hasFeature(.avx)) .{ .vp_w, .minu } else null,6797 .unsigned => if (self.hasFeature(.avx)) .{ .vp_w, .minu } else null,
6778 },6798 },
6779 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {6799 .max => switch (lhs_ty.childType().intInfo(mod).signedness) {
6780 .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .maxs } else null,6800 .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .maxs } else null,
6781 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_w, .maxu } else null,6801 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_w, .maxu } else null,
6782 },6802 },
...@@ -6803,7 +6823,7 @@ fn genBinOp(...@@ -6803,7 +6823,7 @@ fn genBinOp(
6803 .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" },6823 .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" },
6804 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },6824 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
6805 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },6825 .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) {
6807 .signed => if (self.hasFeature(.avx))6827 .signed => if (self.hasFeature(.avx))
6808 .{ .vp_d, .mins }6828 .{ .vp_d, .mins }
6809 else if (self.hasFeature(.sse4_1))6829 else if (self.hasFeature(.sse4_1))
...@@ -6817,7 +6837,7 @@ fn genBinOp(...@@ -6817,7 +6837,7 @@ fn genBinOp(
6817 else6837 else
6818 null,6838 null,
6819 },6839 },
6820 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {6840 .max => switch (lhs_ty.childType().intInfo(mod).signedness) {
6821 .signed => if (self.hasFeature(.avx))6841 .signed => if (self.hasFeature(.avx))
6822 .{ .vp_d, .maxs }6842 .{ .vp_d, .maxs }
6823 else if (self.hasFeature(.sse4_1))6843 else if (self.hasFeature(.sse4_1))
...@@ -6846,11 +6866,11 @@ fn genBinOp(...@@ -6846,11 +6866,11 @@ fn genBinOp(
6846 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,6866 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
6847 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,6867 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
6848 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,6868 .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) {
6850 .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .mins } else null,6870 .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .mins } else null,
6851 .unsigned => if (self.hasFeature(.avx)) .{ .vp_d, .minu } else null,6871 .unsigned => if (self.hasFeature(.avx)) .{ .vp_d, .minu } else null,
6852 },6872 },
6853 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {6873 .max => switch (lhs_ty.childType().intInfo(mod).signedness) {
6854 .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .maxs } else null,6874 .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .maxs } else null,
6855 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_d, .maxu } else null,6875 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_d, .maxu } else null,
6856 },6876 },
...@@ -7206,14 +7226,14 @@ fn genBinOp(...@@ -7206,14 +7226,14 @@ fn genBinOp(
7206 const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size);7226 const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size);
72077227
7208 try self.asmRegisterRegisterRegisterImmediate(7228 try self.asmRegisterRegisterRegisterImmediate(
7209 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {7229 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7210 .Float => switch (lhs_ty.floatBits(self.target.*)) {7230 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7211 32 => .{ .v_ss, .cmp },7231 32 => .{ .v_ss, .cmp },
7212 64 => .{ .v_sd, .cmp },7232 64 => .{ .v_sd, .cmp },
7213 16, 80, 128 => null,7233 16, 80, 128 => null,
7214 else => unreachable,7234 else => unreachable,
7215 },7235 },
7216 .Vector => switch (lhs_ty.childType().zigTypeTag()) {7236 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
7217 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {7237 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
7218 32 => switch (lhs_ty.vectorLen()) {7238 32 => switch (lhs_ty.vectorLen()) {
7219 1 => .{ .v_ss, .cmp },7239 1 => .{ .v_ss, .cmp },
...@@ -7240,14 +7260,14 @@ fn genBinOp(...@@ -7240,14 +7260,14 @@ fn genBinOp(
7240 Immediate.u(3), // unord7260 Immediate.u(3), // unord
7241 );7261 );
7242 try self.asmRegisterRegisterRegisterRegister(7262 try self.asmRegisterRegisterRegisterRegister(
7243 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {7263 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7244 .Float => switch (lhs_ty.floatBits(self.target.*)) {7264 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7245 32 => .{ .v_ps, .blendv },7265 32 => .{ .v_ps, .blendv },
7246 64 => .{ .v_pd, .blendv },7266 64 => .{ .v_pd, .blendv },
7247 16, 80, 128 => null,7267 16, 80, 128 => null,
7248 else => unreachable,7268 else => unreachable,
7249 },7269 },
7250 .Vector => switch (lhs_ty.childType().zigTypeTag()) {7270 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
7251 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {7271 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
7252 32 => switch (lhs_ty.vectorLen()) {7272 32 => switch (lhs_ty.vectorLen()) {
7253 1...8 => .{ .v_ps, .blendv },7273 1...8 => .{ .v_ps, .blendv },
...@@ -7274,14 +7294,14 @@ fn genBinOp(...@@ -7274,14 +7294,14 @@ fn genBinOp(
7274 } else {7294 } else {
7275 const has_blend = self.hasFeature(.sse4_1);7295 const has_blend = self.hasFeature(.sse4_1);
7276 try self.asmRegisterRegisterImmediate(7296 try self.asmRegisterRegisterImmediate(
7277 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {7297 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7278 .Float => switch (lhs_ty.floatBits(self.target.*)) {7298 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7279 32 => .{ ._ss, .cmp },7299 32 => .{ ._ss, .cmp },
7280 64 => .{ ._sd, .cmp },7300 64 => .{ ._sd, .cmp },
7281 16, 80, 128 => null,7301 16, 80, 128 => null,
7282 else => unreachable,7302 else => unreachable,
7283 },7303 },
7284 .Vector => switch (lhs_ty.childType().zigTypeTag()) {7304 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
7285 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {7305 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
7286 32 => switch (lhs_ty.vectorLen()) {7306 32 => switch (lhs_ty.vectorLen()) {
7287 1 => .{ ._ss, .cmp },7307 1 => .{ ._ss, .cmp },
...@@ -7307,14 +7327,14 @@ fn genBinOp(...@@ -7307,14 +7327,14 @@ fn genBinOp(
7307 Immediate.u(if (has_blend) 3 else 7), // unord, ord7327 Immediate.u(if (has_blend) 3 else 7), // unord, ord
7308 );7328 );
7309 if (has_blend) try self.asmRegisterRegisterRegister(7329 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)) {
7311 .Float => switch (lhs_ty.floatBits(self.target.*)) {7331 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7312 32 => .{ ._ps, .blendv },7332 32 => .{ ._ps, .blendv },
7313 64 => .{ ._pd, .blendv },7333 64 => .{ ._pd, .blendv },
7314 16, 80, 128 => null,7334 16, 80, 128 => null,
7315 else => unreachable,7335 else => unreachable,
7316 },7336 },
7317 .Vector => switch (lhs_ty.childType().zigTypeTag()) {7337 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
7318 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {7338 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
7319 32 => switch (lhs_ty.vectorLen()) {7339 32 => switch (lhs_ty.vectorLen()) {
7320 1...4 => .{ ._ps, .blendv },7340 1...4 => .{ ._ps, .blendv },
...@@ -7338,14 +7358,14 @@ fn genBinOp(...@@ -7338,14 +7358,14 @@ fn genBinOp(
7338 mask_reg,7358 mask_reg,
7339 ) else {7359 ) else {
7340 try self.asmRegisterRegister(7360 try self.asmRegisterRegister(
7341 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {7361 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7342 .Float => switch (lhs_ty.floatBits(self.target.*)) {7362 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7343 32 => .{ ._ps, .@"and" },7363 32 => .{ ._ps, .@"and" },
7344 64 => .{ ._pd, .@"and" },7364 64 => .{ ._pd, .@"and" },
7345 16, 80, 128 => null,7365 16, 80, 128 => null,
7346 else => unreachable,7366 else => unreachable,
7347 },7367 },
7348 .Vector => switch (lhs_ty.childType().zigTypeTag()) {7368 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
7349 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {7369 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
7350 32 => switch (lhs_ty.vectorLen()) {7370 32 => switch (lhs_ty.vectorLen()) {
7351 1...4 => .{ ._ps, .@"and" },7371 1...4 => .{ ._ps, .@"and" },
...@@ -7368,14 +7388,14 @@ fn genBinOp(...@@ -7368,14 +7388,14 @@ fn genBinOp(
7368 mask_reg,7388 mask_reg,
7369 );7389 );
7370 try self.asmRegisterRegister(7390 try self.asmRegisterRegister(
7371 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {7391 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7372 .Float => switch (lhs_ty.floatBits(self.target.*)) {7392 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7373 32 => .{ ._ps, .andn },7393 32 => .{ ._ps, .andn },
7374 64 => .{ ._pd, .andn },7394 64 => .{ ._pd, .andn },
7375 16, 80, 128 => null,7395 16, 80, 128 => null,
7376 else => unreachable,7396 else => unreachable,
7377 },7397 },
7378 .Vector => switch (lhs_ty.childType().zigTypeTag()) {7398 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
7379 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {7399 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
7380 32 => switch (lhs_ty.vectorLen()) {7400 32 => switch (lhs_ty.vectorLen()) {
7381 1...4 => .{ ._ps, .andn },7401 1...4 => .{ ._ps, .andn },
...@@ -7398,14 +7418,14 @@ fn genBinOp(...@@ -7398,14 +7418,14 @@ fn genBinOp(
7398 lhs_copy_reg.?,7418 lhs_copy_reg.?,
7399 );7419 );
7400 try self.asmRegisterRegister(7420 try self.asmRegisterRegister(
7401 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {7421 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7402 .Float => switch (lhs_ty.floatBits(self.target.*)) {7422 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7403 32 => .{ ._ps, .@"or" },7423 32 => .{ ._ps, .@"or" },
7404 64 => .{ ._pd, .@"or" },7424 64 => .{ ._pd, .@"or" },
7405 16, 80, 128 => null,7425 16, 80, 128 => null,
7406 else => unreachable,7426 else => unreachable,
7407 },7427 },
7408 .Vector => switch (lhs_ty.childType().zigTypeTag()) {7428 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
7409 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {7429 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
7410 32 => switch (lhs_ty.vectorLen()) {7430 32 => switch (lhs_ty.vectorLen()) {
7411 1...4 => .{ ._ps, .@"or" },7431 1...4 => .{ ._ps, .@"or" },
...@@ -7442,7 +7462,8 @@ fn genBinOpMir(...@@ -7442,7 +7462,8 @@ fn genBinOpMir(
7442 dst_mcv: MCValue,7462 dst_mcv: MCValue,
7443 src_mcv: MCValue,7463 src_mcv: MCValue,
7444) !void {7464) !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));
7446 switch (dst_mcv) {7467 switch (dst_mcv) {
7447 .none,7468 .none,
7448 .unreach,7469 .unreach,
...@@ -7640,7 +7661,7 @@ fn genBinOpMir(...@@ -7640,7 +7661,7 @@ fn genBinOpMir(
7640 defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock);7661 defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock);
76417662
7642 const ty_signedness =7663 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;
7644 const limb_ty = if (abi_size <= 8) ty else switch (ty_signedness) {7665 const limb_ty = if (abi_size <= 8) ty else switch (ty_signedness) {
7645 .signed => Type.usize,7666 .signed => Type.usize,
7646 .unsigned => Type.isize,7667 .unsigned => Type.isize,
...@@ -7796,7 +7817,8 @@ fn genBinOpMir(...@@ -7796,7 +7817,8 @@ fn genBinOpMir(
7796/// Performs multi-operand integer multiplication between dst_mcv and src_mcv, storing the result in dst_mcv.7817/// Performs multi-operand integer multiplication between dst_mcv and src_mcv, storing the result in dst_mcv.
7797/// Does not support byte-size operands.7818/// Does not support byte-size operands.
7798fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {7819fn 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));
7800 switch (dst_mcv) {7822 switch (dst_mcv) {
7801 .none,7823 .none,
7802 .unreach,7824 .unreach,
...@@ -8022,6 +8044,7 @@ fn airFence(self: *Self, inst: Air.Inst.Index) !void {...@@ -8022,6 +8044,7 @@ fn airFence(self: *Self, inst: Air.Inst.Index) !void {
8022}8044}
80238045
8024fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {8046fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {
8047 const mod = self.bin_file.options.module.?;
8025 if (modifier == .always_tail) return self.fail("TODO implement tail calls for x86_64", .{});8048 if (modifier == .always_tail) return self.fail("TODO implement tail calls for x86_64", .{});
8026 const pl_op = self.air.instructions.items(.data)[inst].pl_op;8049 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
8027 const callee = pl_op.operand;8050 const callee = pl_op.operand;
...@@ -8029,7 +8052,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8029,7 +8052,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
8029 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);8052 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
8030 const ty = self.air.typeOf(callee);8053 const ty = self.air.typeOf(callee);
80318054
8032 const fn_ty = switch (ty.zigTypeTag()) {8055 const fn_ty = switch (ty.zigTypeTag(mod)) {
8033 .Fn => ty,8056 .Fn => ty,
8034 .Pointer => ty.childType(),8057 .Pointer => ty.childType(),
8035 else => unreachable,8058 else => unreachable,
...@@ -8077,7 +8100,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8077,7 +8100,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
8077 .none, .unreach => null,8100 .none, .unreach => null,
8078 .indirect => |reg_off| lock: {8101 .indirect => |reg_off| lock: {
8079 const ret_ty = fn_ty.fnReturnType();8102 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));
8081 try self.genSetReg(reg_off.reg, Type.usize, .{8104 try self.genSetReg(reg_off.reg, Type.usize, .{
8082 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },8105 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },
8083 });8106 });
...@@ -8100,8 +8123,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8100,8 +8123,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
81008123
8101 // Due to incremental compilation, how function calls are generated depends8124 // Due to incremental compilation, how function calls are generated depends
8102 // on linking.8125 // on linking.
8103 const mod = self.bin_file.options.module.?;8126 if (self.air.value(callee, mod)) |func_value| {
8104 if (self.air.value(callee)) |func_value| {
8105 if (if (func_value.castTag(.function)) |func_payload|8127 if (if (func_value.castTag(.function)) |func_payload|
8106 func_payload.data.owner_decl8128 func_payload.data.owner_decl
8107 else if (func_value.castTag(.decl_ref)) |decl_ref_payload|8129 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...@@ -8178,7 +8200,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
8178 return self.fail("TODO implement calling bitcasted functions", .{});8200 return self.fail("TODO implement calling bitcasted functions", .{});
8179 }8201 }
8180 } else {8202 } else {
8181 assert(ty.zigTypeTag() == .Pointer);8203 assert(ty.zigTypeTag(mod) == .Pointer);
8182 const mcv = try self.resolveInst(callee);8204 const mcv = try self.resolveInst(callee);
8183 try self.genSetReg(.rax, Type.usize, mcv);8205 try self.genSetReg(.rax, Type.usize, mcv);
8184 try self.asmRegister(.{ ._, .call }, .rax);8206 try self.asmRegister(.{ ._, .call }, .rax);
...@@ -8234,6 +8256,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -8234,6 +8256,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
8234}8256}
82358257
8236fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {8258fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
8259 const mod = self.bin_file.options.module.?;
8237 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8260 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8238 const ty = self.air.typeOf(bin_op.lhs);8261 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 {...@@ -8255,9 +8278,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
8255 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);8278 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
82568279
8257 const result = MCValue{8280 const result = MCValue{
8258 .eflags = switch (ty.zigTypeTag()) {8281 .eflags = switch (ty.zigTypeTag(mod)) {
8259 else => result: {8282 else => result: {
8260 const abi_size = @intCast(u16, ty.abiSize(self.target.*));8283 const abi_size = @intCast(u16, ty.abiSize(mod));
8261 const may_flip: enum {8284 const may_flip: enum {
8262 may_flip,8285 may_flip,
8263 must_flip,8286 must_flip,
...@@ -8290,7 +8313,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -8290,7 +8313,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
8290 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);8313 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
82918314
8292 break :result Condition.fromCompareOperator(8315 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,
8294 result_op: {8317 result_op: {
8295 const flipped_op = if (flipped) op.reverse() else op;8318 const flipped_op = if (flipped) op.reverse() else op;
8296 if (abi_size > 8) switch (flipped_op) {8319 if (abi_size > 8) switch (flipped_op) {
...@@ -8404,7 +8427,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -8404,7 +8427,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
8404 try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp2_reg, tmp1_reg);8427 try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp2_reg, tmp1_reg);
8405 try self.genBinOpMir(.{ ._ss, .ucomi }, ty, tmp1_mcv, tmp2_mcv);8428 try self.genBinOpMir(.{ ._ss, .ucomi }, ty, tmp1_mcv, tmp2_mcv);
8406 } else return self.fail("TODO implement airCmp for {}", .{8429 } else return self.fail("TODO implement airCmp for {}", .{
8407 ty.fmt(self.bin_file.options.module.?),8430 ty.fmt(mod),
8408 }),8431 }),
8409 32 => try self.genBinOpMir(8432 32 => try self.genBinOpMir(
8410 .{ ._ss, .ucomi },8433 .{ ._ss, .ucomi },
...@@ -8419,7 +8442,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -8419,7 +8442,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
8419 src_mcv,8442 src_mcv,
8420 ),8443 ),
8421 else => return self.fail("TODO implement airCmp for {}", .{8444 else => return self.fail("TODO implement airCmp for {}", .{
8422 ty.fmt(self.bin_file.options.module.?),8445 ty.fmt(mod),
8423 }),8446 }),
8424 }8447 }
84258448
...@@ -8454,7 +8477,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -8454,7 +8477,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
8454 self.eflags_inst = inst;8477 self.eflags_inst = inst;
84558478
8456 const op_ty = self.air.typeOf(un_op);8479 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));
8458 const op_mcv = try self.resolveInst(un_op);8481 const op_mcv = try self.resolveInst(un_op);
8459 const dst_reg = switch (op_mcv) {8482 const dst_reg = switch (op_mcv) {
8460 .register => |reg| reg,8483 .register => |reg| reg,
...@@ -8573,7 +8596,8 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {...@@ -8573,7 +8596,8 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
8573}8596}
85748597
8575fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 {8598fn 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);
8577 switch (mcv) {8601 switch (mcv) {
8578 .eflags => |cc| {8602 .eflags => |cc| {
8579 // Here we map the opposites since the jump is to the false branch.8603 // 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 {...@@ -8646,6 +8670,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
8646}8670}
86478671
8648fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue {8672fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue {
8673 const mod = self.bin_file.options.module.?;
8649 switch (opt_mcv) {8674 switch (opt_mcv) {
8650 .register_overflow => |ro| return .{ .eflags = ro.eflags.negate() },8675 .register_overflow => |ro| return .{ .eflags = ro.eflags.negate() },
8651 else => {},8676 else => {},
...@@ -8658,10 +8683,10 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -8658,10 +8683,10 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
8658 const pl_ty = opt_ty.optionalChild(&pl_buf);8683 const pl_ty = opt_ty.optionalChild(&pl_buf);
86598684
8660 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;8685 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))
8662 .{ .off = 0, .ty = if (pl_ty.isSlice()) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }8687 .{ .off = 0, .ty = if (pl_ty.isSlice()) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }
8663 else8688 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
8666 switch (opt_mcv) {8691 switch (opt_mcv) {
8667 .none,8692 .none,
...@@ -8681,14 +8706,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -8681,14 +8706,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
86818706
8682 .register => |opt_reg| {8707 .register => |opt_reg| {
8683 if (some_info.off == 0) {8708 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));
8685 const alias_reg = registerAlias(opt_reg, some_abi_size);8710 const alias_reg = registerAlias(opt_reg, some_abi_size);
8686 assert(some_abi_size * 8 == alias_reg.bitSize());8711 assert(some_abi_size * 8 == alias_reg.bitSize());
8687 try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg);8712 try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg);
8688 return .{ .eflags = .z };8713 return .{ .eflags = .z };
8689 }8714 }
8690 assert(some_info.ty.tag() == .bool);8715 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));
8692 try self.asmRegisterImmediate(8717 try self.asmRegisterImmediate(
8693 .{ ._, .bt },8718 .{ ._, .bt },
8694 registerAlias(opt_reg, opt_abi_size),8719 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...@@ -8707,7 +8732,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
8707 defer self.register_manager.unlockReg(addr_reg_lock);8732 defer self.register_manager.unlockReg(addr_reg_lock);
87088733
8709 try self.genSetReg(addr_reg, Type.usize, opt_mcv.address());8734 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));
8711 try self.asmMemoryImmediate(8736 try self.asmMemoryImmediate(
8712 .{ ._, .cmp },8737 .{ ._, .cmp },
8713 Memory.sib(Memory.PtrSize.fromSize(some_abi_size), .{8738 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...@@ -8720,7 +8745,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
8720 },8745 },
87218746
8722 .indirect, .load_frame => {8747 .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));
8724 try self.asmMemoryImmediate(8749 try self.asmMemoryImmediate(
8725 .{ ._, .cmp },8750 .{ ._, .cmp },
8726 Memory.sib(Memory.PtrSize.fromSize(some_abi_size), switch (opt_mcv) {8751 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...@@ -8742,6 +8767,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
8742}8767}
87438768
8744fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue {8769fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue {
8770 const mod = self.bin_file.options.module.?;
8745 try self.spillEflagsIfOccupied();8771 try self.spillEflagsIfOccupied();
8746 self.eflags_inst = inst;8772 self.eflags_inst = inst;
87478773
...@@ -8750,10 +8776,10 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)...@@ -8750,10 +8776,10 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
8750 const pl_ty = opt_ty.optionalChild(&pl_buf);8776 const pl_ty = opt_ty.optionalChild(&pl_buf);
87518777
8752 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;8778 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))
8754 .{ .off = 0, .ty = if (pl_ty.isSlice()) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }8780 .{ .off = 0, .ty = if (pl_ty.isSlice()) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }
8755 else8781 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
8758 const ptr_reg = switch (ptr_mcv) {8784 const ptr_reg = switch (ptr_mcv) {
8759 .register => |reg| reg,8785 .register => |reg| reg,
...@@ -8762,7 +8788,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)...@@ -8762,7 +8788,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
8762 const ptr_lock = self.register_manager.lockReg(ptr_reg);8788 const ptr_lock = self.register_manager.lockReg(ptr_reg);
8763 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);8789 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));
8766 try self.asmMemoryImmediate(8792 try self.asmMemoryImmediate(
8767 .{ ._, .cmp },8793 .{ ._, .cmp },
8768 Memory.sib(Memory.PtrSize.fromSize(some_abi_size), .{8794 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)...@@ -8775,6 +8801,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
8775}8801}
87768802
8777fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue {8803fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue {
8804 const mod = self.bin_file.options.module.?;
8778 const err_type = ty.errorUnionSet();8805 const err_type = ty.errorUnionSet();
87798806
8780 if (err_type.errorSetIsEmpty()) {8807 if (err_type.errorSetIsEmpty()) {
...@@ -8786,7 +8813,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !...@@ -8786,7 +8813,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !
8786 self.eflags_inst = inst;8813 self.eflags_inst = inst;
8787 }8814 }
87888815
8789 const err_off = errUnionErrorOffset(ty.errorUnionPayload(), self.target.*);8816 const err_off = errUnionErrorOffset(ty.errorUnionPayload(), mod);
8790 switch (operand) {8817 switch (operand) {
8791 .register => |reg| {8818 .register => |reg| {
8792 const eu_lock = self.register_manager.lockReg(reg);8819 const eu_lock = self.register_manager.lockReg(reg);
...@@ -9088,12 +9115,13 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void {...@@ -9088,12 +9115,13 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void {
9088}9115}
90899116
9090fn airBr(self: *Self, inst: Air.Inst.Index) !void {9117fn airBr(self: *Self, inst: Air.Inst.Index) !void {
9118 const mod = self.bin_file.options.module.?;
9091 const br = self.air.instructions.items(.data)[inst].br;9119 const br = self.air.instructions.items(.data)[inst].br;
9092 const src_mcv = try self.resolveInst(br.operand);9120 const src_mcv = try self.resolveInst(br.operand);
90939121
9094 const block_ty = self.air.typeOfIndex(br.block_inst);9122 const block_ty = self.air.typeOfIndex(br.block_inst);
9095 const block_unused =9123 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);
9097 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;9125 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;
9098 const block_data = self.blocks.getPtr(br.block_inst).?;9126 const block_data = self.blocks.getPtr(br.block_inst).?;
9099 const first_br = block_data.relocs.items.len == 0;9127 const first_br = block_data.relocs.items.len == 0;
...@@ -9402,7 +9430,8 @@ const MoveStrategy = union(enum) {...@@ -9402,7 +9430,8 @@ const MoveStrategy = union(enum) {
9402 };9430 };
9403};9431};
9404fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy {9432fn 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)) {
9406 else => return .{ .move = .{ ._, .mov } },9435 else => return .{ .move = .{ ._, .mov } },
9407 .Float => switch (ty.floatBits(self.target.*)) {9436 .Float => switch (ty.floatBits(self.target.*)) {
9408 16 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{9437 16 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{
...@@ -9419,8 +9448,8 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy {...@@ -9419,8 +9448,8 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy {
9419 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },9448 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
9420 else => {},9449 else => {},
9421 },9450 },
9422 .Vector => switch (ty.childType().zigTypeTag()) {9451 .Vector => switch (ty.childType().zigTypeTag(mod)) {
9423 .Int => switch (ty.childType().intInfo(self.target.*).bits) {9452 .Int => switch (ty.childType().intInfo(mod).bits) {
9424 8 => switch (ty.vectorLen()) {9453 8 => switch (ty.vectorLen()) {
9425 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{9454 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{
9426 .insert = .{ .vp_b, .insr },9455 .insert = .{ .vp_b, .insr },
...@@ -9647,7 +9676,8 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError...@@ -9647,7 +9676,8 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
9647}9676}
96489677
9649fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerError!void {9678fn 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));
9651 if (abi_size * 8 > dst_reg.bitSize())9681 if (abi_size * 8 > dst_reg.bitSize())
9652 return self.fail("genSetReg called with a value larger than dst_reg", .{});9682 return self.fail("genSetReg called with a value larger than dst_reg", .{});
9653 switch (src_mcv) {9683 switch (src_mcv) {
...@@ -9730,7 +9760,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -9730,7 +9760,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
9730 .{ .register = try self.copyToTmpRegister(ty, src_mcv) },9760 .{ .register = try self.copyToTmpRegister(ty, src_mcv) },
9731 ),9761 ),
9732 .sse => try self.asmRegisterRegister(9762 .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)) {
9734 else => switch (abi_size) {9764 else => switch (abi_size) {
9735 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },9765 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },
9736 5...8 => if (self.hasFeature(.avx)) .{ .v_q, .mov } else .{ ._q, .mov },9766 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...@@ -9738,7 +9768,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
9738 17...32 => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else null,9768 17...32 => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else null,
9739 else => null,9769 else => null,
9740 },9770 },
9741 .Float => switch (ty.scalarType().floatBits(self.target.*)) {9771 .Float => switch (ty.scalarType(mod).floatBits(self.target.*)) {
9742 16, 128 => switch (abi_size) {9772 16, 128 => switch (abi_size) {
9743 2...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },9773 2...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },
9744 5...8 => if (self.hasFeature(.avx)) .{ .v_q, .mov } else .{ ._q, .mov },9774 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...@@ -9789,7 +9819,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
9789 .indirect => try self.moveStrategy(ty, false),9819 .indirect => try self.moveStrategy(ty, false),
9790 .load_frame => |frame_addr| try self.moveStrategy(9820 .load_frame => |frame_addr| try self.moveStrategy(
9791 ty,9821 ty,
9792 self.getFrameAddrAlignment(frame_addr) >= ty.abiAlignment(self.target.*),9822 self.getFrameAddrAlignment(frame_addr) >= ty.abiAlignment(mod),
9793 ),9823 ),
9794 .lea_frame => .{ .move = .{ ._, .lea } },9824 .lea_frame => .{ .move = .{ ._, .lea } },
9795 else => unreachable,9825 else => unreachable,
...@@ -9821,7 +9851,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -9821,7 +9851,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
9821 switch (try self.moveStrategy(ty, mem.isAlignedGeneric(9851 switch (try self.moveStrategy(ty, mem.isAlignedGeneric(
9822 u32,9852 u32,
9823 @bitCast(u32, small_addr),9853 @bitCast(u32, small_addr),
9824 ty.abiAlignment(self.target.*),9854 ty.abiAlignment(mod),
9825 ))) {9855 ))) {
9826 .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem),9856 .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem),
9827 .insert_extract => |ie| try self.asmRegisterMemoryImmediate(9857 .insert_extract => |ie| try self.asmRegisterMemoryImmediate(
...@@ -9839,7 +9869,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -9839,7 +9869,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
9839 ),9869 ),
9840 }9870 }
9841 },9871 },
9842 .load_direct => |sym_index| switch (ty.zigTypeTag()) {9872 .load_direct => |sym_index| switch (ty.zigTypeTag(mod)) {
9843 else => {9873 else => {
9844 const atom_index = try self.owner.getSymbolIndex(self);9874 const atom_index = try self.owner.getSymbolIndex(self);
9845 _ = try self.addInst(.{9875 _ = try self.addInst(.{
...@@ -9933,7 +9963,8 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -9933,7 +9963,8 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
9933}9963}
99349964
9935fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCValue) InnerError!void {9965fn 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));
9937 const dst_ptr_mcv: MCValue = switch (base) {9968 const dst_ptr_mcv: MCValue = switch (base) {
9938 .none => .{ .immediate = @bitCast(u64, @as(i64, disp)) },9969 .none => .{ .immediate = @bitCast(u64, @as(i64, disp)) },
9939 .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } },9970 .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...@@ -9945,7 +9976,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
9945 try self.genInlineMemset(dst_ptr_mcv, .{ .immediate = 0xaa }, .{ .immediate = abi_size }),9976 try self.genInlineMemset(dst_ptr_mcv, .{ .immediate = 0xaa }, .{ .immediate = abi_size }),
9946 .immediate => |imm| switch (abi_size) {9977 .immediate => |imm| switch (abi_size) {
9947 1, 2, 4 => {9978 1, 2, 4 => {
9948 const immediate = if (ty.isSignedInt())9979 const immediate = if (ty.isSignedInt(mod))
9949 Immediate.s(@truncate(i32, @bitCast(i64, imm)))9980 Immediate.s(@truncate(i32, @bitCast(i64, imm)))
9950 else9981 else
9951 Immediate.u(@intCast(u32, imm));9982 Immediate.u(@intCast(u32, imm));
...@@ -9967,7 +9998,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal...@@ -9967,7 +9998,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
9967 while (offset < abi_size) : (offset += 4) try self.asmMemoryImmediate(9998 while (offset < abi_size) : (offset += 4) try self.asmMemoryImmediate(
9968 .{ ._, .mov },9999 .{ ._, .mov },
9969 Memory.sib(.dword, .{ .base = base, .disp = disp + offset }),10000 Memory.sib(.dword, .{ .base = base, .disp = disp + offset }),
9970 if (ty.isSignedInt())10001 if (ty.isSignedInt(mod))
9971 Immediate.s(@truncate(10002 Immediate.s(@truncate(
9972 i32,10003 i32,
9973 @bitCast(i64, imm) >> (math.cast(u6, offset * 8) orelse 63),10004 @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...@@ -9991,19 +10022,19 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
9991 .none => mem.isAlignedGeneric(10022 .none => mem.isAlignedGeneric(
9992 u32,10023 u32,
9993 @bitCast(u32, disp),10024 @bitCast(u32, disp),
9994 ty.abiAlignment(self.target.*),10025 ty.abiAlignment(mod),
9995 ),10026 ),
9996 .reg => |reg| switch (reg) {10027 .reg => |reg| switch (reg) {
9997 .es, .cs, .ss, .ds => mem.isAlignedGeneric(10028 .es, .cs, .ss, .ds => mem.isAlignedGeneric(
9998 u32,10029 u32,
9999 @bitCast(u32, disp),10030 @bitCast(u32, disp),
10000 ty.abiAlignment(self.target.*),10031 ty.abiAlignment(mod),
10001 ),10032 ),
10002 else => false,10033 else => false,
10003 },10034 },
10004 .frame => |frame_index| self.getFrameAddrAlignment(10035 .frame => |frame_index| self.getFrameAddrAlignment(
10005 .{ .index = frame_index, .off = disp },10036 .{ .index = frame_index, .off = disp },
10006 ) >= ty.abiAlignment(self.target.*),10037 ) >= ty.abiAlignment(mod),
10007 })) {10038 })) {
10008 .move => |tag| try self.asmMemoryRegister(tag, dst_mem, src_alias),10039 .move => |tag| try self.asmMemoryRegister(tag, dst_mem, src_alias),
10009 .insert_extract, .vex_insert_extract => |ie| try self.asmMemoryRegisterImmediate(10040 .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...@@ -10017,13 +10048,13 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
10017 .register_overflow => |ro| {10048 .register_overflow => |ro| {
10018 try self.genSetMem(10049 try self.genSetMem(
10019 base,10050 base,
10020 disp + @intCast(i32, ty.structFieldOffset(0, self.target.*)),10051 disp + @intCast(i32, ty.structFieldOffset(0, mod)),
10021 ty.structFieldType(0),10052 ty.structFieldType(0),
10022 .{ .register = ro.reg },10053 .{ .register = ro.reg },
10023 );10054 );
10024 try self.genSetMem(10055 try self.genSetMem(
10025 base,10056 base,
10026 disp + @intCast(i32, ty.structFieldOffset(1, self.target.*)),10057 disp + @intCast(i32, ty.structFieldOffset(1, mod)),
10027 ty.structFieldType(1),10058 ty.structFieldType(1),
10028 .{ .eflags = ro.eflags },10059 .{ .eflags = ro.eflags },
10029 );10060 );
...@@ -10146,13 +10177,14 @@ fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -10146,13 +10177,14 @@ fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void {
10146}10177}
1014710178
10148fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {10179fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
10180 const mod = self.bin_file.options.module.?;
10149 const ty_op = self.air.instructions.items(.data)[inst].ty_op;10181 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
10150 const dst_ty = self.air.typeOfIndex(inst);10182 const dst_ty = self.air.typeOfIndex(inst);
10151 const src_ty = self.air.typeOf(ty_op.operand);10183 const src_ty = self.air.typeOf(ty_op.operand);
1015210184
10153 const result = result: {10185 const result = result: {
10154 const dst_rc = regClassForType(dst_ty);10186 const dst_rc = regClassForType(dst_ty, mod);
10155 const src_rc = regClassForType(src_ty);10187 const src_rc = regClassForType(src_ty, mod);
10156 const src_mcv = try self.resolveInst(ty_op.operand);10188 const src_mcv = try self.resolveInst(ty_op.operand);
1015710189
10158 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;10190 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 {...@@ -10172,13 +10204,13 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
10172 };10204 };
1017310205
10174 const dst_signedness =10206 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;
10176 const src_signedness =10208 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;
10178 if (dst_signedness == src_signedness) break :result dst_mcv;10210 if (dst_signedness == src_signedness) break :result dst_mcv;
1017910211
10180 const abi_size = @intCast(u16, dst_ty.abiSize(self.target.*));10212 const abi_size = @intCast(u16, dst_ty.abiSize(mod));
10181 const bit_size = @intCast(u16, dst_ty.bitSize(self.target.*));10213 const bit_size = @intCast(u16, dst_ty.bitSize(mod));
10182 if (abi_size * 8 <= bit_size) break :result dst_mcv;10214 if (abi_size * 8 <= bit_size) break :result dst_mcv;
1018310215
10184 const dst_limbs_len = math.divCeil(i32, bit_size, 64) catch unreachable;10216 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 {...@@ -10192,14 +10224,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
10192 const high_lock = self.register_manager.lockReg(high_reg);10224 const high_lock = self.register_manager.lockReg(high_reg);
10193 defer if (high_lock) |lock| self.register_manager.unlockReg(lock);10225 defer if (high_lock) |lock| self.register_manager.unlockReg(lock);
1019410226
10195 var high_pl = Type.Payload.Bits{10227 const high_ty = try mod.intType(dst_signedness, bit_size % 64);
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);
1020310228
10204 try self.truncateRegister(high_ty, high_reg);10229 try self.truncateRegister(high_ty, high_reg);
10205 if (!dst_mcv.isRegister()) try self.genCopy(10230 if (!dst_mcv.isRegister()) try self.genCopy(
...@@ -10213,6 +10238,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -10213,6 +10238,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
10213}10238}
1021410239
10215fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {10240fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
10241 const mod = self.bin_file.options.module.?;
10216 const ty_op = self.air.instructions.items(.data)[inst].ty_op;10242 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1021710243
10218 const slice_ty = self.air.typeOfIndex(inst);10244 const slice_ty = self.air.typeOfIndex(inst);
...@@ -10221,11 +10247,11 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -10221,11 +10247,11 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
10221 const array_ty = ptr_ty.childType();10247 const array_ty = ptr_ty.childType();
10222 const array_len = array_ty.arrayLen();10248 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));
10225 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);10251 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);
10226 try self.genSetMem(10252 try self.genSetMem(
10227 .{ .frame = frame_index },10253 .{ .frame = frame_index },
10228 @intCast(i32, ptr_ty.abiSize(self.target.*)),10254 @intCast(i32, ptr_ty.abiSize(mod)),
10229 Type.usize,10255 Type.usize,
10230 .{ .immediate = array_len },10256 .{ .immediate = array_len },
10231 );10257 );
...@@ -10235,12 +10261,13 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -10235,12 +10261,13 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
10235}10261}
1023610262
10237fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {10263fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
10264 const mod = self.bin_file.options.module.?;
10238 const ty_op = self.air.instructions.items(.data)[inst].ty_op;10265 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1023910266
10240 const src_ty = self.air.typeOf(ty_op.operand);10267 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));
10242 const src_signedness =10269 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;
10244 const dst_ty = self.air.typeOfIndex(inst);10271 const dst_ty = self.air.typeOfIndex(inst);
1024510272
10246 const src_size = math.divCeil(u32, @max(switch (src_signedness) {10273 const src_size = math.divCeil(u32, @max(switch (src_signedness) {
...@@ -10248,7 +10275,7 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {...@@ -10248,7 +10275,7 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
10248 .unsigned => src_bits + 1,10275 .unsigned => src_bits + 1,
10249 }, 32), 8) catch unreachable;10276 }, 32), 8) catch unreachable;
10250 if (src_size > 8) return self.fail("TODO implement airIntToFloat from {} to {}", .{10277 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),
10252 });10279 });
1025310280
10254 const src_mcv = try self.resolveInst(ty_op.operand);10281 const src_mcv = try self.resolveInst(ty_op.operand);
...@@ -10261,12 +10288,12 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {...@@ -10261,12 +10288,12 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
1026110288
10262 if (src_bits < src_size * 8) try self.truncateRegister(src_ty, src_reg);10289 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));
10265 const dst_mcv = MCValue{ .register = dst_reg };10292 const dst_mcv = MCValue{ .register = dst_reg };
10266 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);10293 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
10267 defer self.register_manager.unlockReg(dst_lock);10294 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)) {
10270 .Float => switch (dst_ty.floatBits(self.target.*)) {10297 .Float => switch (dst_ty.floatBits(self.target.*)) {
10271 32 => if (self.hasFeature(.avx)) .{ .v_ss, .cvtsi2 } else .{ ._ss, .cvtsi2 },10298 32 => if (self.hasFeature(.avx)) .{ .v_ss, .cvtsi2 } else .{ ._ss, .cvtsi2 },
10272 64 => if (self.hasFeature(.avx)) .{ .v_sd, .cvtsi2 } else .{ ._sd, .cvtsi2 },10299 64 => if (self.hasFeature(.avx)) .{ .v_sd, .cvtsi2 } else .{ ._sd, .cvtsi2 },
...@@ -10275,7 +10302,7 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {...@@ -10275,7 +10302,7 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
10275 },10302 },
10276 else => null,10303 else => null,
10277 })) |tag| tag else return self.fail("TODO implement airIntToFloat from {} to {}", .{10304 })) |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),
10279 });10306 });
10280 const dst_alias = dst_reg.to128();10307 const dst_alias = dst_reg.to128();
10281 const src_alias = registerAlias(src_reg, src_size);10308 const src_alias = registerAlias(src_reg, src_size);
...@@ -10288,13 +10315,14 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {...@@ -10288,13 +10315,14 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
10288}10315}
1028910316
10290fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {10317fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {
10318 const mod = self.bin_file.options.module.?;
10291 const ty_op = self.air.instructions.items(.data)[inst].ty_op;10319 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1029210320
10293 const src_ty = self.air.typeOf(ty_op.operand);10321 const src_ty = self.air.typeOf(ty_op.operand);
10294 const dst_ty = self.air.typeOfIndex(inst);10322 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));
10296 const dst_signedness =10324 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
10299 const dst_size = math.divCeil(u32, @max(switch (dst_signedness) {10327 const dst_size = math.divCeil(u32, @max(switch (dst_signedness) {
10300 .signed => dst_bits,10328 .signed => dst_bits,
...@@ -10312,13 +10340,13 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -10312,13 +10340,13 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {
10312 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);10340 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
10313 defer self.register_manager.unlockReg(src_lock);10341 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));
10316 const dst_mcv = MCValue{ .register = dst_reg };10344 const dst_mcv = MCValue{ .register = dst_reg };
10317 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);10345 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
10318 defer self.register_manager.unlockReg(dst_lock);10346 defer self.register_manager.unlockReg(dst_lock);
1031910347
10320 try self.asmRegisterRegister(10348 try self.asmRegisterRegister(
10321 if (@as(?Mir.Inst.FixedTag, switch (src_ty.zigTypeTag()) {10349 if (@as(?Mir.Inst.FixedTag, switch (src_ty.zigTypeTag(mod)) {
10322 .Float => switch (src_ty.floatBits(self.target.*)) {10350 .Float => switch (src_ty.floatBits(self.target.*)) {
10323 32 => if (self.hasFeature(.avx)) .{ .v_, .cvttss2si } else .{ ._, .cvttss2si },10351 32 => if (self.hasFeature(.avx)) .{ .v_, .cvttss2si } else .{ ._, .cvttss2si },
10324 64 => if (self.hasFeature(.avx)) .{ .v_, .cvttsd2si } else .{ ._, .cvttsd2si },10352 64 => if (self.hasFeature(.avx)) .{ .v_, .cvttsd2si } else .{ ._, .cvttsd2si },
...@@ -10339,12 +10367,13 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -10339,12 +10367,13 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {
10339}10367}
1034010368
10341fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {10369fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
10370 const mod = self.bin_file.options.module.?;
10342 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;10371 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
10343 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;10372 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
1034410373
10345 const ptr_ty = self.air.typeOf(extra.ptr);10374 const ptr_ty = self.air.typeOf(extra.ptr);
10346 const val_ty = self.air.typeOf(extra.expected_value);10375 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
10349 try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });10378 try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });
10350 const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx });10379 const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx });
...@@ -10433,6 +10462,7 @@ fn atomicOp(...@@ -10433,6 +10462,7 @@ fn atomicOp(
10433 rmw_op: ?std.builtin.AtomicRmwOp,10462 rmw_op: ?std.builtin.AtomicRmwOp,
10434 order: std.builtin.AtomicOrder,10463 order: std.builtin.AtomicOrder,
10435) InnerError!MCValue {10464) InnerError!MCValue {
10465 const mod = self.bin_file.options.module.?;
10436 const ptr_lock = switch (ptr_mcv) {10466 const ptr_lock = switch (ptr_mcv) {
10437 .register => |reg| self.register_manager.lockReg(reg),10467 .register => |reg| self.register_manager.lockReg(reg),
10438 else => null,10468 else => null,
...@@ -10445,7 +10475,7 @@ fn atomicOp(...@@ -10445,7 +10475,7 @@ fn atomicOp(
10445 };10475 };
10446 defer if (val_lock) |lock| self.register_manager.unlockReg(lock);10476 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));
10449 const ptr_size = Memory.PtrSize.fromSize(val_abi_size);10479 const ptr_size = Memory.PtrSize.fromSize(val_abi_size);
10450 const ptr_mem = switch (ptr_mcv) {10480 const ptr_mem = switch (ptr_mcv) {
10451 .immediate, .register, .register_offset, .lea_frame => ptr_mcv.deref().mem(ptr_size),10481 .immediate, .register, .register_offset, .lea_frame => ptr_mcv.deref().mem(ptr_size),
...@@ -10539,8 +10569,8 @@ fn atomicOp(...@@ -10539,8 +10569,8 @@ fn atomicOp(
10539 .Or => try self.genBinOpMir(.{ ._, .@"or" }, val_ty, tmp_mcv, val_mcv),10569 .Or => try self.genBinOpMir(.{ ._, .@"or" }, val_ty, tmp_mcv, val_mcv),
10540 .Xor => try self.genBinOpMir(.{ ._, .xor }, val_ty, tmp_mcv, val_mcv),10570 .Xor => try self.genBinOpMir(.{ ._, .xor }, val_ty, tmp_mcv, val_mcv),
10541 .Min, .Max => {10571 .Min, .Max => {
10542 const cc: Condition = switch (if (val_ty.isAbiInt())10572 const cc: Condition = switch (if (val_ty.isAbiInt(mod))
10543 val_ty.intInfo(self.target.*).signedness10573 val_ty.intInfo(mod).signedness
10544 else10574 else
10545 .unsigned) {10575 .unsigned) {
10546 .unsigned => switch (op) {10576 .unsigned => switch (op) {
...@@ -10728,6 +10758,7 @@ fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOr...@@ -10728,6 +10758,7 @@ fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOr
10728}10758}
1072910759
10730fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {10760fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
10761 const mod = self.bin_file.options.module.?;
10731 if (safety) {10762 if (safety) {
10732 // TODO if the value is undef, write 0xaa bytes to dest10763 // TODO if the value is undef, write 0xaa bytes to dest
10733 } else {10764 } else {
...@@ -10752,7 +10783,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -10752,7 +10783,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
10752 };10783 };
10753 defer if (src_val_lock) |lock| self.register_manager.unlockReg(lock);10784 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
10757 if (elem_abi_size == 1) {10788 if (elem_abi_size == 1) {
10758 const ptr: MCValue = switch (dst_ptr_ty.ptrSize()) {10789 const ptr: MCValue = switch (dst_ptr_ty.ptrSize()) {
...@@ -10897,8 +10928,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {...@@ -10897,8 +10928,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
10897 // We need a properly aligned and sized call frame to be able to call this function.10928 // We need a properly aligned and sized call frame to be able to call this function.
10898 {10929 {
10899 const needed_call_frame = FrameAlloc.init(.{10930 const needed_call_frame = FrameAlloc.init(.{
10900 .size = inst_ty.abiSize(self.target.*),10931 .size = inst_ty.abiSize(mod),
10901 .alignment = inst_ty.abiAlignment(self.target.*),10932 .alignment = inst_ty.abiAlignment(mod),
10902 });10933 });
10903 const frame_allocs_slice = self.frame_allocs.slice();10934 const frame_allocs_slice = self.frame_allocs.slice();
10904 const stack_frame_size =10935 const stack_frame_size =
...@@ -11013,14 +11044,15 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {...@@ -11013,14 +11044,15 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
11013}11044}
1101411045
11015fn airSplat(self: *Self, inst: Air.Inst.Index) !void {11046fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
11047 const mod = self.bin_file.options.module.?;
11016 const ty_op = self.air.instructions.items(.data)[inst].ty_op;11048 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
11017 const vector_ty = self.air.typeOfIndex(inst);11049 const vector_ty = self.air.typeOfIndex(inst);
11018 const dst_rc = regClassForType(vector_ty);11050 const dst_rc = regClassForType(vector_ty, mod);
11019 const scalar_ty = vector_ty.scalarType();11051 const scalar_ty = vector_ty.scalarType(mod);
1102011052
11021 const src_mcv = try self.resolveInst(ty_op.operand);11053 const src_mcv = try self.resolveInst(ty_op.operand);
11022 const result: MCValue = result: {11054 const result: MCValue = result: {
11023 switch (scalar_ty.zigTypeTag()) {11055 switch (scalar_ty.zigTypeTag(mod)) {
11024 else => {},11056 else => {},
11025 .Float => switch (scalar_ty.floatBits(self.target.*)) {11057 .Float => switch (scalar_ty.floatBits(self.target.*)) {
11026 32 => switch (vector_ty.vectorLen()) {11058 32 => switch (vector_ty.vectorLen()) {
...@@ -11233,36 +11265,37 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {...@@ -11233,36 +11265,37 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
11233}11265}
1123411266
11235fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {11267fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11268 const mod = self.bin_file.options.module.?;
11236 const result_ty = self.air.typeOfIndex(inst);11269 const result_ty = self.air.typeOfIndex(inst);
11237 const len = @intCast(usize, result_ty.arrayLen());11270 const len = @intCast(usize, result_ty.arrayLen());
11238 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;11271 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
11239 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);11272 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
11240 const result: MCValue = result: {11273 const result: MCValue = result: {
11241 switch (result_ty.zigTypeTag()) {11274 switch (result_ty.zigTypeTag(mod)) {
11242 .Struct => {11275 .Struct => {
11243 const frame_index =11276 const frame_index =
11244 try self.allocFrameIndex(FrameAlloc.initType(result_ty, self.target.*));11277 try self.allocFrameIndex(FrameAlloc.initType(result_ty, mod));
11245 if (result_ty.containerLayout() == .Packed) {11278 if (result_ty.containerLayout() == .Packed) {
11246 const struct_obj = result_ty.castTag(.@"struct").?.data;11279 const struct_obj = result_ty.castTag(.@"struct").?.data;
11247 try self.genInlineMemset(11280 try self.genInlineMemset(
11248 .{ .lea_frame = .{ .index = frame_index } },11281 .{ .lea_frame = .{ .index = frame_index } },
11249 .{ .immediate = 0 },11282 .{ .immediate = 0 },
11250 .{ .immediate = result_ty.abiSize(self.target.*) },11283 .{ .immediate = result_ty.abiSize(mod) },
11251 );11284 );
11252 for (elements, 0..) |elem, elem_i| {11285 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
11255 const elem_ty = result_ty.structFieldType(elem_i);11288 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));
11257 if (elem_bit_size > 64) {11290 if (elem_bit_size > 64) {
11258 return self.fail(11291 return self.fail(
11259 "TODO airAggregateInit implement packed structs with large fields",11292 "TODO airAggregateInit implement packed structs with large fields",
11260 .{},11293 .{},
11261 );11294 );
11262 }11295 }
11263 const elem_abi_size = @intCast(u32, elem_ty.abiSize(self.target.*));11296 const elem_abi_size = @intCast(u32, elem_ty.abiSize(mod));
11264 const elem_abi_bits = elem_abi_size * 8;11297 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);
11266 const elem_byte_off = @intCast(i32, elem_off / elem_abi_bits * elem_abi_size);11299 const elem_byte_off = @intCast(i32, elem_off / elem_abi_bits * elem_abi_size);
11267 const elem_bit_off = elem_off % elem_abi_bits;11300 const elem_bit_off = elem_off % elem_abi_bits;
11268 const elem_mcv = try self.resolveInst(elem);11301 const elem_mcv = try self.resolveInst(elem);
...@@ -11322,10 +11355,10 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11322,10 +11355,10 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11322 }11355 }
11323 }11356 }
11324 } else for (elements, 0..) |elem, elem_i| {11357 } 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
11327 const elem_ty = result_ty.structFieldType(elem_i);11360 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));
11329 const elem_mcv = try self.resolveInst(elem);11362 const elem_mcv = try self.resolveInst(elem);
11330 const mat_elem_mcv = switch (elem_mcv) {11363 const mat_elem_mcv = switch (elem_mcv) {
11331 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },11364 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },
...@@ -11337,9 +11370,9 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11337,9 +11370,9 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11337 },11370 },
11338 .Array => {11371 .Array => {
11339 const frame_index =11372 const frame_index =
11340 try self.allocFrameIndex(FrameAlloc.initType(result_ty, self.target.*));11373 try self.allocFrameIndex(FrameAlloc.initType(result_ty, mod));
11341 const elem_ty = result_ty.childType();11374 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
11344 for (elements, 0..) |elem, elem_i| {11377 for (elements, 0..) |elem, elem_i| {
11345 const elem_mcv = try self.resolveInst(elem);11378 const elem_mcv = try self.resolveInst(elem);
...@@ -11374,11 +11407,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11374,11 +11407,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11374}11407}
1137511408
11376fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {11409fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
11410 const mod = self.bin_file.options.module.?;
11377 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;11411 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
11378 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;11412 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
11379 const result: MCValue = result: {11413 const result: MCValue = result: {
11380 const union_ty = self.air.typeOfIndex(inst);11414 const union_ty = self.air.typeOfIndex(inst);
11381 const layout = union_ty.unionGetLayout(self.target.*);11415 const layout = union_ty.unionGetLayout(mod);
1138211416
11383 const src_ty = self.air.typeOf(extra.init);11417 const src_ty = self.air.typeOf(extra.init);
11384 const src_mcv = try self.resolveInst(extra.init);11418 const src_mcv = try self.resolveInst(extra.init);
...@@ -11400,7 +11434,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11400,7 +11434,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
11400 const tag_val = Value.initPayload(&tag_pl.base);11434 const tag_val = Value.initPayload(&tag_pl.base);
11401 var tag_int_pl: Value.Payload.U64 = undefined;11435 var tag_int_pl: Value.Payload.U64 = undefined;
11402 const tag_int_val = tag_val.enumToInt(tag_ty, &tag_int_pl);11436 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);
11404 const tag_off = if (layout.tag_align < layout.payload_align)11438 const tag_off = if (layout.tag_align < layout.payload_align)
11405 @intCast(i32, layout.payload_size)11439 @intCast(i32, layout.payload_size)
11406 else11440 else
...@@ -11424,6 +11458,7 @@ fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {...@@ -11424,6 +11458,7 @@ fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
11424}11458}
1142511459
11426fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {11460fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
11461 const mod = self.bin_file.options.module.?;
11427 const pl_op = self.air.instructions.items(.data)[inst].pl_op;11462 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
11428 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;11463 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
11429 const ty = self.air.typeOfIndex(inst);11464 const ty = self.air.typeOfIndex(inst);
...@@ -11466,14 +11501,14 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -11466,14 +11501,14 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
11466 const mir_tag = if (@as(11501 const mir_tag = if (@as(
11467 ?Mir.Inst.FixedTag,11502 ?Mir.Inst.FixedTag,
11468 if (mem.eql(u2, &order, &.{ 1, 3, 2 }) or mem.eql(u2, &order, &.{ 3, 1, 2 }))11503 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)) {
11470 .Float => switch (ty.floatBits(self.target.*)) {11505 .Float => switch (ty.floatBits(self.target.*)) {
11471 32 => .{ .v_ss, .fmadd132 },11506 32 => .{ .v_ss, .fmadd132 },
11472 64 => .{ .v_sd, .fmadd132 },11507 64 => .{ .v_sd, .fmadd132 },
11473 16, 80, 128 => null,11508 16, 80, 128 => null,
11474 else => unreachable,11509 else => unreachable,
11475 },11510 },
11476 .Vector => switch (ty.childType().zigTypeTag()) {11511 .Vector => switch (ty.childType().zigTypeTag(mod)) {
11477 .Float => switch (ty.childType().floatBits(self.target.*)) {11512 .Float => switch (ty.childType().floatBits(self.target.*)) {
11478 32 => switch (ty.vectorLen()) {11513 32 => switch (ty.vectorLen()) {
11479 1 => .{ .v_ss, .fmadd132 },11514 1 => .{ .v_ss, .fmadd132 },
...@@ -11493,14 +11528,14 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -11493,14 +11528,14 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
11493 else => unreachable,11528 else => unreachable,
11494 }11529 }
11495 else if (mem.eql(u2, &order, &.{ 2, 1, 3 }) or mem.eql(u2, &order, &.{ 1, 2, 3 }))11530 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)) {
11497 .Float => switch (ty.floatBits(self.target.*)) {11532 .Float => switch (ty.floatBits(self.target.*)) {
11498 32 => .{ .v_ss, .fmadd213 },11533 32 => .{ .v_ss, .fmadd213 },
11499 64 => .{ .v_sd, .fmadd213 },11534 64 => .{ .v_sd, .fmadd213 },
11500 16, 80, 128 => null,11535 16, 80, 128 => null,
11501 else => unreachable,11536 else => unreachable,
11502 },11537 },
11503 .Vector => switch (ty.childType().zigTypeTag()) {11538 .Vector => switch (ty.childType().zigTypeTag(mod)) {
11504 .Float => switch (ty.childType().floatBits(self.target.*)) {11539 .Float => switch (ty.childType().floatBits(self.target.*)) {
11505 32 => switch (ty.vectorLen()) {11540 32 => switch (ty.vectorLen()) {
11506 1 => .{ .v_ss, .fmadd213 },11541 1 => .{ .v_ss, .fmadd213 },
...@@ -11520,14 +11555,14 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -11520,14 +11555,14 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
11520 else => unreachable,11555 else => unreachable,
11521 }11556 }
11522 else if (mem.eql(u2, &order, &.{ 2, 3, 1 }) or mem.eql(u2, &order, &.{ 3, 2, 1 }))11557 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)) {
11524 .Float => switch (ty.floatBits(self.target.*)) {11559 .Float => switch (ty.floatBits(self.target.*)) {
11525 32 => .{ .v_ss, .fmadd231 },11560 32 => .{ .v_ss, .fmadd231 },
11526 64 => .{ .v_sd, .fmadd231 },11561 64 => .{ .v_sd, .fmadd231 },
11527 16, 80, 128 => null,11562 16, 80, 128 => null,
11528 else => unreachable,11563 else => unreachable,
11529 },11564 },
11530 .Vector => switch (ty.childType().zigTypeTag()) {11565 .Vector => switch (ty.childType().zigTypeTag(mod)) {
11531 .Float => switch (ty.childType().floatBits(self.target.*)) {11566 .Float => switch (ty.childType().floatBits(self.target.*)) {
11532 32 => switch (ty.vectorLen()) {11567 32 => switch (ty.vectorLen()) {
11533 1 => .{ .v_ss, .fmadd231 },11568 1 => .{ .v_ss, .fmadd231 },
...@@ -11555,7 +11590,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -11555,7 +11590,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
11555 var mops: [3]MCValue = undefined;11590 var mops: [3]MCValue = undefined;
11556 for (order, mcvs) |mop_index, mcv| mops[mop_index - 1] = mcv;11591 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));
11559 const mop1_reg = registerAlias(mops[0].getReg().?, abi_size);11594 const mop1_reg = registerAlias(mops[0].getReg().?, abi_size);
11560 const mop2_reg = registerAlias(mops[1].getReg().?, abi_size);11595 const mop2_reg = registerAlias(mops[1].getReg().?, abi_size);
11561 if (mops[2].isRegister()) try self.asmRegisterRegisterRegister(11596 if (mops[2].isRegister()) try self.asmRegisterRegisterRegister(
...@@ -11573,10 +11608,11 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -11573,10 +11608,11 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
11573}11608}
1157411609
11575fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {11610fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
11611 const mod = self.bin_file.options.module.?;
11576 const ty = self.air.typeOf(ref);11612 const ty = self.air.typeOf(ref);
1157711613
11578 // If the type has no codegen bits, no need to store it.11614 // 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
11581 if (Air.refToIndex(ref)) |inst| {11617 if (Air.refToIndex(ref)) |inst| {
11582 const mcv = switch (self.air.instructions.items(.tag)[inst]) {11618 const mcv = switch (self.air.instructions.items(.tag)[inst]) {
...@@ -11584,7 +11620,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {...@@ -11584,7 +11620,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
11584 const gop = try self.const_tracking.getOrPut(self.gpa, inst);11620 const gop = try self.const_tracking.getOrPut(self.gpa, inst);
11585 if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(try self.genTypedValue(.{11621 if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(try self.genTypedValue(.{
11586 .ty = ty,11622 .ty = ty,
11587 .val = self.air.value(ref).?,11623 .val = self.air.value(ref, mod).?,
11588 }));11624 }));
11589 break :tracking gop.value_ptr;11625 break :tracking gop.value_ptr;
11590 },11626 },
...@@ -11597,7 +11633,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {...@@ -11597,7 +11633,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
11597 }11633 }
11598 }11634 }
1159911635
11600 return self.genTypedValue(.{ .ty = ty, .val = self.air.value(ref).? });11636 return self.genTypedValue(.{ .ty = ty, .val = self.air.value(ref, mod).? });
11601}11637}
1160211638
11603fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) *InstTracking {11639fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) *InstTracking {
...@@ -11670,6 +11706,7 @@ fn resolveCallingConventionValues(...@@ -11670,6 +11706,7 @@ fn resolveCallingConventionValues(
11670 var_args: []const Air.Inst.Ref,11706 var_args: []const Air.Inst.Ref,
11671 stack_frame_base: FrameIndex,11707 stack_frame_base: FrameIndex,
11672) !CallMCValues {11708) !CallMCValues {
11709 const mod = self.bin_file.options.module.?;
11673 const cc = fn_ty.fnCallingConvention();11710 const cc = fn_ty.fnCallingConvention();
11674 const param_len = fn_ty.fnParamLen();11711 const param_len = fn_ty.fnParamLen();
11675 const param_types = try self.gpa.alloc(Type, param_len + var_args.len);11712 const param_types = try self.gpa.alloc(Type, param_len + var_args.len);
...@@ -11702,21 +11739,21 @@ fn resolveCallingConventionValues(...@@ -11702,21 +11739,21 @@ fn resolveCallingConventionValues(
11702 switch (self.target.os.tag) {11739 switch (self.target.os.tag) {
11703 .windows => {11740 .windows => {
11704 // Align the stack to 16bytes before allocating shadow stack space (if any).11741 // 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));
11706 },11743 },
11707 else => {},11744 else => {},
11708 }11745 }
1170911746
11710 // Return values11747 // Return values
11711 if (ret_ty.zigTypeTag() == .NoReturn) {11748 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
11712 result.return_value = InstTracking.init(.unreach);11749 result.return_value = InstTracking.init(.unreach);
11713 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {11750 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
11714 // TODO: is this even possible for C calling convention?11751 // TODO: is this even possible for C calling convention?
11715 result.return_value = InstTracking.init(.none);11752 result.return_value = InstTracking.init(.none);
11716 } else {11753 } else {
11717 const classes = switch (self.target.os.tag) {11754 const classes = switch (self.target.os.tag) {
11718 .windows => &[1]abi.Class{abi.classifyWindows(ret_ty, self.target.*)},11755 .windows => &[1]abi.Class{abi.classifyWindows(ret_ty, mod)},
11719 else => mem.sliceTo(&abi.classifySystemV(ret_ty, self.target.*, .ret), .none),11756 else => mem.sliceTo(&abi.classifySystemV(ret_ty, mod, .ret), .none),
11720 };11757 };
11721 if (classes.len > 1) {11758 if (classes.len > 1) {
11722 return self.fail("TODO handle multiple classes per type", .{});11759 return self.fail("TODO handle multiple classes per type", .{});
...@@ -11725,7 +11762,7 @@ fn resolveCallingConventionValues(...@@ -11725,7 +11762,7 @@ fn resolveCallingConventionValues(
11725 result.return_value = switch (classes[0]) {11762 result.return_value = switch (classes[0]) {
11726 .integer => InstTracking.init(.{ .register = registerAlias(11763 .integer => InstTracking.init(.{ .register = registerAlias(
11727 ret_reg,11764 ret_reg,
11728 @intCast(u32, ret_ty.abiSize(self.target.*)),11765 @intCast(u32, ret_ty.abiSize(mod)),
11729 ) }),11766 ) }),
11730 .float, .sse => InstTracking.init(.{ .register = .xmm0 }),11767 .float, .sse => InstTracking.init(.{ .register = .xmm0 }),
11731 .memory => ret: {11768 .memory => ret: {
...@@ -11744,11 +11781,11 @@ fn resolveCallingConventionValues(...@@ -11744,11 +11781,11 @@ fn resolveCallingConventionValues(
1174411781
11745 // Input params11782 // Input params
11746 for (param_types, result.args) |ty, *arg| {11783 for (param_types, result.args) |ty, *arg| {
11747 assert(ty.hasRuntimeBitsIgnoreComptime());11784 assert(ty.hasRuntimeBitsIgnoreComptime(mod));
1174811785
11749 const classes = switch (self.target.os.tag) {11786 const classes = switch (self.target.os.tag) {
11750 .windows => &[1]abi.Class{abi.classifyWindows(ty, self.target.*)},11787 .windows => &[1]abi.Class{abi.classifyWindows(ty, mod)},
11751 else => mem.sliceTo(&abi.classifySystemV(ty, self.target.*, .arg), .none),11788 else => mem.sliceTo(&abi.classifySystemV(ty, mod, .arg), .none),
11752 };11789 };
11753 if (classes.len > 1) {11790 if (classes.len > 1) {
11754 return self.fail("TODO handle multiple classes per type", .{});11791 return self.fail("TODO handle multiple classes per type", .{});
...@@ -11783,8 +11820,8 @@ fn resolveCallingConventionValues(...@@ -11783,8 +11820,8 @@ fn resolveCallingConventionValues(
11783 }),11820 }),
11784 }11821 }
1178511822
11786 const param_size = @intCast(u31, ty.abiSize(self.target.*));11823 const param_size = @intCast(u31, ty.abiSize(mod));
11787 const param_align = @intCast(u31, ty.abiAlignment(self.target.*));11824 const param_align = @intCast(u31, ty.abiAlignment(mod));
11788 result.stack_byte_count =11825 result.stack_byte_count =
11789 mem.alignForwardGeneric(u31, result.stack_byte_count, param_align);11826 mem.alignForwardGeneric(u31, result.stack_byte_count, param_align);
11790 arg.* = .{ .load_frame = .{11827 arg.* = .{ .load_frame = .{
...@@ -11798,13 +11835,13 @@ fn resolveCallingConventionValues(...@@ -11798,13 +11835,13 @@ fn resolveCallingConventionValues(
11798 result.stack_align = 16;11835 result.stack_align = 16;
1179911836
11800 // Return values11837 // Return values
11801 if (ret_ty.zigTypeTag() == .NoReturn) {11838 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
11802 result.return_value = InstTracking.init(.unreach);11839 result.return_value = InstTracking.init(.unreach);
11803 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {11840 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
11804 result.return_value = InstTracking.init(.none);11841 result.return_value = InstTracking.init(.none);
11805 } else {11842 } else {
11806 const ret_reg = abi.getCAbiIntReturnRegs(self.target.*)[0];11843 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));
11808 if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) {11845 if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) {
11809 const aliased_reg = registerAlias(ret_reg, ret_ty_size);11846 const aliased_reg = registerAlias(ret_reg, ret_ty_size);
11810 result.return_value = .{ .short = .{ .register = aliased_reg }, .long = .none };11847 result.return_value = .{ .short = .{ .register = aliased_reg }, .long = .none };
...@@ -11819,12 +11856,12 @@ fn resolveCallingConventionValues(...@@ -11819,12 +11856,12 @@ fn resolveCallingConventionValues(
1181911856
11820 // Input params11857 // Input params
11821 for (param_types, result.args) |ty, *arg| {11858 for (param_types, result.args) |ty, *arg| {
11822 if (!ty.hasRuntimeBitsIgnoreComptime()) {11859 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
11823 arg.* = .none;11860 arg.* = .none;
11824 continue;11861 continue;
11825 }11862 }
11826 const param_size = @intCast(u31, ty.abiSize(self.target.*));11863 const param_size = @intCast(u31, ty.abiSize(mod));
11827 const param_align = @intCast(u31, ty.abiAlignment(self.target.*));11864 const param_align = @intCast(u31, ty.abiAlignment(mod));
11828 result.stack_byte_count =11865 result.stack_byte_count =
11829 mem.alignForwardGeneric(u31, result.stack_byte_count, param_align);11866 mem.alignForwardGeneric(u31, result.stack_byte_count, param_align);
11830 arg.* = .{ .load_frame = .{11867 arg.* = .{ .load_frame = .{
...@@ -11908,9 +11945,10 @@ fn registerAlias(reg: Register, size_bytes: u32) Register {...@@ -11908,9 +11945,10 @@ fn registerAlias(reg: Register, size_bytes: u32) Register {
11908/// Truncates the value in the register in place.11945/// Truncates the value in the register in place.
11909/// Clobbers any remaining bits.11946/// Clobbers any remaining bits.
11910fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {11947fn 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{
11912 .signedness = .unsigned,11950 .signedness = .unsigned,
11913 .bits = @intCast(u16, ty.bitSize(self.target.*)),11951 .bits = @intCast(u16, ty.bitSize(mod)),
11914 };11952 };
11915 const max_reg_bit_width = Register.rax.bitSize();11953 const max_reg_bit_width = Register.rax.bitSize();
11916 switch (int_info.signedness) {11954 switch (int_info.signedness) {
...@@ -11953,8 +11991,9 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {...@@ -11953,8 +11991,9 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
11953}11991}
1195411992
11955fn regBitSize(self: *Self, ty: Type) u64 {11993fn regBitSize(self: *Self, ty: Type) u64 {
11956 const abi_size = ty.abiSize(self.target.*);11994 const mod = self.bin_file.options.module.?;
11957 return switch (ty.zigTypeTag()) {11995 const abi_size = ty.abiSize(mod);
11996 return switch (ty.zigTypeTag(mod)) {
11958 else => switch (abi_size) {11997 else => switch (abi_size) {
11959 1 => 8,11998 1 => 8,
11960 2 => 16,11999 2 => 16,
...@@ -11971,7 +12010,8 @@ fn regBitSize(self: *Self, ty: Type) u64 {...@@ -11971,7 +12010,8 @@ fn regBitSize(self: *Self, ty: Type) u64 {
11971}12010}
1197212011
11973fn regExtraBits(self: *Self, ty: Type) u64 {12012fn 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);
11975}12015}
1197612016
11977fn hasFeature(self: *Self, feature: Target.x86.Feature) bool {12017fn hasFeature(self: *Self, feature: Target.x86.Feature) bool {
src/arch/x86_64/abi.zig+26-56
...@@ -1,10 +1,3 @@...@@ -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
8pub const Class = enum {1pub const Class = enum {
9 integer,2 integer,
10 sse,3 sse,
...@@ -19,7 +12,7 @@ pub const Class = enum {...@@ -19,7 +12,7 @@ pub const Class = enum {
19 float_combine,12 float_combine,
20};13};
2114
22pub fn classifyWindows(ty: Type, target: Target) Class {15pub fn classifyWindows(ty: Type, mod: *const Module) Class {
23 // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-201716 // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
24 // "There's a strict one-to-one correspondence between a function call's arguments17 // "There's a strict one-to-one correspondence between a function call's arguments
25 // and the registers used for those arguments. Any argument that doesn't fit in 818 // 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 {...@@ -28,7 +21,7 @@ pub fn classifyWindows(ty: Type, target: Target) Class {
28 // "All floating point operations are done using the 16 XMM registers."21 // "All floating point operations are done using the 16 XMM registers."
29 // "Structs and unions of size 8, 16, 32, or 64 bits, and __m64 types, are passed22 // "Structs and unions of size 8, 16, 32, or 64 bits, and __m64 types, are passed
30 // as if they were integers of the same size."23 // as if they were integers of the same size."
31 switch (ty.zigTypeTag()) {24 switch (ty.zigTypeTag(mod)) {
32 .Pointer,25 .Pointer,
33 .Int,26 .Int,
34 .Bool,27 .Bool,
...@@ -43,10 +36,10 @@ pub fn classifyWindows(ty: Type, target: Target) Class {...@@ -43,10 +36,10 @@ pub fn classifyWindows(ty: Type, target: Target) Class {
43 .ErrorUnion,36 .ErrorUnion,
44 .AnyFrame,37 .AnyFrame,
45 .Frame,38 .Frame,
46 => switch (ty.abiSize(target)) {39 => switch (ty.abiSize(mod)) {
47 0 => unreachable,40 0 => unreachable,
48 1, 2, 4, 8 => return .integer,41 1, 2, 4, 8 => return .integer,
49 else => switch (ty.zigTypeTag()) {42 else => switch (ty.zigTypeTag(mod)) {
50 .Int => return .win_i128,43 .Int => return .win_i128,
51 .Struct, .Union => if (ty.containerLayout() == .Packed) {44 .Struct, .Union => if (ty.containerLayout() == .Packed) {
52 return .win_i128;45 return .win_i128;
...@@ -75,13 +68,14 @@ pub const Context = enum { ret, arg, other };...@@ -75,13 +68,14 @@ pub const Context = enum { ret, arg, other };
7568
76/// There are a maximum of 8 possible return slots. Returned values are in69/// There are a maximum of 8 possible return slots. Returned values are in
77/// the beginning of the array; unused slots are filled with .none.70/// 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();
79 const memory_class = [_]Class{73 const memory_class = [_]Class{
80 .memory, .none, .none, .none,74 .memory, .none, .none, .none,
81 .none, .none, .none, .none,75 .none, .none, .none, .none,
82 };76 };
83 var result = [1]Class{.none} ** 8;77 var result = [1]Class{.none} ** 8;
84 switch (ty.zigTypeTag()) {78 switch (ty.zigTypeTag(mod)) {
85 .Pointer => switch (ty.ptrSize()) {79 .Pointer => switch (ty.ptrSize()) {
86 .Slice => {80 .Slice => {
87 result[0] = .integer;81 result[0] = .integer;
...@@ -94,7 +88,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {...@@ -94,7 +88,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
94 },88 },
95 },89 },
96 .Int, .Enum, .ErrorSet => {90 .Int, .Enum, .ErrorSet => {
97 const bits = ty.intInfo(target).bits;91 const bits = ty.intInfo(mod).bits;
98 if (bits <= 64) {92 if (bits <= 64) {
99 result[0] = .integer;93 result[0] = .integer;
100 return result;94 return result;
...@@ -165,7 +159,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {...@@ -165,7 +159,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
165 },159 },
166 .Vector => {160 .Vector => {
167 const elem_ty = ty.childType();161 const elem_ty = ty.childType();
168 const bits = elem_ty.bitSize(target) * ty.arrayLen();162 const bits = elem_ty.bitSize(mod) * ty.arrayLen();
169 if (bits <= 64) return .{163 if (bits <= 64) return .{
170 .sse, .none, .none, .none,164 .sse, .none, .none, .none,
171 .none, .none, .none, .none,165 .none, .none, .none, .none,
...@@ -204,7 +198,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {...@@ -204,7 +198,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
204 return memory_class;198 return memory_class;
205 },199 },
206 .Optional => {200 .Optional => {
207 if (ty.isPtrLikeOptional()) {201 if (ty.isPtrLikeOptional(mod)) {
208 result[0] = .integer;202 result[0] = .integer;
209 return result;203 return result;
210 }204 }
...@@ -215,7 +209,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {...@@ -215,7 +209,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
215 // it contains unaligned fields, it has class MEMORY"209 // it contains unaligned fields, it has class MEMORY"
216 // "If the size of the aggregate exceeds a single eightbyte, each is classified210 // "If the size of the aggregate exceeds a single eightbyte, each is classified
217 // separately.".211 // separately.".
218 const ty_size = ty.abiSize(target);212 const ty_size = ty.abiSize(mod);
219 if (ty.containerLayout() == .Packed) {213 if (ty.containerLayout() == .Packed) {
220 assert(ty_size <= 128);214 assert(ty_size <= 128);
221 result[0] = .integer;215 result[0] = .integer;
...@@ -230,12 +224,12 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {...@@ -230,12 +224,12 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
230 const fields = ty.structFields();224 const fields = ty.structFields();
231 for (fields.values()) |field| {225 for (fields.values()) |field| {
232 if (field.abi_align != 0) {226 if (field.abi_align != 0) {
233 if (field.abi_align < field.ty.abiAlignment(target)) {227 if (field.abi_align < field.ty.abiAlignment(mod)) {
234 return memory_class;228 return memory_class;
235 }229 }
236 }230 }
237 const field_size = field.ty.abiSize(target);231 const field_size = field.ty.abiSize(mod);
238 const field_class_array = classifySystemV(field.ty, target, .other);232 const field_class_array = classifySystemV(field.ty, mod, .other);
239 const field_class = std.mem.sliceTo(&field_class_array, .none);233 const field_class = std.mem.sliceTo(&field_class_array, .none);
240 if (byte_i + field_size <= 8) {234 if (byte_i + field_size <= 8) {
241 // Combine this field with the previous one.235 // Combine this field with the previous one.
...@@ -334,7 +328,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {...@@ -334,7 +328,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
334 // it contains unaligned fields, it has class MEMORY"328 // it contains unaligned fields, it has class MEMORY"
335 // "If the size of the aggregate exceeds a single eightbyte, each is classified329 // "If the size of the aggregate exceeds a single eightbyte, each is classified
336 // separately.".330 // separately.".
337 const ty_size = ty.abiSize(target);331 const ty_size = ty.abiSize(mod);
338 if (ty.containerLayout() == .Packed) {332 if (ty.containerLayout() == .Packed) {
339 assert(ty_size <= 128);333 assert(ty_size <= 128);
340 result[0] = .integer;334 result[0] = .integer;
...@@ -347,12 +341,12 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {...@@ -347,12 +341,12 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
347 const fields = ty.unionFields();341 const fields = ty.unionFields();
348 for (fields.values()) |field| {342 for (fields.values()) |field| {
349 if (field.abi_align != 0) {343 if (field.abi_align != 0) {
350 if (field.abi_align < field.ty.abiAlignment(target)) {344 if (field.abi_align < field.ty.abiAlignment(mod)) {
351 return memory_class;345 return memory_class;
352 }346 }
353 }347 }
354 // Combine this field with the previous one.348 // 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);
356 for (&result, 0..) |*result_item, i| {350 for (&result, 0..) |*result_item, i| {
357 const field_item = field_class[i];351 const field_item = field_class[i];
358 // "If both classes are equal, this is the resulting class."352 // "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 {...@@ -426,7 +420,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
426 return result;420 return result;
427 },421 },
428 .Array => {422 .Array => {
429 const ty_size = ty.abiSize(target);423 const ty_size = ty.abiSize(mod);
430 if (ty_size <= 64) {424 if (ty_size <= 64) {
431 result[0] = .integer;425 result[0] = .integer;
432 return result;426 return result;
...@@ -527,10 +521,17 @@ pub const RegisterClass = struct {...@@ -527,10 +521,17 @@ pub const RegisterClass = struct {
527 };521 };
528};522};
529523
524const builtin = @import("builtin");
525const std = @import("std");
526const Target = std.Target;
527const assert = std.debug.assert;
530const testing = std.testing;528const testing = std.testing;
529
531const Module = @import("../../Module.zig");530const Module = @import("../../Module.zig");
531const Register = @import("bits.zig").Register;
532const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
533const Type = @import("../../type.zig").Type;
532const Value = @import("../../value.zig").Value;534const Value = @import("../../value.zig").Value;
533const builtin = @import("builtin");
534535
535fn _field(comptime tag: Type.Tag, offset: u32) Module.Struct.Field {536fn _field(comptime tag: Type.Tag, offset: u32) Module.Struct.Field {
536 return .{537 return .{
...@@ -541,34 +542,3 @@ fn _field(comptime tag: Type.Tag, offset: u32) Module.Struct.Field {...@@ -541,34 +542,3 @@ fn _field(comptime tag: Type.Tag, offset: u32) Module.Struct.Field {
541 .is_comptime = false,542 .is_comptime = false,
542 };543 };
543}544}
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(...@@ -154,7 +154,7 @@ pub fn generateLazySymbol(
154 }154 }
155 mem.writeInt(u32, code.items[offset..][0..4], @intCast(u32, code.items.len), endian);155 mem.writeInt(u32, code.items[offset..][0..4], @intCast(u32, code.items.len), endian);
156 return Result.ok;156 return Result.ok;
157 } else if (lazy_sym.ty.zigTypeTag() == .Enum) {157 } else if (lazy_sym.ty.zigTypeTag(mod) == .Enum) {
158 alignment.* = 1;158 alignment.* = 1;
159 for (lazy_sym.ty.enumFields().keys()) |tag_name| {159 for (lazy_sym.ty.enumFields().keys()) |tag_name| {
160 try code.ensureUnusedCapacity(tag_name.len + 1);160 try code.ensureUnusedCapacity(tag_name.len + 1);
...@@ -186,22 +186,22 @@ pub fn generateSymbol(...@@ -186,22 +186,22 @@ pub fn generateSymbol(
186 typed_value.val = rt.data;186 typed_value.val = rt.data;
187 }187 }
188188
189 const target = bin_file.options.target;189 const mod = bin_file.options.module.?;
190 const target = mod.getTarget();
190 const endian = target.cpu.arch.endian();191 const endian = target.cpu.arch.endian();
191192
192 const mod = bin_file.options.module.?;
193 log.debug("generateSymbol: ty = {}, val = {}", .{193 log.debug("generateSymbol: ty = {}, val = {}", .{
194 typed_value.ty.fmt(mod),194 typed_value.ty.fmt(mod),
195 typed_value.val.fmtValue(typed_value.ty, mod),195 typed_value.val.fmtValue(typed_value.ty, mod),
196 });196 });
197197
198 if (typed_value.val.isUndefDeep()) {198 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;
200 try code.appendNTimes(0xaa, abi_size);200 try code.appendNTimes(0xaa, abi_size);
201 return Result.ok;201 return Result.ok;
202 }202 }
203203
204 switch (typed_value.ty.zigTypeTag()) {204 switch (typed_value.ty.zigTypeTag(mod)) {
205 .Fn => {205 .Fn => {
206 return Result{206 return Result{
207 .fail = try ErrorMsg.create(207 .fail = try ErrorMsg.create(
...@@ -219,7 +219,7 @@ pub fn generateSymbol(...@@ -219,7 +219,7 @@ pub fn generateSymbol(
219 64 => writeFloat(f64, typed_value.val.toFloat(f64), target, endian, try code.addManyAsArray(8)),219 64 => writeFloat(f64, typed_value.val.toFloat(f64), target, endian, try code.addManyAsArray(8)),
220 80 => {220 80 => {
221 writeFloat(f80, typed_value.val.toFloat(f80), target, endian, try code.addManyAsArray(10));221 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;
223 try code.appendNTimes(0, abi_size - 10);223 try code.appendNTimes(0, abi_size - 10);
224 },224 },
225 128 => writeFloat(f128, typed_value.val.toFloat(f128), target, endian, try code.addManyAsArray(16)),225 128 => writeFloat(f128, typed_value.val.toFloat(f128), target, endian, try code.addManyAsArray(16)),
...@@ -242,7 +242,7 @@ pub fn generateSymbol(...@@ -242,7 +242,7 @@ pub fn generateSymbol(
242 try code.ensureUnusedCapacity(bytes.len + 1);242 try code.ensureUnusedCapacity(bytes.len + 1);
243 code.appendSliceAssumeCapacity(bytes);243 code.appendSliceAssumeCapacity(bytes);
244 if (typed_value.ty.sentinel()) |sent_val| {244 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));
246 code.appendAssumeCapacity(byte);246 code.appendAssumeCapacity(byte);
247 }247 }
248 return Result.ok;248 return Result.ok;
...@@ -330,11 +330,11 @@ pub fn generateSymbol(...@@ -330,11 +330,11 @@ pub fn generateSymbol(
330 .zero, .one, .int_u64, .int_big_positive => {330 .zero, .one, .int_u64, .int_big_positive => {
331 switch (target.ptrBitWidth()) {331 switch (target.ptrBitWidth()) {
332 32 => {332 32 => {
333 const x = typed_value.val.toUnsignedInt(target);333 const x = typed_value.val.toUnsignedInt(mod);
334 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, x), endian);334 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, x), endian);
335 },335 },
336 64 => {336 64 => {
337 const x = typed_value.val.toUnsignedInt(target);337 const x = typed_value.val.toUnsignedInt(mod);
338 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);338 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
339 },339 },
340 else => unreachable,340 else => unreachable,
...@@ -399,19 +399,19 @@ pub fn generateSymbol(...@@ -399,19 +399,19 @@ pub fn generateSymbol(
399 },399 },
400 },400 },
401 .Int => {401 .Int => {
402 const info = typed_value.ty.intInfo(target);402 const info = typed_value.ty.intInfo(mod);
403 if (info.bits <= 8) {403 if (info.bits <= 8) {
404 const x: u8 = switch (info.signedness) {404 const x: u8 = switch (info.signedness) {
405 .unsigned => @intCast(u8, typed_value.val.toUnsignedInt(target)),405 .unsigned => @intCast(u8, typed_value.val.toUnsignedInt(mod)),
406 .signed => @bitCast(u8, @intCast(i8, typed_value.val.toSignedInt(target))),406 .signed => @bitCast(u8, @intCast(i8, typed_value.val.toSignedInt(mod))),
407 };407 };
408 try code.append(x);408 try code.append(x);
409 return Result.ok;409 return Result.ok;
410 }410 }
411 if (info.bits > 64) {411 if (info.bits > 64) {
412 var bigint_buffer: Value.BigIntSpace = undefined;412 var bigint_buffer: Value.BigIntSpace = undefined;
413 const bigint = typed_value.val.toBigInt(&bigint_buffer, target);413 const bigint = typed_value.val.toBigInt(&bigint_buffer, mod);
414 const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;414 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
415 const start = code.items.len;415 const start = code.items.len;
416 try code.resize(start + abi_size);416 try code.resize(start + abi_size);
417 bigint.writeTwosComplement(code.items[start..][0..abi_size], endian);417 bigint.writeTwosComplement(code.items[start..][0..abi_size], endian);
...@@ -420,25 +420,25 @@ pub fn generateSymbol(...@@ -420,25 +420,25 @@ pub fn generateSymbol(
420 switch (info.signedness) {420 switch (info.signedness) {
421 .unsigned => {421 .unsigned => {
422 if (info.bits <= 16) {422 if (info.bits <= 16) {
423 const x = @intCast(u16, typed_value.val.toUnsignedInt(target));423 const x = @intCast(u16, typed_value.val.toUnsignedInt(mod));
424 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);424 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);
425 } else if (info.bits <= 32) {425 } 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));
427 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);427 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);
428 } else {428 } else {
429 const x = typed_value.val.toUnsignedInt(target);429 const x = typed_value.val.toUnsignedInt(mod);
430 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);430 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
431 }431 }
432 },432 },
433 .signed => {433 .signed => {
434 if (info.bits <= 16) {434 if (info.bits <= 16) {
435 const x = @intCast(i16, typed_value.val.toSignedInt(target));435 const x = @intCast(i16, typed_value.val.toSignedInt(mod));
436 mem.writeInt(i16, try code.addManyAsArray(2), x, endian);436 mem.writeInt(i16, try code.addManyAsArray(2), x, endian);
437 } else if (info.bits <= 32) {437 } 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));
439 mem.writeInt(i32, try code.addManyAsArray(4), x, endian);439 mem.writeInt(i32, try code.addManyAsArray(4), x, endian);
440 } else {440 } else {
441 const x = typed_value.val.toSignedInt(target);441 const x = typed_value.val.toSignedInt(mod);
442 mem.writeInt(i64, try code.addManyAsArray(8), x, endian);442 mem.writeInt(i64, try code.addManyAsArray(8), x, endian);
443 }443 }
444 },444 },
...@@ -449,9 +449,9 @@ pub fn generateSymbol(...@@ -449,9 +449,9 @@ pub fn generateSymbol(
449 var int_buffer: Value.Payload.U64 = undefined;449 var int_buffer: Value.Payload.U64 = undefined;
450 const int_val = typed_value.enumToInt(&int_buffer);450 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);
453 if (info.bits <= 8) {453 if (info.bits <= 8) {
454 const x = @intCast(u8, int_val.toUnsignedInt(target));454 const x = @intCast(u8, int_val.toUnsignedInt(mod));
455 try code.append(x);455 try code.append(x);
456 return Result.ok;456 return Result.ok;
457 }457 }
...@@ -468,25 +468,25 @@ pub fn generateSymbol(...@@ -468,25 +468,25 @@ pub fn generateSymbol(
468 switch (info.signedness) {468 switch (info.signedness) {
469 .unsigned => {469 .unsigned => {
470 if (info.bits <= 16) {470 if (info.bits <= 16) {
471 const x = @intCast(u16, int_val.toUnsignedInt(target));471 const x = @intCast(u16, int_val.toUnsignedInt(mod));
472 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);472 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);
473 } else if (info.bits <= 32) {473 } else if (info.bits <= 32) {
474 const x = @intCast(u32, int_val.toUnsignedInt(target));474 const x = @intCast(u32, int_val.toUnsignedInt(mod));
475 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);475 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);
476 } else {476 } else {
477 const x = int_val.toUnsignedInt(target);477 const x = int_val.toUnsignedInt(mod);
478 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);478 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
479 }479 }
480 },480 },
481 .signed => {481 .signed => {
482 if (info.bits <= 16) {482 if (info.bits <= 16) {
483 const x = @intCast(i16, int_val.toSignedInt(target));483 const x = @intCast(i16, int_val.toSignedInt(mod));
484 mem.writeInt(i16, try code.addManyAsArray(2), x, endian);484 mem.writeInt(i16, try code.addManyAsArray(2), x, endian);
485 } else if (info.bits <= 32) {485 } else if (info.bits <= 32) {
486 const x = @intCast(i32, int_val.toSignedInt(target));486 const x = @intCast(i32, int_val.toSignedInt(mod));
487 mem.writeInt(i32, try code.addManyAsArray(4), x, endian);487 mem.writeInt(i32, try code.addManyAsArray(4), x, endian);
488 } else {488 } else {
489 const x = int_val.toSignedInt(target);489 const x = int_val.toSignedInt(mod);
490 mem.writeInt(i64, try code.addManyAsArray(8), x, endian);490 mem.writeInt(i64, try code.addManyAsArray(8), x, endian);
491 }491 }
492 },492 },
...@@ -503,7 +503,7 @@ pub fn generateSymbol(...@@ -503,7 +503,7 @@ pub fn generateSymbol(
503 const struct_obj = typed_value.ty.castTag(.@"struct").?.data;503 const struct_obj = typed_value.ty.castTag(.@"struct").?.data;
504 const fields = struct_obj.fields.values();504 const fields = struct_obj.fields.values();
505 const field_vals = typed_value.val.castTag(.aggregate).?.data;505 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;
507 const current_pos = code.items.len;507 const current_pos = code.items.len;
508 try code.resize(current_pos + abi_size);508 try code.resize(current_pos + abi_size);
509 var bits: u16 = 0;509 var bits: u16 = 0;
...@@ -512,8 +512,8 @@ pub fn generateSymbol(...@@ -512,8 +512,8 @@ pub fn generateSymbol(
512 const field_ty = fields[index].ty;512 const field_ty = fields[index].ty;
513 // pointer may point to a decl which must be marked used513 // pointer may point to a decl which must be marked used
514 // but can also result in a relocation. Therefore we handle those seperately.514 // but can also result in a relocation. Therefore we handle those seperately.
515 if (field_ty.zigTypeTag() == .Pointer) {515 if (field_ty.zigTypeTag(mod) == .Pointer) {
516 const field_size = math.cast(usize, field_ty.abiSize(target)) orelse return error.Overflow;516 const field_size = math.cast(usize, field_ty.abiSize(mod)) orelse return error.Overflow;
517 var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size);517 var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size);
518 defer tmp_list.deinit();518 defer tmp_list.deinit();
519 switch (try generateSymbol(bin_file, src_loc, .{519 switch (try generateSymbol(bin_file, src_loc, .{
...@@ -526,7 +526,7 @@ pub fn generateSymbol(...@@ -526,7 +526,7 @@ pub fn generateSymbol(
526 } else {526 } else {
527 field_val.writeToPackedMemory(field_ty, mod, code.items[current_pos..], bits) catch unreachable;527 field_val.writeToPackedMemory(field_ty, mod, code.items[current_pos..], bits) catch unreachable;
528 }528 }
529 bits += @intCast(u16, field_ty.bitSize(target));529 bits += @intCast(u16, field_ty.bitSize(mod));
530 }530 }
531531
532 return Result.ok;532 return Result.ok;
...@@ -536,7 +536,7 @@ pub fn generateSymbol(...@@ -536,7 +536,7 @@ pub fn generateSymbol(
536 const field_vals = typed_value.val.castTag(.aggregate).?.data;536 const field_vals = typed_value.val.castTag(.aggregate).?.data;
537 for (field_vals, 0..) |field_val, index| {537 for (field_vals, 0..) |field_val, index| {
538 const field_ty = typed_value.ty.structFieldType(index);538 const field_ty = typed_value.ty.structFieldType(index);
539 if (!field_ty.hasRuntimeBits()) continue;539 if (!field_ty.hasRuntimeBits(mod)) continue;
540540
541 switch (try generateSymbol(bin_file, src_loc, .{541 switch (try generateSymbol(bin_file, src_loc, .{
542 .ty = field_ty,542 .ty = field_ty,
...@@ -548,7 +548,7 @@ pub fn generateSymbol(...@@ -548,7 +548,7 @@ pub fn generateSymbol(
548 const unpadded_field_end = code.items.len - struct_begin;548 const unpadded_field_end = code.items.len - struct_begin;
549549
550 // Pad struct members if required550 // 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);
552 const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse return error.Overflow;552 const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse return error.Overflow;
553553
554 if (padding > 0) {554 if (padding > 0) {
...@@ -560,7 +560,7 @@ pub fn generateSymbol(...@@ -560,7 +560,7 @@ pub fn generateSymbol(
560 },560 },
561 .Union => {561 .Union => {
562 const union_obj = typed_value.val.castTag(.@"union").?.data;562 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
565 if (layout.payload_size == 0) {565 if (layout.payload_size == 0) {
566 return generateSymbol(bin_file, src_loc, .{566 return generateSymbol(bin_file, src_loc, .{
...@@ -584,7 +584,7 @@ pub fn generateSymbol(...@@ -584,7 +584,7 @@ pub fn generateSymbol(
584 const field_index = typed_value.ty.unionTagFieldIndex(union_obj.tag, mod).?;584 const field_index = typed_value.ty.unionTagFieldIndex(union_obj.tag, mod).?;
585 assert(union_ty.haveFieldTypes());585 assert(union_ty.haveFieldTypes());
586 const field_ty = union_ty.fields.values()[field_index].ty;586 const field_ty = union_ty.fields.values()[field_index].ty;
587 if (!field_ty.hasRuntimeBits()) {587 if (!field_ty.hasRuntimeBits(mod)) {
588 try code.writer().writeByteNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);588 try code.writer().writeByteNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
589 } else {589 } else {
590 switch (try generateSymbol(bin_file, src_loc, .{590 switch (try generateSymbol(bin_file, src_loc, .{
...@@ -595,7 +595,7 @@ pub fn generateSymbol(...@@ -595,7 +595,7 @@ pub fn generateSymbol(
595 .fail => |em| return Result{ .fail = em },595 .fail => |em| return Result{ .fail = em },
596 }596 }
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;
599 if (padding > 0) {599 if (padding > 0) {
600 try code.writer().writeByteNTimes(0, padding);600 try code.writer().writeByteNTimes(0, padding);
601 }601 }
...@@ -620,15 +620,15 @@ pub fn generateSymbol(...@@ -620,15 +620,15 @@ pub fn generateSymbol(
620 .Optional => {620 .Optional => {
621 var opt_buf: Type.Payload.ElemType = undefined;621 var opt_buf: Type.Payload.ElemType = undefined;
622 const payload_type = typed_value.ty.optionalChild(&opt_buf);622 const payload_type = typed_value.ty.optionalChild(&opt_buf);
623 const is_pl = !typed_value.val.isNull();623 const is_pl = !typed_value.val.isNull(mod);
624 const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;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)) {
627 try code.writer().writeByteNTimes(@boolToInt(is_pl), abi_size);627 try code.writer().writeByteNTimes(@boolToInt(is_pl), abi_size);
628 return Result.ok;628 return Result.ok;
629 }629 }
630630
631 if (typed_value.ty.optionalReprIsPayload()) {631 if (typed_value.ty.optionalReprIsPayload(mod)) {
632 if (typed_value.val.castTag(.opt_payload)) |payload| {632 if (typed_value.val.castTag(.opt_payload)) |payload| {
633 switch (try generateSymbol(bin_file, src_loc, .{633 switch (try generateSymbol(bin_file, src_loc, .{
634 .ty = payload_type,634 .ty = payload_type,
...@@ -637,7 +637,7 @@ pub fn generateSymbol(...@@ -637,7 +637,7 @@ pub fn generateSymbol(
637 .ok => {},637 .ok => {},
638 .fail => |em| return Result{ .fail = em },638 .fail => |em| return Result{ .fail = em },
639 }639 }
640 } else if (!typed_value.val.isNull()) {640 } else if (!typed_value.val.isNull(mod)) {
641 switch (try generateSymbol(bin_file, src_loc, .{641 switch (try generateSymbol(bin_file, src_loc, .{
642 .ty = payload_type,642 .ty = payload_type,
643 .val = typed_value.val,643 .val = typed_value.val,
...@@ -652,7 +652,7 @@ pub fn generateSymbol(...@@ -652,7 +652,7 @@ pub fn generateSymbol(
652 return Result.ok;652 return Result.ok;
653 }653 }
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;
656 const value = if (typed_value.val.castTag(.opt_payload)) |payload| payload.data else Value.initTag(.undef);656 const value = if (typed_value.val.castTag(.opt_payload)) |payload| payload.data else Value.initTag(.undef);
657 switch (try generateSymbol(bin_file, src_loc, .{657 switch (try generateSymbol(bin_file, src_loc, .{
658 .ty = payload_type,658 .ty = payload_type,
...@@ -671,7 +671,7 @@ pub fn generateSymbol(...@@ -671,7 +671,7 @@ pub fn generateSymbol(
671 const payload_ty = typed_value.ty.errorUnionPayload();671 const payload_ty = typed_value.ty.errorUnionPayload();
672 const is_payload = typed_value.val.errorUnionIsPayload();672 const is_payload = typed_value.val.errorUnionIsPayload();
673673
674 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {674 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
675 const err_val = if (is_payload) Value.initTag(.zero) else typed_value.val;675 const err_val = if (is_payload) Value.initTag(.zero) else typed_value.val;
676 return generateSymbol(bin_file, src_loc, .{676 return generateSymbol(bin_file, src_loc, .{
677 .ty = error_ty,677 .ty = error_ty,
...@@ -679,9 +679,9 @@ pub fn generateSymbol(...@@ -679,9 +679,9 @@ pub fn generateSymbol(
679 }, code, debug_output, reloc_info);679 }, code, debug_output, reloc_info);
680 }680 }
681681
682 const payload_align = payload_ty.abiAlignment(target);682 const payload_align = payload_ty.abiAlignment(mod);
683 const error_align = Type.anyerror.abiAlignment(target);683 const error_align = Type.anyerror.abiAlignment(mod);
684 const abi_align = typed_value.ty.abiAlignment(target);684 const abi_align = typed_value.ty.abiAlignment(mod);
685685
686 // error value first when its type is larger than the error union's payload686 // error value first when its type is larger than the error union's payload
687 if (error_align > payload_align) {687 if (error_align > payload_align) {
...@@ -743,7 +743,7 @@ pub fn generateSymbol(...@@ -743,7 +743,7 @@ pub fn generateSymbol(
743 try code.writer().writeInt(u32, kv.value, endian);743 try code.writer().writeInt(u32, kv.value, endian);
744 },744 },
745 else => {745 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)));
747 },747 },
748 }748 }
749 return Result.ok;749 return Result.ok;
...@@ -752,7 +752,7 @@ pub fn generateSymbol(...@@ -752,7 +752,7 @@ pub fn generateSymbol(
752 .bytes => {752 .bytes => {
753 const bytes = typed_value.val.castTag(.bytes).?.data;753 const bytes = typed_value.val.castTag(.bytes).?.data;
754 const len = math.cast(usize, typed_value.ty.arrayLen()) orelse return error.Overflow;754 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) orelse755 const padding = math.cast(usize, typed_value.ty.abiSize(mod) - len) orelse
756 return error.Overflow;756 return error.Overflow;
757 try code.ensureUnusedCapacity(len + padding);757 try code.ensureUnusedCapacity(len + padding);
758 code.appendSliceAssumeCapacity(bytes[0..len]);758 code.appendSliceAssumeCapacity(bytes[0..len]);
...@@ -763,8 +763,8 @@ pub fn generateSymbol(...@@ -763,8 +763,8 @@ pub fn generateSymbol(
763 const elem_vals = typed_value.val.castTag(.aggregate).?.data;763 const elem_vals = typed_value.val.castTag(.aggregate).?.data;
764 const elem_ty = typed_value.ty.elemType();764 const elem_ty = typed_value.ty.elemType();
765 const len = math.cast(usize, typed_value.ty.arrayLen()) orelse return error.Overflow;765 const len = math.cast(usize, typed_value.ty.arrayLen()) orelse return error.Overflow;
766 const padding = math.cast(usize, typed_value.ty.abiSize(target) -766 const padding = math.cast(usize, typed_value.ty.abiSize(mod) -
767 (math.divCeil(u64, elem_ty.bitSize(target) * len, 8) catch |err| switch (err) {767 (math.divCeil(u64, elem_ty.bitSize(mod) * len, 8) catch |err| switch (err) {
768 error.DivisionByZero => unreachable,768 error.DivisionByZero => unreachable,
769 else => |e| return e,769 else => |e| return e,
770 })) orelse return error.Overflow;770 })) orelse return error.Overflow;
...@@ -784,8 +784,8 @@ pub fn generateSymbol(...@@ -784,8 +784,8 @@ pub fn generateSymbol(
784 const array = typed_value.val.castTag(.repeated).?.data;784 const array = typed_value.val.castTag(.repeated).?.data;
785 const elem_ty = typed_value.ty.childType();785 const elem_ty = typed_value.ty.childType();
786 const len = typed_value.ty.arrayLen();786 const len = typed_value.ty.arrayLen();
787 const padding = math.cast(usize, typed_value.ty.abiSize(target) -787 const padding = math.cast(usize, typed_value.ty.abiSize(mod) -
788 (math.divCeil(u64, elem_ty.bitSize(target) * len, 8) catch |err| switch (err) {788 (math.divCeil(u64, elem_ty.bitSize(mod) * len, 8) catch |err| switch (err) {
789 error.DivisionByZero => unreachable,789 error.DivisionByZero => unreachable,
790 else => |e| return e,790 else => |e| return e,
791 })) orelse return error.Overflow;791 })) orelse return error.Overflow;
...@@ -805,7 +805,7 @@ pub fn generateSymbol(...@@ -805,7 +805,7 @@ pub fn generateSymbol(
805 .str_lit => {805 .str_lit => {
806 const str_lit = typed_value.val.castTag(.str_lit).?.data;806 const str_lit = typed_value.val.castTag(.str_lit).?.data;
807 const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];807 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) orelse808 const padding = math.cast(usize, typed_value.ty.abiSize(mod) - str_lit.len) orelse
809 return error.Overflow;809 return error.Overflow;
810 try code.ensureUnusedCapacity(str_lit.len + padding);810 try code.ensureUnusedCapacity(str_lit.len + padding);
811 code.appendSliceAssumeCapacity(bytes);811 code.appendSliceAssumeCapacity(bytes);
...@@ -832,7 +832,7 @@ fn lowerParentPtr(...@@ -832,7 +832,7 @@ fn lowerParentPtr(
832 debug_output: DebugInfoOutput,832 debug_output: DebugInfoOutput,
833 reloc_info: RelocInfo,833 reloc_info: RelocInfo,
834) CodeGenError!Result {834) CodeGenError!Result {
835 const target = bin_file.options.target;835 const mod = bin_file.options.module.?;
836 switch (parent_ptr.tag()) {836 switch (parent_ptr.tag()) {
837 .field_ptr => {837 .field_ptr => {
838 const field_ptr = parent_ptr.castTag(.field_ptr).?.data;838 const field_ptr = parent_ptr.castTag(.field_ptr).?.data;
...@@ -843,19 +843,19 @@ fn lowerParentPtr(...@@ -843,19 +843,19 @@ fn lowerParentPtr(
843 field_ptr.container_ptr,843 field_ptr.container_ptr,
844 code,844 code,
845 debug_output,845 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)) {
847 .Pointer => offset: {847 .Pointer => offset: {
848 assert(field_ptr.container_ty.isSlice());848 assert(field_ptr.container_ty.isSlice());
849 var buf: Type.SlicePtrFieldTypeBuffer = undefined;849 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
850 break :offset switch (field_ptr.field_index) {850 break :offset switch (field_ptr.field_index) {
851 0 => 0,851 0 => 0,
852 1 => field_ptr.container_ty.slicePtrFieldType(&buf).abiSize(target),852 1 => field_ptr.container_ty.slicePtrFieldType(&buf).abiSize(mod),
853 else => unreachable,853 else => unreachable,
854 };854 };
855 },855 },
856 .Struct, .Union => field_ptr.container_ty.structFieldOffset(856 .Struct, .Union => field_ptr.container_ty.structFieldOffset(
857 field_ptr.field_index,857 field_ptr.field_index,
858 target,858 mod,
859 ),859 ),
860 else => return Result{ .fail = try ErrorMsg.create(860 else => return Result{ .fail = try ErrorMsg.create(
861 bin_file.allocator,861 bin_file.allocator,
...@@ -875,7 +875,7 @@ fn lowerParentPtr(...@@ -875,7 +875,7 @@ fn lowerParentPtr(
875 elem_ptr.array_ptr,875 elem_ptr.array_ptr,
876 code,876 code,
877 debug_output,877 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))),
879 );879 );
880 },880 },
881 .opt_payload_ptr => {881 .opt_payload_ptr => {
...@@ -900,7 +900,7 @@ fn lowerParentPtr(...@@ -900,7 +900,7 @@ fn lowerParentPtr(
900 eu_payload_ptr.container_ptr,900 eu_payload_ptr.container_ptr,
901 code,901 code,
902 debug_output,902 debug_output,
903 reloc_info.offset(@intCast(u32, errUnionPayloadOffset(pl_ty, target))),903 reloc_info.offset(@intCast(u32, errUnionPayloadOffset(pl_ty, mod))),
904 );904 );
905 },905 },
906 .variable, .decl_ref, .decl_ref_mut => |tag| return lowerDeclRef(906 .variable, .decl_ref, .decl_ref_mut => |tag| return lowerDeclRef(
...@@ -945,7 +945,7 @@ fn lowerDeclRef(...@@ -945,7 +945,7 @@ fn lowerDeclRef(
945 reloc_info: RelocInfo,945 reloc_info: RelocInfo,
946) CodeGenError!Result {946) CodeGenError!Result {
947 const target = bin_file.options.target;947 const target = bin_file.options.target;
948 const module = bin_file.options.module.?;948 const mod = bin_file.options.module.?;
949 if (typed_value.ty.isSlice()) {949 if (typed_value.ty.isSlice()) {
950 // generate ptr950 // generate ptr
951 var buf: Type.SlicePtrFieldTypeBuffer = undefined;951 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
...@@ -961,7 +961,7 @@ fn lowerDeclRef(...@@ -961,7 +961,7 @@ fn lowerDeclRef(
961 // generate length961 // generate length
962 var slice_len: Value.Payload.U64 = .{962 var slice_len: Value.Payload.U64 = .{
963 .base = .{ .tag = .int_u64 },963 .base = .{ .tag = .int_u64 },
964 .data = typed_value.val.sliceLen(module),964 .data = typed_value.val.sliceLen(mod),
965 };965 };
966 switch (try generateSymbol(bin_file, src_loc, .{966 switch (try generateSymbol(bin_file, src_loc, .{
967 .ty = Type.usize,967 .ty = Type.usize,
...@@ -975,14 +975,14 @@ fn lowerDeclRef(...@@ -975,14 +975,14 @@ fn lowerDeclRef(
975 }975 }
976976
977 const ptr_width = target.ptrBitWidth();977 const ptr_width = target.ptrBitWidth();
978 const decl = module.declPtr(decl_index);978 const decl = mod.declPtr(decl_index);
979 const is_fn_body = decl.ty.zigTypeTag() == .Fn;979 const is_fn_body = decl.ty.zigTypeTag(mod) == .Fn;
980 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {980 if (!is_fn_body and !decl.ty.hasRuntimeBits(mod)) {
981 try code.writer().writeByteNTimes(0xaa, @divExact(ptr_width, 8));981 try code.writer().writeByteNTimes(0xaa, @divExact(ptr_width, 8));
982 return Result.ok;982 return Result.ok;
983 }983 }
984984
985 module.markDeclAlive(decl);985 mod.markDeclAlive(decl);
986986
987 const vaddr = try bin_file.getDeclVAddr(decl_index, .{987 const vaddr = try bin_file.getDeclVAddr(decl_index, .{
988 .parent_atom_index = reloc_info.parent_atom_index,988 .parent_atom_index = reloc_info.parent_atom_index,
...@@ -1059,16 +1059,16 @@ fn genDeclRef(...@@ -1059,16 +1059,16 @@ fn genDeclRef(
1059 tv: TypedValue,1059 tv: TypedValue,
1060 decl_index: Module.Decl.Index,1060 decl_index: Module.Decl.Index,
1061) CodeGenError!GenResult {1061) CodeGenError!GenResult {
1062 const module = bin_file.options.module.?;1062 const mod = bin_file.options.module.?;
1063 log.debug("genDeclRef: ty = {}, val = {}", .{ tv.ty.fmt(module), tv.val.fmtValue(tv.ty, module) });1063 log.debug("genDeclRef: ty = {}, val = {}", .{ tv.ty.fmt(mod), tv.val.fmtValue(tv.ty, mod) });
10641064
1065 const target = bin_file.options.target;1065 const target = bin_file.options.target;
1066 const ptr_bits = target.ptrBitWidth();1066 const ptr_bits = target.ptrBitWidth();
1067 const ptr_bytes: u64 = @divExact(ptr_bits, 8);1067 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)) {
1072 const imm: u64 = switch (ptr_bytes) {1072 const imm: u64 = switch (ptr_bytes) {
1073 1 => 0xaa,1073 1 => 0xaa,
1074 2 => 0xaaaa,1074 2 => 0xaaaa,
...@@ -1080,20 +1080,20 @@ fn genDeclRef(...@@ -1080,20 +1080,20 @@ fn genDeclRef(
1080 }1080 }
10811081
1082 // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?1082 // 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| {
1084 if (fn_ty.fnInfo().is_generic) {1084 if (fn_ty.fnInfo().is_generic) {
1085 return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(target) });1085 return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(mod) });
1086 }1086 }
1087 } else if (tv.ty.zigTypeTag() == .Pointer) {1087 } else if (tv.ty.zigTypeTag(mod) == .Pointer) {
1088 const elem_ty = tv.ty.elemType2();1088 const elem_ty = tv.ty.elemType2(mod);
1089 if (!elem_ty.hasRuntimeBits()) {1089 if (!elem_ty.hasRuntimeBits(mod)) {
1090 return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(target) });1090 return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(mod) });
1091 }1091 }
1092 }1092 }
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
1098 if (bin_file.cast(link.File.Elf)) |elf_file| {1098 if (bin_file.cast(link.File.Elf)) |elf_file| {
1099 const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index);1099 const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index);
...@@ -1186,7 +1186,7 @@ pub fn genTypedValue(...@@ -1186,7 +1186,7 @@ pub fn genTypedValue(
1186 }1186 }
1187 }1187 }
11881188
1189 switch (typed_value.ty.zigTypeTag()) {1189 switch (typed_value.ty.zigTypeTag(mod)) {
1190 .Void => return GenResult.mcv(.none),1190 .Void => return GenResult.mcv(.none),
1191 .Pointer => switch (typed_value.ty.ptrSize()) {1191 .Pointer => switch (typed_value.ty.ptrSize()) {
1192 .Slice => {},1192 .Slice => {},
...@@ -1196,18 +1196,18 @@ pub fn genTypedValue(...@@ -1196,18 +1196,18 @@ pub fn genTypedValue(
1196 return GenResult.mcv(.{ .immediate = 0 });1196 return GenResult.mcv(.{ .immediate = 0 });
1197 },1197 },
1198 .int_u64 => {1198 .int_u64 => {
1199 return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(target) });1199 return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(mod) });
1200 },1200 },
1201 else => {},1201 else => {},
1202 }1202 }
1203 },1203 },
1204 },1204 },
1205 .Int => {1205 .Int => {
1206 const info = typed_value.ty.intInfo(target);1206 const info = typed_value.ty.intInfo(mod);
1207 if (info.bits <= ptr_bits) {1207 if (info.bits <= ptr_bits) {
1208 const unsigned = switch (info.signedness) {1208 const unsigned = switch (info.signedness) {
1209 .signed => @bitCast(u64, typed_value.val.toSignedInt(target)),1209 .signed => @bitCast(u64, typed_value.val.toSignedInt(mod)),
1210 .unsigned => typed_value.val.toUnsignedInt(target),1210 .unsigned => typed_value.val.toUnsignedInt(mod),
1211 };1211 };
1212 return GenResult.mcv(.{ .immediate = unsigned });1212 return GenResult.mcv(.{ .immediate = unsigned });
1213 }1213 }
...@@ -1216,7 +1216,7 @@ pub fn genTypedValue(...@@ -1216,7 +1216,7 @@ pub fn genTypedValue(
1216 return GenResult.mcv(.{ .immediate = @boolToInt(typed_value.val.toBool()) });1216 return GenResult.mcv(.{ .immediate = @boolToInt(typed_value.val.toBool()) });
1217 },1217 },
1218 .Optional => {1218 .Optional => {
1219 if (typed_value.ty.isPtrLikeOptional()) {1219 if (typed_value.ty.isPtrLikeOptional(mod)) {
1220 if (typed_value.val.tag() == .null_value) return GenResult.mcv(.{ .immediate = 0 });1220 if (typed_value.val.tag() == .null_value) return GenResult.mcv(.{ .immediate = 0 });
12211221
1222 var buf: Type.Payload.ElemType = undefined;1222 var buf: Type.Payload.ElemType = undefined;
...@@ -1224,8 +1224,8 @@ pub fn genTypedValue(...@@ -1224,8 +1224,8 @@ pub fn genTypedValue(
1224 .ty = typed_value.ty.optionalChild(&buf),1224 .ty = typed_value.ty.optionalChild(&buf),
1225 .val = if (typed_value.val.castTag(.opt_payload)) |pl| pl.data else typed_value.val,1225 .val = if (typed_value.val.castTag(.opt_payload)) |pl| pl.data else typed_value.val,
1226 }, owner_decl_index);1226 }, owner_decl_index);
1227 } else if (typed_value.ty.abiSize(target) == 1) {1227 } else if (typed_value.ty.abiSize(mod) == 1) {
1228 return GenResult.mcv(.{ .immediate = @boolToInt(!typed_value.val.isNull()) });1228 return GenResult.mcv(.{ .immediate = @boolToInt(!typed_value.val.isNull(mod)) });
1229 }1229 }
1230 },1230 },
1231 .Enum => {1231 .Enum => {
...@@ -1241,9 +1241,8 @@ pub fn genTypedValue(...@@ -1241,9 +1241,8 @@ pub fn genTypedValue(
1241 typed_value.ty.cast(Type.Payload.EnumFull).?.data.values;1241 typed_value.ty.cast(Type.Payload.EnumFull).?.data.values;
1242 if (enum_values.count() != 0) {1242 if (enum_values.count() != 0) {
1243 const tag_val = enum_values.keys()[field_index.data];1243 const tag_val = enum_values.keys()[field_index.data];
1244 var buf: Type.Payload.Bits = undefined;
1245 return genTypedValue(bin_file, src_loc, .{1244 return genTypedValue(bin_file, src_loc, .{
1246 .ty = typed_value.ty.intTagType(&buf),1245 .ty = typed_value.ty.intTagType(),
1247 .val = tag_val,1246 .val = tag_val,
1248 }, owner_decl_index);1247 }, owner_decl_index);
1249 } else {1248 } else {
...@@ -1253,8 +1252,7 @@ pub fn genTypedValue(...@@ -1253,8 +1252,7 @@ pub fn genTypedValue(
1253 else => unreachable,1252 else => unreachable,
1254 }1253 }
1255 } else {1254 } else {
1256 var int_tag_buffer: Type.Payload.Bits = undefined;1255 const int_tag_ty = typed_value.ty.intTagType();
1257 const int_tag_ty = typed_value.ty.intTagType(&int_tag_buffer);
1258 return genTypedValue(bin_file, src_loc, .{1256 return genTypedValue(bin_file, src_loc, .{
1259 .ty = int_tag_ty,1257 .ty = int_tag_ty,
1260 .val = typed_value.val,1258 .val = typed_value.val,
...@@ -1281,7 +1279,7 @@ pub fn genTypedValue(...@@ -1281,7 +1279,7 @@ pub fn genTypedValue(
1281 const payload_type = typed_value.ty.errorUnionPayload();1279 const payload_type = typed_value.ty.errorUnionPayload();
1282 const is_pl = typed_value.val.errorUnionIsPayload();1280 const is_pl = typed_value.val.errorUnionIsPayload();
12831281
1284 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {1282 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
1285 // We use the error type directly as the type.1283 // We use the error type directly as the type.
1286 const err_val = if (!is_pl) typed_value.val else Value.initTag(.zero);1284 const err_val = if (!is_pl) typed_value.val else Value.initTag(.zero);
1287 return genTypedValue(bin_file, src_loc, .{1285 return genTypedValue(bin_file, src_loc, .{
...@@ -1306,23 +1304,23 @@ pub fn genTypedValue(...@@ -1306,23 +1304,23 @@ pub fn genTypedValue(
1306 return genUnnamedConst(bin_file, src_loc, typed_value, owner_decl_index);1304 return genUnnamedConst(bin_file, src_loc, typed_value, owner_decl_index);
1307}1305}
13081306
1309pub fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u64 {1307pub fn errUnionPayloadOffset(payload_ty: Type, mod: *const Module) u64 {
1310 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return 0;1308 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return 0;
1311 const payload_align = payload_ty.abiAlignment(target);1309 const payload_align = payload_ty.abiAlignment(mod);
1312 const error_align = Type.anyerror.abiAlignment(target);1310 const error_align = Type.anyerror.abiAlignment(mod);
1313 if (payload_align >= error_align or !payload_ty.hasRuntimeBitsIgnoreComptime()) {1311 if (payload_align >= error_align or !payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1314 return 0;1312 return 0;
1315 } else {1313 } else {
1316 return mem.alignForwardGeneric(u64, Type.anyerror.abiSize(target), payload_align);1314 return mem.alignForwardGeneric(u64, Type.anyerror.abiSize(mod), payload_align);
1317 }1315 }
1318}1316}
13191317
1320pub fn errUnionErrorOffset(payload_ty: Type, target: std.Target) u64 {1318pub fn errUnionErrorOffset(payload_ty: Type, mod: *const Module) u64 {
1321 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return 0;1319 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return 0;
1322 const payload_align = payload_ty.abiAlignment(target);1320 const payload_align = payload_ty.abiAlignment(mod);
1323 const error_align = Type.anyerror.abiAlignment(target);1321 const error_align = Type.anyerror.abiAlignment(mod);
1324 if (payload_align >= error_align and payload_ty.hasRuntimeBitsIgnoreComptime()) {1322 if (payload_align >= error_align and payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1325 return mem.alignForwardGeneric(u64, payload_ty.abiSize(target), error_align);1323 return mem.alignForwardGeneric(u64, payload_ty.abiSize(mod), error_align);
1326 } else {1324 } else {
1327 return 0;1325 return 0;
1328 }1326 }
src/codegen/c.zig+368-359
...@@ -16,6 +16,7 @@ const trace = @import("../tracy.zig").trace;...@@ -16,6 +16,7 @@ const trace = @import("../tracy.zig").trace;
16const LazySrcLoc = Module.LazySrcLoc;16const LazySrcLoc = Module.LazySrcLoc;
17const Air = @import("../Air.zig");17const Air = @import("../Air.zig");
18const Liveness = @import("../Liveness.zig");18const Liveness = @import("../Liveness.zig");
19const InternPool = @import("../InternPool.zig");
1920
20const BigIntLimb = std.math.big.Limb;21const BigIntLimb = std.math.big.Limb;
21const BigInt = std.math.big.int;22const BigInt = std.math.big.int;
...@@ -285,10 +286,11 @@ pub const Function = struct {...@@ -285,10 +286,11 @@ pub const Function = struct {
285 const gop = try f.value_map.getOrPut(inst);286 const gop = try f.value_map.getOrPut(inst);
286 if (gop.found_existing) return gop.value_ptr.*;287 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).?;
289 const ty = f.air.typeOf(ref);291 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: {
292 const writer = f.object.code_header.writer();294 const writer = f.object.code_header.writer();
293 const alignment = 0;295 const alignment = 0;
294 const decl_c_value = try f.allocLocalValue(ty, alignment);296 const decl_c_value = try f.allocLocalValue(ty, alignment);
...@@ -318,11 +320,11 @@ pub const Function = struct {...@@ -318,11 +320,11 @@ pub const Function = struct {
318 /// those which go into `allocs`. This function does not add the resulting local into `allocs`;320 /// those which go into `allocs`. This function does not add the resulting local into `allocs`;
319 /// that responsibility lies with the caller.321 /// that responsibility lies with the caller.
320 fn allocLocalValue(f: *Function, ty: Type, alignment: u32) !CValue {322 fn allocLocalValue(f: *Function, ty: Type, alignment: u32) !CValue {
323 const mod = f.object.dg.module;
321 const gpa = f.object.dg.gpa;324 const gpa = f.object.dg.gpa;
322 const target = f.object.dg.module.getTarget();
323 try f.locals.append(gpa, .{325 try f.locals.append(gpa, .{
324 .cty_idx = try f.typeToIndex(ty, .complete),326 .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)),
326 });328 });
327 return .{ .new_local = @intCast(LocalIndex, f.locals.items.len - 1) };329 return .{ .new_local = @intCast(LocalIndex, f.locals.items.len - 1) };
328 }330 }
...@@ -336,10 +338,10 @@ pub const Function = struct {...@@ -336,10 +338,10 @@ pub const Function = struct {
336 /// Only allocates the local; does not print anything. Will attempt to re-use locals, so should338 /// Only allocates the local; does not print anything. Will attempt to re-use locals, so should
337 /// not be used for persistent locals (i.e. those in `allocs`).339 /// not be used for persistent locals (i.e. those in `allocs`).
338 fn allocAlignedLocal(f: *Function, ty: Type, _: CQualifiers, alignment: u32) !CValue {340 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;
340 if (f.free_locals_map.getPtr(.{342 if (f.free_locals_map.getPtr(.{
341 .cty_idx = try f.typeToIndex(ty, .complete),343 .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)),
343 })) |locals_list| {345 })) |locals_list| {
344 if (locals_list.popOrNull()) |local_entry| {346 if (locals_list.popOrNull()) |local_entry| {
345 return .{ .new_local = local_entry.key };347 return .{ .new_local = local_entry.key };
...@@ -352,8 +354,9 @@ pub const Function = struct {...@@ -352,8 +354,9 @@ pub const Function = struct {
352 fn writeCValue(f: *Function, w: anytype, c_value: CValue, location: ValueRenderLocation) !void {354 fn writeCValue(f: *Function, w: anytype, c_value: CValue, location: ValueRenderLocation) !void {
353 switch (c_value) {355 switch (c_value) {
354 .constant => |inst| {356 .constant => |inst| {
357 const mod = f.object.dg.module;
355 const ty = f.air.typeOf(inst);358 const ty = f.air.typeOf(inst);
356 const val = f.air.value(inst).?;359 const val = f.air.value(inst, mod).?;
357 return f.object.dg.renderValue(w, ty, val, location);360 return f.object.dg.renderValue(w, ty, val, location);
358 },361 },
359 .undef => |ty| return f.object.dg.renderValue(w, ty, Value.undef, location),362 .undef => |ty| return f.object.dg.renderValue(w, ty, Value.undef, location),
...@@ -364,8 +367,9 @@ pub const Function = struct {...@@ -364,8 +367,9 @@ pub const Function = struct {
364 fn writeCValueDeref(f: *Function, w: anytype, c_value: CValue) !void {367 fn writeCValueDeref(f: *Function, w: anytype, c_value: CValue) !void {
365 switch (c_value) {368 switch (c_value) {
366 .constant => |inst| {369 .constant => |inst| {
370 const mod = f.object.dg.module;
367 const ty = f.air.typeOf(inst);371 const ty = f.air.typeOf(inst);
368 const val = f.air.value(inst).?;372 const val = f.air.value(inst, mod).?;
369 try w.writeAll("(*");373 try w.writeAll("(*");
370 try f.object.dg.renderValue(w, ty, val, .Other);374 try f.object.dg.renderValue(w, ty, val, .Other);
371 return w.writeByte(')');375 return w.writeByte(')');
...@@ -377,8 +381,9 @@ pub const Function = struct {...@@ -377,8 +381,9 @@ pub const Function = struct {
377 fn writeCValueMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void {381 fn writeCValueMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void {
378 switch (c_value) {382 switch (c_value) {
379 .constant => |inst| {383 .constant => |inst| {
384 const mod = f.object.dg.module;
380 const ty = f.air.typeOf(inst);385 const ty = f.air.typeOf(inst);
381 const val = f.air.value(inst).?;386 const val = f.air.value(inst, mod).?;
382 try f.object.dg.renderValue(w, ty, val, .Other);387 try f.object.dg.renderValue(w, ty, val, .Other);
383 try w.writeByte('.');388 try w.writeByte('.');
384 return f.writeCValue(w, member, .Other);389 return f.writeCValue(w, member, .Other);
...@@ -390,8 +395,9 @@ pub const Function = struct {...@@ -390,8 +395,9 @@ pub const Function = struct {
390 fn writeCValueDerefMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void {395 fn writeCValueDerefMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void {
391 switch (c_value) {396 switch (c_value) {
392 .constant => |inst| {397 .constant => |inst| {
398 const mod = f.object.dg.module;
393 const ty = f.air.typeOf(inst);399 const ty = f.air.typeOf(inst);
394 const val = f.air.value(inst).?;400 const val = f.air.value(inst, mod).?;
395 try w.writeByte('(');401 try w.writeByte('(');
396 try f.object.dg.renderValue(w, ty, val, .Other);402 try f.object.dg.renderValue(w, ty, val, .Other);
397 try w.writeAll(")->");403 try w.writeAll(")->");
...@@ -522,11 +528,12 @@ pub const DeclGen = struct {...@@ -522,11 +528,12 @@ pub const DeclGen = struct {
522 decl_index: Decl.Index,528 decl_index: Decl.Index,
523 location: ValueRenderLocation,529 location: ValueRenderLocation,
524 ) error{ OutOfMemory, AnalysisFail }!void {530 ) error{ OutOfMemory, AnalysisFail }!void {
525 const decl = dg.module.declPtr(decl_index);531 const mod = dg.module;
532 const decl = mod.declPtr(decl_index);
526 assert(decl.has_tv);533 assert(decl.has_tv);
527534
528 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.535 // 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)) {
530 return dg.writeCValue(writer, .{ .undef = ty });537 return dg.writeCValue(writer, .{ .undef = ty });
531 }538 }
532539
...@@ -553,7 +560,7 @@ pub const DeclGen = struct {...@@ -553,7 +560,7 @@ pub const DeclGen = struct {
553560
554 var len_pl: Value.Payload.U64 = .{561 var len_pl: Value.Payload.U64 = .{
555 .base = .{ .tag = .int_u64 },562 .base = .{ .tag = .int_u64 },
556 .data = val.sliceLen(dg.module),563 .data = val.sliceLen(mod),
557 };564 };
558 const len_val = Value.initPayload(&len_pl.base);565 const len_val = Value.initPayload(&len_pl.base);
559566
...@@ -568,7 +575,7 @@ pub const DeclGen = struct {...@@ -568,7 +575,7 @@ pub const DeclGen = struct {
568 // them). The analysis until now should ensure that the C function575 // them). The analysis until now should ensure that the C function
569 // pointers are compatible. If they are not, then there is a bug576 // pointers are compatible. If they are not, then there is a bug
570 // somewhere and we should let the C compiler tell us about it.577 // 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);
572 if (need_typecast) {579 if (need_typecast) {
573 try writer.writeAll("((");580 try writer.writeAll("((");
574 try dg.renderType(writer, ty);581 try dg.renderType(writer, ty);
...@@ -584,6 +591,8 @@ pub const DeclGen = struct {...@@ -584,6 +591,8 @@ pub const DeclGen = struct {
584 //591 //
585 // Used for .elem_ptr, .field_ptr, .opt_payload_ptr, .eu_payload_ptr592 // Used for .elem_ptr, .field_ptr, .opt_payload_ptr, .eu_payload_ptr
586 fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type, location: ValueRenderLocation) error{ OutOfMemory, AnalysisFail }!void {593 fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type, location: ValueRenderLocation) error{ OutOfMemory, AnalysisFail }!void {
594 const mod = dg.module;
595
587 if (!ptr_ty.isSlice()) {596 if (!ptr_ty.isSlice()) {
588 try writer.writeByte('(');597 try writer.writeByte('(');
589 try dg.renderType(writer, ptr_ty);598 try dg.renderType(writer, ptr_ty);
...@@ -601,7 +610,6 @@ pub const DeclGen = struct {...@@ -601,7 +610,6 @@ pub const DeclGen = struct {
601 try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl_index, location);610 try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl_index, location);
602 },611 },
603 .field_ptr => {612 .field_ptr => {
604 const target = dg.module.getTarget();
605 const field_ptr = ptr_val.castTag(.field_ptr).?.data;613 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
606614
607 // Ensure complete type definition is visible before accessing fields.615 // Ensure complete type definition is visible before accessing fields.
...@@ -615,7 +623,7 @@ pub const DeclGen = struct {...@@ -615,7 +623,7 @@ pub const DeclGen = struct {
615 field_ptr.container_ty,623 field_ptr.container_ty,
616 ptr_ty,624 ptr_ty,
617 @intCast(u32, field_ptr.field_index),625 @intCast(u32, field_ptr.field_index),
618 target,626 mod,
619 )) {627 )) {
620 .begin => try dg.renderParentPtr(628 .begin => try dg.renderParentPtr(
621 writer,629 writer,
...@@ -714,19 +722,20 @@ pub const DeclGen = struct {...@@ -714,19 +722,20 @@ pub const DeclGen = struct {
714 if (val.castTag(.runtime_value)) |rt| {722 if (val.castTag(.runtime_value)) |rt| {
715 val = rt.data;723 val = rt.data;
716 }724 }
717 const target = dg.module.getTarget();725 const mod = dg.module;
726 const target = mod.getTarget();
718 const initializer_type: ValueRenderLocation = switch (location) {727 const initializer_type: ValueRenderLocation = switch (location) {
719 .StaticInitializer => .StaticInitializer,728 .StaticInitializer => .StaticInitializer,
720 else => .Initializer,729 else => .Initializer,
721 };730 };
722731
723 const safety_on = switch (dg.module.optimizeMode()) {732 const safety_on = switch (mod.optimizeMode()) {
724 .Debug, .ReleaseSafe => true,733 .Debug, .ReleaseSafe => true,
725 .ReleaseFast, .ReleaseSmall => false,734 .ReleaseFast, .ReleaseSmall => false,
726 };735 };
727736
728 if (val.isUndefDeep()) {737 if (val.isUndefDeep()) {
729 switch (ty.zigTypeTag()) {738 switch (ty.zigTypeTag(mod)) {
730 .Bool => {739 .Bool => {
731 if (safety_on) {740 if (safety_on) {
732 return writer.writeAll("0xaa");741 return writer.writeAll("0xaa");
...@@ -737,8 +746,8 @@ pub const DeclGen = struct {...@@ -737,8 +746,8 @@ pub const DeclGen = struct {
737 .Int, .Enum, .ErrorSet => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, val, location)}),746 .Int, .Enum, .ErrorSet => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, val, location)}),
738 .Float => {747 .Float => {
739 const bits = ty.floatBits(target);748 const bits = ty.floatBits(target);
740 var repr_pl = Type.Payload.Bits{ .base = .{ .tag = .int_unsigned }, .data = bits };749 // All unsigned ints matching float types are pre-allocated.
741 const repr_ty = Type.initPayload(&repr_pl.base);750 const repr_ty = mod.intType(.unsigned, bits) catch unreachable;
742751
743 try writer.writeAll("zig_cast_");752 try writer.writeAll("zig_cast_");
744 try dg.renderTypeForBuiltinFnName(writer, ty);753 try dg.renderTypeForBuiltinFnName(writer, ty);
...@@ -778,11 +787,11 @@ pub const DeclGen = struct {...@@ -778,11 +787,11 @@ pub const DeclGen = struct {
778 var opt_buf: Type.Payload.ElemType = undefined;787 var opt_buf: Type.Payload.ElemType = undefined;
779 const payload_ty = ty.optionalChild(&opt_buf);788 const payload_ty = ty.optionalChild(&opt_buf);
780789
781 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {790 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
782 return dg.renderValue(writer, Type.bool, val, location);791 return dg.renderValue(writer, Type.bool, val, location);
783 }792 }
784793
785 if (ty.optionalReprIsPayload()) {794 if (ty.optionalReprIsPayload(mod)) {
786 return dg.renderValue(writer, payload_ty, val, location);795 return dg.renderValue(writer, payload_ty, val, location);
787 }796 }
788797
...@@ -811,7 +820,7 @@ pub const DeclGen = struct {...@@ -811,7 +820,7 @@ pub const DeclGen = struct {
811 for (0..ty.structFieldCount()) |field_i| {820 for (0..ty.structFieldCount()) |field_i| {
812 if (ty.structFieldIsComptime(field_i)) continue;821 if (ty.structFieldIsComptime(field_i)) continue;
813 const field_ty = ty.structFieldType(field_i);822 const field_ty = ty.structFieldType(field_i);
814 if (!field_ty.hasRuntimeBits()) continue;823 if (!field_ty.hasRuntimeBits(mod)) continue;
815824
816 if (!empty) try writer.writeByte(',');825 if (!empty) try writer.writeByte(',');
817 try dg.renderValue(writer, field_ty, val, initializer_type);826 try dg.renderValue(writer, field_ty, val, initializer_type);
...@@ -832,17 +841,17 @@ pub const DeclGen = struct {...@@ -832,17 +841,17 @@ pub const DeclGen = struct {
832841
833 try writer.writeByte('{');842 try writer.writeByte('{');
834 if (ty.unionTagTypeSafety()) |tag_ty| {843 if (ty.unionTagTypeSafety()) |tag_ty| {
835 const layout = ty.unionGetLayout(target);844 const layout = ty.unionGetLayout(mod);
836 if (layout.tag_size != 0) {845 if (layout.tag_size != 0) {
837 try writer.writeAll(" .tag = ");846 try writer.writeAll(" .tag = ");
838 try dg.renderValue(writer, tag_ty, val, initializer_type);847 try dg.renderValue(writer, tag_ty, val, initializer_type);
839 }848 }
840 if (ty.unionHasAllZeroBitFieldTypes()) return try writer.writeByte('}');849 if (ty.unionHasAllZeroBitFieldTypes(mod)) return try writer.writeByte('}');
841 if (layout.tag_size != 0) try writer.writeByte(',');850 if (layout.tag_size != 0) try writer.writeByte(',');
842 try writer.writeAll(" .payload = {");851 try writer.writeAll(" .payload = {");
843 }852 }
844 for (ty.unionFields().values()) |field| {853 for (ty.unionFields().values()) |field| {
845 if (!field.ty.hasRuntimeBits()) continue;854 if (!field.ty.hasRuntimeBits(mod)) continue;
846 try dg.renderValue(writer, field.ty, val, initializer_type);855 try dg.renderValue(writer, field.ty, val, initializer_type);
847 break;856 break;
848 }857 }
...@@ -853,7 +862,7 @@ pub const DeclGen = struct {...@@ -853,7 +862,7 @@ pub const DeclGen = struct {
853 const payload_ty = ty.errorUnionPayload();862 const payload_ty = ty.errorUnionPayload();
854 const error_ty = ty.errorUnionSet();863 const error_ty = ty.errorUnionSet();
855864
856 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {865 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
857 return dg.renderValue(writer, error_ty, val, location);866 return dg.renderValue(writer, error_ty, val, location);
858 }867 }
859868
...@@ -916,7 +925,7 @@ pub const DeclGen = struct {...@@ -916,7 +925,7 @@ pub const DeclGen = struct {
916 }925 }
917 unreachable;926 unreachable;
918 }927 }
919 switch (ty.zigTypeTag()) {928 switch (ty.zigTypeTag(mod)) {
920 .Int => switch (val.tag()) {929 .Int => switch (val.tag()) {
921 .field_ptr,930 .field_ptr,
922 .elem_ptr,931 .elem_ptr,
...@@ -931,8 +940,8 @@ pub const DeclGen = struct {...@@ -931,8 +940,8 @@ pub const DeclGen = struct {
931 const bits = ty.floatBits(target);940 const bits = ty.floatBits(target);
932 const f128_val = val.toFloat(f128);941 const f128_val = val.toFloat(f128);
933942
934 var repr_ty_pl = Type.Payload.Bits{ .base = .{ .tag = .int_unsigned }, .data = bits };943 // All unsigned ints matching float types are pre-allocated.
935 const repr_ty = Type.initPayload(&repr_ty_pl.base);944 const repr_ty = mod.intType(.unsigned, bits) catch unreachable;
936945
937 assert(bits <= 128);946 assert(bits <= 128);
938 var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined;947 var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined;
...@@ -1109,7 +1118,7 @@ pub const DeclGen = struct {...@@ -1109,7 +1118,7 @@ pub const DeclGen = struct {
1109 },1118 },
1110 else => unreachable,1119 else => unreachable,
1111 };1120 };
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;
1113 try writer.print("{s}", .{1122 try writer.print("{s}", .{
1114 fmtStringLiteral(bytes[0..@intCast(usize, ty.arrayLen())], sentinel),1123 fmtStringLiteral(bytes[0..@intCast(usize, ty.arrayLen())], sentinel),
1115 });1124 });
...@@ -1131,11 +1140,11 @@ pub const DeclGen = struct {...@@ -1131,11 +1140,11 @@ pub const DeclGen = struct {
1131 var index: usize = 0;1140 var index: usize = 0;
1132 while (index < ai.len) : (index += 1) {1141 while (index < ai.len) : (index += 1) {
1133 const elem_val = try val.elemValue(dg.module, arena_allocator, index);1142 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));
1135 try literal.writeChar(elem_val_u8);1144 try literal.writeChar(elem_val_u8);
1136 }1145 }
1137 if (ai.sentinel) |s| {1146 if (ai.sentinel) |s| {
1138 const s_u8 = @intCast(u8, s.toUnsignedInt(target));1147 const s_u8 = @intCast(u8, s.toUnsignedInt(mod));
1139 if (s_u8 != 0) try literal.writeChar(s_u8);1148 if (s_u8 != 0) try literal.writeChar(s_u8);
1140 }1149 }
1141 try literal.end();1150 try literal.end();
...@@ -1145,7 +1154,7 @@ pub const DeclGen = struct {...@@ -1145,7 +1154,7 @@ pub const DeclGen = struct {
1145 while (index < ai.len) : (index += 1) {1154 while (index < ai.len) : (index += 1) {
1146 if (index != 0) try writer.writeByte(',');1155 if (index != 0) try writer.writeByte(',');
1147 const elem_val = try val.elemValue(dg.module, arena_allocator, index);1156 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));
1149 try writer.print("'\\x{x}'", .{elem_val_u8});1158 try writer.print("'\\x{x}'", .{elem_val_u8});
1150 }1159 }
1151 if (ai.sentinel) |s| {1160 if (ai.sentinel) |s| {
...@@ -1183,10 +1192,10 @@ pub const DeclGen = struct {...@@ -1183,10 +1192,10 @@ pub const DeclGen = struct {
1183 const payload_ty = ty.optionalChild(&opt_buf);1192 const payload_ty = ty.optionalChild(&opt_buf);
11841193
1185 const is_null_val = Value.makeBool(val.tag() == .null_value);1194 const is_null_val = Value.makeBool(val.tag() == .null_value);
1186 if (!payload_ty.hasRuntimeBitsIgnoreComptime())1195 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
1187 return dg.renderValue(writer, Type.bool, is_null_val, location);1196 return dg.renderValue(writer, Type.bool, is_null_val, location);
11881197
1189 if (ty.optionalReprIsPayload()) {1198 if (ty.optionalReprIsPayload(mod)) {
1190 const payload_val = if (val.castTag(.opt_payload)) |pl| pl.data else val;1199 const payload_val = if (val.castTag(.opt_payload)) |pl| pl.data else val;
1191 return dg.renderValue(writer, payload_ty, payload_val, location);1200 return dg.renderValue(writer, payload_ty, payload_val, location);
1192 }1201 }
...@@ -1218,7 +1227,7 @@ pub const DeclGen = struct {...@@ -1218,7 +1227,7 @@ pub const DeclGen = struct {
1218 const error_ty = ty.errorUnionSet();1227 const error_ty = ty.errorUnionSet();
1219 const error_val = if (val.errorUnionIsPayload()) Value.zero else val;1228 const error_val = if (val.errorUnionIsPayload()) Value.zero else val;
12201229
1221 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1230 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1222 return dg.renderValue(writer, error_ty, error_val, location);1231 return dg.renderValue(writer, error_ty, error_val, location);
1223 }1232 }
12241233
...@@ -1263,8 +1272,7 @@ pub const DeclGen = struct {...@@ -1263,8 +1272,7 @@ pub const DeclGen = struct {
1263 }1272 }
1264 },1273 },
1265 else => {1274 else => {
1266 var int_tag_ty_buffer: Type.Payload.Bits = undefined;1275 const int_tag_ty = ty.intTagType();
1267 const int_tag_ty = ty.intTagType(&int_tag_ty_buffer);
1268 return dg.renderValue(writer, int_tag_ty, val, location);1276 return dg.renderValue(writer, int_tag_ty, val, location);
1269 },1277 },
1270 }1278 }
...@@ -1295,7 +1303,7 @@ pub const DeclGen = struct {...@@ -1295,7 +1303,7 @@ pub const DeclGen = struct {
1295 for (field_vals, 0..) |field_val, field_i| {1303 for (field_vals, 0..) |field_val, field_i| {
1296 if (ty.structFieldIsComptime(field_i)) continue;1304 if (ty.structFieldIsComptime(field_i)) continue;
1297 const field_ty = ty.structFieldType(field_i);1305 const field_ty = ty.structFieldType(field_i);
1298 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;1306 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
12991307
1300 if (!empty) try writer.writeByte(',');1308 if (!empty) try writer.writeByte(',');
1301 try dg.renderValue(writer, field_ty, field_val, initializer_type);1309 try dg.renderValue(writer, field_ty, field_val, initializer_type);
...@@ -1306,13 +1314,10 @@ pub const DeclGen = struct {...@@ -1306,13 +1314,10 @@ pub const DeclGen = struct {
1306 },1314 },
1307 .Packed => {1315 .Packed => {
1308 const field_vals = val.castTag(.aggregate).?.data;1316 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{1319 const bits = Type.smallestUnsignedBits(int_info.bits - 1);
1312 .base = .{ .tag = .int_unsigned },1320 const bit_offset_ty = try mod.intType(.unsigned, bits);
1313 .data = Type.smallestUnsignedBits(int_info.bits - 1),
1314 };
1315 const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base);
13161321
1317 var bit_offset_val_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = 0 };1322 var bit_offset_val_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = 0 };
1318 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);1323 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
...@@ -1321,7 +1326,7 @@ pub const DeclGen = struct {...@@ -1321,7 +1326,7 @@ pub const DeclGen = struct {
1321 for (0..field_vals.len) |field_i| {1326 for (0..field_vals.len) |field_i| {
1322 if (ty.structFieldIsComptime(field_i)) continue;1327 if (ty.structFieldIsComptime(field_i)) continue;
1323 const field_ty = ty.structFieldType(field_i);1328 const field_ty = ty.structFieldType(field_i);
1324 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;1329 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
13251330
1326 eff_num_fields += 1;1331 eff_num_fields += 1;
1327 }1332 }
...@@ -1330,7 +1335,7 @@ pub const DeclGen = struct {...@@ -1330,7 +1335,7 @@ pub const DeclGen = struct {
1330 try writer.writeByte('(');1335 try writer.writeByte('(');
1331 try dg.renderValue(writer, ty, Value.undef, initializer_type);1336 try dg.renderValue(writer, ty, Value.undef, initializer_type);
1332 try writer.writeByte(')');1337 try writer.writeByte(')');
1333 } else if (ty.bitSize(target) > 64) {1338 } else if (ty.bitSize(mod) > 64) {
1334 // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))1339 // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))
1335 var num_or = eff_num_fields - 1;1340 var num_or = eff_num_fields - 1;
1336 while (num_or > 0) : (num_or -= 1) {1341 while (num_or > 0) : (num_or -= 1) {
...@@ -1344,7 +1349,7 @@ pub const DeclGen = struct {...@@ -1344,7 +1349,7 @@ pub const DeclGen = struct {
1344 for (field_vals, 0..) |field_val, field_i| {1349 for (field_vals, 0..) |field_val, field_i| {
1345 if (ty.structFieldIsComptime(field_i)) continue;1350 if (ty.structFieldIsComptime(field_i)) continue;
1346 const field_ty = ty.structFieldType(field_i);1351 const field_ty = ty.structFieldType(field_i);
1347 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;1352 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
13481353
1349 const cast_context = IntCastContext{ .value = .{ .value = field_val } };1354 const cast_context = IntCastContext{ .value = .{ .value = field_val } };
1350 if (bit_offset_val_pl.data != 0) {1355 if (bit_offset_val_pl.data != 0) {
...@@ -1362,7 +1367,7 @@ pub const DeclGen = struct {...@@ -1362,7 +1367,7 @@ pub const DeclGen = struct {
1362 if (needs_closing_paren) try writer.writeByte(')');1367 if (needs_closing_paren) try writer.writeByte(')');
1363 if (eff_index != eff_num_fields - 1) try writer.writeAll(", ");1368 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);
1366 needs_closing_paren = true;1371 needs_closing_paren = true;
1367 eff_index += 1;1372 eff_index += 1;
1368 }1373 }
...@@ -1373,7 +1378,7 @@ pub const DeclGen = struct {...@@ -1373,7 +1378,7 @@ pub const DeclGen = struct {
1373 for (field_vals, 0..) |field_val, field_i| {1378 for (field_vals, 0..) |field_val, field_i| {
1374 if (ty.structFieldIsComptime(field_i)) continue;1379 if (ty.structFieldIsComptime(field_i)) continue;
1375 const field_ty = ty.structFieldType(field_i);1380 const field_ty = ty.structFieldType(field_i);
1376 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;1381 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
13771382
1378 if (!empty) try writer.writeAll(" | ");1383 if (!empty) try writer.writeAll(" | ");
1379 try writer.writeByte('(');1384 try writer.writeByte('(');
...@@ -1388,7 +1393,7 @@ pub const DeclGen = struct {...@@ -1388,7 +1393,7 @@ pub const DeclGen = struct {
1388 try dg.renderValue(writer, field_ty, field_val, .Other);1393 try dg.renderValue(writer, field_ty, field_val, .Other);
1389 }1394 }
13901395
1391 bit_offset_val_pl.data += field_ty.bitSize(target);1396 bit_offset_val_pl.data += field_ty.bitSize(mod);
1392 empty = false;1397 empty = false;
1393 }1398 }
1394 try writer.writeByte(')');1399 try writer.writeByte(')');
...@@ -1408,12 +1413,12 @@ pub const DeclGen = struct {...@@ -1408,12 +1413,12 @@ pub const DeclGen = struct {
1408 const field_ty = ty.unionFields().values()[field_i].ty;1413 const field_ty = ty.unionFields().values()[field_i].ty;
1409 const field_name = ty.unionFields().keys()[field_i];1414 const field_name = ty.unionFields().keys()[field_i];
1410 if (ty.containerLayout() == .Packed) {1415 if (ty.containerLayout() == .Packed) {
1411 if (field_ty.hasRuntimeBits()) {1416 if (field_ty.hasRuntimeBits(mod)) {
1412 if (field_ty.isPtrAtRuntime()) {1417 if (field_ty.isPtrAtRuntime(mod)) {
1413 try writer.writeByte('(');1418 try writer.writeByte('(');
1414 try dg.renderType(writer, ty);1419 try dg.renderType(writer, ty);
1415 try writer.writeByte(')');1420 try writer.writeByte(')');
1416 } else if (field_ty.zigTypeTag() == .Float) {1421 } else if (field_ty.zigTypeTag(mod) == .Float) {
1417 try writer.writeByte('(');1422 try writer.writeByte('(');
1418 try dg.renderType(writer, ty);1423 try dg.renderType(writer, ty);
1419 try writer.writeByte(')');1424 try writer.writeByte(')');
...@@ -1427,21 +1432,21 @@ pub const DeclGen = struct {...@@ -1427,21 +1432,21 @@ pub const DeclGen = struct {
14271432
1428 try writer.writeByte('{');1433 try writer.writeByte('{');
1429 if (ty.unionTagTypeSafety()) |tag_ty| {1434 if (ty.unionTagTypeSafety()) |tag_ty| {
1430 const layout = ty.unionGetLayout(target);1435 const layout = ty.unionGetLayout(mod);
1431 if (layout.tag_size != 0) {1436 if (layout.tag_size != 0) {
1432 try writer.writeAll(" .tag = ");1437 try writer.writeAll(" .tag = ");
1433 try dg.renderValue(writer, tag_ty, union_obj.tag, initializer_type);1438 try dg.renderValue(writer, tag_ty, union_obj.tag, initializer_type);
1434 }1439 }
1435 if (ty.unionHasAllZeroBitFieldTypes()) return try writer.writeByte('}');1440 if (ty.unionHasAllZeroBitFieldTypes(mod)) return try writer.writeByte('}');
1436 if (layout.tag_size != 0) try writer.writeByte(',');1441 if (layout.tag_size != 0) try writer.writeByte(',');
1437 try writer.writeAll(" .payload = {");1442 try writer.writeAll(" .payload = {");
1438 }1443 }
1439 if (field_ty.hasRuntimeBits()) {1444 if (field_ty.hasRuntimeBits(mod)) {
1440 try writer.print(" .{ } = ", .{fmtIdent(field_name)});1445 try writer.print(" .{ } = ", .{fmtIdent(field_name)});
1441 try dg.renderValue(writer, field_ty, union_obj.val, initializer_type);1446 try dg.renderValue(writer, field_ty, union_obj.val, initializer_type);
1442 try writer.writeByte(' ');1447 try writer.writeByte(' ');
1443 } else for (ty.unionFields().values()) |field| {1448 } else for (ty.unionFields().values()) |field| {
1444 if (!field.ty.hasRuntimeBits()) continue;1449 if (!field.ty.hasRuntimeBits(mod)) continue;
1445 try dg.renderValue(writer, field.ty, Value.undef, initializer_type);1450 try dg.renderValue(writer, field.ty, Value.undef, initializer_type);
1446 break;1451 break;
1447 }1452 }
...@@ -1478,9 +1483,9 @@ pub const DeclGen = struct {...@@ -1478,9 +1483,9 @@ pub const DeclGen = struct {
1478 },1483 },
1479 ) !void {1484 ) !void {
1480 const store = &dg.ctypes.set;1485 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);
1484 const fn_cty_idx = try dg.typeToIndex(fn_decl.ty, kind);1489 const fn_cty_idx = try dg.typeToIndex(fn_decl.ty, kind);
14851490
1486 const fn_info = fn_decl.ty.fnInfo();1491 const fn_info = fn_decl.ty.fnInfo();
...@@ -1498,7 +1503,7 @@ pub const DeclGen = struct {...@@ -1498,7 +1503,7 @@ pub const DeclGen = struct {
1498 const trailing = try renderTypePrefix(1503 const trailing = try renderTypePrefix(
1499 dg.decl_index,1504 dg.decl_index,
1500 store.*,1505 store.*,
1501 module,1506 mod,
1502 w,1507 w,
1503 fn_cty_idx,1508 fn_cty_idx,
1504 .suffix,1509 .suffix,
...@@ -1525,7 +1530,7 @@ pub const DeclGen = struct {...@@ -1525,7 +1530,7 @@ pub const DeclGen = struct {
1525 try renderTypeSuffix(1530 try renderTypeSuffix(
1526 dg.decl_index,1531 dg.decl_index,
1527 store.*,1532 store.*,
1528 module,1533 mod,
1529 w,1534 w,
1530 fn_cty_idx,1535 fn_cty_idx,
1531 .suffix,1536 .suffix,
...@@ -1577,9 +1582,9 @@ pub const DeclGen = struct {...@@ -1577,9 +1582,9 @@ pub const DeclGen = struct {
15771582
1578 fn renderCType(dg: *DeclGen, w: anytype, idx: CType.Index) error{ OutOfMemory, AnalysisFail }!void {1583 fn renderCType(dg: *DeclGen, w: anytype, idx: CType.Index) error{ OutOfMemory, AnalysisFail }!void {
1579 const store = &dg.ctypes.set;1584 const store = &dg.ctypes.set;
1580 const module = dg.module;1585 const mod = dg.module;
1581 _ = try renderTypePrefix(dg.decl_index, store.*, module, w, idx, .suffix, .{});1586 _ = try renderTypePrefix(dg.decl_index, store.*, mod, w, idx, .suffix, .{});
1582 try renderTypeSuffix(dg.decl_index, store.*, module, w, idx, .suffix, .{});1587 try renderTypeSuffix(dg.decl_index, store.*, mod, w, idx, .suffix, .{});
1583 }1588 }
15841589
1585 const IntCastContext = union(enum) {1590 const IntCastContext = union(enum) {
...@@ -1619,18 +1624,18 @@ pub const DeclGen = struct {...@@ -1619,18 +1624,18 @@ pub const DeclGen = struct {
1619 /// | > 64 bit integer | < 64 bit integer | zig_make_<dest_ty>(0, src)1624 /// | > 64 bit integer | < 64 bit integer | zig_make_<dest_ty>(0, src)
1620 /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))1625 /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))
1621 fn renderIntCast(dg: *DeclGen, w: anytype, dest_ty: Type, context: IntCastContext, src_ty: Type, location: ValueRenderLocation) !void {1626 fn renderIntCast(dg: *DeclGen, w: anytype, dest_ty: Type, context: IntCastContext, src_ty: Type, location: ValueRenderLocation) !void {
1622 const target = dg.module.getTarget();1627 const mod = dg.module;
1623 const dest_bits = dest_ty.bitSize(target);1628 const dest_bits = dest_ty.bitSize(mod);
1624 const dest_int_info = dest_ty.intInfo(target);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);
1627 const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) {1632 const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) {
1628 .unsigned => Type.usize,1633 .unsigned => Type.usize,
1629 .signed => Type.isize,1634 .signed => Type.isize,
1630 } else src_ty;1635 } else src_ty;
16311636
1632 const src_bits = src_eff_ty.bitSize(target);1637 const src_bits = src_eff_ty.bitSize(mod);
1633 const src_int_info = if (src_eff_ty.isAbiInt()) src_eff_ty.intInfo(target) else null;1638 const src_int_info = if (src_eff_ty.isAbiInt(mod)) src_eff_ty.intInfo(mod) else null;
1634 if (dest_bits <= 64 and src_bits <= 64) {1639 if (dest_bits <= 64 and src_bits <= 64) {
1635 const needs_cast = src_int_info == null or1640 const needs_cast = src_int_info == null or
1636 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or1641 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or
...@@ -1703,8 +1708,8 @@ pub const DeclGen = struct {...@@ -1703,8 +1708,8 @@ pub const DeclGen = struct {
1703 alignment: u32,1708 alignment: u32,
1704 kind: CType.Kind,1709 kind: CType.Kind,
1705 ) error{ OutOfMemory, AnalysisFail }!void {1710 ) error{ OutOfMemory, AnalysisFail }!void {
1706 const target = dg.module.getTarget();1711 const mod = dg.module;
1707 const alignas = CType.AlignAs.init(alignment, ty.abiAlignment(target));1712 const alignas = CType.AlignAs.init(alignment, ty.abiAlignment(mod));
1708 try dg.renderCTypeAndName(w, try dg.typeToIndex(ty, kind), name, qualifiers, alignas);1713 try dg.renderCTypeAndName(w, try dg.typeToIndex(ty, kind), name, qualifiers, alignas);
1709 }1714 }
17101715
...@@ -1717,7 +1722,7 @@ pub const DeclGen = struct {...@@ -1717,7 +1722,7 @@ pub const DeclGen = struct {
1717 alignas: CType.AlignAs,1722 alignas: CType.AlignAs,
1718 ) error{ OutOfMemory, AnalysisFail }!void {1723 ) error{ OutOfMemory, AnalysisFail }!void {
1719 const store = &dg.ctypes.set;1724 const store = &dg.ctypes.set;
1720 const module = dg.module;1725 const mod = dg.module;
17211726
1722 switch (std.math.order(alignas.@"align", alignas.abi)) {1727 switch (std.math.order(alignas.@"align", alignas.abi)) {
1723 .lt => try w.print("zig_under_align({}) ", .{alignas.getAlign()}),1728 .lt => try w.print("zig_under_align({}) ", .{alignas.getAlign()}),
...@@ -1726,22 +1731,23 @@ pub const DeclGen = struct {...@@ -1726,22 +1731,23 @@ pub const DeclGen = struct {
1726 }1731 }
17271732
1728 const trailing =1733 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);
1730 try w.print("{}", .{trailing});1735 try w.print("{}", .{trailing});
1731 try dg.writeCValue(w, name);1736 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, .{});
1733 }1738 }
17341739
1735 fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {1740 fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {
1741 const mod = dg.module;
1736 switch (tv.val.tag()) {1742 switch (tv.val.tag()) {
1737 .extern_fn => return true,1743 .extern_fn => return true,
1738 .function => {1744 .function => {
1739 const func = tv.val.castTag(.function).?.data;1745 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);
1741 },1747 },
1742 .variable => {1748 .variable => {
1743 const variable = tv.val.castTag(.variable).?.data;1749 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);
1745 },1751 },
1746 else => unreachable,1752 else => unreachable,
1747 }1753 }
...@@ -1838,10 +1844,11 @@ pub const DeclGen = struct {...@@ -1838,10 +1844,11 @@ pub const DeclGen = struct {
1838 }1844 }
18391845
1840 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: Decl.Index, export_index: u32) !void {1846 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: Decl.Index, export_index: u32) !void {
1841 const decl = dg.module.declPtr(decl_index);1847 const mod = dg.module;
1842 dg.module.markDeclAlive(decl);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| {
1845 try writer.writeAll(exports.items[export_index].options.name);1852 try writer.writeAll(exports.items[export_index].options.name);
1846 } else if (decl.isExtern()) {1853 } else if (decl.isExtern()) {
1847 try writer.writeAll(mem.span(decl.name));1854 try writer.writeAll(mem.span(decl.name));
...@@ -1850,7 +1857,7 @@ pub const DeclGen = struct {...@@ -1850,7 +1857,7 @@ pub const DeclGen = struct {
1850 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.1857 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
1851 var name: [100]u8 = undefined;1858 var name: [100]u8 = undefined;
1852 var name_stream = std.io.fixedBufferStream(&name);1859 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) {
1854 error.NoSpaceLeft => {},1861 error.NoSpaceLeft => {},
1855 };1862 };
1856 try writer.print("{}__{d}", .{1863 try writer.print("{}__{d}", .{
...@@ -1894,10 +1901,10 @@ pub const DeclGen = struct {...@@ -1894,10 +1901,10 @@ pub const DeclGen = struct {
1894 .bits => {},1901 .bits => {},
1895 }1902 }
18961903
1897 const target = dg.module.getTarget();1904 const mod = dg.module;
1898 const int_info = if (ty.isAbiInt()) ty.intInfo(target) else std.builtin.Type.Int{1905 const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{
1899 .signedness = .unsigned,1906 .signedness = .unsigned,
1900 .bits = @intCast(u16, ty.bitSize(target)),1907 .bits = @intCast(u16, ty.bitSize(mod)),
1901 };1908 };
19021909
1903 if (is_big) try writer.print(", {}", .{int_info.signedness == .signed});1910 if (is_big) try writer.print(", {}", .{int_info.signedness == .signed});
...@@ -1916,6 +1923,7 @@ pub const DeclGen = struct {...@@ -1916,6 +1923,7 @@ pub const DeclGen = struct {
1916 val: Value,1923 val: Value,
1917 loc: ValueRenderLocation,1924 loc: ValueRenderLocation,
1918 ) !std.fmt.Formatter(formatIntLiteral) {1925 ) !std.fmt.Formatter(formatIntLiteral) {
1926 const mod = dg.module;
1919 const kind: CType.Kind = switch (loc) {1927 const kind: CType.Kind = switch (loc) {
1920 .FunctionArgument => .parameter,1928 .FunctionArgument => .parameter,
1921 .Initializer, .Other => .complete,1929 .Initializer, .Other => .complete,
...@@ -1923,7 +1931,7 @@ pub const DeclGen = struct {...@@ -1923,7 +1931,7 @@ pub const DeclGen = struct {
1923 };1931 };
1924 return std.fmt.Formatter(formatIntLiteral){ .data = .{1932 return std.fmt.Formatter(formatIntLiteral){ .data = .{
1925 .dg = dg,1933 .dg = dg,
1926 .int_info = ty.intInfo(dg.module.getTarget()),1934 .int_info = ty.intInfo(mod),
1927 .kind = kind,1935 .kind = kind,
1928 .cty = try dg.typeToCType(ty, kind),1936 .cty = try dg.typeToCType(ty, kind),
1929 .val = val,1937 .val = val,
...@@ -2646,11 +2654,12 @@ pub fn genDecl(o: *Object) !void {...@@ -2646,11 +2654,12 @@ pub fn genDecl(o: *Object) !void {
2646 const tracy = trace(@src());2654 const tracy = trace(@src());
2647 defer tracy.end();2655 defer tracy.end();
26482656
2657 const mod = o.dg.module;
2649 const decl = o.dg.decl.?;2658 const decl = o.dg.decl.?;
2650 const decl_c_value = .{ .decl = o.dg.decl_index.unwrap().? };2659 const decl_c_value = .{ .decl = o.dg.decl_index.unwrap().? };
2651 const tv: TypedValue = .{ .ty = decl.ty, .val = decl.val };2660 const tv: TypedValue = .{ .ty = decl.ty, .val = decl.val };
26522661
2653 if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime()) return;2662 if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return;
2654 if (tv.val.tag() == .extern_fn) {2663 if (tv.val.tag() == .extern_fn) {
2655 const fwd_decl_writer = o.dg.fwd_decl.writer();2664 const fwd_decl_writer = o.dg.fwd_decl.writer();
2656 try fwd_decl_writer.writeAll("zig_extern ");2665 try fwd_decl_writer.writeAll("zig_extern ");
...@@ -2704,8 +2713,9 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {...@@ -2704,8 +2713,9 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
2704 .val = dg.decl.?.val,2713 .val = dg.decl.?.val,
2705 };2714 };
2706 const writer = dg.fwd_decl.writer();2715 const writer = dg.fwd_decl.writer();
2716 const mod = dg.module;
27072717
2708 switch (tv.ty.zigTypeTag()) {2718 switch (tv.ty.zigTypeTag(mod)) {
2709 .Fn => {2719 .Fn => {
2710 const is_global = dg.declIsGlobal(tv);2720 const is_global = dg.declIsGlobal(tv);
2711 if (is_global) {2721 if (is_global) {
...@@ -2791,6 +2801,7 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con...@@ -2791,6 +2801,7 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con
2791}2801}
27922802
2793fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {2803fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {
2804 const mod = f.object.dg.module;
2794 const air_tags = f.air.instructions.items(.tag);2805 const air_tags = f.air.instructions.items(.tag);
27952806
2796 for (body) |inst| {2807 for (body) |inst| {
...@@ -2826,10 +2837,10 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,...@@ -2826,10 +2837,10 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
2826 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none),2837 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none),
2827 .rem => blk: {2838 .rem => blk: {
2828 const bin_op = f.air.instructions.items(.data)[inst].bin_op;2839 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);
2830 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),2841 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),
2831 // so we only check one.2842 // so we only check one.
2832 break :blk if (lhs_scalar_ty.isInt())2843 break :blk if (lhs_scalar_ty.isInt(mod))
2833 try airBinOp(f, inst, "%", "rem", .none)2844 try airBinOp(f, inst, "%", "rem", .none)
2834 else2845 else
2835 try airBinFloatOp(f, inst, "fmod");2846 try airBinFloatOp(f, inst, "fmod");
...@@ -3095,9 +3106,10 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [...@@ -3095,9 +3106,10 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
3095}3106}
30963107
3097fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {3108fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3109 const mod = f.object.dg.module;
3098 const inst_ty = f.air.typeOfIndex(inst);3110 const inst_ty = f.air.typeOfIndex(inst);
3099 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3111 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3100 if (!inst_ty.hasRuntimeBitsIgnoreComptime()) {3112 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3101 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3113 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3102 return .none;3114 return .none;
3103 }3115 }
...@@ -3120,13 +3132,14 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3120,13 +3132,14 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3120}3132}
31213133
3122fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {3134fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3135 const mod = f.object.dg.module;
3123 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;3136 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
3124 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3137 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
31253138
3126 const inst_ty = f.air.typeOfIndex(inst);3139 const inst_ty = f.air.typeOfIndex(inst);
3127 const ptr_ty = f.air.typeOf(bin_op.lhs);3140 const ptr_ty = f.air.typeOf(bin_op.lhs);
3128 const elem_ty = ptr_ty.childType();3141 const elem_ty = ptr_ty.childType();
3129 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime();3142 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod);
31303143
3131 const ptr = try f.resolveInst(bin_op.lhs);3144 const ptr = try f.resolveInst(bin_op.lhs);
3132 const index = try f.resolveInst(bin_op.rhs);3145 const index = try f.resolveInst(bin_op.rhs);
...@@ -3155,9 +3168,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3155,9 +3168,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3155}3168}
31563169
3157fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {3170fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3171 const mod = f.object.dg.module;
3158 const inst_ty = f.air.typeOfIndex(inst);3172 const inst_ty = f.air.typeOfIndex(inst);
3159 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3173 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3160 if (!inst_ty.hasRuntimeBitsIgnoreComptime()) {3174 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3161 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3175 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3162 return .none;3176 return .none;
3163 }3177 }
...@@ -3180,13 +3194,14 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3180,13 +3194,14 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3180}3194}
31813195
3182fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {3196fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3197 const mod = f.object.dg.module;
3183 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;3198 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
3184 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3199 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
31853200
3186 const inst_ty = f.air.typeOfIndex(inst);3201 const inst_ty = f.air.typeOfIndex(inst);
3187 const slice_ty = f.air.typeOf(bin_op.lhs);3202 const slice_ty = f.air.typeOf(bin_op.lhs);
3188 const elem_ty = slice_ty.elemType2();3203 const elem_ty = slice_ty.elemType2(mod);
3189 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime();3204 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod);
31903205
3191 const slice = try f.resolveInst(bin_op.lhs);3206 const slice = try f.resolveInst(bin_op.lhs);
3192 const index = try f.resolveInst(bin_op.rhs);3207 const index = try f.resolveInst(bin_op.rhs);
...@@ -3209,9 +3224,10 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3209,9 +3224,10 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3209}3224}
32103225
3211fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {3226fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3227 const mod = f.object.dg.module;
3212 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3228 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3213 const inst_ty = f.air.typeOfIndex(inst);3229 const inst_ty = f.air.typeOfIndex(inst);
3214 if (!inst_ty.hasRuntimeBitsIgnoreComptime()) {3230 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3215 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3231 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3216 return .none;3232 return .none;
3217 }3233 }
...@@ -3234,14 +3250,14 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3234,14 +3250,14 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3234}3250}
32353251
3236fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {3252fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
3253 const mod = f.object.dg.module;
3237 const inst_ty = f.air.typeOfIndex(inst);3254 const inst_ty = f.air.typeOfIndex(inst);
3238 const elem_type = inst_ty.elemType();3255 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();
3242 const local = try f.allocLocalValue(3258 const local = try f.allocLocalValue(
3243 elem_type,3259 elem_type,
3244 inst_ty.ptrAlignment(target),3260 inst_ty.ptrAlignment(mod),
3245 );3261 );
3246 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });3262 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
3247 const gpa = f.object.dg.module.gpa;3263 const gpa = f.object.dg.module.gpa;
...@@ -3250,14 +3266,14 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3250,14 +3266,14 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
3250}3266}
32513267
3252fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {3268fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3269 const mod = f.object.dg.module;
3253 const inst_ty = f.air.typeOfIndex(inst);3270 const inst_ty = f.air.typeOfIndex(inst);
3254 const elem_ty = inst_ty.elemType();3271 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();
3258 const local = try f.allocLocalValue(3274 const local = try f.allocLocalValue(
3259 elem_ty,3275 elem_ty,
3260 inst_ty.ptrAlignment(target),3276 inst_ty.ptrAlignment(mod),
3261 );3277 );
3262 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });3278 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
3263 const gpa = f.object.dg.module.gpa;3279 const gpa = f.object.dg.module.gpa;
...@@ -3290,14 +3306,15 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3290,14 +3306,15 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
3290}3306}
32913307
3292fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {3308fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3309 const mod = f.object.dg.module;
3293 const ty_op = f.air.instructions.items(.data)[inst].ty_op;3310 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
32943311
3295 const ptr_ty = f.air.typeOf(ty_op.operand);3312 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);
3297 const ptr_info = ptr_scalar_ty.ptrInfo().data;3314 const ptr_info = ptr_scalar_ty.ptrInfo().data;
3298 const src_ty = ptr_info.pointee_type;3315 const src_ty = ptr_info.pointee_type;
32993316
3300 if (!src_ty.hasRuntimeBitsIgnoreComptime()) {3317 if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3301 try reap(f, inst, &.{ty_op.operand});3318 try reap(f, inst, &.{ty_op.operand});
3302 return .none;3319 return .none;
3303 }3320 }
...@@ -3306,9 +3323,8 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3306,9 +3323,8 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33063323
3307 try reap(f, inst, &.{ty_op.operand});3324 try reap(f, inst, &.{ty_op.operand});
33083325
3309 const target = f.object.dg.module.getTarget();3326 const is_aligned = ptr_info.@"align" == 0 or ptr_info.@"align" >= src_ty.abiAlignment(mod);
3310 const is_aligned = ptr_info.@"align" == 0 or ptr_info.@"align" >= src_ty.abiAlignment(target);3327 const is_array = lowersToArray(src_ty, mod);
3311 const is_array = lowersToArray(src_ty, target);
3312 const need_memcpy = !is_aligned or is_array;3328 const need_memcpy = !is_aligned or is_array;
33133329
3314 const writer = f.object.writer();3330 const writer = f.object.writer();
...@@ -3327,17 +3343,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3327,17 +3343,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3327 try f.renderType(writer, src_ty);3343 try f.renderType(writer, src_ty);
3328 try writer.writeAll("))");3344 try writer.writeAll("))");
3329 } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) {3345 } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) {
3330 var host_pl = Type.Payload.Bits{3346 const host_bits: u16 = ptr_info.host_size * 8;
3331 .base = .{ .tag = .int_unsigned },3347 const host_ty = try mod.intType(.unsigned, host_bits);
3332 .data = ptr_info.host_size * 8,
3333 };
3334 const host_ty = Type.initPayload(&host_pl.base);
33353348
3336 var bit_offset_ty_pl = Type.Payload.Bits{3349 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
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);
33413350
3342 var bit_offset_val_pl: Value.Payload.U64 = .{3351 var bit_offset_val_pl: Value.Payload.U64 = .{
3343 .base = .{ .tag = .int_u64 },3352 .base = .{ .tag = .int_u64 },
...@@ -3345,11 +3354,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3345,11 +3354,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3345 };3354 };
3346 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);3355 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
33473356
3348 var field_pl = Type.Payload.Bits{3357 const field_ty = try mod.intType(.unsigned, @intCast(u16, src_ty.bitSize(mod)));
3349 .base = .{ .tag = .int_unsigned },
3350 .data = @intCast(u16, src_ty.bitSize(target)),
3351 };
3352 const field_ty = Type.initPayload(&field_pl.base);
33533358
3354 try f.writeCValue(writer, local, .Other);3359 try f.writeCValue(writer, local, .Other);
3355 try v.elem(f, writer);3360 try v.elem(f, writer);
...@@ -3360,9 +3365,9 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3360,9 +3365,9 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3360 try writer.writeAll("((");3365 try writer.writeAll("((");
3361 try f.renderType(writer, field_ty);3366 try f.renderType(writer, field_ty);
3362 try writer.writeByte(')');3367 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;
3364 if (cant_cast) {3369 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", .{});
3366 try writer.writeAll("zig_lo_");3371 try writer.writeAll("zig_lo_");
3367 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);3372 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
3368 try writer.writeByte('(');3373 try writer.writeByte('(');
...@@ -3390,23 +3395,23 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3390,23 +3395,23 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3390}3395}
33913396
3392fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {3397fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
3398 const mod = f.object.dg.module;
3393 const un_op = f.air.instructions.items(.data)[inst].un_op;3399 const un_op = f.air.instructions.items(.data)[inst].un_op;
3394 const writer = f.object.writer();3400 const writer = f.object.writer();
3395 const target = f.object.dg.module.getTarget();
3396 const op_inst = Air.refToIndex(un_op);3401 const op_inst = Air.refToIndex(un_op);
3397 const op_ty = f.air.typeOf(un_op);3402 const op_ty = f.air.typeOf(un_op);
3398 const ret_ty = if (is_ptr) op_ty.childType() else op_ty;3403 const ret_ty = if (is_ptr) op_ty.childType() else op_ty;
3399 var lowered_ret_buf: LowerFnRetTyBuffer = undefined;3404 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
3402 if (op_inst != null and f.air.instructions.items(.tag)[op_inst.?] == .call_always_tail) {3407 if (op_inst != null and f.air.instructions.items(.tag)[op_inst.?] == .call_always_tail) {
3403 try reap(f, inst, &.{un_op});3408 try reap(f, inst, &.{un_op});
3404 _ = try airCall(f, op_inst.?, .always_tail);3409 _ = try airCall(f, op_inst.?, .always_tail);
3405 } else if (lowered_ret_ty.hasRuntimeBitsIgnoreComptime()) {3410 } else if (lowered_ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3406 const operand = try f.resolveInst(un_op);3411 const operand = try f.resolveInst(un_op);
3407 try reap(f, inst, &.{un_op});3412 try reap(f, inst, &.{un_op});
3408 var deref = is_ptr;3413 var deref = is_ptr;
3409 const is_array = lowersToArray(ret_ty, target);3414 const is_array = lowersToArray(ret_ty, mod);
3410 const ret_val = if (is_array) ret_val: {3415 const ret_val = if (is_array) ret_val: {
3411 const array_local = try f.allocLocal(inst, lowered_ret_ty);3416 const array_local = try f.allocLocal(inst, lowered_ret_ty);
3412 try writer.writeAll("memcpy(");3417 try writer.writeAll("memcpy(");
...@@ -3442,15 +3447,16 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {...@@ -3442,15 +3447,16 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
3442}3447}
34433448
3444fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {3449fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
3450 const mod = f.object.dg.module;
3445 const ty_op = f.air.instructions.items(.data)[inst].ty_op;3451 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
34463452
3447 const operand = try f.resolveInst(ty_op.operand);3453 const operand = try f.resolveInst(ty_op.operand);
3448 try reap(f, inst, &.{ty_op.operand});3454 try reap(f, inst, &.{ty_op.operand});
34493455
3450 const inst_ty = f.air.typeOfIndex(inst);3456 const inst_ty = f.air.typeOfIndex(inst);
3451 const inst_scalar_ty = inst_ty.scalarType();3457 const inst_scalar_ty = inst_ty.scalarType(mod);
3452 const operand_ty = f.air.typeOf(ty_op.operand);3458 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
3455 const writer = f.object.writer();3461 const writer = f.object.writer();
3456 const local = try f.allocLocal(inst, inst_ty);3462 const local = try f.allocLocal(inst, inst_ty);
...@@ -3467,20 +3473,20 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3467,20 +3473,20 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
3467}3473}
34683474
3469fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {3475fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3476 const mod = f.object.dg.module;
3470 const ty_op = f.air.instructions.items(.data)[inst].ty_op;3477 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
34713478
3472 const operand = try f.resolveInst(ty_op.operand);3479 const operand = try f.resolveInst(ty_op.operand);
3473 try reap(f, inst, &.{ty_op.operand});3480 try reap(f, inst, &.{ty_op.operand});
3474 const inst_ty = f.air.typeOfIndex(inst);3481 const inst_ty = f.air.typeOfIndex(inst);
3475 const inst_scalar_ty = inst_ty.scalarType();3482 const inst_scalar_ty = inst_ty.scalarType(mod);
3476 const target = f.object.dg.module.getTarget();3483 const dest_int_info = inst_scalar_ty.intInfo(mod);
3477 const dest_int_info = inst_scalar_ty.intInfo(target);
3478 const dest_bits = dest_int_info.bits;3484 const dest_bits = dest_int_info.bits;
3479 const dest_c_bits = toCIntBits(dest_int_info.bits) orelse3485 const dest_c_bits = toCIntBits(dest_int_info.bits) orelse
3480 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});3486 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
3481 const operand_ty = f.air.typeOf(ty_op.operand);3487 const operand_ty = f.air.typeOf(ty_op.operand);
3482 const scalar_ty = operand_ty.scalarType();3488 const scalar_ty = operand_ty.scalarType(mod);
3483 const scalar_int_info = scalar_ty.intInfo(target);3489 const scalar_int_info = scalar_ty.intInfo(mod);
34843490
3485 const writer = f.object.writer();3491 const writer = f.object.writer();
3486 const local = try f.allocLocal(inst, inst_ty);3492 const local = try f.allocLocal(inst, inst_ty);
...@@ -3515,7 +3521,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3515,7 +3521,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3515 var stack align(@alignOf(ExpectedContents)) =3521 var stack align(@alignOf(ExpectedContents)) =
3516 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());3522 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);
3519 try writer.writeAll("zig_and_");3525 try writer.writeAll("zig_and_");
3520 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);3526 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
3521 try writer.writeByte('(');3527 try writer.writeByte('(');
...@@ -3577,17 +3583,18 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3577,17 +3583,18 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {
3577}3583}
35783584
3579fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {3585fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3586 const mod = f.object.dg.module;
3580 // *a = b;3587 // *a = b;
3581 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3588 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
35823589
3583 const ptr_ty = f.air.typeOf(bin_op.lhs);3590 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);
3585 const ptr_info = ptr_scalar_ty.ptrInfo().data;3592 const ptr_info = ptr_scalar_ty.ptrInfo().data;
35863593
3587 const ptr_val = try f.resolveInst(bin_op.lhs);3594 const ptr_val = try f.resolveInst(bin_op.lhs);
3588 const src_ty = f.air.typeOf(bin_op.rhs);3595 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
3592 if (val_is_undef) {3599 if (val_is_undef) {
3593 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3600 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 {...@@ -3602,10 +3609,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3602 return .none;3609 return .none;
3603 }3610 }
36043611
3605 const target = f.object.dg.module.getTarget();
3606 const is_aligned = ptr_info.@"align" == 0 or3612 const is_aligned = ptr_info.@"align" == 0 or
3607 ptr_info.@"align" >= ptr_info.pointee_type.abiAlignment(target);3613 ptr_info.@"align" >= ptr_info.pointee_type.abiAlignment(mod);
3608 const is_array = lowersToArray(ptr_info.pointee_type, target);3614 const is_array = lowersToArray(ptr_info.pointee_type, mod);
3609 const need_memcpy = !is_aligned or is_array;3615 const need_memcpy = !is_aligned or is_array;
36103616
3611 const src_val = try f.resolveInst(bin_op.rhs);3617 const src_val = try f.resolveInst(bin_op.rhs);
...@@ -3647,14 +3653,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3647,14 +3653,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3647 }3653 }
3648 } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) {3654 } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) {
3649 const host_bits = ptr_info.host_size * 8;3655 const host_bits = ptr_info.host_size * 8;
3650 var host_pl = Type.Payload.Bits{ .base = .{ .tag = .int_unsigned }, .data = host_bits };3656 const host_ty = try mod.intType(.unsigned, host_bits);
3651 const host_ty = Type.initPayload(&host_pl.base);
36523657
3653 var bit_offset_ty_pl = Type.Payload.Bits{3658 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
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);
36583659
3659 var bit_offset_val_pl: Value.Payload.U64 = .{3660 var bit_offset_val_pl: Value.Payload.U64 = .{
3660 .base = .{ .tag = .int_u64 },3661 .base = .{ .tag = .int_u64 },
...@@ -3662,7 +3663,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3662,7 +3663,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3662 };3663 };
3663 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);3664 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
3667 const ExpectedContents = [BigInt.Managed.default_capacity]BigIntLimb;3668 const ExpectedContents = [BigInt.Managed.default_capacity]BigIntLimb;
3668 var stack align(@alignOf(ExpectedContents)) =3669 var stack align(@alignOf(ExpectedContents)) =
...@@ -3693,9 +3694,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3693,9 +3694,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3693 try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(host_ty, mask_val)});3694 try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(host_ty, mask_val)});
3694 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);3695 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
3695 try writer.writeByte('(');3696 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;
3697 if (cant_cast) {3698 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", .{});
3699 try writer.writeAll("zig_make_");3700 try writer.writeAll("zig_make_");
3700 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);3701 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
3701 try writer.writeAll("(0, ");3702 try writer.writeAll("(0, ");
...@@ -3705,7 +3706,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3705,7 +3706,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3705 try writer.writeByte(')');3706 try writer.writeByte(')');
3706 }3707 }
37073708
3708 if (src_ty.isPtrAtRuntime()) {3709 if (src_ty.isPtrAtRuntime(mod)) {
3709 try writer.writeByte('(');3710 try writer.writeByte('(');
3710 try f.renderType(writer, Type.usize);3711 try f.renderType(writer, Type.usize);
3711 try writer.writeByte(')');3712 try writer.writeByte(')');
...@@ -3728,6 +3729,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3728,6 +3729,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3728}3729}
37293730
3730fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue {3731fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue {
3732 const mod = f.object.dg.module;
3731 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;3733 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
3732 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3734 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:...@@ -3737,7 +3739,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
37373739
3738 const inst_ty = f.air.typeOfIndex(inst);3740 const inst_ty = f.air.typeOfIndex(inst);
3739 const operand_ty = f.air.typeOf(bin_op.lhs);3741 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
3742 const w = f.object.writer();3744 const w = f.object.writer();
3743 const local = try f.allocLocal(inst, inst_ty);3745 const local = try f.allocLocal(inst, inst_ty);
...@@ -3765,9 +3767,10 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:...@@ -3765,9 +3767,10 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
3765}3767}
37663768
3767fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {3769fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
3770 const mod = f.object.dg.module;
3768 const ty_op = f.air.instructions.items(.data)[inst].ty_op;3771 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
3769 const operand_ty = f.air.typeOf(ty_op.operand);3772 const operand_ty = f.air.typeOf(ty_op.operand);
3770 const scalar_ty = operand_ty.scalarType();3773 const scalar_ty = operand_ty.scalarType(mod);
3771 if (scalar_ty.tag() != .bool) return try airUnBuiltinCall(f, inst, "not", .bits);3774 if (scalar_ty.tag() != .bool) return try airUnBuiltinCall(f, inst, "not", .bits);
37723775
3773 const op = try f.resolveInst(ty_op.operand);3776 const op = try f.resolveInst(ty_op.operand);
...@@ -3797,11 +3800,11 @@ fn airBinOp(...@@ -3797,11 +3800,11 @@ fn airBinOp(
3797 operation: []const u8,3800 operation: []const u8,
3798 info: BuiltinInfo,3801 info: BuiltinInfo,
3799) !CValue {3802) !CValue {
3803 const mod = f.object.dg.module;
3800 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3804 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3801 const operand_ty = f.air.typeOf(bin_op.lhs);3805 const operand_ty = f.air.typeOf(bin_op.lhs);
3802 const scalar_ty = operand_ty.scalarType();3806 const scalar_ty = operand_ty.scalarType(mod);
3803 const target = f.object.dg.module.getTarget();3807 if ((scalar_ty.isInt(mod) and scalar_ty.bitSize(mod) > 64) or scalar_ty.isRuntimeFloat())
3804 if ((scalar_ty.isInt() and scalar_ty.bitSize(target) > 64) or scalar_ty.isRuntimeFloat())
3805 return try airBinBuiltinCall(f, inst, operation, info);3808 return try airBinBuiltinCall(f, inst, operation, info);
38063809
3807 const lhs = try f.resolveInst(bin_op.lhs);3810 const lhs = try f.resolveInst(bin_op.lhs);
...@@ -3835,12 +3838,12 @@ fn airCmpOp(...@@ -3835,12 +3838,12 @@ fn airCmpOp(
3835 data: anytype,3838 data: anytype,
3836 operator: std.math.CompareOperator,3839 operator: std.math.CompareOperator,
3837) !CValue {3840) !CValue {
3841 const mod = f.object.dg.module;
3838 const lhs_ty = f.air.typeOf(data.lhs);3842 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();3845 const scalar_bits = scalar_ty.bitSize(mod);
3842 const scalar_bits = scalar_ty.bitSize(target);3846 if (scalar_ty.isInt(mod) and scalar_bits > 64)
3843 if (scalar_ty.isInt() and scalar_bits > 64)
3844 return airCmpBuiltinCall(3847 return airCmpBuiltinCall(
3845 f,3848 f,
3846 inst,3849 inst,
...@@ -3885,12 +3888,12 @@ fn airEquality(...@@ -3885,12 +3888,12 @@ fn airEquality(
3885 inst: Air.Inst.Index,3888 inst: Air.Inst.Index,
3886 operator: std.math.CompareOperator,3889 operator: std.math.CompareOperator,
3887) !CValue {3890) !CValue {
3891 const mod = f.object.dg.module;
3888 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3892 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
38893893
3890 const operand_ty = f.air.typeOf(bin_op.lhs);3894 const operand_ty = f.air.typeOf(bin_op.lhs);
3891 const target = f.object.dg.module.getTarget();3895 const operand_bits = operand_ty.bitSize(mod);
3892 const operand_bits = operand_ty.bitSize(target);3896 if (operand_ty.isInt(mod) and operand_bits > 64)
3893 if (operand_ty.isInt() and operand_bits > 64)
3894 return airCmpBuiltinCall(3897 return airCmpBuiltinCall(
3895 f,3898 f,
3896 inst,3899 inst,
...@@ -3912,7 +3915,7 @@ fn airEquality(...@@ -3912,7 +3915,7 @@ fn airEquality(
3912 try f.writeCValue(writer, local, .Other);3915 try f.writeCValue(writer, local, .Other);
3913 try writer.writeAll(" = ");3916 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)) {
3916 // (A && B) || (C && (A == B))3919 // (A && B) || (C && (A == B))
3917 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload3920 // 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 {...@@ -3965,6 +3968,7 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
3965}3968}
39663969
3967fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {3970fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
3971 const mod = f.object.dg.module;
3968 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;3972 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
3969 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3973 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 {...@@ -3973,8 +3977,8 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
3973 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3977 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
39743978
3975 const inst_ty = f.air.typeOfIndex(inst);3979 const inst_ty = f.air.typeOfIndex(inst);
3976 const inst_scalar_ty = inst_ty.scalarType();3980 const inst_scalar_ty = inst_ty.scalarType(mod);
3977 const elem_ty = inst_scalar_ty.elemType2();3981 const elem_ty = inst_scalar_ty.elemType2(mod);
39783982
3979 const local = try f.allocLocal(inst, inst_ty);3983 const local = try f.allocLocal(inst, inst_ty);
3980 const writer = f.object.writer();3984 const writer = f.object.writer();
...@@ -3983,7 +3987,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {...@@ -3983,7 +3987,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
3983 try v.elem(f, writer);3987 try v.elem(f, writer);
3984 try writer.writeAll(" = ");3988 try writer.writeAll(" = ");
39853989
3986 if (elem_ty.hasRuntimeBitsIgnoreComptime()) {3990 if (elem_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3987 // We must convert to and from integer types to prevent UB if the operation3991 // We must convert to and from integer types to prevent UB if the operation
3988 // results in a NULL pointer, or if LHS is NULL. The operation is only UB3992 // results in a NULL pointer, or if LHS is NULL. The operation is only UB
3989 // if the result is NULL and then dereferenced.3993 // if the result is NULL and then dereferenced.
...@@ -4012,13 +4016,13 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {...@@ -4012,13 +4016,13 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
4012}4016}
40134017
4014fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue {4018fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue {
4019 const mod = f.object.dg.module;
4015 const bin_op = f.air.instructions.items(.data)[inst].bin_op;4020 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
40164021
4017 const inst_ty = f.air.typeOfIndex(inst);4022 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();4025 if (inst_scalar_ty.isInt(mod) and inst_scalar_ty.bitSize(mod) > 64)
4021 if (inst_scalar_ty.isInt() and inst_scalar_ty.bitSize(target) > 64)
4022 return try airBinBuiltinCall(f, inst, operation[1..], .none);4026 return try airBinBuiltinCall(f, inst, operation[1..], .none);
4023 if (inst_scalar_ty.isRuntimeFloat())4027 if (inst_scalar_ty.isRuntimeFloat())
4024 return try airBinFloatOp(f, inst, operation);4028 return try airBinFloatOp(f, inst, operation);
...@@ -4092,12 +4096,11 @@ fn airCall(...@@ -4092,12 +4096,11 @@ fn airCall(
4092 inst: Air.Inst.Index,4096 inst: Air.Inst.Index,
4093 modifier: std.builtin.CallModifier,4097 modifier: std.builtin.CallModifier,
4094) !CValue {4098) !CValue {
4099 const mod = f.object.dg.module;
4095 // Not even allowed to call panic in a naked function.4100 // Not even allowed to call panic in a naked function.
4096 if (f.object.dg.decl) |decl| if (decl.ty.fnCallingConvention() == .Naked) return .none;4101 if (f.object.dg.decl) |decl| if (decl.ty.fnCallingConvention() == .Naked) return .none;
40974102
4098 const gpa = f.object.dg.gpa;4103 const gpa = f.object.dg.gpa;
4099 const module = f.object.dg.module;
4100 const target = module.getTarget();
4101 const writer = f.object.writer();4104 const writer = f.object.writer();
41024105
4103 const pl_op = f.air.instructions.items(.data)[inst].pl_op;4106 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
...@@ -4116,7 +4119,7 @@ fn airCall(...@@ -4116,7 +4119,7 @@ fn airCall(
4116 resolved_arg.* = try f.resolveInst(arg);4119 resolved_arg.* = try f.resolveInst(arg);
4117 if (arg_cty != try f.typeToIndex(arg_ty, .complete)) {4120 if (arg_cty != try f.typeToIndex(arg_ty, .complete)) {
4118 var lowered_arg_buf: LowerFnRetTyBuffer = undefined;4121 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
4121 const array_local = try f.allocLocal(inst, lowered_arg_ty);4124 const array_local = try f.allocLocal(inst, lowered_arg_ty);
4122 try writer.writeAll("memcpy(");4125 try writer.writeAll("memcpy(");
...@@ -4139,7 +4142,7 @@ fn airCall(...@@ -4139,7 +4142,7 @@ fn airCall(
4139 }4142 }
41404143
4141 const callee_ty = f.air.typeOf(pl_op.operand);4144 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)) {
4143 .Fn => callee_ty,4146 .Fn => callee_ty,
4144 .Pointer => callee_ty.childType(),4147 .Pointer => callee_ty.childType(),
4145 else => unreachable,4148 else => unreachable,
...@@ -4147,13 +4150,13 @@ fn airCall(...@@ -4147,13 +4150,13 @@ fn airCall(
41474150
4148 const ret_ty = fn_ty.fnReturnType();4151 const ret_ty = fn_ty.fnReturnType();
4149 var lowered_ret_buf: LowerFnRetTyBuffer = undefined;4152 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
4152 const result_local = result: {4155 const result_local = result: {
4153 if (modifier == .always_tail) {4156 if (modifier == .always_tail) {
4154 try writer.writeAll("zig_always_tail return ");4157 try writer.writeAll("zig_always_tail return ");
4155 break :result .none;4158 break :result .none;
4156 } else if (!lowered_ret_ty.hasRuntimeBitsIgnoreComptime()) {4159 } else if (!lowered_ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4157 break :result .none;4160 break :result .none;
4158 } else if (f.liveness.isUnused(inst)) {4161 } else if (f.liveness.isUnused(inst)) {
4159 try writer.writeByte('(');4162 try writer.writeByte('(');
...@@ -4171,7 +4174,7 @@ fn airCall(...@@ -4171,7 +4174,7 @@ fn airCall(
4171 callee: {4174 callee: {
4172 known: {4175 known: {
4173 const fn_decl = fn_decl: {4176 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;
4175 break :fn_decl switch (callee_val.tag()) {4178 break :fn_decl switch (callee_val.tag()) {
4176 .extern_fn => callee_val.castTag(.extern_fn).?.data.owner_decl,4179 .extern_fn => callee_val.castTag(.extern_fn).?.data.owner_decl,
4177 .function => callee_val.castTag(.function).?.data.owner_decl,4180 .function => callee_val.castTag(.function).?.data.owner_decl,
...@@ -4181,9 +4184,9 @@ fn airCall(...@@ -4181,9 +4184,9 @@ fn airCall(
4181 };4184 };
4182 switch (modifier) {4185 switch (modifier) {
4183 .auto, .always_tail => try f.object.dg.renderDeclName(writer, fn_decl, 0),4186 .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(4187 inline .never_tail, .never_inline => |m| try writer.writeAll(try f.getLazyFnName(
4185 @unionInit(LazyFnKey, @tagName(mod), fn_decl),4188 @unionInit(LazyFnKey, @tagName(m), fn_decl),
4186 @unionInit(LazyFnValue.Data, @tagName(mod), {}),4189 @unionInit(LazyFnValue.Data, @tagName(m), {}),
4187 )),4190 )),
4188 else => unreachable,4191 else => unreachable,
4189 }4192 }
...@@ -4211,7 +4214,7 @@ fn airCall(...@@ -4211,7 +4214,7 @@ fn airCall(
4211 try writer.writeAll(");\n");4214 try writer.writeAll(");\n");
42124215
4213 const result = result: {4216 const result = result: {
4214 if (result_local == .none or !lowersToArray(ret_ty, target))4217 if (result_local == .none or !lowersToArray(ret_ty, mod))
4215 break :result result_local;4218 break :result result_local;
42164219
4217 const array_local = try f.allocLocal(inst, ret_ty);4220 const array_local = try f.allocLocal(inst, ret_ty);
...@@ -4254,9 +4257,10 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4254,9 +4257,10 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {
4254}4257}
42554258
4256fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {4259fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4260 const mod = f.object.dg.module;
4257 const pl_op = f.air.instructions.items(.data)[inst].pl_op;4261 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
4258 const name = f.air.nullTerminatedString(pl_op.payload);4262 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;
4260 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);4264 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
42614265
4262 try reap(f, inst, &.{pl_op.operand});4266 try reap(f, inst, &.{pl_op.operand});
...@@ -4330,12 +4334,13 @@ fn lowerTry(...@@ -4330,12 +4334,13 @@ fn lowerTry(
4330 err_union_ty: Type,4334 err_union_ty: Type,
4331 is_ptr: bool,4335 is_ptr: bool,
4332) !CValue {4336) !CValue {
4337 const mod = f.object.dg.module;
4333 const err_union = try f.resolveInst(operand);4338 const err_union = try f.resolveInst(operand);
4334 const inst_ty = f.air.typeOfIndex(inst);4339 const inst_ty = f.air.typeOfIndex(inst);
4335 const liveness_condbr = f.liveness.getCondBr(inst);4340 const liveness_condbr = f.liveness.getCondBr(inst);
4336 const writer = f.object.writer();4341 const writer = f.object.writer();
4337 const payload_ty = err_union_ty.errorUnionPayload();4342 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
4340 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {4345 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
4341 try writer.writeAll("if (");4346 try writer.writeAll("if (");
...@@ -4431,6 +4436,8 @@ const LocalResult = struct {...@@ -4431,6 +4436,8 @@ const LocalResult = struct {
4431 need_free: bool,4436 need_free: bool,
44324437
4433 fn move(lr: LocalResult, f: *Function, inst: Air.Inst.Index, dest_ty: Type) !CValue {4438 fn move(lr: LocalResult, f: *Function, inst: Air.Inst.Index, dest_ty: Type) !CValue {
4439 const mod = f.object.dg.module;
4440
4434 if (lr.need_free) {4441 if (lr.need_free) {
4435 // Move the freshly allocated local to be owned by this instruction,4442 // Move the freshly allocated local to be owned by this instruction,
4436 // by returning it here instead of freeing it.4443 // by returning it here instead of freeing it.
...@@ -4441,7 +4448,7 @@ const LocalResult = struct {...@@ -4441,7 +4448,7 @@ const LocalResult = struct {
4441 try lr.free(f);4448 try lr.free(f);
4442 const writer = f.object.writer();4449 const writer = f.object.writer();
4443 try f.writeCValue(writer, local, .Other);4450 try f.writeCValue(writer, local, .Other);
4444 if (dest_ty.isAbiInt()) {4451 if (dest_ty.isAbiInt(mod)) {
4445 try writer.writeAll(" = ");4452 try writer.writeAll(" = ");
4446 } else {4453 } else {
4447 try writer.writeAll(" = (");4454 try writer.writeAll(" = (");
...@@ -4461,12 +4468,13 @@ const LocalResult = struct {...@@ -4461,12 +4468,13 @@ const LocalResult = struct {
4461};4468};
44624469
4463fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !LocalResult {4470fn 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();
4465 const writer = f.object.writer();4473 const writer = f.object.writer();
44664474
4467 if (operand_ty.isAbiInt() and dest_ty.isAbiInt()) {4475 if (operand_ty.isAbiInt(mod) and dest_ty.isAbiInt(mod)) {
4468 const src_info = dest_ty.intInfo(target);4476 const src_info = dest_ty.intInfo(mod);
4469 const dest_info = operand_ty.intInfo(target);4477 const dest_info = operand_ty.intInfo(mod);
4470 if (src_info.signedness == dest_info.signedness and4478 if (src_info.signedness == dest_info.signedness and
4471 src_info.bits == dest_info.bits)4479 src_info.bits == dest_info.bits)
4472 {4480 {
...@@ -4477,7 +4485,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca...@@ -4477,7 +4485,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
4477 }4485 }
4478 }4486 }
44794487
4480 if (dest_ty.isPtrAtRuntime() and operand_ty.isPtrAtRuntime()) {4488 if (dest_ty.isPtrAtRuntime(mod) and operand_ty.isPtrAtRuntime(mod)) {
4481 const local = try f.allocLocal(0, dest_ty);4489 const local = try f.allocLocal(0, dest_ty);
4482 try f.writeCValue(writer, local, .Other);4490 try f.writeCValue(writer, local, .Other);
4483 try writer.writeAll(" = (");4491 try writer.writeAll(" = (");
...@@ -4494,7 +4502,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca...@@ -4494,7 +4502,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
4494 const operand_lval = if (operand == .constant) blk: {4502 const operand_lval = if (operand == .constant) blk: {
4495 const operand_local = try f.allocLocal(0, operand_ty);4503 const operand_local = try f.allocLocal(0, operand_ty);
4496 try f.writeCValue(writer, operand_local, .Other);4504 try f.writeCValue(writer, operand_local, .Other);
4497 if (operand_ty.isAbiInt()) {4505 if (operand_ty.isAbiInt(mod)) {
4498 try writer.writeAll(" = ");4506 try writer.writeAll(" = ");
4499 } else {4507 } else {
4500 try writer.writeAll(" = (");4508 try writer.writeAll(" = (");
...@@ -4516,13 +4524,10 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca...@@ -4516,13 +4524,10 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
4516 try writer.writeAll("));\n");4524 try writer.writeAll("));\n");
45174525
4518 // Ensure padding bits have the expected value.4526 // Ensure padding bits have the expected value.
4519 if (dest_ty.isAbiInt()) {4527 if (dest_ty.isAbiInt(mod)) {
4520 const dest_cty = try f.typeToCType(dest_ty, .complete);4528 const dest_cty = try f.typeToCType(dest_ty, .complete);
4521 const dest_info = dest_ty.intInfo(target);4529 const dest_info = dest_ty.intInfo(mod);
4522 var info_ty_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dest_info.signedness) {4530 var bits: u16 = dest_info.bits;
4523 .unsigned => .int_unsigned,
4524 .signed => .int_signed,
4525 } }, .data = dest_info.bits };
4526 var wrap_cty: ?CType = null;4531 var wrap_cty: ?CType = null;
4527 var need_bitcasts = false;4532 var need_bitcasts = false;
45284533
...@@ -4535,9 +4540,9 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca...@@ -4535,9 +4540,9 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
4535 const elem_cty = f.indexToCType(pl.data.elem_type);4540 const elem_cty = f.indexToCType(pl.data.elem_type);
4536 wrap_cty = elem_cty.toSignedness(dest_info.signedness);4541 wrap_cty = elem_cty.toSignedness(dest_info.signedness);
4537 need_bitcasts = wrap_cty.?.tag() == .zig_i128;4542 need_bitcasts = wrap_cty.?.tag() == .zig_i128;
4538 info_ty_pl.data -= 1;4543 bits -= 1;
4539 info_ty_pl.data %= @intCast(u16, f.byteSize(elem_cty) * 8);4544 bits %= @intCast(u16, f.byteSize(elem_cty) * 8);
4540 info_ty_pl.data += 1;4545 bits += 1;
4541 }4546 }
4542 try writer.writeAll(" = ");4547 try writer.writeAll(" = ");
4543 if (need_bitcasts) {4548 if (need_bitcasts) {
...@@ -4546,7 +4551,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca...@@ -4546,7 +4551,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
4546 try writer.writeByte('(');4551 try writer.writeByte('(');
4547 }4552 }
4548 try writer.writeAll("zig_wrap_");4553 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);
4550 if (wrap_cty) |cty|4555 if (wrap_cty) |cty|
4551 try f.object.dg.renderCTypeForBuiltinFnName(writer, cty)4556 try f.object.dg.renderCTypeForBuiltinFnName(writer, cty)
4552 else4557 else
...@@ -4675,6 +4680,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4675,6 +4680,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
4675}4680}
46764681
4677fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {4682fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4683 const mod = f.object.dg.module;
4678 const pl_op = f.air.instructions.items(.data)[inst].pl_op;4684 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
4679 const condition = try f.resolveInst(pl_op.operand);4685 const condition = try f.resolveInst(pl_op.operand);
4680 try reap(f, inst, &.{pl_op.operand});4686 try reap(f, inst, &.{pl_op.operand});
...@@ -4683,11 +4689,11 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4683,11 +4689,11 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4683 const writer = f.object.writer();4689 const writer = f.object.writer();
46844690
4685 try writer.writeAll("switch (");4691 try writer.writeAll("switch (");
4686 if (condition_ty.zigTypeTag() == .Bool) {4692 if (condition_ty.zigTypeTag(mod) == .Bool) {
4687 try writer.writeByte('(');4693 try writer.writeByte('(');
4688 try f.renderType(writer, Type.u1);4694 try f.renderType(writer, Type.u1);
4689 try writer.writeByte(')');4695 try writer.writeByte(')');
4690 } else if (condition_ty.isPtrAtRuntime()) {4696 } else if (condition_ty.isPtrAtRuntime(mod)) {
4691 try writer.writeByte('(');4697 try writer.writeByte('(');
4692 try f.renderType(writer, Type.usize);4698 try f.renderType(writer, Type.usize);
4693 try writer.writeByte(')');4699 try writer.writeByte(')');
...@@ -4714,12 +4720,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4714,12 +4720,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4714 for (items) |item| {4720 for (items) |item| {
4715 try f.object.indent_writer.insertNewline();4721 try f.object.indent_writer.insertNewline();
4716 try writer.writeAll("case ");4722 try writer.writeAll("case ");
4717 if (condition_ty.isPtrAtRuntime()) {4723 if (condition_ty.isPtrAtRuntime(mod)) {
4718 try writer.writeByte('(');4724 try writer.writeByte('(');
4719 try f.renderType(writer, Type.usize);4725 try f.renderType(writer, Type.usize);
4720 try writer.writeByte(')');4726 try writer.writeByte(')');
4721 }4727 }
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);
4723 try writer.writeByte(':');4729 try writer.writeByte(':');
4724 }4730 }
4725 try writer.writeByte(' ');4731 try writer.writeByte(' ');
...@@ -4764,6 +4770,7 @@ fn asmInputNeedsLocal(constraint: []const u8, value: CValue) bool {...@@ -4764,6 +4770,7 @@ fn asmInputNeedsLocal(constraint: []const u8, value: CValue) bool {
4764}4770}
47654771
4766fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {4772fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4773 const mod = f.object.dg.module;
4767 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;4774 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
4768 const extra = f.air.extraData(Air.Asm, ty_pl.payload);4775 const extra = f.air.extraData(Air.Asm, ty_pl.payload);
4769 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;4776 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
...@@ -4778,7 +4785,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4778,7 +4785,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4778 const result = result: {4785 const result = result: {
4779 const writer = f.object.writer();4786 const writer = f.object.writer();
4780 const inst_ty = f.air.typeOfIndex(inst);4787 const inst_ty = f.air.typeOfIndex(inst);
4781 const local = if (inst_ty.hasRuntimeBitsIgnoreComptime()) local: {4788 const local = if (inst_ty.hasRuntimeBitsIgnoreComptime(mod)) local: {
4782 const local = try f.allocLocal(inst, inst_ty);4789 const local = try f.allocLocal(inst, inst_ty);
4783 if (f.wantSafety()) {4790 if (f.wantSafety()) {
4784 try f.writeCValue(writer, local, .Other);4791 try f.writeCValue(writer, local, .Other);
...@@ -5025,6 +5032,7 @@ fn airIsNull(...@@ -5025,6 +5032,7 @@ fn airIsNull(
5025 operator: []const u8,5032 operator: []const u8,
5026 is_ptr: bool,5033 is_ptr: bool,
5027) !CValue {5034) !CValue {
5035 const mod = f.object.dg.module;
5028 const un_op = f.air.instructions.items(.data)[inst].un_op;5036 const un_op = f.air.instructions.items(.data)[inst].un_op;
50295037
5030 const writer = f.object.writer();5038 const writer = f.object.writer();
...@@ -5046,14 +5054,14 @@ fn airIsNull(...@@ -5046,14 +5054,14 @@ fn airIsNull(
5046 const payload_ty = optional_ty.optionalChild(&payload_buf);5054 const payload_ty = optional_ty.optionalChild(&payload_buf);
5047 var slice_ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;5055 var slice_ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
50485056
5049 const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime())5057 const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
5050 TypedValue{ .ty = Type.bool, .val = Value.true }5058 TypedValue{ .ty = Type.bool, .val = Value.true }
5051 else if (optional_ty.isPtrLikeOptional())5059 else if (optional_ty.isPtrLikeOptional(mod))
5052 // operand is a regular pointer, test `operand !=/== NULL`5060 // operand is a regular pointer, test `operand !=/== NULL`
5053 TypedValue{ .ty = optional_ty, .val = Value.null }5061 TypedValue{ .ty = optional_ty, .val = Value.null }
5054 else if (payload_ty.zigTypeTag() == .ErrorSet)5062 else if (payload_ty.zigTypeTag(mod) == .ErrorSet)
5055 TypedValue{ .ty = payload_ty, .val = Value.zero }5063 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: {
5057 try writer.writeAll(".ptr");5065 try writer.writeAll(".ptr");
5058 const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf);5066 const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf);
5059 break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null };5067 break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null };
...@@ -5070,6 +5078,7 @@ fn airIsNull(...@@ -5070,6 +5078,7 @@ fn airIsNull(
5070}5078}
50715079
5072fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {5080fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
5081 const mod = f.object.dg.module;
5073 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5082 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
50745083
5075 const operand = try f.resolveInst(ty_op.operand);5084 const operand = try f.resolveInst(ty_op.operand);
...@@ -5079,7 +5088,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5079,7 +5088,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
5079 var buf: Type.Payload.ElemType = undefined;5088 var buf: Type.Payload.ElemType = undefined;
5080 const payload_ty = opt_ty.optionalChild(&buf);5089 const payload_ty = opt_ty.optionalChild(&buf);
50815090
5082 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {5091 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5083 return .none;5092 return .none;
5084 }5093 }
50855094
...@@ -5087,7 +5096,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5087,7 +5096,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
5087 const writer = f.object.writer();5096 const writer = f.object.writer();
5088 const local = try f.allocLocal(inst, inst_ty);5097 const local = try f.allocLocal(inst, inst_ty);
50895098
5090 if (opt_ty.optionalReprIsPayload()) {5099 if (opt_ty.optionalReprIsPayload(mod)) {
5091 try f.writeCValue(writer, local, .Other);5100 try f.writeCValue(writer, local, .Other);
5092 try writer.writeAll(" = ");5101 try writer.writeAll(" = ");
5093 try f.writeCValue(writer, operand, .Other);5102 try f.writeCValue(writer, operand, .Other);
...@@ -5104,6 +5113,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5104,6 +5113,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
5104}5113}
51055114
5106fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {5115fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5116 const mod = f.object.dg.module;
5107 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5117 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
51085118
5109 const writer = f.object.writer();5119 const writer = f.object.writer();
...@@ -5113,14 +5123,14 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5113,14 +5123,14 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5113 const opt_ty = ptr_ty.childType();5123 const opt_ty = ptr_ty.childType();
5114 const inst_ty = f.air.typeOfIndex(inst);5124 const inst_ty = f.air.typeOfIndex(inst);
51155125
5116 if (!inst_ty.childType().hasRuntimeBitsIgnoreComptime()) {5126 if (!inst_ty.childType().hasRuntimeBitsIgnoreComptime(mod)) {
5117 return .{ .undef = inst_ty };5127 return .{ .undef = inst_ty };
5118 }5128 }
51195129
5120 const local = try f.allocLocal(inst, inst_ty);5130 const local = try f.allocLocal(inst, inst_ty);
5121 try f.writeCValue(writer, local, .Other);5131 try f.writeCValue(writer, local, .Other);
51225132
5123 if (opt_ty.optionalReprIsPayload()) {5133 if (opt_ty.optionalReprIsPayload(mod)) {
5124 // the operand is just a regular pointer, no need to do anything special.5134 // the operand is just a regular pointer, no need to do anything special.
5125 // *?*T -> **T and ?*T -> *T are **T -> **T and *T -> *T in C5135 // *?*T -> **T and ?*T -> *T are **T -> **T and *T -> *T in C
5126 try writer.writeAll(" = ");5136 try writer.writeAll(" = ");
...@@ -5134,6 +5144,7 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5134,6 +5144,7 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5134}5144}
51355145
5136fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {5146fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5147 const mod = f.object.dg.module;
5137 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5148 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
5138 const writer = f.object.writer();5149 const writer = f.object.writer();
5139 const operand = try f.resolveInst(ty_op.operand);5150 const operand = try f.resolveInst(ty_op.operand);
...@@ -5144,7 +5155,7 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5144,7 +5155,7 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
51445155
5145 const inst_ty = f.air.typeOfIndex(inst);5156 const inst_ty = f.air.typeOfIndex(inst);
51465157
5147 if (opt_ty.optionalReprIsPayload()) {5158 if (opt_ty.optionalReprIsPayload(mod)) {
5148 if (f.liveness.isUnused(inst)) {5159 if (f.liveness.isUnused(inst)) {
5149 return .none;5160 return .none;
5150 }5161 }
...@@ -5179,36 +5190,36 @@ fn fieldLocation(...@@ -5179,36 +5190,36 @@ fn fieldLocation(
5179 container_ty: Type,5190 container_ty: Type,
5180 field_ptr_ty: Type,5191 field_ptr_ty: Type,
5181 field_index: u32,5192 field_index: u32,
5182 target: std.Target,5193 mod: *const Module,
5183) union(enum) {5194) union(enum) {
5184 begin: void,5195 begin: void,
5185 field: CValue,5196 field: CValue,
5186 byte_offset: u32,5197 byte_offset: u32,
5187 end: void,5198 end: void,
5188} {5199} {
5189 return switch (container_ty.zigTypeTag()) {5200 return switch (container_ty.zigTypeTag(mod)) {
5190 .Struct => switch (container_ty.containerLayout()) {5201 .Struct => switch (container_ty.containerLayout()) {
5191 .Auto, .Extern => for (field_index..container_ty.structFieldCount()) |next_field_index| {5202 .Auto, .Extern => for (field_index..container_ty.structFieldCount()) |next_field_index| {
5192 if (container_ty.structFieldIsComptime(next_field_index)) continue;5203 if (container_ty.structFieldIsComptime(next_field_index)) continue;
5193 const field_ty = container_ty.structFieldType(next_field_index);5204 const field_ty = container_ty.structFieldType(next_field_index);
5194 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;5205 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
51955206
5196 break .{ .field = if (container_ty.isSimpleTuple())5207 break .{ .field = if (container_ty.isSimpleTuple())
5197 .{ .field = next_field_index }5208 .{ .field = next_field_index }
5198 else5209 else
5199 .{ .identifier = container_ty.structFieldName(next_field_index) } };5210 .{ .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,
5201 .Packed => if (field_ptr_ty.ptrInfo().data.host_size == 0)5212 .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) }
5203 else5214 else
5204 .begin,5215 .begin,
5205 },5216 },
5206 .Union => switch (container_ty.containerLayout()) {5217 .Union => switch (container_ty.containerLayout()) {
5207 .Auto, .Extern => {5218 .Auto, .Extern => {
5208 const field_ty = container_ty.structFieldType(field_index);5219 const field_ty = container_ty.structFieldType(field_index);
5209 if (!field_ty.hasRuntimeBitsIgnoreComptime())5220 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod))
5210 return if (container_ty.unionTagTypeSafety() != null and5221 return if (container_ty.unionTagTypeSafety() != null and
5211 !container_ty.unionHasAllZeroBitFieldTypes())5222 !container_ty.unionHasAllZeroBitFieldTypes(mod))
5212 .{ .field = .{ .identifier = "payload" } }5223 .{ .field = .{ .identifier = "payload" } }
5213 else5224 else
5214 .begin;5225 .begin;
...@@ -5252,10 +5263,10 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue...@@ -5252,10 +5263,10 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
5252}5263}
52535264
5254fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {5265fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5266 const mod = f.object.dg.module;
5255 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;5267 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
5256 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;5268 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
52575269
5258 const target = f.object.dg.module.getTarget();
5259 const container_ptr_ty = f.air.typeOfIndex(inst);5270 const container_ptr_ty = f.air.typeOfIndex(inst);
5260 const container_ty = container_ptr_ty.childType();5271 const container_ty = container_ptr_ty.childType();
52615272
...@@ -5270,7 +5281,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5270,7 +5281,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5270 try f.renderType(writer, container_ptr_ty);5281 try f.renderType(writer, container_ptr_ty);
5271 try writer.writeByte(')');5282 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)) {
5274 .begin => try f.writeCValue(writer, field_ptr_val, .Initializer),5285 .begin => try f.writeCValue(writer, field_ptr_val, .Initializer),
5275 .field => |field| {5286 .field => |field| {
5276 var u8_ptr_pl = field_ptr_ty.ptrInfo();5287 var u8_ptr_pl = field_ptr_ty.ptrInfo();
...@@ -5321,7 +5332,7 @@ fn fieldPtr(...@@ -5321,7 +5332,7 @@ fn fieldPtr(
5321 container_ptr_val: CValue,5332 container_ptr_val: CValue,
5322 field_index: u32,5333 field_index: u32,
5323) !CValue {5334) !CValue {
5324 const target = f.object.dg.module.getTarget();5335 const mod = f.object.dg.module;
5325 const container_ty = container_ptr_ty.elemType();5336 const container_ty = container_ptr_ty.elemType();
5326 const field_ptr_ty = f.air.typeOfIndex(inst);5337 const field_ptr_ty = f.air.typeOfIndex(inst);
53275338
...@@ -5335,7 +5346,7 @@ fn fieldPtr(...@@ -5335,7 +5346,7 @@ fn fieldPtr(
5335 try f.renderType(writer, field_ptr_ty);5346 try f.renderType(writer, field_ptr_ty);
5336 try writer.writeByte(')');5347 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)) {
5339 .begin => try f.writeCValue(writer, container_ptr_val, .Initializer),5350 .begin => try f.writeCValue(writer, container_ptr_val, .Initializer),
5340 .field => |field| {5351 .field => |field| {
5341 try writer.writeByte('&');5352 try writer.writeByte('&');
...@@ -5370,16 +5381,16 @@ fn fieldPtr(...@@ -5370,16 +5381,16 @@ fn fieldPtr(
5370}5381}
53715382
5372fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {5383fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5384 const mod = f.object.dg.module;
5373 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;5385 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
5374 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;5386 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
53755387
5376 const inst_ty = f.air.typeOfIndex(inst);5388 const inst_ty = f.air.typeOfIndex(inst);
5377 if (!inst_ty.hasRuntimeBitsIgnoreComptime()) {5389 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5378 try reap(f, inst, &.{extra.struct_operand});5390 try reap(f, inst, &.{extra.struct_operand});
5379 return .none;5391 return .none;
5380 }5392 }
53815393
5382 const target = f.object.dg.module.getTarget();
5383 const struct_byval = try f.resolveInst(extra.struct_operand);5394 const struct_byval = try f.resolveInst(extra.struct_operand);
5384 try reap(f, inst, &.{extra.struct_operand});5395 try reap(f, inst, &.{extra.struct_operand});
5385 const struct_ty = f.air.typeOf(extra.struct_operand);5396 const struct_ty = f.air.typeOf(extra.struct_operand);
...@@ -5396,32 +5407,21 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5396,32 +5407,21 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5396 .{ .identifier = struct_ty.structFieldName(extra.field_index) },5407 .{ .identifier = struct_ty.structFieldName(extra.field_index) },
5397 .Packed => {5408 .Packed => {
5398 const struct_obj = struct_ty.castTag(.@"struct").?.data;5409 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{5412 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
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);
54065413
5407 var bit_offset_val_pl: Value.Payload.U64 = .{5414 var bit_offset_val_pl: Value.Payload.U64 = .{
5408 .base = .{ .tag = .int_u64 },5415 .base = .{ .tag = .int_u64 },
5409 .data = struct_obj.packedFieldBitOffset(target, extra.field_index),5416 .data = struct_obj.packedFieldBitOffset(mod, extra.field_index),
5410 };5417 };
5411 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);5418 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
54125419
5413 const field_int_signedness = if (inst_ty.isAbiInt())5420 const field_int_signedness = if (inst_ty.isAbiInt(mod))
5414 inst_ty.intInfo(target).signedness5421 inst_ty.intInfo(mod).signedness
5415 else5422 else
5416 .unsigned;5423 .unsigned;
5417 var field_int_pl = Type.Payload.Bits{5424 const field_int_ty = try mod.intType(field_int_signedness, @intCast(u16, inst_ty.bitSize(mod)));
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);
54255425
5426 const temp_local = try f.allocLocal(inst, field_int_ty);5426 const temp_local = try f.allocLocal(inst, field_int_ty);
5427 try f.writeCValue(writer, temp_local, .Other);5427 try f.writeCValue(writer, temp_local, .Other);
...@@ -5432,7 +5432,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5432,7 +5432,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5432 try writer.writeByte(')');5432 try writer.writeByte(')');
5433 const cant_cast = int_info.bits > 64;5433 const cant_cast = int_info.bits > 64;
5434 if (cant_cast) {5434 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", .{});
5436 try writer.writeAll("zig_lo_");5436 try writer.writeAll("zig_lo_");
5437 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);5437 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5438 try writer.writeByte('(');5438 try writer.writeByte('(');
...@@ -5511,6 +5511,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5511,6 +5511,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5511/// *(E!T) -> E5511/// *(E!T) -> E
5512/// Note that the result is never a pointer.5512/// Note that the result is never a pointer.
5513fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {5513fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5514 const mod = f.object.dg.module;
5514 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5515 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
55155516
5516 const inst_ty = f.air.typeOfIndex(inst);5517 const inst_ty = f.air.typeOfIndex(inst);
...@@ -5518,13 +5519,13 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5518,13 +5519,13 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5518 const operand_ty = f.air.typeOf(ty_op.operand);5519 const operand_ty = f.air.typeOf(ty_op.operand);
5519 try reap(f, inst, &.{ty_op.operand});5520 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;
5522 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;5523 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
5523 const error_ty = error_union_ty.errorUnionSet();5524 const error_ty = error_union_ty.errorUnionSet();
5524 const payload_ty = error_union_ty.errorUnionPayload();5525 const payload_ty = error_union_ty.errorUnionPayload();
5525 const local = try f.allocLocal(inst, inst_ty);5526 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) {
5528 // The store will be 'x = x'; elide it.5529 // The store will be 'x = x'; elide it.
5529 return local;5530 return local;
5530 }5531 }
...@@ -5533,7 +5534,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5533,7 +5534,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5533 try f.writeCValue(writer, local, .Other);5534 try f.writeCValue(writer, local, .Other);
5534 try writer.writeAll(" = ");5535 try writer.writeAll(" = ");
55355536
5536 if (!payload_ty.hasRuntimeBits()) {5537 if (!payload_ty.hasRuntimeBits(mod)) {
5537 try f.writeCValue(writer, operand, .Other);5538 try f.writeCValue(writer, operand, .Other);
5538 } else {5539 } else {
5539 if (!error_ty.errorSetIsEmpty())5540 if (!error_ty.errorSetIsEmpty())
...@@ -5549,6 +5550,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5549,6 +5550,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5549}5550}
55505551
5551fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {5552fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
5553 const mod = f.object.dg.module;
5552 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5554 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
55535555
5554 const inst_ty = f.air.typeOfIndex(inst);5556 const inst_ty = f.air.typeOfIndex(inst);
...@@ -5558,7 +5560,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu...@@ -5558,7 +5560,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
5558 const error_union_ty = if (is_ptr) operand_ty.childType() else operand_ty;5560 const error_union_ty = if (is_ptr) operand_ty.childType() else operand_ty;
55595561
5560 const writer = f.object.writer();5562 const writer = f.object.writer();
5561 if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) {5563 if (!error_union_ty.errorUnionPayload().hasRuntimeBits(mod)) {
5562 if (!is_ptr) return .none;5564 if (!is_ptr) return .none;
55635565
5564 const local = try f.allocLocal(inst, inst_ty);5566 const local = try f.allocLocal(inst, inst_ty);
...@@ -5584,10 +5586,11 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu...@@ -5584,10 +5586,11 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
5584}5586}
55855587
5586fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {5588fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
5589 const mod = f.object.dg.module;
5587 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5590 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
55885591
5589 const inst_ty = f.air.typeOfIndex(inst);5592 const inst_ty = f.air.typeOfIndex(inst);
5590 const repr_is_payload = inst_ty.optionalReprIsPayload();5593 const repr_is_payload = inst_ty.optionalReprIsPayload(mod);
5591 const payload_ty = f.air.typeOf(ty_op.operand);5594 const payload_ty = f.air.typeOf(ty_op.operand);
5592 const payload = try f.resolveInst(ty_op.operand);5595 const payload = try f.resolveInst(ty_op.operand);
5593 try reap(f, inst, &.{ty_op.operand});5596 try reap(f, inst, &.{ty_op.operand});
...@@ -5615,11 +5618,12 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5615,11 +5618,12 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
5615}5618}
56165619
5617fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {5620fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5621 const mod = f.object.dg.module;
5618 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5622 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
56195623
5620 const inst_ty = f.air.typeOfIndex(inst);5624 const inst_ty = f.air.typeOfIndex(inst);
5621 const payload_ty = inst_ty.errorUnionPayload();5625 const payload_ty = inst_ty.errorUnionPayload();
5622 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime();5626 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
5623 const err_ty = inst_ty.errorUnionSet();5627 const err_ty = inst_ty.errorUnionSet();
5624 const err = try f.resolveInst(ty_op.operand);5628 const err = try f.resolveInst(ty_op.operand);
5625 try reap(f, inst, &.{ty_op.operand});5629 try reap(f, inst, &.{ty_op.operand});
...@@ -5653,6 +5657,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5653,6 +5657,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5653}5657}
56545658
5655fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {5659fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5660 const mod = f.object.dg.module;
5656 const writer = f.object.writer();5661 const writer = f.object.writer();
5657 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5662 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
5658 const operand = try f.resolveInst(ty_op.operand);5663 const operand = try f.resolveInst(ty_op.operand);
...@@ -5662,7 +5667,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5662,7 +5667,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5662 const payload_ty = error_union_ty.errorUnionPayload();5667 const payload_ty = error_union_ty.errorUnionPayload();
56635668
5664 // First, set the non-error value.5669 // First, set the non-error value.
5665 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {5670 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5666 try f.writeCValueDeref(writer, operand);5671 try f.writeCValueDeref(writer, operand);
5667 try writer.writeAll(" = ");5672 try writer.writeAll(" = ");
5668 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other);5673 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other);
...@@ -5703,12 +5708,13 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5703,12 +5708,13 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue {
5703}5708}
57045709
5705fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {5710fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
5711 const mod = f.object.dg.module;
5706 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5712 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
57075713
5708 const inst_ty = f.air.typeOfIndex(inst);5714 const inst_ty = f.air.typeOfIndex(inst);
5709 const payload_ty = inst_ty.errorUnionPayload();5715 const payload_ty = inst_ty.errorUnionPayload();
5710 const payload = try f.resolveInst(ty_op.operand);5716 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);
5712 const err_ty = inst_ty.errorUnionSet();5718 const err_ty = inst_ty.errorUnionSet();
5713 try reap(f, inst, &.{ty_op.operand});5719 try reap(f, inst, &.{ty_op.operand});
57145720
...@@ -5735,6 +5741,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5735,6 +5741,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
5735}5741}
57365742
5737fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue {5743fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue {
5744 const mod = f.object.dg.module;
5738 const un_op = f.air.instructions.items(.data)[inst].un_op;5745 const un_op = f.air.instructions.items(.data)[inst].un_op;
57395746
5740 const writer = f.object.writer();5747 const writer = f.object.writer();
...@@ -5750,7 +5757,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -5750,7 +5757,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
5750 try writer.writeAll(" = ");5757 try writer.writeAll(" = ");
57515758
5752 if (!error_ty.errorSetIsEmpty())5759 if (!error_ty.errorSetIsEmpty())
5753 if (payload_ty.hasRuntimeBits())5760 if (payload_ty.hasRuntimeBits(mod))
5754 if (is_ptr)5761 if (is_ptr)
5755 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })5762 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
5756 else5763 else
...@@ -5768,6 +5775,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -5768,6 +5775,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
5768}5775}
57695776
5770fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {5777fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
5778 const mod = f.object.dg.module;
5771 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5779 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
57725780
5773 const operand = try f.resolveInst(ty_op.operand);5781 const operand = try f.resolveInst(ty_op.operand);
...@@ -5784,7 +5792,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5784,7 +5792,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
5784 if (operand == .undef) {5792 if (operand == .undef) {
5785 var buf: Type.SlicePtrFieldTypeBuffer = undefined;5793 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
5786 try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(&buf) }, .Initializer);5794 try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(&buf) }, .Initializer);
5787 } else if (array_ty.hasRuntimeBitsIgnoreComptime()) {5795 } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5788 try writer.writeAll("&(");5796 try writer.writeAll("&(");
5789 try f.writeCValueDeref(writer, operand);5797 try f.writeCValueDeref(writer, operand);
5790 try writer.print(")[{}]", .{try f.fmtIntLiteral(Type.usize, Value.zero)});5798 try writer.print(")[{}]", .{try f.fmtIntLiteral(Type.usize, Value.zero)});
...@@ -5801,6 +5809,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5801,6 +5809,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
5801}5809}
58025810
5803fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {5811fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
5812 const mod = f.object.dg.module;
5804 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5813 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
58055814
5806 const inst_ty = f.air.typeOfIndex(inst);5815 const inst_ty = f.air.typeOfIndex(inst);
...@@ -5810,10 +5819,10 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5810,10 +5819,10 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
5810 const target = f.object.dg.module.getTarget();5819 const target = f.object.dg.module.getTarget();
5811 const operation = if (inst_ty.isRuntimeFloat() and operand_ty.isRuntimeFloat())5820 const operation = if (inst_ty.isRuntimeFloat() and operand_ty.isRuntimeFloat())
5812 if (inst_ty.floatBits(target) < operand_ty.floatBits(target)) "trunc" else "extend"5821 if (inst_ty.floatBits(target) < operand_ty.floatBits(target)) "trunc" else "extend"
5813 else if (inst_ty.isInt() and operand_ty.isRuntimeFloat())5822 else if (inst_ty.isInt(mod) and operand_ty.isRuntimeFloat())
5814 if (inst_ty.isSignedInt()) "fix" else "fixuns"5823 if (inst_ty.isSignedInt(mod)) "fix" else "fixuns"
5815 else if (inst_ty.isRuntimeFloat() and operand_ty.isInt())5824 else if (inst_ty.isRuntimeFloat() and operand_ty.isInt(mod))
5816 if (operand_ty.isSignedInt()) "float" else "floatun"5825 if (operand_ty.isSignedInt(mod)) "float" else "floatun"
5817 else5826 else
5818 unreachable;5827 unreachable;
58195828
...@@ -5822,19 +5831,19 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5822,19 +5831,19 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
5822 try f.writeCValue(writer, local, .Other);5831 try f.writeCValue(writer, local, .Other);
58235832
5824 try writer.writeAll(" = ");5833 try writer.writeAll(" = ");
5825 if (inst_ty.isInt() and operand_ty.isRuntimeFloat()) {5834 if (inst_ty.isInt(mod) and operand_ty.isRuntimeFloat()) {
5826 try writer.writeAll("zig_wrap_");5835 try writer.writeAll("zig_wrap_");
5827 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);5836 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
5828 try writer.writeByte('(');5837 try writer.writeByte('(');
5829 }5838 }
5830 try writer.writeAll("zig_");5839 try writer.writeAll("zig_");
5831 try writer.writeAll(operation);5840 try writer.writeAll(operation);
5832 try writer.writeAll(compilerRtAbbrev(operand_ty, target));5841 try writer.writeAll(compilerRtAbbrev(operand_ty, mod));
5833 try writer.writeAll(compilerRtAbbrev(inst_ty, target));5842 try writer.writeAll(compilerRtAbbrev(inst_ty, mod));
5834 try writer.writeByte('(');5843 try writer.writeByte('(');
5835 try f.writeCValue(writer, operand, .FunctionArgument);5844 try f.writeCValue(writer, operand, .FunctionArgument);
5836 try writer.writeByte(')');5845 try writer.writeByte(')');
5837 if (inst_ty.isInt() and operand_ty.isRuntimeFloat()) {5846 if (inst_ty.isInt(mod) and operand_ty.isRuntimeFloat()) {
5838 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);5847 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);
5839 try writer.writeByte(')');5848 try writer.writeByte(')');
5840 }5849 }
...@@ -5871,14 +5880,15 @@ fn airUnBuiltinCall(...@@ -5871,14 +5880,15 @@ fn airUnBuiltinCall(
5871 operation: []const u8,5880 operation: []const u8,
5872 info: BuiltinInfo,5881 info: BuiltinInfo,
5873) !CValue {5882) !CValue {
5883 const mod = f.object.dg.module;
5874 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5884 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
58755885
5876 const operand = try f.resolveInst(ty_op.operand);5886 const operand = try f.resolveInst(ty_op.operand);
5877 try reap(f, inst, &.{ty_op.operand});5887 try reap(f, inst, &.{ty_op.operand});
5878 const inst_ty = f.air.typeOfIndex(inst);5888 const inst_ty = f.air.typeOfIndex(inst);
5879 const inst_scalar_ty = inst_ty.scalarType();5889 const inst_scalar_ty = inst_ty.scalarType(mod);
5880 const operand_ty = f.air.typeOf(ty_op.operand);5890 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
5883 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);5893 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
5884 const ref_ret = inst_scalar_cty.tag() == .array;5894 const ref_ret = inst_scalar_cty.tag() == .array;
...@@ -5914,6 +5924,7 @@ fn airBinBuiltinCall(...@@ -5914,6 +5924,7 @@ fn airBinBuiltinCall(
5914 operation: []const u8,5924 operation: []const u8,
5915 info: BuiltinInfo,5925 info: BuiltinInfo,
5916) !CValue {5926) !CValue {
5927 const mod = f.object.dg.module;
5917 const bin_op = f.air.instructions.items(.data)[inst].bin_op;5928 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
59185929
5919 const operand_ty = f.air.typeOf(bin_op.lhs);5930 const operand_ty = f.air.typeOf(bin_op.lhs);
...@@ -5925,8 +5936,8 @@ fn airBinBuiltinCall(...@@ -5925,8 +5936,8 @@ fn airBinBuiltinCall(
5925 if (!is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });5936 if (!is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
59265937
5927 const inst_ty = f.air.typeOfIndex(inst);5938 const inst_ty = f.air.typeOfIndex(inst);
5928 const inst_scalar_ty = inst_ty.scalarType();5939 const inst_scalar_ty = inst_ty.scalarType(mod);
5929 const scalar_ty = operand_ty.scalarType();5940 const scalar_ty = operand_ty.scalarType(mod);
59305941
5931 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);5942 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
5932 const ref_ret = inst_scalar_cty.tag() == .array;5943 const ref_ret = inst_scalar_cty.tag() == .array;
...@@ -5968,14 +5979,15 @@ fn airCmpBuiltinCall(...@@ -5968,14 +5979,15 @@ fn airCmpBuiltinCall(
5968 operation: enum { cmp, operator },5979 operation: enum { cmp, operator },
5969 info: BuiltinInfo,5980 info: BuiltinInfo,
5970) !CValue {5981) !CValue {
5982 const mod = f.object.dg.module;
5971 const lhs = try f.resolveInst(data.lhs);5983 const lhs = try f.resolveInst(data.lhs);
5972 const rhs = try f.resolveInst(data.rhs);5984 const rhs = try f.resolveInst(data.rhs);
5973 try reap(f, inst, &.{ data.lhs, data.rhs });5985 try reap(f, inst, &.{ data.lhs, data.rhs });
59745986
5975 const inst_ty = f.air.typeOfIndex(inst);5987 const inst_ty = f.air.typeOfIndex(inst);
5976 const inst_scalar_ty = inst_ty.scalarType();5988 const inst_scalar_ty = inst_ty.scalarType(mod);
5977 const operand_ty = f.air.typeOf(data.lhs);5989 const operand_ty = f.air.typeOf(data.lhs);
5978 const scalar_ty = operand_ty.scalarType();5990 const scalar_ty = operand_ty.scalarType(mod);
59795991
5980 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);5992 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
5981 const ref_ret = inst_scalar_cty.tag() == .array;5993 const ref_ret = inst_scalar_cty.tag() == .array;
...@@ -6017,6 +6029,7 @@ fn airCmpBuiltinCall(...@@ -6017,6 +6029,7 @@ fn airCmpBuiltinCall(
6017}6029}
60186030
6019fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue {6031fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue {
6032 const mod = f.object.dg.module;
6020 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;6033 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
6021 const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;6034 const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
6022 const inst_ty = f.air.typeOfIndex(inst);6035 const inst_ty = f.air.typeOfIndex(inst);
...@@ -6030,15 +6043,13 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6030,15 +6043,13 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6030 const new_value_mat = try Materialize.start(f, inst, writer, ty, new_value);6043 const new_value_mat = try Materialize.start(f, inst, writer, ty, new_value);
6031 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });6044 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });
60326045
6033 const target = f.object.dg.module.getTarget();6046 const repr_ty = if (ty.isRuntimeFloat())
6034 var repr_pl = Type.Payload.Bits{6047 mod.intType(.unsigned, @intCast(u16, ty.abiSize(mod) * 8)) catch unreachable
6035 .base = .{ .tag = .int_unsigned },6048 else
6036 .data = @intCast(u16, ty.abiSize(target) * 8),6049 ty;
6037 };
6038 const repr_ty = if (ty.isRuntimeFloat()) Type.initPayload(&repr_pl.base) else ty;
60396050
6040 const local = try f.allocLocal(inst, inst_ty);6051 const local = try f.allocLocal(inst, inst_ty);
6041 if (inst_ty.isPtrLikeOptional()) {6052 if (inst_ty.isPtrLikeOptional(mod)) {
6042 {6053 {
6043 const a = try Assignment.start(f, writer, ty);6054 const a = try Assignment.start(f, writer, ty);
6044 try f.writeCValue(writer, local, .Other);6055 try f.writeCValue(writer, local, .Other);
...@@ -6123,6 +6134,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6123,6 +6134,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6123}6134}
61246135
6125fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {6136fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6137 const mod = f.object.dg.module;
6126 const pl_op = f.air.instructions.items(.data)[inst].pl_op;6138 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
6127 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;6139 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;
6128 const inst_ty = f.air.typeOfIndex(inst);6140 const inst_ty = f.air.typeOfIndex(inst);
...@@ -6135,14 +6147,10 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6135,14 +6147,10 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6135 const operand_mat = try Materialize.start(f, inst, writer, ty, operand);6147 const operand_mat = try Materialize.start(f, inst, writer, ty, operand);
6136 try reap(f, inst, &.{ pl_op.operand, extra.operand });6148 try reap(f, inst, &.{ pl_op.operand, extra.operand });
61376149
6138 const target = f.object.dg.module.getTarget();6150 const repr_bits = @intCast(u16, ty.abiSize(mod) * 8);
6139 var repr_pl = Type.Payload.Bits{
6140 .base = .{ .tag = .int_unsigned },
6141 .data = @intCast(u16, ty.abiSize(target) * 8),
6142 };
6143 const is_float = ty.isRuntimeFloat();6151 const is_float = ty.isRuntimeFloat();
6144 const is_128 = repr_pl.data == 128;6152 const is_128 = repr_bits == 128;
6145 const repr_ty = if (is_float) Type.initPayload(&repr_pl.base) else ty;6153 const repr_ty = if (is_float) mod.intType(.unsigned, repr_bits) catch unreachable else ty;
61466154
6147 const local = try f.allocLocal(inst, inst_ty);6155 const local = try f.allocLocal(inst, inst_ty);
6148 try writer.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});6156 try writer.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});
...@@ -6181,18 +6189,17 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6181,18 +6189,17 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6181}6189}
61826190
6183fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {6191fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6192 const mod = f.object.dg.module;
6184 const atomic_load = f.air.instructions.items(.data)[inst].atomic_load;6193 const atomic_load = f.air.instructions.items(.data)[inst].atomic_load;
6185 const ptr = try f.resolveInst(atomic_load.ptr);6194 const ptr = try f.resolveInst(atomic_load.ptr);
6186 try reap(f, inst, &.{atomic_load.ptr});6195 try reap(f, inst, &.{atomic_load.ptr});
6187 const ptr_ty = f.air.typeOf(atomic_load.ptr);6196 const ptr_ty = f.air.typeOf(atomic_load.ptr);
6188 const ty = ptr_ty.childType();6197 const ty = ptr_ty.childType();
61896198
6190 const target = f.object.dg.module.getTarget();6199 const repr_ty = if (ty.isRuntimeFloat())
6191 var repr_pl = Type.Payload.Bits{6200 mod.intType(.unsigned, @intCast(u16, ty.abiSize(mod) * 8)) catch unreachable
6192 .base = .{ .tag = .int_unsigned },6201 else
6193 .data = @intCast(u16, ty.abiSize(target) * 8),6202 ty;
6194 };
6195 const repr_ty = if (ty.isRuntimeFloat()) Type.initPayload(&repr_pl.base) else ty;
61966203
6197 const inst_ty = f.air.typeOfIndex(inst);6204 const inst_ty = f.air.typeOfIndex(inst);
6198 const writer = f.object.writer();6205 const writer = f.object.writer();
...@@ -6218,6 +6225,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6218,6 +6225,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6218}6225}
62196226
6220fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {6227fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {
6228 const mod = f.object.dg.module;
6221 const bin_op = f.air.instructions.items(.data)[inst].bin_op;6229 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
6222 const ptr_ty = f.air.typeOf(bin_op.lhs);6230 const ptr_ty = f.air.typeOf(bin_op.lhs);
6223 const ty = ptr_ty.childType();6231 const ty = ptr_ty.childType();
...@@ -6228,12 +6236,10 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa...@@ -6228,12 +6236,10 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
6228 const element_mat = try Materialize.start(f, inst, writer, ty, element);6236 const element_mat = try Materialize.start(f, inst, writer, ty, element);
6229 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6237 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
62306238
6231 const target = f.object.dg.module.getTarget();6239 const repr_ty = if (ty.isRuntimeFloat())
6232 var repr_pl = Type.Payload.Bits{6240 mod.intType(.unsigned, @intCast(u16, ty.abiSize(mod) * 8)) catch unreachable
6233 .base = .{ .tag = .int_unsigned },6241 else
6234 .data = @intCast(u16, ty.abiSize(target) * 8),6242 ty;
6235 };
6236 const repr_ty = if (ty.isRuntimeFloat()) Type.initPayload(&repr_pl.base) else ty;
62376243
6238 try writer.writeAll("zig_atomic_store((zig_atomic(");6244 try writer.writeAll("zig_atomic_store((zig_atomic(");
6239 try f.renderType(writer, ty);6245 try f.renderType(writer, ty);
...@@ -6262,14 +6268,14 @@ fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !vo...@@ -6262,14 +6268,14 @@ fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !vo
6262}6268}
62636269
6264fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {6270fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6271 const mod = f.object.dg.module;
6265 const bin_op = f.air.instructions.items(.data)[inst].bin_op;6272 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
6266 const dest_ty = f.air.typeOf(bin_op.lhs);6273 const dest_ty = f.air.typeOf(bin_op.lhs);
6267 const dest_slice = try f.resolveInst(bin_op.lhs);6274 const dest_slice = try f.resolveInst(bin_op.lhs);
6268 const value = try f.resolveInst(bin_op.rhs);6275 const value = try f.resolveInst(bin_op.rhs);
6269 const elem_ty = f.air.typeOf(bin_op.rhs);6276 const elem_ty = f.air.typeOf(bin_op.rhs);
6270 const target = f.object.dg.module.getTarget();6277 const elem_abi_size = elem_ty.abiSize(mod);
6271 const elem_abi_size = elem_ty.abiSize(target);6278 const val_is_undef = if (f.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;
6272 const val_is_undef = if (f.air.value(bin_op.rhs)) |val| val.isUndefDeep() else false;
6273 const writer = f.object.writer();6279 const writer = f.object.writer();
62746280
6275 if (val_is_undef) {6281 if (val_is_undef) {
...@@ -6383,12 +6389,12 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -6383,12 +6389,12 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6383}6389}
63846390
6385fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {6391fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
6392 const mod = f.object.dg.module;
6386 const bin_op = f.air.instructions.items(.data)[inst].bin_op;6393 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
6387 const dest_ptr = try f.resolveInst(bin_op.lhs);6394 const dest_ptr = try f.resolveInst(bin_op.lhs);
6388 const src_ptr = try f.resolveInst(bin_op.rhs);6395 const src_ptr = try f.resolveInst(bin_op.rhs);
6389 const dest_ty = f.air.typeOf(bin_op.lhs);6396 const dest_ty = f.air.typeOf(bin_op.lhs);
6390 const src_ty = f.air.typeOf(bin_op.rhs);6397 const src_ty = f.air.typeOf(bin_op.rhs);
6391 const target = f.object.dg.module.getTarget();
6392 const writer = f.object.writer();6398 const writer = f.object.writer();
63936399
6394 try writer.writeAll("memcpy(");6400 try writer.writeAll("memcpy(");
...@@ -6399,7 +6405,7 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6399,7 +6405,7 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
6399 switch (dest_ty.ptrSize()) {6405 switch (dest_ty.ptrSize()) {
6400 .Slice => {6406 .Slice => {
6401 const elem_ty = dest_ty.childType();6407 const elem_ty = dest_ty.childType();
6402 const elem_abi_size = elem_ty.abiSize(target);6408 const elem_abi_size = elem_ty.abiSize(mod);
6403 try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" });6409 try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" });
6404 if (elem_abi_size > 1) {6410 if (elem_abi_size > 1) {
6405 try writer.print(" * {d});\n", .{elem_abi_size});6411 try writer.print(" * {d});\n", .{elem_abi_size});
...@@ -6410,7 +6416,7 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6410,7 +6416,7 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
6410 .One => {6416 .One => {
6411 const array_ty = dest_ty.childType();6417 const array_ty = dest_ty.childType();
6412 const elem_ty = array_ty.childType();6418 const elem_ty = array_ty.childType();
6413 const elem_abi_size = elem_ty.abiSize(target);6419 const elem_abi_size = elem_ty.abiSize(mod);
6414 const len = array_ty.arrayLen() * elem_abi_size;6420 const len = array_ty.arrayLen() * elem_abi_size;
6415 try writer.print("{d});\n", .{len});6421 try writer.print("{d});\n", .{len});
6416 },6422 },
...@@ -6422,14 +6428,14 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6422,14 +6428,14 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
6422}6428}
64236429
6424fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {6430fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6431 const mod = f.object.dg.module;
6425 const bin_op = f.air.instructions.items(.data)[inst].bin_op;6432 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
6426 const union_ptr = try f.resolveInst(bin_op.lhs);6433 const union_ptr = try f.resolveInst(bin_op.lhs);
6427 const new_tag = try f.resolveInst(bin_op.rhs);6434 const new_tag = try f.resolveInst(bin_op.rhs);
6428 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6435 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
64296436
6430 const target = f.object.dg.module.getTarget();
6431 const union_ty = f.air.typeOf(bin_op.lhs).childType();6437 const union_ty = f.air.typeOf(bin_op.lhs).childType();
6432 const layout = union_ty.unionGetLayout(target);6438 const layout = union_ty.unionGetLayout(mod);
6433 if (layout.tag_size == 0) return .none;6439 if (layout.tag_size == 0) return .none;
6434 const tag_ty = union_ty.unionTagTypeSafety().?;6440 const tag_ty = union_ty.unionTagTypeSafety().?;
64356441
...@@ -6443,14 +6449,14 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6443,14 +6449,14 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6443}6449}
64446450
6445fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {6451fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6452 const mod = f.object.dg.module;
6446 const ty_op = f.air.instructions.items(.data)[inst].ty_op;6453 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
64476454
6448 const operand = try f.resolveInst(ty_op.operand);6455 const operand = try f.resolveInst(ty_op.operand);
6449 try reap(f, inst, &.{ty_op.operand});6456 try reap(f, inst, &.{ty_op.operand});
64506457
6451 const union_ty = f.air.typeOf(ty_op.operand);6458 const union_ty = f.air.typeOf(ty_op.operand);
6452 const target = f.object.dg.module.getTarget();6459 const layout = union_ty.unionGetLayout(mod);
6453 const layout = union_ty.unionGetLayout(target);
6454 if (layout.tag_size == 0) return .none;6460 if (layout.tag_size == 0) return .none;
64556461
6456 const inst_ty = f.air.typeOfIndex(inst);6462 const inst_ty = f.air.typeOfIndex(inst);
...@@ -6501,13 +6507,14 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6501,13 +6507,14 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
6501}6507}
65026508
6503fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {6509fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
6510 const mod = f.object.dg.module;
6504 const ty_op = f.air.instructions.items(.data)[inst].ty_op;6511 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
65056512
6506 const operand = try f.resolveInst(ty_op.operand);6513 const operand = try f.resolveInst(ty_op.operand);
6507 try reap(f, inst, &.{ty_op.operand});6514 try reap(f, inst, &.{ty_op.operand});
65086515
6509 const inst_ty = f.air.typeOfIndex(inst);6516 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
6512 const writer = f.object.writer();6519 const writer = f.object.writer();
6513 const local = try f.allocLocal(inst, inst_ty);6520 const local = try f.allocLocal(inst, inst_ty);
...@@ -6555,6 +6562,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6555,6 +6562,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
6555}6562}
65566563
6557fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {6564fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
6565 const mod = f.object.dg.module;
6558 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;6566 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
6559 const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data;6567 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 {...@@ -6562,8 +6570,6 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
6562 const lhs = try f.resolveInst(extra.a);6570 const lhs = try f.resolveInst(extra.a);
6563 const rhs = try f.resolveInst(extra.b);6571 const rhs = try f.resolveInst(extra.b);
65646572
6565 const module = f.object.dg.module;
6566 const target = module.getTarget();
6567 const inst_ty = f.air.typeOfIndex(inst);6573 const inst_ty = f.air.typeOfIndex(inst);
65686574
6569 const writer = f.object.writer();6575 const writer = f.object.writer();
...@@ -6581,7 +6587,7 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6581,7 +6587,7 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
6581 try writer.writeAll("] = ");6587 try writer.writeAll("] = ");
65826588
6583 var buf: Value.ElemValueBuffer = undefined;6589 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);
6585 var src_pl = Value.Payload.U64{6591 var src_pl = Value.Payload.U64{
6586 .base = .{ .tag = .int_u64 },6592 .base = .{ .tag = .int_u64 },
6587 .data = @intCast(u64, mask_elem ^ mask_elem >> 63),6593 .data = @intCast(u64, mask_elem ^ mask_elem >> 63),
...@@ -6597,16 +6603,17 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6597,16 +6603,17 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
6597}6603}
65986604
6599fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {6605fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6606 const mod = f.object.dg.module;
6600 const reduce = f.air.instructions.items(.data)[inst].reduce;6607 const reduce = f.air.instructions.items(.data)[inst].reduce;
66016608
6602 const target = f.object.dg.module.getTarget();6609 const target = mod.getTarget();
6603 const scalar_ty = f.air.typeOfIndex(inst);6610 const scalar_ty = f.air.typeOfIndex(inst);
6604 const operand = try f.resolveInst(reduce.operand);6611 const operand = try f.resolveInst(reduce.operand);
6605 try reap(f, inst, &.{reduce.operand});6612 try reap(f, inst, &.{reduce.operand});
6606 const operand_ty = f.air.typeOf(reduce.operand);6613 const operand_ty = f.air.typeOf(reduce.operand);
6607 const writer = f.object.writer();6614 const writer = f.object.writer();
66086615
6609 const use_operator = scalar_ty.bitSize(target) <= 64;6616 const use_operator = scalar_ty.bitSize(mod) <= 64;
6610 const op: union(enum) {6617 const op: union(enum) {
6611 const Func = struct { operation: []const u8, info: BuiltinInfo = .none };6618 const Func = struct { operation: []const u8, info: BuiltinInfo = .none };
6612 float_op: Func,6619 float_op: Func,
...@@ -6617,28 +6624,28 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6617,28 +6624,28 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6617 .And => if (use_operator) .{ .infix = " &= " } else .{ .builtin = .{ .operation = "and" } },6624 .And => if (use_operator) .{ .infix = " &= " } else .{ .builtin = .{ .operation = "and" } },
6618 .Or => if (use_operator) .{ .infix = " |= " } else .{ .builtin = .{ .operation = "or" } },6625 .Or => if (use_operator) .{ .infix = " |= " } else .{ .builtin = .{ .operation = "or" } },
6619 .Xor => if (use_operator) .{ .infix = " ^= " } else .{ .builtin = .{ .operation = "xor" } },6626 .Xor => if (use_operator) .{ .infix = " ^= " } else .{ .builtin = .{ .operation = "xor" } },
6620 .Min => switch (scalar_ty.zigTypeTag()) {6627 .Min => switch (scalar_ty.zigTypeTag(mod)) {
6621 .Int => if (use_operator) .{ .ternary = " < " } else .{6628 .Int => if (use_operator) .{ .ternary = " < " } else .{
6622 .builtin = .{ .operation = "min" },6629 .builtin = .{ .operation = "min" },
6623 },6630 },
6624 .Float => .{ .float_op = .{ .operation = "fmin" } },6631 .Float => .{ .float_op = .{ .operation = "fmin" } },
6625 else => unreachable,6632 else => unreachable,
6626 },6633 },
6627 .Max => switch (scalar_ty.zigTypeTag()) {6634 .Max => switch (scalar_ty.zigTypeTag(mod)) {
6628 .Int => if (use_operator) .{ .ternary = " > " } else .{6635 .Int => if (use_operator) .{ .ternary = " > " } else .{
6629 .builtin = .{ .operation = "max" },6636 .builtin = .{ .operation = "max" },
6630 },6637 },
6631 .Float => .{ .float_op = .{ .operation = "fmax" } },6638 .Float => .{ .float_op = .{ .operation = "fmax" } },
6632 else => unreachable,6639 else => unreachable,
6633 },6640 },
6634 .Add => switch (scalar_ty.zigTypeTag()) {6641 .Add => switch (scalar_ty.zigTypeTag(mod)) {
6635 .Int => if (use_operator) .{ .infix = " += " } else .{6642 .Int => if (use_operator) .{ .infix = " += " } else .{
6636 .builtin = .{ .operation = "addw", .info = .bits },6643 .builtin = .{ .operation = "addw", .info = .bits },
6637 },6644 },
6638 .Float => .{ .builtin = .{ .operation = "add" } },6645 .Float => .{ .builtin = .{ .operation = "add" } },
6639 else => unreachable,6646 else => unreachable,
6640 },6647 },
6641 .Mul => switch (scalar_ty.zigTypeTag()) {6648 .Mul => switch (scalar_ty.zigTypeTag(mod)) {
6642 .Int => if (use_operator) .{ .infix = " *= " } else .{6649 .Int => if (use_operator) .{ .infix = " *= " } else .{
6643 .builtin = .{ .operation = "mulw", .info = .bits },6650 .builtin = .{ .operation = "mulw", .info = .bits },
6644 },6651 },
...@@ -6680,22 +6687,22 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6680,22 +6687,22 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
66806687
6681 try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) {6688 try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) {
6682 .Or, .Xor, .Add => Value.zero,6689 .Or, .Xor, .Add => Value.zero,
6683 .And => switch (scalar_ty.zigTypeTag()) {6690 .And => switch (scalar_ty.zigTypeTag(mod)) {
6684 .Bool => Value.one,6691 .Bool => Value.one,
6685 else => switch (scalar_ty.intInfo(target).signedness) {6692 else => switch (scalar_ty.intInfo(mod).signedness) {
6686 .unsigned => try scalar_ty.maxInt(stack.get(), target),6693 .unsigned => try scalar_ty.maxInt(stack.get(), mod),
6687 .signed => Value.negative_one,6694 .signed => Value.negative_one,
6688 },6695 },
6689 },6696 },
6690 .Min => switch (scalar_ty.zigTypeTag()) {6697 .Min => switch (scalar_ty.zigTypeTag(mod)) {
6691 .Bool => Value.one,6698 .Bool => Value.one,
6692 .Int => try scalar_ty.maxInt(stack.get(), target),6699 .Int => try scalar_ty.maxInt(stack.get(), mod),
6693 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),6700 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),
6694 else => unreachable,6701 else => unreachable,
6695 },6702 },
6696 .Max => switch (scalar_ty.zigTypeTag()) {6703 .Max => switch (scalar_ty.zigTypeTag(mod)) {
6697 .Bool => Value.zero,6704 .Bool => Value.zero,
6698 .Int => try scalar_ty.minInt(stack.get(), target),6705 .Int => try scalar_ty.minInt(stack.get(), mod),
6699 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),6706 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),
6700 else => unreachable,6707 else => unreachable,
6701 },6708 },
...@@ -6753,6 +6760,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6753,6 +6760,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6753}6760}
67546761
6755fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {6762fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6763 const mod = f.object.dg.module;
6756 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;6764 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
6757 const inst_ty = f.air.typeOfIndex(inst);6765 const inst_ty = f.air.typeOfIndex(inst);
6758 const len = @intCast(usize, inst_ty.arrayLen());6766 const len = @intCast(usize, inst_ty.arrayLen());
...@@ -6770,11 +6778,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6770,11 +6778,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6770 }6778 }
6771 }6779 }
67726780
6773 const target = f.object.dg.module.getTarget();
6774
6775 const writer = f.object.writer();6781 const writer = f.object.writer();
6776 const local = try f.allocLocal(inst, inst_ty);6782 const local = try f.allocLocal(inst, inst_ty);
6777 switch (inst_ty.zigTypeTag()) {6783 switch (inst_ty.zigTypeTag(mod)) {
6778 .Array, .Vector => {6784 .Array, .Vector => {
6779 const elem_ty = inst_ty.childType();6785 const elem_ty = inst_ty.childType();
6780 const a = try Assignment.init(f, elem_ty);6786 const a = try Assignment.init(f, elem_ty);
...@@ -6799,7 +6805,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6799,7 +6805,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6799 .Auto, .Extern => for (resolved_elements, 0..) |element, field_i| {6805 .Auto, .Extern => for (resolved_elements, 0..) |element, field_i| {
6800 if (inst_ty.structFieldIsComptime(field_i)) continue;6806 if (inst_ty.structFieldIsComptime(field_i)) continue;
6801 const field_ty = inst_ty.structFieldType(field_i);6807 const field_ty = inst_ty.structFieldType(field_i);
6802 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;6808 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
68036809
6804 const a = try Assignment.start(f, writer, field_ty);6810 const a = try Assignment.start(f, writer, field_ty);
6805 try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple())6811 try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple())
...@@ -6813,13 +6819,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6813,13 +6819,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6813 .Packed => {6819 .Packed => {
6814 try f.writeCValue(writer, local, .Other);6820 try f.writeCValue(writer, local, .Other);
6815 try writer.writeAll(" = ");6821 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{6824 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
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);
68236825
6824 var bit_offset_val_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = 0 };6826 var bit_offset_val_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = 0 };
6825 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);6827 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
...@@ -6828,7 +6830,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6828,7 +6830,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6828 for (0..elements.len) |field_i| {6830 for (0..elements.len) |field_i| {
6829 if (inst_ty.structFieldIsComptime(field_i)) continue;6831 if (inst_ty.structFieldIsComptime(field_i)) continue;
6830 const field_ty = inst_ty.structFieldType(field_i);6832 const field_ty = inst_ty.structFieldType(field_i);
6831 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;6833 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
68326834
6833 if (!empty) {6835 if (!empty) {
6834 try writer.writeAll("zig_or_");6836 try writer.writeAll("zig_or_");
...@@ -6841,7 +6843,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6841,7 +6843,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6841 for (resolved_elements, 0..) |element, field_i| {6843 for (resolved_elements, 0..) |element, field_i| {
6842 if (inst_ty.structFieldIsComptime(field_i)) continue;6844 if (inst_ty.structFieldIsComptime(field_i)) continue;
6843 const field_ty = inst_ty.structFieldType(field_i);6845 const field_ty = inst_ty.structFieldType(field_i);
6844 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;6846 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
68456847
6846 if (!empty) try writer.writeAll(", ");6848 if (!empty) try writer.writeAll(", ");
6847 // TODO: Skip this entire shift if val is 0?6849 // TODO: Skip this entire shift if val is 0?
...@@ -6849,13 +6851,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6849,13 +6851,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6849 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);6851 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
6850 try writer.writeByte('(');6852 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))) {
6853 try f.renderIntCast(writer, inst_ty, element, .{}, field_ty, .FunctionArgument);6855 try f.renderIntCast(writer, inst_ty, element, .{}, field_ty, .FunctionArgument);
6854 } else {6856 } else {
6855 try writer.writeByte('(');6857 try writer.writeByte('(');
6856 try f.renderType(writer, inst_ty);6858 try f.renderType(writer, inst_ty);
6857 try writer.writeByte(')');6859 try writer.writeByte(')');
6858 if (field_ty.isPtrAtRuntime()) {6860 if (field_ty.isPtrAtRuntime(mod)) {
6859 try writer.writeByte('(');6861 try writer.writeByte('(');
6860 try f.renderType(writer, switch (int_info.signedness) {6862 try f.renderType(writer, switch (int_info.signedness) {
6861 .unsigned => Type.usize,6863 .unsigned => Type.usize,
...@@ -6872,7 +6874,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6872,7 +6874,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6872 try writer.writeByte(')');6874 try writer.writeByte(')');
6873 if (!empty) try writer.writeByte(')');6875 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);
6876 empty = false;6878 empty = false;
6877 }6879 }
68786880
...@@ -6886,11 +6888,11 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6886,11 +6888,11 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6886}6888}
68876889
6888fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {6890fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
6891 const mod = f.object.dg.module;
6889 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;6892 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
6890 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;6893 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
68916894
6892 const union_ty = f.air.typeOfIndex(inst);6895 const union_ty = f.air.typeOfIndex(inst);
6893 const target = f.object.dg.module.getTarget();
6894 const union_obj = union_ty.cast(Type.Payload.Union).?.data;6896 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
6895 const field_name = union_obj.fields.keys()[extra.field_index];6897 const field_name = union_obj.fields.keys()[extra.field_index];
6896 const payload_ty = f.air.typeOf(extra.init);6898 const payload_ty = f.air.typeOf(extra.init);
...@@ -6908,7 +6910,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6908,7 +6910,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
6908 }6910 }
69096911
6910 const field: CValue = if (union_ty.unionTagTypeSafety()) |tag_ty| field: {6912 const field: CValue = if (union_ty.unionTagTypeSafety()) |tag_ty| field: {
6911 const layout = union_ty.unionGetLayout(target);6913 const layout = union_ty.unionGetLayout(mod);
6912 if (layout.tag_size != 0) {6914 if (layout.tag_size != 0) {
6913 const field_index = tag_ty.enumFieldIndex(field_name).?;6915 const field_index = tag_ty.enumFieldIndex(field_name).?;
69146916
...@@ -6991,13 +6993,14 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6991,13 +6993,14 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
6991}6993}
69926994
6993fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {6995fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
6996 const mod = f.object.dg.module;
6994 const un_op = f.air.instructions.items(.data)[inst].un_op;6997 const un_op = f.air.instructions.items(.data)[inst].un_op;
69956998
6996 const operand = try f.resolveInst(un_op);6999 const operand = try f.resolveInst(un_op);
6997 try reap(f, inst, &.{un_op});7000 try reap(f, inst, &.{un_op});
69987001
6999 const operand_ty = f.air.typeOf(un_op);7002 const operand_ty = f.air.typeOf(un_op);
7000 const scalar_ty = operand_ty.scalarType();7003 const scalar_ty = operand_ty.scalarType(mod);
70017004
7002 const writer = f.object.writer();7005 const writer = f.object.writer();
7003 const local = try f.allocLocal(inst, operand_ty);7006 const local = try f.allocLocal(inst, operand_ty);
...@@ -7016,13 +7019,14 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7016,13 +7019,14 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
7016}7019}
70177020
7018fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue {7021fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue {
7022 const mod = f.object.dg.module;
7019 const un_op = f.air.instructions.items(.data)[inst].un_op;7023 const un_op = f.air.instructions.items(.data)[inst].un_op;
70207024
7021 const operand = try f.resolveInst(un_op);7025 const operand = try f.resolveInst(un_op);
7022 try reap(f, inst, &.{un_op});7026 try reap(f, inst, &.{un_op});
70237027
7024 const inst_ty = f.air.typeOfIndex(inst);7028 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
7027 const writer = f.object.writer();7031 const writer = f.object.writer();
7028 const local = try f.allocLocal(inst, inst_ty);7032 const local = try f.allocLocal(inst, inst_ty);
...@@ -7043,6 +7047,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal...@@ -7043,6 +7047,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal
7043}7047}
70447048
7045fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue {7049fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue {
7050 const mod = f.object.dg.module;
7046 const bin_op = f.air.instructions.items(.data)[inst].bin_op;7051 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
70477052
7048 const lhs = try f.resolveInst(bin_op.lhs);7053 const lhs = try f.resolveInst(bin_op.lhs);
...@@ -7050,7 +7055,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa...@@ -7050,7 +7055,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
7050 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });7055 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
70517056
7052 const inst_ty = f.air.typeOfIndex(inst);7057 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
7055 const writer = f.object.writer();7060 const writer = f.object.writer();
7056 const local = try f.allocLocal(inst, inst_ty);7061 const local = try f.allocLocal(inst, inst_ty);
...@@ -7074,6 +7079,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa...@@ -7074,6 +7079,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
7074}7079}
70757080
7076fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {7081fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7082 const mod = f.object.dg.module;
7077 const pl_op = f.air.instructions.items(.data)[inst].pl_op;7083 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
7078 const bin_op = f.air.extraData(Air.Bin, pl_op.payload).data;7084 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 {...@@ -7083,7 +7089,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7083 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand });7089 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand });
70847090
7085 const inst_ty = f.air.typeOfIndex(inst);7091 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
7088 const writer = f.object.writer();7094 const writer = f.object.writer();
7089 const local = try f.allocLocal(inst, inst_ty);7095 const local = try f.allocLocal(inst, inst_ty);
...@@ -7279,8 +7285,9 @@ fn signAbbrev(signedness: std.builtin.Signedness) u8 {...@@ -7279,8 +7285,9 @@ fn signAbbrev(signedness: std.builtin.Signedness) u8 {
7279 };7285 };
7280}7286}
72817287
7282fn compilerRtAbbrev(ty: Type, target: std.Target) []const u8 {7288fn compilerRtAbbrev(ty: Type, mod: *Module) []const u8 {
7283 return if (ty.isInt()) switch (ty.intInfo(target).bits) {7289 const target = mod.getTarget();
7290 return if (ty.isInt(mod)) switch (ty.intInfo(mod).bits) {
7284 1...32 => "si",7291 1...32 => "si",
7285 33...64 => "di",7292 33...64 => "di",
7286 65...128 => "ti",7293 65...128 => "ti",
...@@ -7407,7 +7414,7 @@ fn undefPattern(comptime IntType: type) IntType {...@@ -7407,7 +7414,7 @@ fn undefPattern(comptime IntType: type) IntType {
74077414
7408const FormatIntLiteralContext = struct {7415const FormatIntLiteralContext = struct {
7409 dg: *DeclGen,7416 dg: *DeclGen,
7410 int_info: std.builtin.Type.Int,7417 int_info: InternPool.Key.IntType,
7411 kind: CType.Kind,7418 kind: CType.Kind,
7412 cty: CType,7419 cty: CType,
7413 val: Value,7420 val: Value,
...@@ -7418,7 +7425,8 @@ fn formatIntLiteral(...@@ -7418,7 +7425,8 @@ fn formatIntLiteral(
7418 options: std.fmt.FormatOptions,7425 options: std.fmt.FormatOptions,
7419 writer: anytype,7426 writer: anytype,
7420) @TypeOf(writer).Error!void {7427) @TypeOf(writer).Error!void {
7421 const target = data.dg.module.getTarget();7428 const mod = data.dg.module;
7429 const target = mod.getTarget();
74227430
7423 const ExpectedContents = struct {7431 const ExpectedContents = struct {
7424 const base = 10;7432 const base = 10;
...@@ -7449,7 +7457,7 @@ fn formatIntLiteral(...@@ -7449,7 +7457,7 @@ fn formatIntLiteral(
7449 };7457 };
7450 undef_int.truncate(undef_int.toConst(), data.int_info.signedness, data.int_info.bits);7458 undef_int.truncate(undef_int.toConst(), data.int_info.signedness, data.int_info.bits);
7451 break :blk undef_int.toConst();7459 break :blk undef_int.toConst();
7452 } else data.val.toBigInt(&int_buf, target);7460 } else data.val.toBigInt(&int_buf, mod);
7453 assert(int.fitsInTwosComp(data.int_info.signedness, data.int_info.bits));7461 assert(int.fitsInTwosComp(data.int_info.signedness, data.int_info.bits));
74547462
7455 const c_bits = @intCast(usize, data.cty.byteSize(data.dg.ctypes.set, target) * 8);7463 const c_bits = @intCast(usize, data.cty.byteSize(data.dg.ctypes.set, target) * 8);
...@@ -7684,7 +7692,8 @@ const Vectorize = struct {...@@ -7684,7 +7692,8 @@ const Vectorize = struct {
7684 index: CValue = .none,7692 index: CValue = .none,
76857693
7686 pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize {7694 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: {
7688 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() };7697 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() };
76897698
7690 const local = try f.allocLocal(inst, Type.usize);7699 const local = try f.allocLocal(inst, Type.usize);
...@@ -7727,10 +7736,10 @@ const LowerFnRetTyBuffer = struct {...@@ -7727,10 +7736,10 @@ const LowerFnRetTyBuffer = struct {
7727 values: [1]Value,7736 values: [1]Value,
7728 payload: Type.Payload.AnonStruct,7737 payload: Type.Payload.AnonStruct,
7729};7738};
7730fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, target: std.Target) Type {7739fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, mod: *const Module) Type {
7731 if (ret_ty.zigTypeTag() == .NoReturn) return Type.initTag(.noreturn);7740 if (ret_ty.zigTypeTag(mod) == .NoReturn) return Type.initTag(.noreturn);
77327741
7733 if (lowersToArray(ret_ty, target)) {7742 if (lowersToArray(ret_ty, mod)) {
7734 buffer.names = [1][]const u8{"array"};7743 buffer.names = [1][]const u8{"array"};
7735 buffer.types = [1]Type{ret_ty};7744 buffer.types = [1]Type{ret_ty};
7736 buffer.values = [1]Value{Value.initTag(.unreachable_value)};7745 buffer.values = [1]Value{Value.initTag(.unreachable_value)};
...@@ -7742,13 +7751,13 @@ fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, target: std.Target) T...@@ -7742,13 +7751,13 @@ fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, target: std.Target) T
7742 return Type.initPayload(&buffer.payload.base);7751 return Type.initPayload(&buffer.payload.base);
7743 }7752 }
77447753
7745 return if (ret_ty.hasRuntimeBitsIgnoreComptime()) ret_ty else Type.void;7754 return if (ret_ty.hasRuntimeBitsIgnoreComptime(mod)) ret_ty else Type.void;
7746}7755}
77477756
7748fn lowersToArray(ty: Type, target: std.Target) bool {7757fn lowersToArray(ty: Type, mod: *const Module) bool {
7749 return switch (ty.zigTypeTag()) {7758 return switch (ty.zigTypeTag(mod)) {
7750 .Array, .Vector => return true,7759 .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,
7752 };7761 };
7753}7762}
77547763
src/codegen/c/type.zig+74-76
...@@ -292,19 +292,19 @@ pub const CType = extern union {...@@ -292,19 +292,19 @@ pub const CType = extern union {
292 .abi = std.math.log2_int(u32, abi_alignment),292 .abi = std.math.log2_int(u32, abi_alignment),
293 };293 };
294 }294 }
295 pub fn abiAlign(ty: Type, target: Target) AlignAs {295 pub fn abiAlign(ty: Type, mod: *const Module) AlignAs {
296 const abi_align = ty.abiAlignment(target);296 const abi_align = ty.abiAlignment(mod);
297 return init(abi_align, abi_align);297 return init(abi_align, abi_align);
298 }298 }
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 {
300 return init(300 return init(
301 struct_ty.structFieldAlign(field_i, target),301 struct_ty.structFieldAlign(field_i, mod),
302 struct_ty.structFieldType(field_i).abiAlignment(target),302 struct_ty.structFieldType(field_i).abiAlignment(mod),
303 );303 );
304 }304 }
305 pub fn unionPayloadAlign(union_ty: Type, target: Target) AlignAs {305 pub fn unionPayloadAlign(union_ty: Type, mod: *const Module) AlignAs {
306 const union_obj = union_ty.cast(Type.Payload.Union).?.data;306 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);
308 return init(union_payload_align, union_payload_align);308 return init(union_payload_align, union_payload_align);
309 }309 }
310310
...@@ -344,8 +344,8 @@ pub const CType = extern union {...@@ -344,8 +344,8 @@ pub const CType = extern union {
344 return self.map.entries.items(.hash)[index - Tag.no_payload_count];344 return self.map.entries.items(.hash)[index - Tag.no_payload_count];
345 }345 }
346346
347 pub fn typeToIndex(self: Set, ty: Type, target: Target, kind: Kind) ?Index {347 pub fn typeToIndex(self: Set, ty: Type, mod: *Module, kind: Kind) ?Index {
348 const lookup = Convert.Lookup{ .imm = .{ .set = &self, .target = target } };348 const lookup = Convert.Lookup{ .imm = .{ .set = &self, .mod = mod } };
349349
350 var convert: Convert = undefined;350 var convert: Convert = undefined;
351 convert.initType(ty, kind, lookup) catch unreachable;351 convert.initType(ty, kind, lookup) catch unreachable;
...@@ -405,7 +405,7 @@ pub const CType = extern union {...@@ -405,7 +405,7 @@ pub const CType = extern union {
405 );405 );
406 if (!gop.found_existing) {406 if (!gop.found_existing) {
407 errdefer _ = self.set.map.pop();407 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);
409 }409 }
410 if (std.debug.runtime_safety) {410 if (std.debug.runtime_safety) {
411 const adapter = TypeAdapter64{411 const adapter = TypeAdapter64{
...@@ -1236,10 +1236,10 @@ pub const CType = extern union {...@@ -1236,10 +1236,10 @@ pub const CType = extern union {
1236 }1236 }
12371237
1238 pub const Lookup = union(enum) {1238 pub const Lookup = union(enum) {
1239 fail: Target,1239 fail: *Module,
1240 imm: struct {1240 imm: struct {
1241 set: *const Store.Set,1241 set: *const Store.Set,
1242 target: Target,1242 mod: *Module,
1243 },1243 },
1244 mut: struct {1244 mut: struct {
1245 promoted: *Store.Promoted,1245 promoted: *Store.Promoted,
...@@ -1254,10 +1254,14 @@ pub const CType = extern union {...@@ -1254,10 +1254,14 @@ pub const CType = extern union {
1254 }1254 }
12551255
1256 pub fn getTarget(self: @This()) Target {1256 pub fn getTarget(self: @This()) Target {
1257 return self.getModule().getTarget();
1258 }
1259
1260 pub fn getModule(self: @This()) *Module {
1257 return switch (self) {1261 return switch (self) {
1258 .fail => |target| target,1262 .fail => |mod| mod,
1259 .imm => |imm| imm.target,1263 .imm => |imm| imm.mod,
1260 .mut => |mut| mut.mod.getTarget(),1264 .mut => |mut| mut.mod,
1261 };1265 };
1262 }1266 }
12631267
...@@ -1272,7 +1276,7 @@ pub const CType = extern union {...@@ -1272,7 +1276,7 @@ pub const CType = extern union {
1272 pub fn typeToIndex(self: @This(), ty: Type, kind: Kind) !?Index {1276 pub fn typeToIndex(self: @This(), ty: Type, kind: Kind) !?Index {
1273 return switch (self) {1277 return switch (self) {
1274 .fail => null,1278 .fail => null,
1275 .imm => |imm| imm.set.typeToIndex(ty, imm.target, kind),1279 .imm => |imm| imm.set.typeToIndex(ty, imm.mod, kind),
1276 .mut => |mut| try mut.promoted.typeToIndex(ty, mut.mod, kind),1280 .mut => |mut| try mut.promoted.typeToIndex(ty, mut.mod, kind),
1277 };1281 };
1278 }1282 }
...@@ -1284,7 +1288,7 @@ pub const CType = extern union {...@@ -1284,7 +1288,7 @@ pub const CType = extern union {
1284 pub fn freeze(self: @This()) @This() {1288 pub fn freeze(self: @This()) @This() {
1285 return switch (self) {1289 return switch (self) {
1286 .fail, .imm => self,1290 .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 } },
1288 };1292 };
1289 }1293 }
1290 };1294 };
...@@ -1338,7 +1342,7 @@ pub const CType = extern union {...@@ -1338,7 +1342,7 @@ pub const CType = extern union {
1338 self.storage.anon.fields[0] = .{1342 self.storage.anon.fields[0] = .{
1339 .name = "array",1343 .name = "array",
1340 .type = array_idx,1344 .type = array_idx,
1341 .alignas = AlignAs.abiAlign(ty, lookup.getTarget()),1345 .alignas = AlignAs.abiAlign(ty, lookup.getModule()),
1342 };1346 };
1343 self.initAnon(kind, fwd_idx, 1);1347 self.initAnon(kind, fwd_idx, 1);
1344 } else self.init(switch (kind) {1348 } else self.init(switch (kind) {
...@@ -1350,12 +1354,12 @@ pub const CType = extern union {...@@ -1350,12 +1354,12 @@ pub const CType = extern union {
1350 }1354 }
13511355
1352 pub fn initType(self: *@This(), ty: Type, kind: Kind, lookup: Lookup) !void {1356 pub fn initType(self: *@This(), ty: Type, kind: Kind, lookup: Lookup) !void {
1353 const target = lookup.getTarget();1357 const mod = lookup.getModule();
13541358
1355 self.* = undefined;1359 self.* = undefined;
1356 if (!ty.isFnOrHasRuntimeBitsIgnoreComptime())1360 if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(mod))
1357 self.init(.void)1361 self.init(.void)
1358 else if (ty.isAbiInt()) switch (ty.tag()) {1362 else if (ty.isAbiInt(mod)) switch (ty.tag()) {
1359 .usize => self.init(.uintptr_t),1363 .usize => self.init(.uintptr_t),
1360 .isize => self.init(.intptr_t),1364 .isize => self.init(.intptr_t),
1361 .c_char => self.init(.char),1365 .c_char => self.init(.char),
...@@ -1367,13 +1371,13 @@ pub const CType = extern union {...@@ -1367,13 +1371,13 @@ pub const CType = extern union {
1367 .c_ulong => self.init(.@"unsigned long"),1371 .c_ulong => self.init(.@"unsigned long"),
1368 .c_longlong => self.init(.@"long long"),1372 .c_longlong => self.init(.@"long long"),
1369 .c_ulonglong => self.init(.@"unsigned long long"),1373 .c_ulonglong => self.init(.@"unsigned long long"),
1370 else => switch (tagFromIntInfo(ty.intInfo(target))) {1374 else => switch (tagFromIntInfo(ty.intInfo(mod))) {
1371 .void => unreachable,1375 .void => unreachable,
1372 else => |t| self.init(t),1376 else => |t| self.init(t),
1373 .array => switch (kind) {1377 .array => switch (kind) {
1374 .forward, .complete, .global => {1378 .forward, .complete, .global => {
1375 const abi_size = ty.abiSize(target);1379 const abi_size = ty.abiSize(mod);
1376 const abi_align = ty.abiAlignment(target);1380 const abi_align = ty.abiAlignment(mod);
1377 self.storage = .{ .seq = .{ .base = .{ .tag = .array }, .data = .{1381 self.storage = .{ .seq = .{ .base = .{ .tag = .array }, .data = .{
1378 .len = @divExact(abi_size, abi_align),1382 .len = @divExact(abi_size, abi_align),
1379 .elem_type = tagFromIntInfo(.{1383 .elem_type = tagFromIntInfo(.{
...@@ -1389,7 +1393,7 @@ pub const CType = extern union {...@@ -1389,7 +1393,7 @@ pub const CType = extern union {
1389 .payload => unreachable,1393 .payload => unreachable,
1390 },1394 },
1391 },1395 },
1392 } else switch (ty.zigTypeTag()) {1396 } else switch (ty.zigTypeTag(mod)) {
1393 .Frame => unreachable,1397 .Frame => unreachable,
1394 .AnyFrame => unreachable,1398 .AnyFrame => unreachable,
13951399
...@@ -1434,12 +1438,12 @@ pub const CType = extern union {...@@ -1434,12 +1438,12 @@ pub const CType = extern union {
1434 self.storage.anon.fields[0] = .{1438 self.storage.anon.fields[0] = .{
1435 .name = "ptr",1439 .name = "ptr",
1436 .type = ptr_idx,1440 .type = ptr_idx,
1437 .alignas = AlignAs.abiAlign(ptr_ty, target),1441 .alignas = AlignAs.abiAlign(ptr_ty, mod),
1438 };1442 };
1439 self.storage.anon.fields[1] = .{1443 self.storage.anon.fields[1] = .{
1440 .name = "len",1444 .name = "len",
1441 .type = Tag.uintptr_t.toIndex(),1445 .type = Tag.uintptr_t.toIndex(),
1442 .alignas = AlignAs.abiAlign(Type.usize, target),1446 .alignas = AlignAs.abiAlign(Type.usize, mod),
1443 };1447 };
1444 self.initAnon(kind, fwd_idx, 2);1448 self.initAnon(kind, fwd_idx, 2);
1445 } else self.init(switch (kind) {1449 } else self.init(switch (kind) {
...@@ -1462,12 +1466,8 @@ pub const CType = extern union {...@@ -1462,12 +1466,8 @@ pub const CType = extern union {
1462 },1466 },
1463 };1467 };
14641468
1465 var host_int_pl = Type.Payload.Bits{
1466 .base = .{ .tag = .int_unsigned },
1467 .data = info.host_size * 8,
1468 };
1469 const pointee_ty = if (info.host_size > 0 and info.vector_index == .none)1469 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)
1471 else1471 else
1472 info.pointee_type;1472 info.pointee_type;
14731473
...@@ -1490,11 +1490,9 @@ pub const CType = extern union {...@@ -1490,11 +1490,9 @@ pub const CType = extern union {
1490 if (ty.castTag(.@"struct")) |struct_obj| {1490 if (ty.castTag(.@"struct")) |struct_obj| {
1491 try self.initType(struct_obj.data.backing_int_ty, kind, lookup);1491 try self.initType(struct_obj.data.backing_int_ty, kind, lookup);
1492 } else {1492 } else {
1493 var buf: Type.Payload.Bits = .{1493 const bits = @intCast(u16, ty.bitSize(mod));
1494 .base = .{ .tag = .int_unsigned },1494 const int_ty = try mod.intType(.unsigned, bits);
1495 .data = @intCast(u16, ty.bitSize(target)),1495 try self.initType(int_ty, kind, lookup);
1496 };
1497 try self.initType(Type.initPayload(&buf.base), kind, lookup);
1498 }1496 }
1499 } else if (ty.isTupleOrAnonStruct()) {1497 } else if (ty.isTupleOrAnonStruct()) {
1500 if (lookup.isMutable()) {1498 if (lookup.isMutable()) {
...@@ -1505,7 +1503,7 @@ pub const CType = extern union {...@@ -1505,7 +1503,7 @@ pub const CType = extern union {
1505 }) |field_i| {1503 }) |field_i| {
1506 const field_ty = ty.structFieldType(field_i);1504 const field_ty = ty.structFieldType(field_i);
1507 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or1505 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or
1508 !field_ty.hasRuntimeBitsIgnoreComptime()) continue;1506 !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
1509 _ = try lookup.typeToIndex(field_ty, switch (kind) {1507 _ = try lookup.typeToIndex(field_ty, switch (kind) {
1510 .forward, .forward_parameter => .forward,1508 .forward, .forward_parameter => .forward,
1511 .complete, .parameter => .complete,1509 .complete, .parameter => .complete,
...@@ -1555,7 +1553,7 @@ pub const CType = extern union {...@@ -1555,7 +1553,7 @@ pub const CType = extern union {
1555 self.storage.anon.fields[field_count] = .{1553 self.storage.anon.fields[field_count] = .{
1556 .name = "payload",1554 .name = "payload",
1557 .type = payload_idx.?,1555 .type = payload_idx.?,
1558 .alignas = AlignAs.unionPayloadAlign(ty, target),1556 .alignas = AlignAs.unionPayloadAlign(ty, mod),
1559 };1557 };
1560 field_count += 1;1558 field_count += 1;
1561 }1559 }
...@@ -1563,7 +1561,7 @@ pub const CType = extern union {...@@ -1563,7 +1561,7 @@ pub const CType = extern union {
1563 self.storage.anon.fields[field_count] = .{1561 self.storage.anon.fields[field_count] = .{
1564 .name = "tag",1562 .name = "tag",
1565 .type = tag_idx.?,1563 .type = tag_idx.?,
1566 .alignas = AlignAs.abiAlign(tag_ty.?, target),1564 .alignas = AlignAs.abiAlign(tag_ty.?, mod),
1567 };1565 };
1568 field_count += 1;1566 field_count += 1;
1569 }1567 }
...@@ -1576,7 +1574,7 @@ pub const CType = extern union {...@@ -1576,7 +1574,7 @@ pub const CType = extern union {
1576 } };1574 } };
1577 self.value = .{ .cty = initPayload(&self.storage.anon.pl.complete) };1575 self.value = .{ .cty = initPayload(&self.storage.anon.pl.complete) };
1578 } else self.init(.@"struct");1576 } else self.init(.@"struct");
1579 } else if (kind == .payload and ty.unionHasAllZeroBitFieldTypes()) {1577 } else if (kind == .payload and ty.unionHasAllZeroBitFieldTypes(mod)) {
1580 self.init(.void);1578 self.init(.void);
1581 } else {1579 } else {
1582 var is_packed = false;1580 var is_packed = false;
...@@ -1586,9 +1584,9 @@ pub const CType = extern union {...@@ -1586,9 +1584,9 @@ pub const CType = extern union {
1586 else => unreachable,1584 else => unreachable,
1587 }) |field_i| {1585 }) |field_i| {
1588 const field_ty = ty.structFieldType(field_i);1586 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);
1592 if (field_align.@"align" < field_align.abi) {1590 if (field_align.@"align" < field_align.abi) {
1593 is_packed = true;1591 is_packed = true;
1594 if (!lookup.isMutable()) break;1592 if (!lookup.isMutable()) break;
...@@ -1643,8 +1641,8 @@ pub const CType = extern union {...@@ -1643,8 +1641,8 @@ pub const CType = extern union {
1643 .Optional => {1641 .Optional => {
1644 var buf: Type.Payload.ElemType = undefined;1642 var buf: Type.Payload.ElemType = undefined;
1645 const payload_ty = ty.optionalChild(&buf);1643 const payload_ty = ty.optionalChild(&buf);
1646 if (payload_ty.hasRuntimeBitsIgnoreComptime()) {1644 if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1647 if (ty.optionalReprIsPayload()) {1645 if (ty.optionalReprIsPayload(mod)) {
1648 try self.initType(payload_ty, kind, lookup);1646 try self.initType(payload_ty, kind, lookup);
1649 } else if (switch (kind) {1647 } else if (switch (kind) {
1650 .forward, .forward_parameter => @as(Index, undefined),1648 .forward, .forward_parameter => @as(Index, undefined),
...@@ -1661,12 +1659,12 @@ pub const CType = extern union {...@@ -1661,12 +1659,12 @@ pub const CType = extern union {
1661 self.storage.anon.fields[0] = .{1659 self.storage.anon.fields[0] = .{
1662 .name = "payload",1660 .name = "payload",
1663 .type = payload_idx,1661 .type = payload_idx,
1664 .alignas = AlignAs.abiAlign(payload_ty, target),1662 .alignas = AlignAs.abiAlign(payload_ty, mod),
1665 };1663 };
1666 self.storage.anon.fields[1] = .{1664 self.storage.anon.fields[1] = .{
1667 .name = "is_null",1665 .name = "is_null",
1668 .type = Tag.bool.toIndex(),1666 .type = Tag.bool.toIndex(),
1669 .alignas = AlignAs.abiAlign(Type.bool, target),1667 .alignas = AlignAs.abiAlign(Type.bool, mod),
1670 };1668 };
1671 self.initAnon(kind, fwd_idx, 2);1669 self.initAnon(kind, fwd_idx, 2);
1672 } else self.init(switch (kind) {1670 } else self.init(switch (kind) {
...@@ -1699,12 +1697,12 @@ pub const CType = extern union {...@@ -1699,12 +1697,12 @@ pub const CType = extern union {
1699 self.storage.anon.fields[0] = .{1697 self.storage.anon.fields[0] = .{
1700 .name = "payload",1698 .name = "payload",
1701 .type = payload_idx,1699 .type = payload_idx,
1702 .alignas = AlignAs.abiAlign(payload_ty, target),1700 .alignas = AlignAs.abiAlign(payload_ty, mod),
1703 };1701 };
1704 self.storage.anon.fields[1] = .{1702 self.storage.anon.fields[1] = .{
1705 .name = "error",1703 .name = "error",
1706 .type = error_idx,1704 .type = error_idx,
1707 .alignas = AlignAs.abiAlign(error_ty, target),1705 .alignas = AlignAs.abiAlign(error_ty, mod),
1708 };1706 };
1709 self.initAnon(kind, fwd_idx, 2);1707 self.initAnon(kind, fwd_idx, 2);
1710 } else self.init(switch (kind) {1708 } else self.init(switch (kind) {
...@@ -1733,7 +1731,7 @@ pub const CType = extern union {...@@ -1733,7 +1731,7 @@ pub const CType = extern union {
1733 };1731 };
1734 _ = try lookup.typeToIndex(info.return_type, param_kind);1732 _ = try lookup.typeToIndex(info.return_type, param_kind);
1735 for (info.param_types) |param_type| {1733 for (info.param_types) |param_type| {
1736 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;1734 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;
1737 _ = try lookup.typeToIndex(param_type, param_kind);1735 _ = try lookup.typeToIndex(param_type, param_kind);
1738 }1736 }
1739 }1737 }
...@@ -1900,16 +1898,16 @@ pub const CType = extern union {...@@ -1900,16 +1898,16 @@ pub const CType = extern union {
1900 }1898 }
1901 }1899 }
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 {
1904 var convert: Convert = undefined;1902 var convert: Convert = undefined;
1905 try convert.initType(ty, kind, .{ .imm = .{ .set = &store.set, .target = target } });1903 try convert.initType(ty, kind, .{ .imm = .{ .set = &store.set, .mod = mod } });
1906 return createFromConvert(store, ty, target, kind, &convert);1904 return createFromConvert(store, ty, mod, kind, &convert);
1907 }1905 }
19081906
1909 fn createFromConvert(1907 fn createFromConvert(
1910 store: *Store.Promoted,1908 store: *Store.Promoted,
1911 ty: Type,1909 ty: Type,
1912 target: Target,1910 mod: *Module,
1913 kind: Kind,1911 kind: Kind,
1914 convert: Convert,1912 convert: Convert,
1915 ) !CType {1913 ) !CType {
...@@ -1930,7 +1928,7 @@ pub const CType = extern union {...@@ -1930,7 +1928,7 @@ pub const CType = extern union {
1930 .packed_struct,1928 .packed_struct,
1931 .packed_union,1929 .packed_union,
1932 => {1930 => {
1933 const zig_ty_tag = ty.zigTypeTag();1931 const zig_ty_tag = ty.zigTypeTag(mod);
1934 const fields_len = switch (zig_ty_tag) {1932 const fields_len = switch (zig_ty_tag) {
1935 .Struct => ty.structFieldCount(),1933 .Struct => ty.structFieldCount(),
1936 .Union => ty.unionFields().count(),1934 .Union => ty.unionFields().count(),
...@@ -1941,7 +1939,7 @@ pub const CType = extern union {...@@ -1941,7 +1939,7 @@ pub const CType = extern union {
1941 for (0..fields_len) |field_i| {1939 for (0..fields_len) |field_i| {
1942 const field_ty = ty.structFieldType(field_i);1940 const field_ty = ty.structFieldType(field_i);
1943 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or1941 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or
1944 !field_ty.hasRuntimeBitsIgnoreComptime()) continue;1942 !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
1945 c_fields_len += 1;1943 c_fields_len += 1;
1946 }1944 }
19471945
...@@ -1950,7 +1948,7 @@ pub const CType = extern union {...@@ -1950,7 +1948,7 @@ pub const CType = extern union {
1950 for (0..fields_len) |field_i| {1948 for (0..fields_len) |field_i| {
1951 const field_ty = ty.structFieldType(field_i);1949 const field_ty = ty.structFieldType(field_i);
1952 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or1950 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or
1953 !field_ty.hasRuntimeBitsIgnoreComptime()) continue;1951 !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
19541952
1955 defer c_field_i += 1;1953 defer c_field_i += 1;
1956 fields_pl[c_field_i] = .{1954 fields_pl[c_field_i] = .{
...@@ -1962,12 +1960,12 @@ pub const CType = extern union {...@@ -1962,12 +1960,12 @@ pub const CType = extern union {
1962 .Union => ty.unionFields().keys()[field_i],1960 .Union => ty.unionFields().keys()[field_i],
1963 else => unreachable,1961 else => unreachable,
1964 }),1962 }),
1965 .type = store.set.typeToIndex(field_ty, target, switch (kind) {1963 .type = store.set.typeToIndex(field_ty, mod, switch (kind) {
1966 .forward, .forward_parameter => .forward,1964 .forward, .forward_parameter => .forward,
1967 .complete, .parameter, .payload => .complete,1965 .complete, .parameter, .payload => .complete,
1968 .global => .global,1966 .global => .global,
1969 }).?,1967 }).?,
1970 .alignas = AlignAs.fieldAlign(ty, field_i, target),1968 .alignas = AlignAs.fieldAlign(ty, field_i, mod),
1971 };1969 };
1972 }1970 }
19731971
...@@ -2004,7 +2002,7 @@ pub const CType = extern union {...@@ -2004,7 +2002,7 @@ pub const CType = extern union {
2004 const struct_pl = try arena.create(Payload.Aggregate);2002 const struct_pl = try arena.create(Payload.Aggregate);
2005 struct_pl.* = .{ .base = .{ .tag = t }, .data = .{2003 struct_pl.* = .{ .base = .{ .tag = t }, .data = .{
2006 .fields = fields_pl,2004 .fields = fields_pl,
2007 .fwd_decl = store.set.typeToIndex(ty, target, .forward).?,2005 .fwd_decl = store.set.typeToIndex(ty, mod, .forward).?,
2008 } };2006 } };
2009 return initPayload(struct_pl);2007 return initPayload(struct_pl);
2010 },2008 },
...@@ -2026,21 +2024,21 @@ pub const CType = extern union {...@@ -2026,21 +2024,21 @@ pub const CType = extern union {
20262024
2027 var c_params_len: usize = 0;2025 var c_params_len: usize = 0;
2028 for (info.param_types) |param_type| {2026 for (info.param_types) |param_type| {
2029 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;2027 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;
2030 c_params_len += 1;2028 c_params_len += 1;
2031 }2029 }
20322030
2033 const params_pl = try arena.alloc(Index, c_params_len);2031 const params_pl = try arena.alloc(Index, c_params_len);
2034 var c_param_i: usize = 0;2032 var c_param_i: usize = 0;
2035 for (info.param_types) |param_type| {2033 for (info.param_types) |param_type| {
2036 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;2034 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;
2037 params_pl[c_param_i] = store.set.typeToIndex(param_type, target, param_kind).?;2035 params_pl[c_param_i] = store.set.typeToIndex(param_type, mod, param_kind).?;
2038 c_param_i += 1;2036 c_param_i += 1;
2039 }2037 }
20402038
2041 const fn_pl = try arena.create(Payload.Function);2039 const fn_pl = try arena.create(Payload.Function);
2042 fn_pl.* = .{ .base = .{ .tag = t }, .data = .{2040 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).?,
2044 .param_types = params_pl,2042 .param_types = params_pl,
2045 } };2043 } };
2046 return initPayload(fn_pl);2044 return initPayload(fn_pl);
...@@ -2067,12 +2065,12 @@ pub const CType = extern union {...@@ -2067,12 +2065,12 @@ pub const CType = extern union {
2067 }2065 }
20682066
2069 pub fn eql(self: @This(), ty: Type, cty: CType) bool {2067 pub fn eql(self: @This(), ty: Type, cty: CType) bool {
2068 const mod = self.lookup.getModule();
2070 switch (self.convert.value) {2069 switch (self.convert.value) {
2071 .cty => |c| return c.eql(cty),2070 .cty => |c| return c.eql(cty),
2072 .tag => |t| {2071 .tag => |t| {
2073 if (t != cty.tag()) return false;2072 if (t != cty.tag()) return false;
20742073
2075 const target = self.lookup.getTarget();
2076 switch (t) {2074 switch (t) {
2077 .fwd_anon_struct,2075 .fwd_anon_struct,
2078 .fwd_anon_union,2076 .fwd_anon_union,
...@@ -2084,7 +2082,7 @@ pub const CType = extern union {...@@ -2084,7 +2082,7 @@ pub const CType = extern union {
2084 ]u8 = undefined;2082 ]u8 = undefined;
2085 const c_fields = cty.cast(Payload.Fields).?.data;2083 const c_fields = cty.cast(Payload.Fields).?.data;
20862084
2087 const zig_ty_tag = ty.zigTypeTag();2085 const zig_ty_tag = ty.zigTypeTag(mod);
2088 var c_field_i: usize = 0;2086 var c_field_i: usize = 0;
2089 for (0..switch (zig_ty_tag) {2087 for (0..switch (zig_ty_tag) {
2090 .Struct => ty.structFieldCount(),2088 .Struct => ty.structFieldCount(),
...@@ -2093,7 +2091,7 @@ pub const CType = extern union {...@@ -2093,7 +2091,7 @@ pub const CType = extern union {
2093 }) |field_i| {2091 }) |field_i| {
2094 const field_ty = ty.structFieldType(field_i);2092 const field_ty = ty.structFieldType(field_i);
2095 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or2093 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or
2096 !field_ty.hasRuntimeBitsIgnoreComptime()) continue;2094 !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
20972095
2098 defer c_field_i += 1;2096 defer c_field_i += 1;
2099 const c_field = &c_fields[c_field_i];2097 const c_field = &c_fields[c_field_i];
...@@ -2113,7 +2111,7 @@ pub const CType = extern union {...@@ -2113,7 +2111,7 @@ pub const CType = extern union {
2113 else => unreachable,2111 else => unreachable,
2114 },2112 },
2115 mem.span(c_field.name),2113 mem.span(c_field.name),
2116 ) or AlignAs.fieldAlign(ty, field_i, target).@"align" !=2114 ) or AlignAs.fieldAlign(ty, field_i, mod).@"align" !=
2117 c_field.alignas.@"align") return false;2115 c_field.alignas.@"align") return false;
2118 }2116 }
2119 return true;2117 return true;
...@@ -2146,7 +2144,7 @@ pub const CType = extern union {...@@ -2146,7 +2144,7 @@ pub const CType = extern union {
2146 .function,2144 .function,
2147 .varargs_function,2145 .varargs_function,
2148 => {2146 => {
2149 if (ty.zigTypeTag() != .Fn) return false;2147 if (ty.zigTypeTag(mod) != .Fn) return false;
21502148
2151 const info = ty.fnInfo();2149 const info = ty.fnInfo();
2152 assert(!info.is_generic);2150 assert(!info.is_generic);
...@@ -2162,7 +2160,7 @@ pub const CType = extern union {...@@ -2162,7 +2160,7 @@ pub const CType = extern union {
21622160
2163 var c_param_i: usize = 0;2161 var c_param_i: usize = 0;
2164 for (info.param_types) |param_type| {2162 for (info.param_types) |param_type| {
2165 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;2163 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;
21662164
2167 if (c_param_i >= data.param_types.len) return false;2165 if (c_param_i >= data.param_types.len) return false;
2168 const param_cty = data.param_types[c_param_i];2166 const param_cty = data.param_types[c_param_i];
...@@ -2202,7 +2200,7 @@ pub const CType = extern union {...@@ -2202,7 +2200,7 @@ pub const CType = extern union {
2202 .tag => |t| {2200 .tag => |t| {
2203 autoHash(hasher, t);2201 autoHash(hasher, t);
22042202
2205 const target = self.lookup.getTarget();2203 const mod = self.lookup.getModule();
2206 switch (t) {2204 switch (t) {
2207 .fwd_anon_struct,2205 .fwd_anon_struct,
2208 .fwd_anon_union,2206 .fwd_anon_union,
...@@ -2211,15 +2209,15 @@ pub const CType = extern union {...@@ -2211,15 +2209,15 @@ pub const CType = extern union {
2211 std.fmt.count("f{}", .{std.math.maxInt(usize)})2209 std.fmt.count("f{}", .{std.math.maxInt(usize)})
2212 ]u8 = undefined;2210 ]u8 = undefined;
22132211
2214 const zig_ty_tag = ty.zigTypeTag();2212 const zig_ty_tag = ty.zigTypeTag(mod);
2215 for (0..switch (ty.zigTypeTag()) {2213 for (0..switch (ty.zigTypeTag(mod)) {
2216 .Struct => ty.structFieldCount(),2214 .Struct => ty.structFieldCount(),
2217 .Union => ty.unionFields().count(),2215 .Union => ty.unionFields().count(),
2218 else => unreachable,2216 else => unreachable,
2219 }) |field_i| {2217 }) |field_i| {
2220 const field_ty = ty.structFieldType(field_i);2218 const field_ty = ty.structFieldType(field_i);
2221 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or2219 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or
2222 !field_ty.hasRuntimeBitsIgnoreComptime()) continue;2220 !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
22232221
2224 self.updateHasherRecurse(hasher, field_ty, switch (self.kind) {2222 self.updateHasherRecurse(hasher, field_ty, switch (self.kind) {
2225 .forward, .forward_parameter => .forward,2223 .forward, .forward_parameter => .forward,
...@@ -2234,7 +2232,7 @@ pub const CType = extern union {...@@ -2234,7 +2232,7 @@ pub const CType = extern union {
2234 .Union => ty.unionFields().keys()[field_i],2232 .Union => ty.unionFields().keys()[field_i],
2235 else => unreachable,2233 else => unreachable,
2236 });2234 });
2237 autoHash(hasher, AlignAs.fieldAlign(ty, field_i, target).@"align");2235 autoHash(hasher, AlignAs.fieldAlign(ty, field_i, mod).@"align");
2238 }2236 }
2239 },2237 },
22402238
...@@ -2271,7 +2269,7 @@ pub const CType = extern union {...@@ -2271,7 +2269,7 @@ pub const CType = extern union {
22712269
2272 self.updateHasherRecurse(hasher, info.return_type, param_kind);2270 self.updateHasherRecurse(hasher, info.return_type, param_kind);
2273 for (info.param_types) |param_type| {2271 for (info.param_types) |param_type| {
2274 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;2272 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;
2275 self.updateHasherRecurse(hasher, param_type, param_kind);2273 self.updateHasherRecurse(hasher, param_type, param_kind);
2276 }2274 }
2277 },2275 },
src/codegen/llvm.zig+812-745
...@@ -598,7 +598,7 @@ pub const Object = struct {...@@ -598,7 +598,7 @@ pub const Object = struct {
598 };598 };
599 const llvm_slice_ty = self.context.structType(&type_fields, type_fields.len, .False);599 const llvm_slice_ty = self.context.structType(&type_fields, type_fields.len, .False);
600 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);600 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
603 const error_name_list = mod.error_name_list.items;603 const error_name_list = mod.error_name_list.items;
604 const llvm_errors = try mod.gpa.alloc(*llvm.Value, error_name_list.len);604 const llvm_errors = try mod.gpa.alloc(*llvm.Value, error_name_list.len);
...@@ -880,28 +880,28 @@ pub const Object = struct {...@@ -880,28 +880,28 @@ pub const Object = struct {
880880
881 pub fn updateFunc(881 pub fn updateFunc(
882 o: *Object,882 o: *Object,
883 module: *Module,883 mod: *Module,
884 func: *Module.Fn,884 func: *Module.Fn,
885 air: Air,885 air: Air,
886 liveness: Liveness,886 liveness: Liveness,
887 ) !void {887 ) !void {
888 const decl_index = func.owner_decl;888 const decl_index = func.owner_decl;
889 const decl = module.declPtr(decl_index);889 const decl = mod.declPtr(decl_index);
890 const target = module.getTarget();890 const target = mod.getTarget();
891891
892 var dg: DeclGen = .{892 var dg: DeclGen = .{
893 .context = o.context,893 .context = o.context,
894 .object = o,894 .object = o,
895 .module = module,895 .module = mod,
896 .decl_index = decl_index,896 .decl_index = decl_index,
897 .decl = decl,897 .decl = decl,
898 .err_msg = null,898 .err_msg = null,
899 .gpa = module.gpa,899 .gpa = mod.gpa,
900 };900 };
901901
902 const llvm_func = try dg.resolveLlvmFunction(decl_index);902 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| {
905 dg.addFnAttrInt(llvm_func, "alignstack", align_info.alignment);905 dg.addFnAttrInt(llvm_func, "alignstack", align_info.alignment);
906 dg.addFnAttr(llvm_func, "noinline");906 dg.addFnAttr(llvm_func, "noinline");
907 } else {907 } else {
...@@ -922,7 +922,7 @@ pub const Object = struct {...@@ -922,7 +922,7 @@ pub const Object = struct {
922 }922 }
923923
924 // TODO: disable this if safety is off for the function scope924 // 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;
926 if (ssp_buf_size != 0) {926 if (ssp_buf_size != 0) {
927 var buf: [12]u8 = undefined;927 var buf: [12]u8 = undefined;
928 const arg = std.fmt.bufPrintZ(&buf, "{d}", .{ssp_buf_size}) catch unreachable;928 const arg = std.fmt.bufPrintZ(&buf, "{d}", .{ssp_buf_size}) catch unreachable;
...@@ -931,7 +931,7 @@ pub const Object = struct {...@@ -931,7 +931,7 @@ pub const Object = struct {
931 }931 }
932932
933 // TODO: disable this if safety is off for the function scope933 // 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) {
935 dg.addFnAttrString(llvm_func, "probe-stack", "__zig_probe_stack");935 dg.addFnAttrString(llvm_func, "probe-stack", "__zig_probe_stack");
936 } else if (target.os.tag == .uefi) {936 } else if (target.os.tag == .uefi) {
937 dg.addFnAttrString(llvm_func, "no-stack-arg-probe", "");937 dg.addFnAttrString(llvm_func, "no-stack-arg-probe", "");
...@@ -954,17 +954,17 @@ pub const Object = struct {...@@ -954,17 +954,17 @@ pub const Object = struct {
954954
955 // This gets the LLVM values from the function and stores them in `dg.args`.955 // This gets the LLVM values from the function and stores them in `dg.args`.
956 const fn_info = decl.ty.fnInfo();956 const fn_info = decl.ty.fnInfo();
957 const sret = firstParamSRet(fn_info, target);957 const sret = firstParamSRet(fn_info, mod);
958 const ret_ptr = if (sret) llvm_func.getParam(0) else null;958 const ret_ptr = if (sret) llvm_func.getParam(0) else null;
959 const gpa = dg.gpa;959 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) {
962 .signed => dg.addAttr(llvm_func, 0, "signext"),962 .signed => dg.addAttr(llvm_func, 0, "signext"),
963 .unsigned => dg.addAttr(llvm_func, 0, "zeroext"),963 .unsigned => dg.addAttr(llvm_func, 0, "zeroext"),
964 };964 };
965965
966 const err_return_tracing = fn_info.return_type.isError() and966 const err_return_tracing = fn_info.return_type.isError(mod) and
967 module.comp.bin_file.options.error_return_tracing;967 mod.comp.bin_file.options.error_return_tracing;
968968
969 const err_ret_trace = if (err_return_tracing)969 const err_ret_trace = if (err_return_tracing)
970 llvm_func.getParam(@boolToInt(ret_ptr != null))970 llvm_func.getParam(@boolToInt(ret_ptr != null))
...@@ -989,8 +989,8 @@ pub const Object = struct {...@@ -989,8 +989,8 @@ pub const Object = struct {
989 const param = llvm_func.getParam(llvm_arg_i);989 const param = llvm_func.getParam(llvm_arg_i);
990 try args.ensureUnusedCapacity(1);990 try args.ensureUnusedCapacity(1);
991991
992 if (isByRef(param_ty)) {992 if (isByRef(param_ty, mod)) {
993 const alignment = param_ty.abiAlignment(target);993 const alignment = param_ty.abiAlignment(mod);
994 const param_llvm_ty = param.typeOf();994 const param_llvm_ty = param.typeOf();
995 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);995 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
996 const store_inst = builder.buildStore(param, arg_ptr);996 const store_inst = builder.buildStore(param, arg_ptr);
...@@ -1007,14 +1007,14 @@ pub const Object = struct {...@@ -1007,14 +1007,14 @@ pub const Object = struct {
1007 const param_ty = fn_info.param_types[it.zig_index - 1];1007 const param_ty = fn_info.param_types[it.zig_index - 1];
1008 const param_llvm_ty = try dg.lowerType(param_ty);1008 const param_llvm_ty = try dg.lowerType(param_ty);
1009 const param = llvm_func.getParam(llvm_arg_i);1009 const param = llvm_func.getParam(llvm_arg_i);
1010 const alignment = param_ty.abiAlignment(target);1010 const alignment = param_ty.abiAlignment(mod);
10111011
1012 dg.addByRefParamAttrs(llvm_func, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);1012 dg.addByRefParamAttrs(llvm_func, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);
1013 llvm_arg_i += 1;1013 llvm_arg_i += 1;
10141014
1015 try args.ensureUnusedCapacity(1);1015 try args.ensureUnusedCapacity(1);
10161016
1017 if (isByRef(param_ty)) {1017 if (isByRef(param_ty, mod)) {
1018 args.appendAssumeCapacity(param);1018 args.appendAssumeCapacity(param);
1019 } else {1019 } else {
1020 const load_inst = builder.buildLoad(param_llvm_ty, param, "");1020 const load_inst = builder.buildLoad(param_llvm_ty, param, "");
...@@ -1026,14 +1026,14 @@ pub const Object = struct {...@@ -1026,14 +1026,14 @@ pub const Object = struct {
1026 const param_ty = fn_info.param_types[it.zig_index - 1];1026 const param_ty = fn_info.param_types[it.zig_index - 1];
1027 const param_llvm_ty = try dg.lowerType(param_ty);1027 const param_llvm_ty = try dg.lowerType(param_ty);
1028 const param = llvm_func.getParam(llvm_arg_i);1028 const param = llvm_func.getParam(llvm_arg_i);
1029 const alignment = param_ty.abiAlignment(target);1029 const alignment = param_ty.abiAlignment(mod);
10301030
1031 dg.addArgAttr(llvm_func, llvm_arg_i, "noundef");1031 dg.addArgAttr(llvm_func, llvm_arg_i, "noundef");
1032 llvm_arg_i += 1;1032 llvm_arg_i += 1;
10331033
1034 try args.ensureUnusedCapacity(1);1034 try args.ensureUnusedCapacity(1);
10351035
1036 if (isByRef(param_ty)) {1036 if (isByRef(param_ty, mod)) {
1037 args.appendAssumeCapacity(param);1037 args.appendAssumeCapacity(param);
1038 } else {1038 } else {
1039 const load_inst = builder.buildLoad(param_llvm_ty, param, "");1039 const load_inst = builder.buildLoad(param_llvm_ty, param, "");
...@@ -1048,10 +1048,10 @@ pub const Object = struct {...@@ -1048,10 +1048,10 @@ pub const Object = struct {
1048 llvm_arg_i += 1;1048 llvm_arg_i += 1;
10491049
1050 const param_llvm_ty = try dg.lowerType(param_ty);1050 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));
1052 const int_llvm_ty = dg.context.intType(abi_size * 8);1052 const int_llvm_ty = dg.context.intType(abi_size * 8);
1053 const alignment = @max(1053 const alignment = @max(
1054 param_ty.abiAlignment(target),1054 param_ty.abiAlignment(mod),
1055 dg.object.target_data.abiAlignmentOfType(int_llvm_ty),1055 dg.object.target_data.abiAlignmentOfType(int_llvm_ty),
1056 );1056 );
1057 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);1057 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
...@@ -1060,7 +1060,7 @@ pub const Object = struct {...@@ -1060,7 +1060,7 @@ pub const Object = struct {
10601060
1061 try args.ensureUnusedCapacity(1);1061 try args.ensureUnusedCapacity(1);
10621062
1063 if (isByRef(param_ty)) {1063 if (isByRef(param_ty, mod)) {
1064 args.appendAssumeCapacity(arg_ptr);1064 args.appendAssumeCapacity(arg_ptr);
1065 } else {1065 } else {
1066 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");1066 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
...@@ -1078,7 +1078,7 @@ pub const Object = struct {...@@ -1078,7 +1078,7 @@ pub const Object = struct {
1078 dg.addArgAttr(llvm_func, llvm_arg_i, "noalias");1078 dg.addArgAttr(llvm_func, llvm_arg_i, "noalias");
1079 }1079 }
1080 }1080 }
1081 if (param_ty.zigTypeTag() != .Optional) {1081 if (param_ty.zigTypeTag(mod) != .Optional) {
1082 dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");1082 dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
1083 }1083 }
1084 if (!ptr_info.mutable) {1084 if (!ptr_info.mutable) {
...@@ -1087,7 +1087,7 @@ pub const Object = struct {...@@ -1087,7 +1087,7 @@ pub const Object = struct {
1087 if (ptr_info.@"align" != 0) {1087 if (ptr_info.@"align" != 0) {
1088 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");1088 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");
1089 } else {1089 } 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);
1091 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);1091 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
1092 }1092 }
1093 const ptr_param = llvm_func.getParam(llvm_arg_i);1093 const ptr_param = llvm_func.getParam(llvm_arg_i);
...@@ -1105,7 +1105,7 @@ pub const Object = struct {...@@ -1105,7 +1105,7 @@ pub const Object = struct {
1105 const field_types = it.llvm_types_buffer[0..it.llvm_types_len];1105 const field_types = it.llvm_types_buffer[0..it.llvm_types_len];
1106 const param_ty = fn_info.param_types[it.zig_index - 1];1106 const param_ty = fn_info.param_types[it.zig_index - 1];
1107 const param_llvm_ty = try dg.lowerType(param_ty);1107 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);
1109 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target);1109 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target);
1110 const llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);1110 const llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
1111 for (field_types, 0..) |_, field_i_usize| {1111 for (field_types, 0..) |_, field_i_usize| {
...@@ -1117,7 +1117,7 @@ pub const Object = struct {...@@ -1117,7 +1117,7 @@ pub const Object = struct {
1117 store_inst.setAlignment(target.ptrBitWidth() / 8);1117 store_inst.setAlignment(target.ptrBitWidth() / 8);
1118 }1118 }
11191119
1120 const is_by_ref = isByRef(param_ty);1120 const is_by_ref = isByRef(param_ty, mod);
1121 const loaded = if (is_by_ref) arg_ptr else l: {1121 const loaded = if (is_by_ref) arg_ptr else l: {
1122 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");1122 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
1123 load_inst.setAlignment(param_alignment);1123 load_inst.setAlignment(param_alignment);
...@@ -1139,11 +1139,11 @@ pub const Object = struct {...@@ -1139,11 +1139,11 @@ pub const Object = struct {
1139 const param = llvm_func.getParam(llvm_arg_i);1139 const param = llvm_func.getParam(llvm_arg_i);
1140 llvm_arg_i += 1;1140 llvm_arg_i += 1;
11411141
1142 const alignment = param_ty.abiAlignment(target);1142 const alignment = param_ty.abiAlignment(mod);
1143 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);1143 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
1144 _ = builder.buildStore(param, arg_ptr);1144 _ = builder.buildStore(param, arg_ptr);
11451145
1146 if (isByRef(param_ty)) {1146 if (isByRef(param_ty, mod)) {
1147 try args.append(arg_ptr);1147 try args.append(arg_ptr);
1148 } else {1148 } else {
1149 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");1149 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
...@@ -1157,11 +1157,11 @@ pub const Object = struct {...@@ -1157,11 +1157,11 @@ pub const Object = struct {
1157 const param = llvm_func.getParam(llvm_arg_i);1157 const param = llvm_func.getParam(llvm_arg_i);
1158 llvm_arg_i += 1;1158 llvm_arg_i += 1;
11591159
1160 const alignment = param_ty.abiAlignment(target);1160 const alignment = param_ty.abiAlignment(mod);
1161 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);1161 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
1162 _ = builder.buildStore(param, arg_ptr);1162 _ = builder.buildStore(param, arg_ptr);
11631163
1164 if (isByRef(param_ty)) {1164 if (isByRef(param_ty, mod)) {
1165 try args.append(arg_ptr);1165 try args.append(arg_ptr);
1166 } else {1166 } else {
1167 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");1167 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
...@@ -1180,7 +1180,7 @@ pub const Object = struct {...@@ -1180,7 +1180,7 @@ pub const Object = struct {
11801180
1181 const line_number = decl.src_line + 1;1181 const line_number = decl.src_line + 1;
1182 const is_internal_linkage = decl.val.tag() != .extern_fn and1182 const is_internal_linkage = decl.val.tag() != .extern_fn and
1183 !module.decl_exports.contains(decl_index);1183 !mod.decl_exports.contains(decl_index);
1184 const noret_bit: c_uint = if (fn_info.return_type.isNoReturn())1184 const noret_bit: c_uint = if (fn_info.return_type.isNoReturn())
1185 llvm.DIFlags.NoReturn1185 llvm.DIFlags.NoReturn
1186 else1186 else
...@@ -1196,7 +1196,7 @@ pub const Object = struct {...@@ -1196,7 +1196,7 @@ pub const Object = struct {
1196 true, // is definition1196 true, // is definition
1197 line_number + func.lbrace_line, // scope line1197 line_number + func.lbrace_line, // scope line
1198 llvm.DIFlags.StaticMember | noret_bit,1198 llvm.DIFlags.StaticMember | noret_bit,
1199 module.comp.bin_file.options.optimize_mode != .Debug,1199 mod.comp.bin_file.options.optimize_mode != .Debug,
1200 null, // decl_subprogram1200 null, // decl_subprogram
1201 );1201 );
1202 try dg.object.di_map.put(gpa, decl, subprogram.toNode());1202 try dg.object.di_map.put(gpa, decl, subprogram.toNode());
...@@ -1219,7 +1219,7 @@ pub const Object = struct {...@@ -1219,7 +1219,7 @@ pub const Object = struct {
1219 .func_inst_table = .{},1219 .func_inst_table = .{},
1220 .llvm_func = llvm_func,1220 .llvm_func = llvm_func,
1221 .blocks = .{},1221 .blocks = .{},
1222 .single_threaded = module.comp.bin_file.options.single_threaded,1222 .single_threaded = mod.comp.bin_file.options.single_threaded,
1223 .di_scope = di_scope,1223 .di_scope = di_scope,
1224 .di_file = di_file,1224 .di_file = di_file,
1225 .base_line = dg.decl.src_line,1225 .base_line = dg.decl.src_line,
...@@ -1232,14 +1232,14 @@ pub const Object = struct {...@@ -1232,14 +1232,14 @@ pub const Object = struct {
1232 fg.genBody(air.getMainBody()) catch |err| switch (err) {1232 fg.genBody(air.getMainBody()) catch |err| switch (err) {
1233 error.CodegenFail => {1233 error.CodegenFail => {
1234 decl.analysis = .codegen_failure;1234 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.?);
1236 dg.err_msg = null;1236 dg.err_msg = null;
1237 return;1237 return;
1238 },1238 },
1239 else => |e| return e,1239 else => |e| return e,
1240 };1240 };
12411241
1242 try o.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));1242 try o.updateDeclExports(mod, decl_index, mod.getDeclExports(decl_index));
1243 }1243 }
12441244
1245 pub fn updateDecl(self: *Object, module: *Module, decl_index: Module.Decl.Index) !void {1245 pub fn updateDecl(self: *Object, module: *Module, decl_index: Module.Decl.Index) !void {
...@@ -1275,37 +1275,40 @@ pub const Object = struct {...@@ -1275,37 +1275,40 @@ pub const Object = struct {
12751275
1276 pub fn updateDeclExports(1276 pub fn updateDeclExports(
1277 self: *Object,1277 self: *Object,
1278 module: *Module,1278 mod: *Module,
1279 decl_index: Module.Decl.Index,1279 decl_index: Module.Decl.Index,
1280 exports: []const *Module.Export,1280 exports: []const *Module.Export,
1281 ) !void {1281 ) !void {
1282 const gpa = mod.gpa;
1282 // If the module does not already have the function, we ignore this function call1283 // If the module does not already have the function, we ignore this function call
1283 // because we call `updateDeclExports` at the end of `updateFunc` and `updateDecl`.1284 // because we call `updateDeclExports` at the end of `updateFunc` and `updateDecl`.
1284 const llvm_global = self.decl_map.get(decl_index) orelse return;1285 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);
1286 if (decl.isExtern()) {1287 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);
1288 const mangle_name = is_wasm_fn and1289 const mangle_name = is_wasm_fn and
1289 decl.getExternFn().?.lib_name != null and1290 decl.getExternFn().?.lib_name != null and
1290 !std.mem.eql(u8, std.mem.sliceTo(decl.getExternFn().?.lib_name.?, 0), "c");1291 !std.mem.eql(u8, std.mem.sliceTo(decl.getExternFn().?.lib_name.?, 0), "c");
1291 const decl_name = if (mangle_name) name: {1292 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 });
1293 break :name tmp.ptr;1296 break :name tmp.ptr;
1294 } else decl.name;1297 } 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
1297 llvm_global.setValueName(decl_name);1300 llvm_global.setValueName(decl_name);
1298 if (self.getLlvmGlobal(decl_name)) |other_global| {1301 if (self.getLlvmGlobal(decl_name)) |other_global| {
1299 if (other_global != llvm_global) {1302 if (other_global != llvm_global) {
1300 log.debug("updateDeclExports isExtern()=true setValueName({s}) conflict", .{decl.name});1303 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, {});
1302 }1305 }
1303 }1306 }
1304 llvm_global.setUnnamedAddr(.False);1307 llvm_global.setUnnamedAddr(.False);
1305 llvm_global.setLinkage(.External);1308 llvm_global.setLinkage(.External);
1306 if (module.wantDllExports()) llvm_global.setDLLStorageClass(.Default);1309 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default);
1307 if (self.di_map.get(decl)) |di_node| {1310 if (self.di_map.get(decl)) |di_node| {
1308 if (try decl.isFunction()) {1311 if (try decl.isFunction(mod)) {
1309 const di_func = @ptrCast(*llvm.DISubprogram, di_node);1312 const di_func = @ptrCast(*llvm.DISubprogram, di_node);
1310 const linkage_name = llvm.MDString.get(self.context, decl.name, std.mem.len(decl.name));1313 const linkage_name = llvm.MDString.get(self.context, decl.name, std.mem.len(decl.name));
1311 di_func.replaceLinkageName(linkage_name);1314 di_func.replaceLinkageName(linkage_name);
...@@ -1329,9 +1332,9 @@ pub const Object = struct {...@@ -1329,9 +1332,9 @@ pub const Object = struct {
1329 const exp_name = exports[0].options.name;1332 const exp_name = exports[0].options.name;
1330 llvm_global.setValueName2(exp_name.ptr, exp_name.len);1333 llvm_global.setValueName2(exp_name.ptr, exp_name.len);
1331 llvm_global.setUnnamedAddr(.False);1334 llvm_global.setUnnamedAddr(.False);
1332 if (module.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport);1335 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport);
1333 if (self.di_map.get(decl)) |di_node| {1336 if (self.di_map.get(decl)) |di_node| {
1334 if (try decl.isFunction()) {1337 if (try decl.isFunction(mod)) {
1335 const di_func = @ptrCast(*llvm.DISubprogram, di_node);1338 const di_func = @ptrCast(*llvm.DISubprogram, di_node);
1336 const linkage_name = llvm.MDString.get(self.context, exp_name.ptr, exp_name.len);1339 const linkage_name = llvm.MDString.get(self.context, exp_name.ptr, exp_name.len);
1337 di_func.replaceLinkageName(linkage_name);1340 di_func.replaceLinkageName(linkage_name);
...@@ -1353,8 +1356,8 @@ pub const Object = struct {...@@ -1353,8 +1356,8 @@ pub const Object = struct {
1353 .protected => llvm_global.setVisibility(.Protected),1356 .protected => llvm_global.setVisibility(.Protected),
1354 }1357 }
1355 if (exports[0].options.section) |section| {1358 if (exports[0].options.section) |section| {
1356 const section_z = try module.gpa.dupeZ(u8, section);1359 const section_z = try gpa.dupeZ(u8, section);
1357 defer module.gpa.free(section_z);1360 defer gpa.free(section_z);
1358 llvm_global.setSection(section_z);1361 llvm_global.setSection(section_z);
1359 }1362 }
1360 if (decl.val.castTag(.variable)) |variable| {1363 if (decl.val.castTag(.variable)) |variable| {
...@@ -1370,8 +1373,8 @@ pub const Object = struct {...@@ -1370,8 +1373,8 @@ pub const Object = struct {
1370 // Until then we iterate over existing aliases and make them point1373 // Until then we iterate over existing aliases and make them point
1371 // to the correct decl, or otherwise add a new alias. Old aliases are leaked.1374 // to the correct decl, or otherwise add a new alias. Old aliases are leaked.
1372 for (exports[1..]) |exp| {1375 for (exports[1..]) |exp| {
1373 const exp_name_z = try module.gpa.dupeZ(u8, exp.options.name);1376 const exp_name_z = try gpa.dupeZ(u8, exp.options.name);
1374 defer module.gpa.free(exp_name_z);1377 defer gpa.free(exp_name_z);
13751378
1376 if (self.llvm_module.getNamedGlobalAlias(exp_name_z.ptr, exp_name_z.len)) |alias| {1379 if (self.llvm_module.getNamedGlobalAlias(exp_name_z.ptr, exp_name_z.len)) |alias| {
1377 alias.setAliasee(llvm_global);1380 alias.setAliasee(llvm_global);
...@@ -1385,14 +1388,14 @@ pub const Object = struct {...@@ -1385,14 +1388,14 @@ pub const Object = struct {
1385 }1388 }
1386 }1389 }
1387 } else {1390 } else {
1388 const fqn = try decl.getFullyQualifiedName(module);1391 const fqn = try decl.getFullyQualifiedName(mod);
1389 defer module.gpa.free(fqn);1392 defer gpa.free(fqn);
1390 llvm_global.setValueName2(fqn.ptr, fqn.len);1393 llvm_global.setValueName2(fqn.ptr, fqn.len);
1391 llvm_global.setLinkage(.Internal);1394 llvm_global.setLinkage(.Internal);
1392 if (module.wantDllExports()) llvm_global.setDLLStorageClass(.Default);1395 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default);
1393 llvm_global.setUnnamedAddr(.True);1396 llvm_global.setUnnamedAddr(.True);
1394 if (decl.val.castTag(.variable)) |variable| {1397 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;
1396 if (variable.data.is_threadlocal and !single_threaded) {1399 if (variable.data.is_threadlocal and !single_threaded) {
1397 llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel);1400 llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel);
1398 } else {1401 } else {
...@@ -1479,14 +1482,15 @@ pub const Object = struct {...@@ -1479,14 +1482,15 @@ pub const Object = struct {
1479 const gpa = o.gpa;1482 const gpa = o.gpa;
1480 const target = o.target;1483 const target = o.target;
1481 const dib = o.di_builder.?;1484 const dib = o.di_builder.?;
1482 switch (ty.zigTypeTag()) {1485 const mod = o.module;
1486 switch (ty.zigTypeTag(mod)) {
1483 .Void, .NoReturn => {1487 .Void, .NoReturn => {
1484 const di_type = dib.createBasicType("void", 0, DW.ATE.signed);1488 const di_type = dib.createBasicType("void", 0, DW.ATE.signed);
1485 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);1489 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
1486 return di_type;1490 return di_type;
1487 },1491 },
1488 .Int => {1492 .Int => {
1489 const info = ty.intInfo(target);1493 const info = ty.intInfo(mod);
1490 assert(info.bits != 0);1494 assert(info.bits != 0);
1491 const name = try ty.nameAlloc(gpa, o.module);1495 const name = try ty.nameAlloc(gpa, o.module);
1492 defer gpa.free(name);1496 defer gpa.free(name);
...@@ -1494,7 +1498,7 @@ pub const Object = struct {...@@ -1494,7 +1498,7 @@ pub const Object = struct {
1494 .signed => DW.ATE.signed,1498 .signed => DW.ATE.signed,
1495 .unsigned => DW.ATE.unsigned,1499 .unsigned => DW.ATE.unsigned,
1496 };1500 };
1497 const di_bits = ty.abiSize(target) * 8; // lldb cannot handle non-byte sized types1501 const di_bits = ty.abiSize(mod) * 8; // lldb cannot handle non-byte sized types
1498 const di_type = dib.createBasicType(name, di_bits, dwarf_encoding);1502 const di_type = dib.createBasicType(name, di_bits, dwarf_encoding);
1499 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);1503 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
1500 return di_type;1504 return di_type;
...@@ -1503,7 +1507,7 @@ pub const Object = struct {...@@ -1503,7 +1507,7 @@ pub const Object = struct {
1503 const owner_decl_index = ty.getOwnerDecl();1507 const owner_decl_index = ty.getOwnerDecl();
1504 const owner_decl = o.module.declPtr(owner_decl_index);1508 const owner_decl = o.module.declPtr(owner_decl_index);
15051509
1506 if (!ty.hasRuntimeBitsIgnoreComptime()) {1510 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
1507 const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);1511 const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
1508 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`1512 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
1509 // means we can't use `gop` anymore.1513 // means we can't use `gop` anymore.
...@@ -1522,9 +1526,8 @@ pub const Object = struct {...@@ -1522,9 +1526,8 @@ pub const Object = struct {
1522 };1526 };
1523 const field_index_val = Value.initPayload(&buf_field_index.base);1527 const field_index_val = Value.initPayload(&buf_field_index.base);
15241528
1525 var buffer: Type.Payload.Bits = undefined;1529 const int_ty = ty.intTagType();
1526 const int_ty = ty.intTagType(&buffer);1530 const int_info = ty.intInfo(mod);
1527 const int_info = ty.intInfo(target);
1528 assert(int_info.bits != 0);1531 assert(int_info.bits != 0);
15291532
1530 for (field_names, 0..) |field_name, i| {1533 for (field_names, 0..) |field_name, i| {
...@@ -1536,7 +1539,7 @@ pub const Object = struct {...@@ -1536,7 +1539,7 @@ pub const Object = struct {
1536 const field_int_val = field_index_val.enumToInt(ty, &buf_u64);1539 const field_int_val = field_index_val.enumToInt(ty, &buf_u64);
15371540
1538 var bigint_space: Value.BigIntSpace = undefined;1541 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
1541 if (bigint.limbs.len == 1) {1544 if (bigint.limbs.len == 1) {
1542 enumerators[i] = dib.createEnumerator(field_name_z, bigint.limbs[0], int_info.signedness == .unsigned);1545 enumerators[i] = dib.createEnumerator(field_name_z, bigint.limbs[0], int_info.signedness == .unsigned);
...@@ -1566,8 +1569,8 @@ pub const Object = struct {...@@ -1566,8 +1569,8 @@ pub const Object = struct {
1566 name,1569 name,
1567 di_file,1570 di_file,
1568 owner_decl.src_node + 1,1571 owner_decl.src_node + 1,
1569 ty.abiSize(target) * 8,1572 ty.abiSize(mod) * 8,
1570 ty.abiAlignment(target) * 8,1573 ty.abiAlignment(mod) * 8,
1571 enumerators.ptr,1574 enumerators.ptr,
1572 @intCast(c_int, enumerators.len),1575 @intCast(c_int, enumerators.len),
1573 try o.lowerDebugType(int_ty, .full),1576 try o.lowerDebugType(int_ty, .full),
...@@ -1604,7 +1607,7 @@ pub const Object = struct {...@@ -1604,7 +1607,7 @@ pub const Object = struct {
1604 !ptr_info.mutable or1607 !ptr_info.mutable or
1605 ptr_info.@"volatile" or1608 ptr_info.@"volatile" or
1606 ptr_info.size == .Many or ptr_info.size == .C or1609 ptr_info.size == .Many or ptr_info.size == .C or
1607 !ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime())1610 !ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime(mod))
1608 {1611 {
1609 var payload: Type.Payload.Pointer = .{1612 var payload: Type.Payload.Pointer = .{
1610 .data = .{1613 .data = .{
...@@ -1623,7 +1626,7 @@ pub const Object = struct {...@@ -1623,7 +1626,7 @@ pub const Object = struct {
1623 },1626 },
1624 },1627 },
1625 };1628 };
1626 if (!ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime()) {1629 if (!ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime(mod)) {
1627 payload.data.pointee_type = Type.anyopaque;1630 payload.data.pointee_type = Type.anyopaque;
1628 }1631 }
1629 const bland_ptr_ty = Type.initPayload(&payload.base);1632 const bland_ptr_ty = Type.initPayload(&payload.base);
...@@ -1657,10 +1660,10 @@ pub const Object = struct {...@@ -1657,10 +1660,10 @@ pub const Object = struct {
1657 break :blk fwd_decl;1660 break :blk fwd_decl;
1658 };1661 };
16591662
1660 const ptr_size = ptr_ty.abiSize(target);1663 const ptr_size = ptr_ty.abiSize(mod);
1661 const ptr_align = ptr_ty.abiAlignment(target);1664 const ptr_align = ptr_ty.abiAlignment(mod);
1662 const len_size = len_ty.abiSize(target);1665 const len_size = len_ty.abiSize(mod);
1663 const len_align = len_ty.abiAlignment(target);1666 const len_align = len_ty.abiAlignment(mod);
16641667
1665 var offset: u64 = 0;1668 var offset: u64 = 0;
1666 offset += ptr_size;1669 offset += ptr_size;
...@@ -1697,8 +1700,8 @@ pub const Object = struct {...@@ -1697,8 +1700,8 @@ pub const Object = struct {
1697 name.ptr,1700 name.ptr,
1698 di_file,1701 di_file,
1699 line,1702 line,
1700 ty.abiSize(target) * 8, // size in bits1703 ty.abiSize(mod) * 8, // size in bits
1701 ty.abiAlignment(target) * 8, // align in bits1704 ty.abiAlignment(mod) * 8, // align in bits
1702 0, // flags1705 0, // flags
1703 null, // derived from1706 null, // derived from
1704 &fields,1707 &fields,
...@@ -1719,7 +1722,7 @@ pub const Object = struct {...@@ -1719,7 +1722,7 @@ pub const Object = struct {
1719 const ptr_di_ty = dib.createPointerType(1722 const ptr_di_ty = dib.createPointerType(
1720 elem_di_ty,1723 elem_di_ty,
1721 target.ptrBitWidth(),1724 target.ptrBitWidth(),
1722 ty.ptrAlignment(target) * 8,1725 ty.ptrAlignment(mod) * 8,
1723 name,1726 name,
1724 );1727 );
1725 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1728 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
...@@ -1750,8 +1753,8 @@ pub const Object = struct {...@@ -1750,8 +1753,8 @@ pub const Object = struct {
1750 },1753 },
1751 .Array => {1754 .Array => {
1752 const array_di_ty = dib.createArrayType(1755 const array_di_ty = dib.createArrayType(
1753 ty.abiSize(target) * 8,1756 ty.abiSize(mod) * 8,
1754 ty.abiAlignment(target) * 8,1757 ty.abiAlignment(mod) * 8,
1755 try o.lowerDebugType(ty.childType(), .full),1758 try o.lowerDebugType(ty.childType(), .full),
1756 @intCast(c_int, ty.arrayLen()),1759 @intCast(c_int, ty.arrayLen()),
1757 );1760 );
...@@ -1760,14 +1763,14 @@ pub const Object = struct {...@@ -1760,14 +1763,14 @@ pub const Object = struct {
1760 return array_di_ty;1763 return array_di_ty;
1761 },1764 },
1762 .Vector => {1765 .Vector => {
1763 const elem_ty = ty.elemType2();1766 const elem_ty = ty.elemType2(mod);
1764 // Vector elements cannot be padded since that would make1767 // Vector elements cannot be padded since that would make
1765 // @bitSizOf(elem) * len > @bitSizOf(vec).1768 // @bitSizOf(elem) * len > @bitSizOf(vec).
1766 // Neither gdb nor lldb seem to be able to display non-byte sized1769 // Neither gdb nor lldb seem to be able to display non-byte sized
1767 // vectors properly.1770 // vectors properly.
1768 const elem_di_type = switch (elem_ty.zigTypeTag()) {1771 const elem_di_type = switch (elem_ty.zigTypeTag(mod)) {
1769 .Int => blk: {1772 .Int => blk: {
1770 const info = elem_ty.intInfo(target);1773 const info = elem_ty.intInfo(mod);
1771 assert(info.bits != 0);1774 assert(info.bits != 0);
1772 const name = try ty.nameAlloc(gpa, o.module);1775 const name = try ty.nameAlloc(gpa, o.module);
1773 defer gpa.free(name);1776 defer gpa.free(name);
...@@ -1782,8 +1785,8 @@ pub const Object = struct {...@@ -1782,8 +1785,8 @@ pub const Object = struct {
1782 };1785 };
17831786
1784 const vector_di_ty = dib.createVectorType(1787 const vector_di_ty = dib.createVectorType(
1785 ty.abiSize(target) * 8,1788 ty.abiSize(mod) * 8,
1786 ty.abiAlignment(target) * 8,1789 ty.abiAlignment(mod) * 8,
1787 elem_di_type,1790 elem_di_type,
1788 ty.vectorLen(),1791 ty.vectorLen(),
1789 );1792 );
...@@ -1796,13 +1799,13 @@ pub const Object = struct {...@@ -1796,13 +1799,13 @@ pub const Object = struct {
1796 defer gpa.free(name);1799 defer gpa.free(name);
1797 var buf: Type.Payload.ElemType = undefined;1800 var buf: Type.Payload.ElemType = undefined;
1798 const child_ty = ty.optionalChild(&buf);1801 const child_ty = ty.optionalChild(&buf);
1799 if (!child_ty.hasRuntimeBitsIgnoreComptime()) {1802 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1800 const di_bits = 8; // lldb cannot handle non-byte sized types1803 const di_bits = 8; // lldb cannot handle non-byte sized types
1801 const di_ty = dib.createBasicType(name, di_bits, DW.ATE.boolean);1804 const di_ty = dib.createBasicType(name, di_bits, DW.ATE.boolean);
1802 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);1805 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
1803 return di_ty;1806 return di_ty;
1804 }1807 }
1805 if (ty.optionalReprIsPayload()) {1808 if (ty.optionalReprIsPayload(mod)) {
1806 const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);1809 const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);
1807 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1810 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1808 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .mod = o.module });1811 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 {...@@ -1826,10 +1829,10 @@ pub const Object = struct {
1826 };1829 };
18271830
1828 const non_null_ty = Type.u8;1831 const non_null_ty = Type.u8;
1829 const payload_size = child_ty.abiSize(target);1832 const payload_size = child_ty.abiSize(mod);
1830 const payload_align = child_ty.abiAlignment(target);1833 const payload_align = child_ty.abiAlignment(mod);
1831 const non_null_size = non_null_ty.abiSize(target);1834 const non_null_size = non_null_ty.abiSize(mod);
1832 const non_null_align = non_null_ty.abiAlignment(target);1835 const non_null_align = non_null_ty.abiAlignment(mod);
18331836
1834 var offset: u64 = 0;1837 var offset: u64 = 0;
1835 offset += payload_size;1838 offset += payload_size;
...@@ -1866,8 +1869,8 @@ pub const Object = struct {...@@ -1866,8 +1869,8 @@ pub const Object = struct {
1866 name.ptr,1869 name.ptr,
1867 di_file,1870 di_file,
1868 line,1871 line,
1869 ty.abiSize(target) * 8, // size in bits1872 ty.abiSize(mod) * 8, // size in bits
1870 ty.abiAlignment(target) * 8, // align in bits1873 ty.abiAlignment(mod) * 8, // align in bits
1871 0, // flags1874 0, // flags
1872 null, // derived from1875 null, // derived from
1873 &fields,1876 &fields,
...@@ -1883,7 +1886,7 @@ pub const Object = struct {...@@ -1883,7 +1886,7 @@ pub const Object = struct {
1883 },1886 },
1884 .ErrorUnion => {1887 .ErrorUnion => {
1885 const payload_ty = ty.errorUnionPayload();1888 const payload_ty = ty.errorUnionPayload();
1886 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1889 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1887 const err_set_di_ty = try o.lowerDebugType(Type.anyerror, .full);1890 const err_set_di_ty = try o.lowerDebugType(Type.anyerror, .full);
1888 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1891 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1889 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty), .{ .mod = o.module });1892 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 {...@@ -1907,10 +1910,10 @@ pub const Object = struct {
1907 break :blk fwd_decl;1910 break :blk fwd_decl;
1908 };1911 };
19091912
1910 const error_size = Type.anyerror.abiSize(target);1913 const error_size = Type.anyerror.abiSize(mod);
1911 const error_align = Type.anyerror.abiAlignment(target);1914 const error_align = Type.anyerror.abiAlignment(mod);
1912 const payload_size = payload_ty.abiSize(target);1915 const payload_size = payload_ty.abiSize(mod);
1913 const payload_align = payload_ty.abiAlignment(target);1916 const payload_align = payload_ty.abiAlignment(mod);
19141917
1915 var error_index: u32 = undefined;1918 var error_index: u32 = undefined;
1916 var payload_index: u32 = undefined;1919 var payload_index: u32 = undefined;
...@@ -1957,8 +1960,8 @@ pub const Object = struct {...@@ -1957,8 +1960,8 @@ pub const Object = struct {
1957 name.ptr,1960 name.ptr,
1958 di_file,1961 di_file,
1959 line,1962 line,
1960 ty.abiSize(target) * 8, // size in bits1963 ty.abiSize(mod) * 8, // size in bits
1961 ty.abiAlignment(target) * 8, // align in bits1964 ty.abiAlignment(mod) * 8, // align in bits
1962 0, // flags1965 0, // flags
1963 null, // derived from1966 null, // derived from
1964 &fields,1967 &fields,
...@@ -1988,12 +1991,12 @@ pub const Object = struct {...@@ -1988,12 +1991,12 @@ pub const Object = struct {
1988 const struct_obj = payload.data;1991 const struct_obj = payload.data;
1989 if (struct_obj.layout == .Packed and struct_obj.haveFieldTypes()) {1992 if (struct_obj.layout == .Packed and struct_obj.haveFieldTypes()) {
1990 assert(struct_obj.haveLayout());1993 assert(struct_obj.haveLayout());
1991 const info = struct_obj.backing_int_ty.intInfo(target);1994 const info = struct_obj.backing_int_ty.intInfo(mod);
1992 const dwarf_encoding: c_uint = switch (info.signedness) {1995 const dwarf_encoding: c_uint = switch (info.signedness) {
1993 .signed => DW.ATE.signed,1996 .signed => DW.ATE.signed,
1994 .unsigned => DW.ATE.unsigned,1997 .unsigned => DW.ATE.unsigned,
1995 };1998 };
1996 const di_bits = ty.abiSize(target) * 8; // lldb cannot handle non-byte sized types1999 const di_bits = ty.abiSize(mod) * 8; // lldb cannot handle non-byte sized types
1997 const di_ty = dib.createBasicType(name, di_bits, dwarf_encoding);2000 const di_ty = dib.createBasicType(name, di_bits, dwarf_encoding);
1998 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);2001 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
1999 return di_ty;2002 return di_ty;
...@@ -2026,10 +2029,10 @@ pub const Object = struct {...@@ -2026,10 +2029,10 @@ pub const Object = struct {
20262029
2027 for (tuple.types, 0..) |field_ty, i| {2030 for (tuple.types, 0..) |field_ty, i| {
2028 const field_val = tuple.values[i];2031 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);2034 const field_size = field_ty.abiSize(mod);
2032 const field_align = field_ty.abiAlignment(target);2035 const field_align = field_ty.abiAlignment(mod);
2033 const field_offset = std.mem.alignForwardGeneric(u64, offset, field_align);2036 const field_offset = std.mem.alignForwardGeneric(u64, offset, field_align);
2034 offset = field_offset + field_size;2037 offset = field_offset + field_size;
20352038
...@@ -2057,8 +2060,8 @@ pub const Object = struct {...@@ -2057,8 +2060,8 @@ pub const Object = struct {
2057 name.ptr,2060 name.ptr,
2058 null, // file2061 null, // file
2059 0, // line2062 0, // line
2060 ty.abiSize(target) * 8, // size in bits2063 ty.abiSize(mod) * 8, // size in bits
2061 ty.abiAlignment(target) * 8, // align in bits2064 ty.abiAlignment(mod) * 8, // align in bits
2062 0, // flags2065 0, // flags
2063 null, // derived from2066 null, // derived from
2064 di_fields.items.ptr,2067 di_fields.items.ptr,
...@@ -2093,7 +2096,7 @@ pub const Object = struct {...@@ -2093,7 +2096,7 @@ pub const Object = struct {
2093 }2096 }
2094 }2097 }
20952098
2096 if (!ty.hasRuntimeBitsIgnoreComptime()) {2099 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
2097 const owner_decl_index = ty.getOwnerDecl();2100 const owner_decl_index = ty.getOwnerDecl();
2098 const struct_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);2101 const struct_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
2099 dib.replaceTemporary(fwd_decl, struct_di_ty);2102 dib.replaceTemporary(fwd_decl, struct_di_ty);
...@@ -2114,11 +2117,11 @@ pub const Object = struct {...@@ -2114,11 +2117,11 @@ pub const Object = struct {
2114 comptime assert(struct_layout_version == 2);2117 comptime assert(struct_layout_version == 2);
2115 var offset: u64 = 0;2118 var offset: u64 = 0;
21162119
2117 var it = ty.castTag(.@"struct").?.data.runtimeFieldIterator();2120 var it = ty.castTag(.@"struct").?.data.runtimeFieldIterator(mod);
2118 while (it.next()) |field_and_index| {2121 while (it.next()) |field_and_index| {
2119 const field = field_and_index.field;2122 const field = field_and_index.field;
2120 const field_size = field.ty.abiSize(target);2123 const field_size = field.ty.abiSize(mod);
2121 const field_align = field.alignment(target, layout);2124 const field_align = field.alignment(mod, layout);
2122 const field_offset = std.mem.alignForwardGeneric(u64, offset, field_align);2125 const field_offset = std.mem.alignForwardGeneric(u64, offset, field_align);
2123 offset = field_offset + field_size;2126 offset = field_offset + field_size;
21242127
...@@ -2143,8 +2146,8 @@ pub const Object = struct {...@@ -2143,8 +2146,8 @@ pub const Object = struct {
2143 name.ptr,2146 name.ptr,
2144 null, // file2147 null, // file
2145 0, // line2148 0, // line
2146 ty.abiSize(target) * 8, // size in bits2149 ty.abiSize(mod) * 8, // size in bits
2147 ty.abiAlignment(target) * 8, // align in bits2150 ty.abiAlignment(mod) * 8, // align in bits
2148 0, // flags2151 0, // flags
2149 null, // derived from2152 null, // derived from
2150 di_fields.items.ptr,2153 di_fields.items.ptr,
...@@ -2179,7 +2182,7 @@ pub const Object = struct {...@@ -2179,7 +2182,7 @@ pub const Object = struct {
2179 };2182 };
21802183
2181 const union_obj = ty.cast(Type.Payload.Union).?.data;2184 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)) {
2183 const union_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);2186 const union_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
2184 dib.replaceTemporary(fwd_decl, union_di_ty);2187 dib.replaceTemporary(fwd_decl, union_di_ty);
2185 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`2188 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
...@@ -2188,7 +2191,7 @@ pub const Object = struct {...@@ -2188,7 +2191,7 @@ pub const Object = struct {
2188 return union_di_ty;2191 return union_di_ty;
2189 }2192 }
21902193
2191 const layout = ty.unionGetLayout(target);2194 const layout = ty.unionGetLayout(mod);
21922195
2193 if (layout.payload_size == 0) {2196 if (layout.payload_size == 0) {
2194 const tag_di_ty = try o.lowerDebugType(union_obj.tag_ty, .full);2197 const tag_di_ty = try o.lowerDebugType(union_obj.tag_ty, .full);
...@@ -2198,8 +2201,8 @@ pub const Object = struct {...@@ -2198,8 +2201,8 @@ pub const Object = struct {
2198 name.ptr,2201 name.ptr,
2199 null, // file2202 null, // file
2200 0, // line2203 0, // line
2201 ty.abiSize(target) * 8, // size in bits2204 ty.abiSize(mod) * 8, // size in bits
2202 ty.abiAlignment(target) * 8, // align in bits2205 ty.abiAlignment(mod) * 8, // align in bits
2203 0, // flags2206 0, // flags
2204 null, // derived from2207 null, // derived from
2205 &di_fields,2208 &di_fields,
...@@ -2225,10 +2228,10 @@ pub const Object = struct {...@@ -2225,10 +2228,10 @@ pub const Object = struct {
2225 const field_name = kv.key_ptr.*;2228 const field_name = kv.key_ptr.*;
2226 const field = kv.value_ptr.*;2229 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);2233 const field_size = field.ty.abiSize(mod);
2231 const field_align = field.normalAlignment(target);2234 const field_align = field.normalAlignment(mod);
22322235
2233 const field_name_copy = try gpa.dupeZ(u8, field_name);2236 const field_name_copy = try gpa.dupeZ(u8, field_name);
2234 defer gpa.free(field_name_copy);2237 defer gpa.free(field_name_copy);
...@@ -2258,8 +2261,8 @@ pub const Object = struct {...@@ -2258,8 +2261,8 @@ pub const Object = struct {
2258 union_name.ptr,2261 union_name.ptr,
2259 null, // file2262 null, // file
2260 0, // line2263 0, // line
2261 ty.abiSize(target) * 8, // size in bits2264 ty.abiSize(mod) * 8, // size in bits
2262 ty.abiAlignment(target) * 8, // align in bits2265 ty.abiAlignment(mod) * 8, // align in bits
2263 0, // flags2266 0, // flags
2264 di_fields.items.ptr,2267 di_fields.items.ptr,
2265 @intCast(c_int, di_fields.items.len),2268 @intCast(c_int, di_fields.items.len),
...@@ -2319,8 +2322,8 @@ pub const Object = struct {...@@ -2319,8 +2322,8 @@ pub const Object = struct {
2319 name.ptr,2322 name.ptr,
2320 null, // file2323 null, // file
2321 0, // line2324 0, // line
2322 ty.abiSize(target) * 8, // size in bits2325 ty.abiSize(mod) * 8, // size in bits
2323 ty.abiAlignment(target) * 8, // align in bits2326 ty.abiAlignment(mod) * 8, // align in bits
2324 0, // flags2327 0, // flags
2325 null, // derived from2328 null, // derived from
2326 &full_di_fields,2329 &full_di_fields,
...@@ -2341,8 +2344,8 @@ pub const Object = struct {...@@ -2341,8 +2344,8 @@ pub const Object = struct {
2341 defer param_di_types.deinit();2344 defer param_di_types.deinit();
23422345
2343 // Return type goes first.2346 // Return type goes first.
2344 if (fn_info.return_type.hasRuntimeBitsIgnoreComptime()) {2347 if (fn_info.return_type.hasRuntimeBitsIgnoreComptime(mod)) {
2345 const sret = firstParamSRet(fn_info, target);2348 const sret = firstParamSRet(fn_info, mod);
2346 const di_ret_ty = if (sret) Type.void else fn_info.return_type;2349 const di_ret_ty = if (sret) Type.void else fn_info.return_type;
2347 try param_di_types.append(try o.lowerDebugType(di_ret_ty, .full));2350 try param_di_types.append(try o.lowerDebugType(di_ret_ty, .full));
23482351
...@@ -2358,7 +2361,7 @@ pub const Object = struct {...@@ -2358,7 +2361,7 @@ pub const Object = struct {
2358 try param_di_types.append(try o.lowerDebugType(Type.void, .full));2361 try param_di_types.append(try o.lowerDebugType(Type.void, .full));
2359 }2362 }
23602363
2361 if (fn_info.return_type.isError() and2364 if (fn_info.return_type.isError(mod) and
2362 o.module.comp.bin_file.options.error_return_tracing)2365 o.module.comp.bin_file.options.error_return_tracing)
2363 {2366 {
2364 var ptr_ty_payload: Type.Payload.ElemType = .{2367 var ptr_ty_payload: Type.Payload.ElemType = .{
...@@ -2370,9 +2373,9 @@ pub const Object = struct {...@@ -2370,9 +2373,9 @@ pub const Object = struct {
2370 }2373 }
23712374
2372 for (fn_info.param_types) |param_ty| {2375 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)) {
2376 var ptr_ty_payload: Type.Payload.ElemType = .{2379 var ptr_ty_payload: Type.Payload.ElemType = .{
2377 .base = .{ .tag = .single_mut_pointer },2380 .base = .{ .tag = .single_mut_pointer },
2378 .data = param_ty,2381 .data = param_ty,
...@@ -2450,7 +2453,7 @@ pub const Object = struct {...@@ -2450,7 +2453,7 @@ pub const Object = struct {
24502453
2451 const stack_trace_str: []const u8 = "StackTrace";2454 const stack_trace_str: []const u8 = "StackTrace";
2452 // buffer is only used for int_type, `builtin` is a struct.2455 // 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();
2454 const builtin_namespace = builtin_ty.getNamespace().?;2457 const builtin_namespace = builtin_ty.getNamespace().?;
2455 const stack_trace_decl_index = builtin_namespace.decls2458 const stack_trace_decl_index = builtin_namespace.decls
2456 .getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .mod = mod }).?;2459 .getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .mod = mod }).?;
...@@ -2458,7 +2461,7 @@ pub const Object = struct {...@@ -2458,7 +2461,7 @@ pub const Object = struct {
24582461
2459 // Sema should have ensured that StackTrace was analyzed.2462 // Sema should have ensured that StackTrace was analyzed.
2460 assert(stack_trace_decl.has_tv);2463 assert(stack_trace_decl.has_tv);
2461 return stack_trace_decl.val.toType(undefined);2464 return stack_trace_decl.val.toType();
2462 }2465 }
2463};2466};
24642467
...@@ -2495,9 +2498,10 @@ pub const DeclGen = struct {...@@ -2495,9 +2498,10 @@ pub const DeclGen = struct {
2495 if (decl.val.castTag(.extern_fn)) |extern_fn| {2498 if (decl.val.castTag(.extern_fn)) |extern_fn| {
2496 _ = try dg.resolveLlvmFunction(extern_fn.data.owner_decl);2499 _ = try dg.resolveLlvmFunction(extern_fn.data.owner_decl);
2497 } else {2500 } else {
2498 const target = dg.module.getTarget();2501 const mod = dg.module;
2502 const target = mod.getTarget();
2499 var global = try dg.resolveGlobalDecl(decl_index);2503 var global = try dg.resolveGlobalDecl(decl_index);
2500 global.setAlignment(decl.getAlignment(target));2504 global.setAlignment(decl.getAlignment(mod));
2501 if (decl.@"linksection") |section| global.setSection(section);2505 if (decl.@"linksection") |section| global.setSection(section);
2502 assert(decl.has_tv);2506 assert(decl.has_tv);
2503 const init_val = if (decl.val.castTag(.variable)) |payload| init_val: {2507 const init_val = if (decl.val.castTag(.variable)) |payload| init_val: {
...@@ -2569,19 +2573,20 @@ pub const DeclGen = struct {...@@ -2569,19 +2573,20 @@ pub const DeclGen = struct {
2569 /// Note that this can be called before the function's semantic analysis has2573 /// Note that this can be called before the function's semantic analysis has
2570 /// completed, so if any attributes rely on that, they must be done in updateFunc, not here.2574 /// completed, so if any attributes rely on that, they must be done in updateFunc, not here.
2571 fn resolveLlvmFunction(dg: *DeclGen, decl_index: Module.Decl.Index) !*llvm.Value {2575 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);
2573 const zig_fn_type = decl.ty;2578 const zig_fn_type = decl.ty;
2574 const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl_index);2579 const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl_index);
2575 if (gop.found_existing) return gop.value_ptr.*;2580 if (gop.found_existing) return gop.value_ptr.*;
25762581
2577 assert(decl.has_tv);2582 assert(decl.has_tv);
2578 const fn_info = zig_fn_type.fnInfo();2583 const fn_info = zig_fn_type.fnInfo();
2579 const target = dg.module.getTarget();2584 const target = mod.getTarget();
2580 const sret = firstParamSRet(fn_info, target);2585 const sret = firstParamSRet(fn_info, mod);
25812586
2582 const fn_type = try dg.lowerType(zig_fn_type);2587 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);
2585 defer dg.gpa.free(fqn);2590 defer dg.gpa.free(fqn);
25862591
2587 const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);2592 const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
...@@ -2593,7 +2598,7 @@ pub const DeclGen = struct {...@@ -2593,7 +2598,7 @@ pub const DeclGen = struct {
2593 llvm_fn.setLinkage(.Internal);2598 llvm_fn.setLinkage(.Internal);
2594 llvm_fn.setUnnamedAddr(.True);2599 llvm_fn.setUnnamedAddr(.True);
2595 } else {2600 } else {
2596 if (dg.module.getTarget().isWasm()) {2601 if (target.isWasm()) {
2597 dg.addFnAttrString(llvm_fn, "wasm-import-name", std.mem.sliceTo(decl.name, 0));2602 dg.addFnAttrString(llvm_fn, "wasm-import-name", std.mem.sliceTo(decl.name, 0));
2598 if (decl.getExternFn().?.lib_name) |lib_name| {2603 if (decl.getExternFn().?.lib_name) |lib_name| {
2599 const module_name = std.mem.sliceTo(lib_name, 0);2604 const module_name = std.mem.sliceTo(lib_name, 0);
...@@ -2612,8 +2617,8 @@ pub const DeclGen = struct {...@@ -2612,8 +2617,8 @@ pub const DeclGen = struct {
2612 llvm_fn.addSretAttr(raw_llvm_ret_ty);2617 llvm_fn.addSretAttr(raw_llvm_ret_ty);
2613 }2618 }
26142619
2615 const err_return_tracing = fn_info.return_type.isError() and2620 const err_return_tracing = fn_info.return_type.isError(mod) and
2616 dg.module.comp.bin_file.options.error_return_tracing;2621 mod.comp.bin_file.options.error_return_tracing;
26172622
2618 if (err_return_tracing) {2623 if (err_return_tracing) {
2619 dg.addArgAttr(llvm_fn, @boolToInt(sret), "nonnull");2624 dg.addArgAttr(llvm_fn, @boolToInt(sret), "nonnull");
...@@ -2656,14 +2661,14 @@ pub const DeclGen = struct {...@@ -2656,14 +2661,14 @@ pub const DeclGen = struct {
2656 .byval => {2661 .byval => {
2657 const param_index = it.zig_index - 1;2662 const param_index = it.zig_index - 1;
2658 const param_ty = fn_info.param_types[param_index];2663 const param_ty = fn_info.param_types[param_index];
2659 if (!isByRef(param_ty)) {2664 if (!isByRef(param_ty, mod)) {
2660 dg.addByValParamAttrs(llvm_fn, param_ty, param_index, fn_info, it.llvm_index - 1);2665 dg.addByValParamAttrs(llvm_fn, param_ty, param_index, fn_info, it.llvm_index - 1);
2661 }2666 }
2662 },2667 },
2663 .byref => {2668 .byref => {
2664 const param_ty = fn_info.param_types[it.zig_index - 1];2669 const param_ty = fn_info.param_types[it.zig_index - 1];
2665 const param_llvm_ty = try dg.lowerType(param_ty);2670 const param_llvm_ty = try dg.lowerType(param_ty);
2666 const alignment = param_ty.abiAlignment(target);2671 const alignment = param_ty.abiAlignment(mod);
2667 dg.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);2672 dg.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
2668 },2673 },
2669 .byref_mut => {2674 .byref_mut => {
...@@ -2784,12 +2789,13 @@ pub const DeclGen = struct {...@@ -2784,12 +2789,13 @@ pub const DeclGen = struct {
27842789
2785 fn lowerType(dg: *DeclGen, t: Type) Allocator.Error!*llvm.Type {2790 fn lowerType(dg: *DeclGen, t: Type) Allocator.Error!*llvm.Type {
2786 const llvm_ty = try lowerTypeInner(dg, t);2791 const llvm_ty = try lowerTypeInner(dg, t);
2792 const mod = dg.module;
2787 if (std.debug.runtime_safety and false) check: {2793 if (std.debug.runtime_safety and false) check: {
2788 if (t.zigTypeTag() == .Opaque) break :check;2794 if (t.zigTypeTag(mod) == .Opaque) break :check;
2789 if (!t.hasRuntimeBits()) break :check;2795 if (!t.hasRuntimeBits(mod)) break :check;
2790 if (!llvm_ty.isSized().toBool()) break :check;2796 if (!llvm_ty.isSized().toBool()) break :check;
27912797
2792 const zig_size = t.abiSize(dg.module.getTarget());2798 const zig_size = t.abiSize(mod);
2793 const llvm_size = dg.object.target_data.abiSizeOfType(llvm_ty);2799 const llvm_size = dg.object.target_data.abiSizeOfType(llvm_ty);
2794 if (llvm_size != zig_size) {2800 if (llvm_size != zig_size) {
2795 log.err("when lowering {}, Zig ABI size = {d} but LLVM ABI size = {d}", .{2801 log.err("when lowering {}, Zig ABI size = {d} but LLVM ABI size = {d}", .{
...@@ -2802,18 +2808,18 @@ pub const DeclGen = struct {...@@ -2802,18 +2808,18 @@ pub const DeclGen = struct {
28022808
2803 fn lowerTypeInner(dg: *DeclGen, t: Type) Allocator.Error!*llvm.Type {2809 fn lowerTypeInner(dg: *DeclGen, t: Type) Allocator.Error!*llvm.Type {
2804 const gpa = dg.gpa;2810 const gpa = dg.gpa;
2805 const target = dg.module.getTarget();2811 const mod = dg.module;
2806 switch (t.zigTypeTag()) {2812 const target = mod.getTarget();
2813 switch (t.zigTypeTag(mod)) {
2807 .Void, .NoReturn => return dg.context.voidType(),2814 .Void, .NoReturn => return dg.context.voidType(),
2808 .Int => {2815 .Int => {
2809 const info = t.intInfo(target);2816 const info = t.intInfo(mod);
2810 assert(info.bits != 0);2817 assert(info.bits != 0);
2811 return dg.context.intType(info.bits);2818 return dg.context.intType(info.bits);
2812 },2819 },
2813 .Enum => {2820 .Enum => {
2814 var buffer: Type.Payload.Bits = undefined;2821 const int_ty = t.intTagType();
2815 const int_ty = t.intTagType(&buffer);2822 const bit_count = int_ty.intInfo(mod).bits;
2816 const bit_count = int_ty.intInfo(target).bits;
2817 assert(bit_count != 0);2823 assert(bit_count != 0);
2818 return dg.context.intType(bit_count);2824 return dg.context.intType(bit_count);
2819 },2825 },
...@@ -2863,7 +2869,7 @@ pub const DeclGen = struct {...@@ -2863,7 +2869,7 @@ pub const DeclGen = struct {
2863 },2869 },
2864 .Array => {2870 .Array => {
2865 const elem_ty = t.childType();2871 const elem_ty = t.childType();
2866 assert(elem_ty.onePossibleValue() == null);2872 assert(elem_ty.onePossibleValue(mod) == null);
2867 const elem_llvm_ty = try dg.lowerType(elem_ty);2873 const elem_llvm_ty = try dg.lowerType(elem_ty);
2868 const total_len = t.arrayLen() + @boolToInt(t.sentinel() != null);2874 const total_len = t.arrayLen() + @boolToInt(t.sentinel() != null);
2869 return elem_llvm_ty.arrayType(@intCast(c_uint, total_len));2875 return elem_llvm_ty.arrayType(@intCast(c_uint, total_len));
...@@ -2875,11 +2881,11 @@ pub const DeclGen = struct {...@@ -2875,11 +2881,11 @@ pub const DeclGen = struct {
2875 .Optional => {2881 .Optional => {
2876 var buf: Type.Payload.ElemType = undefined;2882 var buf: Type.Payload.ElemType = undefined;
2877 const child_ty = t.optionalChild(&buf);2883 const child_ty = t.optionalChild(&buf);
2878 if (!child_ty.hasRuntimeBitsIgnoreComptime()) {2884 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2879 return dg.context.intType(8);2885 return dg.context.intType(8);
2880 }2886 }
2881 const payload_llvm_ty = try dg.lowerType(child_ty);2887 const payload_llvm_ty = try dg.lowerType(child_ty);
2882 if (t.optionalReprIsPayload()) {2888 if (t.optionalReprIsPayload(mod)) {
2883 return payload_llvm_ty;2889 return payload_llvm_ty;
2884 }2890 }
28852891
...@@ -2887,8 +2893,8 @@ pub const DeclGen = struct {...@@ -2887,8 +2893,8 @@ pub const DeclGen = struct {
2887 var fields_buf: [3]*llvm.Type = .{2893 var fields_buf: [3]*llvm.Type = .{
2888 payload_llvm_ty, dg.context.intType(8), undefined,2894 payload_llvm_ty, dg.context.intType(8), undefined,
2889 };2895 };
2890 const offset = child_ty.abiSize(target) + 1;2896 const offset = child_ty.abiSize(mod) + 1;
2891 const abi_size = t.abiSize(target);2897 const abi_size = t.abiSize(mod);
2892 const padding = @intCast(c_uint, abi_size - offset);2898 const padding = @intCast(c_uint, abi_size - offset);
2893 if (padding == 0) {2899 if (padding == 0) {
2894 return dg.context.structType(&fields_buf, 2, .False);2900 return dg.context.structType(&fields_buf, 2, .False);
...@@ -2898,17 +2904,17 @@ pub const DeclGen = struct {...@@ -2898,17 +2904,17 @@ pub const DeclGen = struct {
2898 },2904 },
2899 .ErrorUnion => {2905 .ErrorUnion => {
2900 const payload_ty = t.errorUnionPayload();2906 const payload_ty = t.errorUnionPayload();
2901 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {2907 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2902 return try dg.lowerType(Type.anyerror);2908 return try dg.lowerType(Type.anyerror);
2903 }2909 }
2904 const llvm_error_type = try dg.lowerType(Type.anyerror);2910 const llvm_error_type = try dg.lowerType(Type.anyerror);
2905 const llvm_payload_type = try dg.lowerType(payload_ty);2911 const llvm_payload_type = try dg.lowerType(payload_ty);
29062912
2907 const payload_align = payload_ty.abiAlignment(target);2913 const payload_align = payload_ty.abiAlignment(mod);
2908 const error_align = Type.anyerror.abiAlignment(target);2914 const error_align = Type.anyerror.abiAlignment(mod);
29092915
2910 const payload_size = payload_ty.abiSize(target);2916 const payload_size = payload_ty.abiSize(mod);
2911 const error_size = Type.anyerror.abiSize(target);2917 const error_size = Type.anyerror.abiSize(mod);
29122918
2913 var fields_buf: [3]*llvm.Type = undefined;2919 var fields_buf: [3]*llvm.Type = undefined;
2914 if (error_align > payload_align) {2920 if (error_align > payload_align) {
...@@ -2964,9 +2970,9 @@ pub const DeclGen = struct {...@@ -2964,9 +2970,9 @@ pub const DeclGen = struct {
29642970
2965 for (tuple.types, 0..) |field_ty, i| {2971 for (tuple.types, 0..) |field_ty, i| {
2966 const field_val = tuple.values[i];2972 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);
2970 big_align = @max(big_align, field_align);2976 big_align = @max(big_align, field_align);
2971 const prev_offset = offset;2977 const prev_offset = offset;
2972 offset = std.mem.alignForwardGeneric(u64, offset, field_align);2978 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
...@@ -2979,7 +2985,7 @@ pub const DeclGen = struct {...@@ -2979,7 +2985,7 @@ pub const DeclGen = struct {
2979 const field_llvm_ty = try dg.lowerType(field_ty);2985 const field_llvm_ty = try dg.lowerType(field_ty);
2980 try llvm_field_types.append(gpa, field_llvm_ty);2986 try llvm_field_types.append(gpa, field_llvm_ty);
29812987
2982 offset += field_ty.abiSize(target);2988 offset += field_ty.abiSize(mod);
2983 }2989 }
2984 {2990 {
2985 const prev_offset = offset;2991 const prev_offset = offset;
...@@ -3027,11 +3033,11 @@ pub const DeclGen = struct {...@@ -3027,11 +3033,11 @@ pub const DeclGen = struct {
3027 var big_align: u32 = 1;3033 var big_align: u32 = 1;
3028 var any_underaligned_fields = false;3034 var any_underaligned_fields = false;
30293035
3030 var it = struct_obj.runtimeFieldIterator();3036 var it = struct_obj.runtimeFieldIterator(mod);
3031 while (it.next()) |field_and_index| {3037 while (it.next()) |field_and_index| {
3032 const field = field_and_index.field;3038 const field = field_and_index.field;
3033 const field_align = field.alignment(target, struct_obj.layout);3039 const field_align = field.alignment(mod, struct_obj.layout);
3034 const field_ty_align = field.ty.abiAlignment(target);3040 const field_ty_align = field.ty.abiAlignment(mod);
3035 any_underaligned_fields = any_underaligned_fields or3041 any_underaligned_fields = any_underaligned_fields or
3036 field_align < field_ty_align;3042 field_align < field_ty_align;
3037 big_align = @max(big_align, field_align);3043 big_align = @max(big_align, field_align);
...@@ -3046,7 +3052,7 @@ pub const DeclGen = struct {...@@ -3046,7 +3052,7 @@ pub const DeclGen = struct {
3046 const field_llvm_ty = try dg.lowerType(field.ty);3052 const field_llvm_ty = try dg.lowerType(field.ty);
3047 try llvm_field_types.append(gpa, field_llvm_ty);3053 try llvm_field_types.append(gpa, field_llvm_ty);
30483054
3049 offset += field.ty.abiSize(target);3055 offset += field.ty.abiSize(mod);
3050 }3056 }
3051 {3057 {
3052 const prev_offset = offset;3058 const prev_offset = offset;
...@@ -3074,11 +3080,11 @@ pub const DeclGen = struct {...@@ -3074,11 +3080,11 @@ pub const DeclGen = struct {
3074 // reference, we need to copy it here.3080 // reference, we need to copy it here.
3075 gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());3081 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);
3078 const union_obj = t.cast(Type.Payload.Union).?.data;3084 const union_obj = t.cast(Type.Payload.Union).?.data;
30793085
3080 if (union_obj.layout == .Packed) {3086 if (union_obj.layout == .Packed) {
3081 const bitsize = @intCast(c_uint, t.bitSize(target));3087 const bitsize = @intCast(c_uint, t.bitSize(mod));
3082 const int_llvm_ty = dg.context.intType(bitsize);3088 const int_llvm_ty = dg.context.intType(bitsize);
3083 gop.value_ptr.* = int_llvm_ty;3089 gop.value_ptr.* = int_llvm_ty;
3084 return int_llvm_ty;3090 return int_llvm_ty;
...@@ -3155,19 +3161,19 @@ pub const DeclGen = struct {...@@ -3155,19 +3161,19 @@ pub const DeclGen = struct {
3155 }3161 }
31563162
3157 fn lowerTypeFn(dg: *DeclGen, fn_ty: Type) Allocator.Error!*llvm.Type {3163 fn lowerTypeFn(dg: *DeclGen, fn_ty: Type) Allocator.Error!*llvm.Type {
3158 const target = dg.module.getTarget();3164 const mod = dg.module;
3159 const fn_info = fn_ty.fnInfo();3165 const fn_info = fn_ty.fnInfo();
3160 const llvm_ret_ty = try lowerFnRetTy(dg, fn_info);3166 const llvm_ret_ty = try lowerFnRetTy(dg, fn_info);
31613167
3162 var llvm_params = std.ArrayList(*llvm.Type).init(dg.gpa);3168 var llvm_params = std.ArrayList(*llvm.Type).init(dg.gpa);
3163 defer llvm_params.deinit();3169 defer llvm_params.deinit();
31643170
3165 if (firstParamSRet(fn_info, target)) {3171 if (firstParamSRet(fn_info, mod)) {
3166 try llvm_params.append(dg.context.pointerType(0));3172 try llvm_params.append(dg.context.pointerType(0));
3167 }3173 }
31683174
3169 if (fn_info.return_type.isError() and3175 if (fn_info.return_type.isError(mod) and
3170 dg.module.comp.bin_file.options.error_return_tracing)3176 mod.comp.bin_file.options.error_return_tracing)
3171 {3177 {
3172 var ptr_ty_payload: Type.Payload.ElemType = .{3178 var ptr_ty_payload: Type.Payload.ElemType = .{
3173 .base = .{ .tag = .single_mut_pointer },3179 .base = .{ .tag = .single_mut_pointer },
...@@ -3189,14 +3195,14 @@ pub const DeclGen = struct {...@@ -3189,14 +3195,14 @@ pub const DeclGen = struct {
3189 },3195 },
3190 .abi_sized_int => {3196 .abi_sized_int => {
3191 const param_ty = fn_info.param_types[it.zig_index - 1];3197 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));
3193 try llvm_params.append(dg.context.intType(abi_size * 8));3199 try llvm_params.append(dg.context.intType(abi_size * 8));
3194 },3200 },
3195 .slice => {3201 .slice => {
3196 const param_ty = fn_info.param_types[it.zig_index - 1];3202 const param_ty = fn_info.param_types[it.zig_index - 1];
3197 var buf: Type.SlicePtrFieldTypeBuffer = undefined;3203 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
3198 var opt_buf: Type.Payload.ElemType = undefined;3204 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)
3200 param_ty.optionalChild(&opt_buf).slicePtrFieldType(&buf)3206 param_ty.optionalChild(&opt_buf).slicePtrFieldType(&buf)
3201 else3207 else
3202 param_ty.slicePtrFieldType(&buf);3208 param_ty.slicePtrFieldType(&buf);
...@@ -3215,7 +3221,7 @@ pub const DeclGen = struct {...@@ -3215,7 +3221,7 @@ pub const DeclGen = struct {
3215 },3221 },
3216 .float_array => |count| {3222 .float_array => |count| {
3217 const param_ty = fn_info.param_types[it.zig_index - 1];3223 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).?);
3219 const field_count = @intCast(c_uint, count);3225 const field_count = @intCast(c_uint, count);
3220 const arr_ty = float_ty.arrayType(field_count);3226 const arr_ty = float_ty.arrayType(field_count);
3221 try llvm_params.append(arr_ty);3227 try llvm_params.append(arr_ty);
...@@ -3239,11 +3245,12 @@ pub const DeclGen = struct {...@@ -3239,11 +3245,12 @@ pub const DeclGen = struct {
3239 /// being a zero bit type, but it should still be lowered as an i8 in such case.3245 /// being a zero bit type, but it should still be lowered as an i8 in such case.
3240 /// There are other similar cases handled here as well.3246 /// There are other similar cases handled here as well.
3241 fn lowerPtrElemTy(dg: *DeclGen, elem_ty: Type) Allocator.Error!*llvm.Type {3247 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)) {
3243 .Opaque => true,3250 .Opaque => true,
3244 .Fn => !elem_ty.fnInfo().is_generic,3251 .Fn => !elem_ty.fnInfo().is_generic,
3245 .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(),3252 .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(mod),
3246 else => elem_ty.hasRuntimeBitsIgnoreComptime(),3253 else => elem_ty.hasRuntimeBitsIgnoreComptime(mod),
3247 };3254 };
3248 const llvm_elem_ty = if (lower_elem_ty)3255 const llvm_elem_ty = if (lower_elem_ty)
3249 try dg.lowerType(elem_ty)3256 try dg.lowerType(elem_ty)
...@@ -3262,9 +3269,9 @@ pub const DeclGen = struct {...@@ -3262,9 +3269,9 @@ pub const DeclGen = struct {
3262 const llvm_type = try dg.lowerType(tv.ty);3269 const llvm_type = try dg.lowerType(tv.ty);
3263 return llvm_type.getUndef();3270 return llvm_type.getUndef();
3264 }3271 }
3265 const target = dg.module.getTarget();3272 const mod = dg.module;
32663273 const target = mod.getTarget();
3267 switch (tv.ty.zigTypeTag()) {3274 switch (tv.ty.zigTypeTag(mod)) {
3268 .Bool => {3275 .Bool => {
3269 const llvm_type = try dg.lowerType(tv.ty);3276 const llvm_type = try dg.lowerType(tv.ty);
3270 return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull();3277 return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull();
...@@ -3276,8 +3283,8 @@ pub const DeclGen = struct {...@@ -3276,8 +3283,8 @@ pub const DeclGen = struct {
3276 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),3283 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),
3277 else => {3284 else => {
3278 var bigint_space: Value.BigIntSpace = undefined;3285 var bigint_space: Value.BigIntSpace = undefined;
3279 const bigint = tv.val.toBigInt(&bigint_space, target);3286 const bigint = tv.val.toBigInt(&bigint_space, mod);
3280 const int_info = tv.ty.intInfo(target);3287 const int_info = tv.ty.intInfo(mod);
3281 assert(int_info.bits != 0);3288 assert(int_info.bits != 0);
3282 const llvm_type = dg.context.intType(int_info.bits);3289 const llvm_type = dg.context.intType(int_info.bits);
32833290
...@@ -3304,9 +3311,9 @@ pub const DeclGen = struct {...@@ -3304,9 +3311,9 @@ pub const DeclGen = struct {
3304 const int_val = tv.enumToInt(&int_buffer);3311 const int_val = tv.enumToInt(&int_buffer);
33053312
3306 var bigint_space: Value.BigIntSpace = undefined;3313 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);
3310 const llvm_type = dg.context.intType(int_info.bits);3317 const llvm_type = dg.context.intType(int_info.bits);
33113318
3312 const unsigned_val = v: {3319 const unsigned_val = v: {
...@@ -3408,7 +3415,7 @@ pub const DeclGen = struct {...@@ -3408,7 +3415,7 @@ pub const DeclGen = struct {
3408 },3415 },
3409 .int_u64, .one, .int_big_positive, .lazy_align, .lazy_size => {3416 .int_u64, .one, .int_big_positive, .lazy_align, .lazy_size => {
3410 const llvm_usize = try dg.lowerType(Type.usize);3417 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);
3412 return llvm_int.constIntToPtr(try dg.lowerType(tv.ty));3419 return llvm_int.constIntToPtr(try dg.lowerType(tv.ty));
3413 },3420 },
3414 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {3421 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {
...@@ -3439,7 +3446,7 @@ pub const DeclGen = struct {...@@ -3439,7 +3446,7 @@ pub const DeclGen = struct {
3439 const str_lit = tv.val.castTag(.str_lit).?.data;3446 const str_lit = tv.val.castTag(.str_lit).?.data;
3440 const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len];3447 const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
3441 if (tv.ty.sentinel()) |sent_val| {3448 if (tv.ty.sentinel()) |sent_val| {
3442 const byte = @intCast(u8, sent_val.toUnsignedInt(target));3449 const byte = @intCast(u8, sent_val.toUnsignedInt(mod));
3443 if (byte == 0 and bytes.len > 0) {3450 if (byte == 0 and bytes.len > 0) {
3444 return dg.context.constString(3451 return dg.context.constString(
3445 bytes.ptr,3452 bytes.ptr,
...@@ -3549,13 +3556,13 @@ pub const DeclGen = struct {...@@ -3549,13 +3556,13 @@ pub const DeclGen = struct {
3549 const payload_ty = tv.ty.optionalChild(&buf);3556 const payload_ty = tv.ty.optionalChild(&buf);
35503557
3551 const llvm_i8 = dg.context.intType(8);3558 const llvm_i8 = dg.context.intType(8);
3552 const is_pl = !tv.val.isNull();3559 const is_pl = !tv.val.isNull(mod);
3553 const non_null_bit = if (is_pl) llvm_i8.constInt(1, .False) else llvm_i8.constNull();3560 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)) {
3555 return non_null_bit;3562 return non_null_bit;
3556 }3563 }
3557 const llvm_ty = try dg.lowerType(tv.ty);3564 const llvm_ty = try dg.lowerType(tv.ty);
3558 if (tv.ty.optionalReprIsPayload()) {3565 if (tv.ty.optionalReprIsPayload(mod)) {
3559 if (tv.val.castTag(.opt_payload)) |payload| {3566 if (tv.val.castTag(.opt_payload)) |payload| {
3560 return dg.lowerValue(.{ .ty = payload_ty, .val = payload.data });3567 return dg.lowerValue(.{ .ty = payload_ty, .val = payload.data });
3561 } else if (is_pl) {3568 } else if (is_pl) {
...@@ -3564,7 +3571,7 @@ pub const DeclGen = struct {...@@ -3564,7 +3571,7 @@ pub const DeclGen = struct {
3564 return llvm_ty.constNull();3571 return llvm_ty.constNull();
3565 }3572 }
3566 }3573 }
3567 assert(payload_ty.zigTypeTag() != .Fn);3574 assert(payload_ty.zigTypeTag(mod) != .Fn);
35683575
3569 const llvm_field_count = llvm_ty.countStructElementTypes();3576 const llvm_field_count = llvm_ty.countStructElementTypes();
3570 var fields_buf: [3]*llvm.Value = undefined;3577 var fields_buf: [3]*llvm.Value = undefined;
...@@ -3607,14 +3614,14 @@ pub const DeclGen = struct {...@@ -3607,14 +3614,14 @@ pub const DeclGen = struct {
3607 const payload_type = tv.ty.errorUnionPayload();3614 const payload_type = tv.ty.errorUnionPayload();
3608 const is_pl = tv.val.errorUnionIsPayload();3615 const is_pl = tv.val.errorUnionIsPayload();
36093616
3610 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {3617 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
3611 // We use the error type directly as the type.3618 // We use the error type directly as the type.
3612 const err_val = if (!is_pl) tv.val else Value.initTag(.zero);3619 const err_val = if (!is_pl) tv.val else Value.initTag(.zero);
3613 return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val });3620 return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val });
3614 }3621 }
36153622
3616 const payload_align = payload_type.abiAlignment(target);3623 const payload_align = payload_type.abiAlignment(mod);
3617 const error_align = Type.anyerror.abiAlignment(target);3624 const error_align = Type.anyerror.abiAlignment(mod);
3618 const llvm_error_value = try dg.lowerValue(.{3625 const llvm_error_value = try dg.lowerValue(.{
3619 .ty = Type.anyerror,3626 .ty = Type.anyerror,
3620 .val = if (is_pl) Value.initTag(.zero) else tv.val,3627 .val = if (is_pl) Value.initTag(.zero) else tv.val,
...@@ -3661,9 +3668,9 @@ pub const DeclGen = struct {...@@ -3661,9 +3668,9 @@ pub const DeclGen = struct {
36613668
3662 for (tuple.types, 0..) |field_ty, i| {3669 for (tuple.types, 0..) |field_ty, i| {
3663 if (tuple.values[i].tag() != .unreachable_value) continue;3670 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);
3667 big_align = @max(big_align, field_align);3674 big_align = @max(big_align, field_align);
3668 const prev_offset = offset;3675 const prev_offset = offset;
3669 offset = std.mem.alignForwardGeneric(u64, offset, field_align);3676 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
...@@ -3685,7 +3692,7 @@ pub const DeclGen = struct {...@@ -3685,7 +3692,7 @@ pub const DeclGen = struct {
36853692
3686 llvm_fields.appendAssumeCapacity(field_llvm_val);3693 llvm_fields.appendAssumeCapacity(field_llvm_val);
36873694
3688 offset += field_ty.abiSize(target);3695 offset += field_ty.abiSize(mod);
3689 }3696 }
3690 {3697 {
3691 const prev_offset = offset;3698 const prev_offset = offset;
...@@ -3715,7 +3722,7 @@ pub const DeclGen = struct {...@@ -3715,7 +3722,7 @@ pub const DeclGen = struct {
37153722
3716 if (struct_obj.layout == .Packed) {3723 if (struct_obj.layout == .Packed) {
3717 assert(struct_obj.haveLayout());3724 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);
3719 const int_llvm_ty = dg.context.intType(@intCast(c_uint, big_bits));3726 const int_llvm_ty = dg.context.intType(@intCast(c_uint, big_bits));
3720 const fields = struct_obj.fields.values();3727 const fields = struct_obj.fields.values();
3721 comptime assert(Type.packed_struct_layout_version == 2);3728 comptime assert(Type.packed_struct_layout_version == 2);
...@@ -3723,15 +3730,15 @@ pub const DeclGen = struct {...@@ -3723,15 +3730,15 @@ pub const DeclGen = struct {
3723 var running_bits: u16 = 0;3730 var running_bits: u16 = 0;
3724 for (field_vals, 0..) |field_val, i| {3731 for (field_vals, 0..) |field_val, i| {
3725 const field = fields[i];3732 const field = fields[i];
3726 if (!field.ty.hasRuntimeBitsIgnoreComptime()) continue;3733 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
37273734
3728 const non_int_val = try dg.lowerValue(.{3735 const non_int_val = try dg.lowerValue(.{
3729 .ty = field.ty,3736 .ty = field.ty,
3730 .val = field_val,3737 .val = field_val,
3731 });3738 });
3732 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));3739 const ty_bit_size = @intCast(u16, field.ty.bitSize(mod));
3733 const small_int_ty = dg.context.intType(ty_bit_size);3740 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))
3735 non_int_val.constPtrToInt(small_int_ty)3742 non_int_val.constPtrToInt(small_int_ty)
3736 else3743 else
3737 non_int_val.constBitCast(small_int_ty);3744 non_int_val.constBitCast(small_int_ty);
...@@ -3756,10 +3763,10 @@ pub const DeclGen = struct {...@@ -3756,10 +3763,10 @@ pub const DeclGen = struct {
3756 var big_align: u32 = 0;3763 var big_align: u32 = 0;
3757 var need_unnamed = false;3764 var need_unnamed = false;
37583765
3759 var it = struct_obj.runtimeFieldIterator();3766 var it = struct_obj.runtimeFieldIterator(mod);
3760 while (it.next()) |field_and_index| {3767 while (it.next()) |field_and_index| {
3761 const field = field_and_index.field;3768 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);
3763 big_align = @max(big_align, field_align);3770 big_align = @max(big_align, field_align);
3764 const prev_offset = offset;3771 const prev_offset = offset;
3765 offset = std.mem.alignForwardGeneric(u64, offset, field_align);3772 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
...@@ -3781,7 +3788,7 @@ pub const DeclGen = struct {...@@ -3781,7 +3788,7 @@ pub const DeclGen = struct {
37813788
3782 llvm_fields.appendAssumeCapacity(field_llvm_val);3789 llvm_fields.appendAssumeCapacity(field_llvm_val);
37833790
3784 offset += field.ty.abiSize(target);3791 offset += field.ty.abiSize(mod);
3785 }3792 }
3786 {3793 {
3787 const prev_offset = offset;3794 const prev_offset = offset;
...@@ -3810,7 +3817,7 @@ pub const DeclGen = struct {...@@ -3810,7 +3817,7 @@ pub const DeclGen = struct {
3810 const llvm_union_ty = try dg.lowerType(tv.ty);3817 const llvm_union_ty = try dg.lowerType(tv.ty);
3811 const tag_and_val = tv.val.castTag(.@"union").?.data;3818 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
3815 if (layout.payload_size == 0) {3822 if (layout.payload_size == 0) {
3816 return lowerValue(dg, .{3823 return lowerValue(dg, .{
...@@ -3824,12 +3831,12 @@ pub const DeclGen = struct {...@@ -3824,12 +3831,12 @@ pub const DeclGen = struct {
38243831
3825 const field_ty = union_obj.fields.values()[field_index].ty;3832 const field_ty = union_obj.fields.values()[field_index].ty;
3826 if (union_obj.layout == .Packed) {3833 if (union_obj.layout == .Packed) {
3827 if (!field_ty.hasRuntimeBits())3834 if (!field_ty.hasRuntimeBits(mod))
3828 return llvm_union_ty.constNull();3835 return llvm_union_ty.constNull();
3829 const non_int_val = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });3836 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));
3831 const small_int_ty = dg.context.intType(ty_bit_size);3838 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))
3833 non_int_val.constPtrToInt(small_int_ty)3840 non_int_val.constPtrToInt(small_int_ty)
3834 else3841 else
3835 non_int_val.constBitCast(small_int_ty);3842 non_int_val.constBitCast(small_int_ty);
...@@ -3842,13 +3849,13 @@ pub const DeclGen = struct {...@@ -3842,13 +3849,13 @@ pub const DeclGen = struct {
3842 // must pointer cast to the expected type before accessing the union.3849 // must pointer cast to the expected type before accessing the union.
3843 var need_unnamed: bool = layout.most_aligned_field != field_index;3850 var need_unnamed: bool = layout.most_aligned_field != field_index;
3844 const payload = p: {3851 const payload = p: {
3845 if (!field_ty.hasRuntimeBitsIgnoreComptime()) {3852 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3846 const padding_len = @intCast(c_uint, layout.payload_size);3853 const padding_len = @intCast(c_uint, layout.payload_size);
3847 break :p dg.context.intType(8).arrayType(padding_len).getUndef();3854 break :p dg.context.intType(8).arrayType(padding_len).getUndef();
3848 }3855 }
3849 const field = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });3856 const field = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });
3850 need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field);3857 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);
3852 if (field_size == layout.payload_size) {3859 if (field_size == layout.payload_size) {
3853 break :p field;3860 break :p field;
3854 }3861 }
...@@ -4012,7 +4019,8 @@ pub const DeclGen = struct {...@@ -4012,7 +4019,8 @@ pub const DeclGen = struct {
4012 }4019 }
40134020
4014 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {4021 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();
4016 switch (ptr_val.tag()) {4024 switch (ptr_val.tag()) {
4017 .decl_ref_mut => {4025 .decl_ref_mut => {
4018 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;4026 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;
...@@ -4045,13 +4053,13 @@ pub const DeclGen = struct {...@@ -4045,13 +4053,13 @@ pub const DeclGen = struct {
40454053
4046 const field_index = @intCast(u32, field_ptr.field_index);4054 const field_index = @intCast(u32, field_ptr.field_index);
4047 const llvm_u32 = dg.context.intType(32);4055 const llvm_u32 = dg.context.intType(32);
4048 switch (parent_ty.zigTypeTag()) {4056 switch (parent_ty.zigTypeTag(mod)) {
4049 .Union => {4057 .Union => {
4050 if (parent_ty.containerLayout() == .Packed) {4058 if (parent_ty.containerLayout() == .Packed) {
4051 return parent_llvm_ptr;4059 return parent_llvm_ptr;
4052 }4060 }
40534061
4054 const layout = parent_ty.unionGetLayout(target);4062 const layout = parent_ty.unionGetLayout(mod);
4055 if (layout.payload_size == 0) {4063 if (layout.payload_size == 0) {
4056 // In this case a pointer to the union and a pointer to any4064 // In this case a pointer to the union and a pointer to any
4057 // (void) payload is the same.4065 // (void) payload is the same.
...@@ -4077,8 +4085,8 @@ pub const DeclGen = struct {...@@ -4077,8 +4085,8 @@ pub const DeclGen = struct {
4077 const prev_bits = b: {4085 const prev_bits = b: {
4078 var b: usize = 0;4086 var b: usize = 0;
4079 for (parent_ty.structFields().values()[0..field_index]) |field| {4087 for (parent_ty.structFields().values()[0..field_index]) |field| {
4080 if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime()) continue;4088 if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
4081 b += @intCast(usize, field.ty.bitSize(target));4089 b += @intCast(usize, field.ty.bitSize(mod));
4082 }4090 }
4083 break :b b;4091 break :b b;
4084 };4092 };
...@@ -4091,14 +4099,14 @@ pub const DeclGen = struct {...@@ -4091,14 +4099,14 @@ pub const DeclGen = struct {
4091 var ty_buf: Type.Payload.Pointer = undefined;4099 var ty_buf: Type.Payload.Pointer = undefined;
40924100
4093 const parent_llvm_ty = try dg.lowerType(parent_ty);4101 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| {
4095 const indices: [2]*llvm.Value = .{4103 const indices: [2]*llvm.Value = .{
4096 llvm_u32.constInt(0, .False),4104 llvm_u32.constInt(0, .False),
4097 llvm_u32.constInt(llvm_field_index, .False),4105 llvm_u32.constInt(llvm_field_index, .False),
4098 };4106 };
4099 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4107 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4100 } else {4108 } 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);
4102 const indices: [1]*llvm.Value = .{llvm_index};4110 const indices: [1]*llvm.Value = .{llvm_index};
4103 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4111 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4104 }4112 }
...@@ -4132,8 +4140,8 @@ pub const DeclGen = struct {...@@ -4132,8 +4140,8 @@ pub const DeclGen = struct {
4132 var buf: Type.Payload.ElemType = undefined;4140 var buf: Type.Payload.ElemType = undefined;
41334141
4134 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);4142 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);
4135 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or4143 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or
4136 payload_ty.optionalReprIsPayload())4144 payload_ty.optionalReprIsPayload(mod))
4137 {4145 {
4138 // In this case, we represent pointer to optional the same as pointer4146 // In this case, we represent pointer to optional the same as pointer
4139 // to the payload.4147 // to the payload.
...@@ -4153,13 +4161,13 @@ pub const DeclGen = struct {...@@ -4153,13 +4161,13 @@ pub const DeclGen = struct {
4153 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, true);4161 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, true);
41544162
4155 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();4163 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();
4156 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {4164 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4157 // In this case, we represent pointer to error union the same as pointer4165 // In this case, we represent pointer to error union the same as pointer
4158 // to the payload.4166 // to the payload.
4159 return parent_llvm_ptr;4167 return parent_llvm_ptr;
4160 }4168 }
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;
4163 const llvm_u32 = dg.context.intType(32);4171 const llvm_u32 = dg.context.intType(32);
4164 const indices: [2]*llvm.Value = .{4172 const indices: [2]*llvm.Value = .{
4165 llvm_u32.constInt(0, .False),4173 llvm_u32.constInt(0, .False),
...@@ -4177,12 +4185,13 @@ pub const DeclGen = struct {...@@ -4177,12 +4185,13 @@ pub const DeclGen = struct {
4177 tv: TypedValue,4185 tv: TypedValue,
4178 decl_index: Module.Decl.Index,4186 decl_index: Module.Decl.Index,
4179 ) Error!*llvm.Value {4187 ) Error!*llvm.Value {
4188 const mod = self.module;
4180 if (tv.ty.isSlice()) {4189 if (tv.ty.isSlice()) {
4181 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4190 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4182 const ptr_ty = tv.ty.slicePtrFieldType(&buf);4191 const ptr_ty = tv.ty.slicePtrFieldType(&buf);
4183 var slice_len: Value.Payload.U64 = .{4192 var slice_len: Value.Payload.U64 = .{
4184 .base = .{ .tag = .int_u64 },4193 .base = .{ .tag = .int_u64 },
4185 .data = tv.val.sliceLen(self.module),4194 .data = tv.val.sliceLen(mod),
4186 };4195 };
4187 const fields: [2]*llvm.Value = .{4196 const fields: [2]*llvm.Value = .{
4188 try self.lowerValue(.{4197 try self.lowerValue(.{
...@@ -4202,7 +4211,7 @@ pub const DeclGen = struct {...@@ -4202,7 +4211,7 @@ pub const DeclGen = struct {
4202 // const bar = foo;4211 // const bar = foo;
4203 // ... &bar;4212 // ... &bar;
4204 // `bar` is just an alias and we actually want to lower a reference to `foo`.4213 // `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);
4206 if (decl.val.castTag(.function)) |func| {4215 if (decl.val.castTag(.function)) |func| {
4207 if (func.data.owner_decl != decl_index) {4216 if (func.data.owner_decl != decl_index) {
4208 return self.lowerDeclRefValue(tv, func.data.owner_decl);4217 return self.lowerDeclRefValue(tv, func.data.owner_decl);
...@@ -4213,21 +4222,21 @@ pub const DeclGen = struct {...@@ -4213,21 +4222,21 @@ pub const DeclGen = struct {
4213 }4222 }
4214 }4223 }
42154224
4216 const is_fn_body = decl.ty.zigTypeTag() == .Fn;4225 const is_fn_body = decl.ty.zigTypeTag(mod) == .Fn;
4217 if ((!is_fn_body and !decl.ty.hasRuntimeBits()) or4226 if ((!is_fn_body and !decl.ty.hasRuntimeBits(mod)) or
4218 (is_fn_body and decl.ty.fnInfo().is_generic))4227 (is_fn_body and decl.ty.fnInfo().is_generic))
4219 {4228 {
4220 return self.lowerPtrToVoid(tv.ty);4229 return self.lowerPtrToVoid(tv.ty);
4221 }4230 }
42224231
4223 self.module.markDeclAlive(decl);4232 mod.markDeclAlive(decl);
42244233
4225 const llvm_decl_val = if (is_fn_body)4234 const llvm_decl_val = if (is_fn_body)
4226 try self.resolveLlvmFunction(decl_index)4235 try self.resolveLlvmFunction(decl_index)
4227 else4236 else
4228 try self.resolveGlobalDecl(decl_index);4237 try self.resolveGlobalDecl(decl_index);
42294238
4230 const target = self.module.getTarget();4239 const target = mod.getTarget();
4231 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);4240 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
4232 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);4241 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
4233 const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: {4242 const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: {
...@@ -4236,7 +4245,7 @@ pub const DeclGen = struct {...@@ -4236,7 +4245,7 @@ pub const DeclGen = struct {
4236 } else llvm_decl_val;4245 } else llvm_decl_val;
42374246
4238 const llvm_type = try self.lowerType(tv.ty);4247 const llvm_type = try self.lowerType(tv.ty);
4239 if (tv.ty.zigTypeTag() == .Int) {4248 if (tv.ty.zigTypeTag(mod) == .Int) {
4240 return llvm_val.constPtrToInt(llvm_type);4249 return llvm_val.constPtrToInt(llvm_type);
4241 } else {4250 } else {
4242 return llvm_val.constBitCast(llvm_type);4251 return llvm_val.constBitCast(llvm_type);
...@@ -4338,21 +4347,20 @@ pub const DeclGen = struct {...@@ -4338,21 +4347,20 @@ pub const DeclGen = struct {
4338 /// RMW exchange of floating-point values is bitcasted to same-sized integer4347 /// RMW exchange of floating-point values is bitcasted to same-sized integer
4339 /// types to work around a LLVM deficiency when targeting ARM/AArch64.4348 /// types to work around a LLVM deficiency when targeting ARM/AArch64.
4340 fn getAtomicAbiType(dg: *DeclGen, ty: Type, is_rmw_xchg: bool) ?*llvm.Type {4349 fn getAtomicAbiType(dg: *DeclGen, ty: Type, is_rmw_xchg: bool) ?*llvm.Type {
4341 const target = dg.module.getTarget();4350 const mod = dg.module;
4342 var buffer: Type.Payload.Bits = undefined;4351 const int_ty = switch (ty.zigTypeTag(mod)) {
4343 const int_ty = switch (ty.zigTypeTag()) {
4344 .Int => ty,4352 .Int => ty,
4345 .Enum => ty.intTagType(&buffer),4353 .Enum => ty.intTagType(),
4346 .Float => {4354 .Float => {
4347 if (!is_rmw_xchg) return null;4355 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));
4349 },4357 },
4350 .Bool => return dg.context.intType(8),4358 .Bool => return dg.context.intType(8),
4351 else => return null,4359 else => return null,
4352 };4360 };
4353 const bit_count = int_ty.intInfo(target).bits;4361 const bit_count = int_ty.intInfo(mod).bits;
4354 if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) {4362 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));
4356 } else {4364 } else {
4357 return null;4365 return null;
4358 }4366 }
...@@ -4366,15 +4374,15 @@ pub const DeclGen = struct {...@@ -4366,15 +4374,15 @@ pub const DeclGen = struct {
4366 fn_info: Type.Payload.Function.Data,4374 fn_info: Type.Payload.Function.Data,
4367 llvm_arg_i: u32,4375 llvm_arg_i: u32,
4368 ) void {4376 ) void {
4369 const target = dg.module.getTarget();4377 const mod = dg.module;
4370 if (param_ty.isPtrAtRuntime()) {4378 if (param_ty.isPtrAtRuntime(mod)) {
4371 const ptr_info = param_ty.ptrInfo().data;4379 const ptr_info = param_ty.ptrInfo().data;
4372 if (math.cast(u5, param_index)) |i| {4380 if (math.cast(u5, param_index)) |i| {
4373 if (@truncate(u1, fn_info.noalias_bits >> i) != 0) {4381 if (@truncate(u1, fn_info.noalias_bits >> i) != 0) {
4374 dg.addArgAttr(llvm_fn, llvm_arg_i, "noalias");4382 dg.addArgAttr(llvm_fn, llvm_arg_i, "noalias");
4375 }4383 }
4376 }4384 }
4377 if (!param_ty.isPtrLikeOptional() and !ptr_info.@"allowzero") {4385 if (!param_ty.isPtrLikeOptional(mod) and !ptr_info.@"allowzero") {
4378 dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");4386 dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
4379 }4387 }
4380 if (!ptr_info.mutable) {4388 if (!ptr_info.mutable) {
...@@ -4383,13 +4391,10 @@ pub const DeclGen = struct {...@@ -4383,13 +4391,10 @@ pub const DeclGen = struct {
4383 if (ptr_info.@"align" != 0) {4391 if (ptr_info.@"align" != 0) {
4384 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", ptr_info.@"align");4392 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", ptr_info.@"align");
4385 } else {4393 } else {
4386 const elem_align = @max(4394 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
4387 ptr_info.pointee_type.abiAlignment(target),
4388 1,
4389 );
4390 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align);4395 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align);
4391 }4396 }
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) {
4393 .signed => dg.addArgAttr(llvm_fn, llvm_arg_i, "signext"),4398 .signed => dg.addArgAttr(llvm_fn, llvm_arg_i, "signext"),
4394 .unsigned => dg.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),4399 .unsigned => dg.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),
4395 };4400 };
...@@ -4490,9 +4495,10 @@ pub const FuncGen = struct {...@@ -4490,9 +4495,10 @@ pub const FuncGen = struct {
4490 const gop = try self.func_inst_table.getOrPut(self.dg.gpa, inst);4495 const gop = try self.func_inst_table.getOrPut(self.dg.gpa, inst);
4491 if (gop.found_existing) return gop.value_ptr.*;4496 if (gop.found_existing) return gop.value_ptr.*;
44924497
4498 const mod = self.dg.module;
4493 const llvm_val = try self.resolveValue(.{4499 const llvm_val = try self.resolveValue(.{
4494 .ty = self.air.typeOf(inst),4500 .ty = self.air.typeOf(inst),
4495 .val = self.air.value(inst).?,4501 .val = self.air.value(inst, mod).?,
4496 });4502 });
4497 gop.value_ptr.* = llvm_val;4503 gop.value_ptr.* = llvm_val;
4498 return llvm_val;4504 return llvm_val;
...@@ -4500,11 +4506,12 @@ pub const FuncGen = struct {...@@ -4500,11 +4506,12 @@ pub const FuncGen = struct {
45004506
4501 fn resolveValue(self: *FuncGen, tv: TypedValue) !*llvm.Value {4507 fn resolveValue(self: *FuncGen, tv: TypedValue) !*llvm.Value {
4502 const llvm_val = try self.dg.lowerValue(tv);4508 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
4505 // We have an LLVM value but we need to create a global constant and4512 // We have an LLVM value but we need to create a global constant and
4506 // set the value as its initializer, and then return a pointer to the global.4513 // 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();
4508 const llvm_wanted_addrspace = toLlvmAddressSpace(.generic, target);4515 const llvm_wanted_addrspace = toLlvmAddressSpace(.generic, target);
4509 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(.generic, target);4516 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(.generic, target);
4510 const global = self.dg.object.llvm_module.addGlobalInAddressSpace(llvm_val.typeOf(), "", llvm_actual_addrspace);4517 const global = self.dg.object.llvm_module.addGlobalInAddressSpace(llvm_val.typeOf(), "", llvm_actual_addrspace);
...@@ -4512,7 +4519,7 @@ pub const FuncGen = struct {...@@ -4512,7 +4519,7 @@ pub const FuncGen = struct {
4512 global.setLinkage(.Private);4519 global.setLinkage(.Private);
4513 global.setGlobalConstant(.True);4520 global.setGlobalConstant(.True);
4514 global.setUnnamedAddr(.True);4521 global.setUnnamedAddr(.True);
4515 global.setAlignment(tv.ty.abiAlignment(target));4522 global.setAlignment(tv.ty.abiAlignment(mod));
4516 const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace)4523 const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace)
4517 global.constAddrSpaceCast(self.context.pointerType(llvm_wanted_addrspace))4524 global.constAddrSpaceCast(self.context.pointerType(llvm_wanted_addrspace))
4518 else4525 else
...@@ -4775,7 +4782,8 @@ pub const FuncGen = struct {...@@ -4775,7 +4782,8 @@ pub const FuncGen = struct {
4775 const extra = self.air.extraData(Air.Call, pl_op.payload);4782 const extra = self.air.extraData(Air.Call, pl_op.payload);
4776 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);4783 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
4777 const callee_ty = self.air.typeOf(pl_op.operand);4784 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)) {
4779 .Fn => callee_ty,4787 .Fn => callee_ty,
4780 .Pointer => callee_ty.childType(),4788 .Pointer => callee_ty.childType(),
4781 else => unreachable,4789 else => unreachable,
...@@ -4783,20 +4791,20 @@ pub const FuncGen = struct {...@@ -4783,20 +4791,20 @@ pub const FuncGen = struct {
4783 const fn_info = zig_fn_ty.fnInfo();4791 const fn_info = zig_fn_ty.fnInfo();
4784 const return_type = fn_info.return_type;4792 const return_type = fn_info.return_type;
4785 const llvm_fn = try self.resolveInst(pl_op.operand);4793 const llvm_fn = try self.resolveInst(pl_op.operand);
4786 const target = self.dg.module.getTarget();4794 const target = mod.getTarget();
4787 const sret = firstParamSRet(fn_info, target);4795 const sret = firstParamSRet(fn_info, mod);
47884796
4789 var llvm_args = std.ArrayList(*llvm.Value).init(self.gpa);4797 var llvm_args = std.ArrayList(*llvm.Value).init(self.gpa);
4790 defer llvm_args.deinit();4798 defer llvm_args.deinit();
47914799
4792 const ret_ptr = if (!sret) null else blk: {4800 const ret_ptr = if (!sret) null else blk: {
4793 const llvm_ret_ty = try self.dg.lowerType(return_type);4801 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));
4795 try llvm_args.append(ret_ptr);4803 try llvm_args.append(ret_ptr);
4796 break :blk ret_ptr;4804 break :blk ret_ptr;
4797 };4805 };
47984806
4799 const err_return_tracing = fn_info.return_type.isError() and4807 const err_return_tracing = fn_info.return_type.isError(mod) and
4800 self.dg.module.comp.bin_file.options.error_return_tracing;4808 self.dg.module.comp.bin_file.options.error_return_tracing;
4801 if (err_return_tracing) {4809 if (err_return_tracing) {
4802 try llvm_args.append(self.err_ret_trace.?);4810 try llvm_args.append(self.err_ret_trace.?);
...@@ -4810,8 +4818,8 @@ pub const FuncGen = struct {...@@ -4810,8 +4818,8 @@ pub const FuncGen = struct {
4810 const param_ty = self.air.typeOf(arg);4818 const param_ty = self.air.typeOf(arg);
4811 const llvm_arg = try self.resolveInst(arg);4819 const llvm_arg = try self.resolveInst(arg);
4812 const llvm_param_ty = try self.dg.lowerType(param_ty);4820 const llvm_param_ty = try self.dg.lowerType(param_ty);
4813 if (isByRef(param_ty)) {4821 if (isByRef(param_ty, mod)) {
4814 const alignment = param_ty.abiAlignment(target);4822 const alignment = param_ty.abiAlignment(mod);
4815 const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, "");4823 const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, "");
4816 load_inst.setAlignment(alignment);4824 load_inst.setAlignment(alignment);
4817 try llvm_args.append(load_inst);4825 try llvm_args.append(load_inst);
...@@ -4823,10 +4831,10 @@ pub const FuncGen = struct {...@@ -4823,10 +4831,10 @@ pub const FuncGen = struct {
4823 const arg = args[it.zig_index - 1];4831 const arg = args[it.zig_index - 1];
4824 const param_ty = self.air.typeOf(arg);4832 const param_ty = self.air.typeOf(arg);
4825 const llvm_arg = try self.resolveInst(arg);4833 const llvm_arg = try self.resolveInst(arg);
4826 if (isByRef(param_ty)) {4834 if (isByRef(param_ty, mod)) {
4827 try llvm_args.append(llvm_arg);4835 try llvm_args.append(llvm_arg);
4828 } else {4836 } else {
4829 const alignment = param_ty.abiAlignment(target);4837 const alignment = param_ty.abiAlignment(mod);
4830 const param_llvm_ty = llvm_arg.typeOf();4838 const param_llvm_ty = llvm_arg.typeOf();
4831 const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);4839 const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);
4832 const store_inst = self.builder.buildStore(llvm_arg, arg_ptr);4840 const store_inst = self.builder.buildStore(llvm_arg, arg_ptr);
...@@ -4839,10 +4847,10 @@ pub const FuncGen = struct {...@@ -4839,10 +4847,10 @@ pub const FuncGen = struct {
4839 const param_ty = self.air.typeOf(arg);4847 const param_ty = self.air.typeOf(arg);
4840 const llvm_arg = try self.resolveInst(arg);4848 const llvm_arg = try self.resolveInst(arg);
48414849
4842 const alignment = param_ty.abiAlignment(target);4850 const alignment = param_ty.abiAlignment(mod);
4843 const param_llvm_ty = try self.dg.lowerType(param_ty);4851 const param_llvm_ty = try self.dg.lowerType(param_ty);
4844 const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);4852 const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);
4845 if (isByRef(param_ty)) {4853 if (isByRef(param_ty, mod)) {
4846 const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, "");4854 const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, "");
4847 load_inst.setAlignment(alignment);4855 load_inst.setAlignment(alignment);
48484856
...@@ -4859,11 +4867,11 @@ pub const FuncGen = struct {...@@ -4859,11 +4867,11 @@ pub const FuncGen = struct {
4859 const arg = args[it.zig_index - 1];4867 const arg = args[it.zig_index - 1];
4860 const param_ty = self.air.typeOf(arg);4868 const param_ty = self.air.typeOf(arg);
4861 const llvm_arg = try self.resolveInst(arg);4869 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));
4863 const int_llvm_ty = self.context.intType(abi_size * 8);4871 const int_llvm_ty = self.context.intType(abi_size * 8);
48644872
4865 if (isByRef(param_ty)) {4873 if (isByRef(param_ty, mod)) {
4866 const alignment = param_ty.abiAlignment(target);4874 const alignment = param_ty.abiAlignment(mod);
4867 const load_inst = self.builder.buildLoad(int_llvm_ty, llvm_arg, "");4875 const load_inst = self.builder.buildLoad(int_llvm_ty, llvm_arg, "");
4868 load_inst.setAlignment(alignment);4876 load_inst.setAlignment(alignment);
4869 try llvm_args.append(load_inst);4877 try llvm_args.append(load_inst);
...@@ -4871,7 +4879,7 @@ pub const FuncGen = struct {...@@ -4871,7 +4879,7 @@ pub const FuncGen = struct {
4871 // LLVM does not allow bitcasting structs so we must allocate4879 // LLVM does not allow bitcasting structs so we must allocate
4872 // a local, store as one type, and then load as another type.4880 // a local, store as one type, and then load as another type.
4873 const alignment = @max(4881 const alignment = @max(
4874 param_ty.abiAlignment(target),4882 param_ty.abiAlignment(mod),
4875 self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty),4883 self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty),
4876 );4884 );
4877 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);4885 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);
...@@ -4896,11 +4904,11 @@ pub const FuncGen = struct {...@@ -4896,11 +4904,11 @@ pub const FuncGen = struct {
4896 const param_ty = self.air.typeOf(arg);4904 const param_ty = self.air.typeOf(arg);
4897 const llvm_types = it.llvm_types_buffer[0..it.llvm_types_len];4905 const llvm_types = it.llvm_types_buffer[0..it.llvm_types_len];
4898 const llvm_arg = try self.resolveInst(arg);4906 const llvm_arg = try self.resolveInst(arg);
4899 const is_by_ref = isByRef(param_ty);4907 const is_by_ref = isByRef(param_ty, mod);
4900 const arg_ptr = if (is_by_ref) llvm_arg else p: {4908 const arg_ptr = if (is_by_ref) llvm_arg else p: {
4901 const p = self.buildAlloca(llvm_arg.typeOf(), null);4909 const p = self.buildAlloca(llvm_arg.typeOf(), null);
4902 const store_inst = self.builder.buildStore(llvm_arg, p);4910 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));
4904 break :p p;4912 break :p p;
4905 };4913 };
49064914
...@@ -4924,17 +4932,17 @@ pub const FuncGen = struct {...@@ -4924,17 +4932,17 @@ pub const FuncGen = struct {
4924 const arg = args[it.zig_index - 1];4932 const arg = args[it.zig_index - 1];
4925 const arg_ty = self.air.typeOf(arg);4933 const arg_ty = self.air.typeOf(arg);
4926 var llvm_arg = try self.resolveInst(arg);4934 var llvm_arg = try self.resolveInst(arg);
4927 if (!isByRef(arg_ty)) {4935 if (!isByRef(arg_ty, mod)) {
4928 const p = self.buildAlloca(llvm_arg.typeOf(), null);4936 const p = self.buildAlloca(llvm_arg.typeOf(), null);
4929 const store_inst = self.builder.buildStore(llvm_arg, p);4937 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));
4931 llvm_arg = store_inst;4939 llvm_arg = store_inst;
4932 }4940 }
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).?);
4935 const array_llvm_ty = float_ty.arrayType(count);4943 const array_llvm_ty = float_ty.arrayType(count);
49364944
4937 const alignment = arg_ty.abiAlignment(target);4945 const alignment = arg_ty.abiAlignment(mod);
4938 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");4946 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");
4939 load_inst.setAlignment(alignment);4947 load_inst.setAlignment(alignment);
4940 try llvm_args.append(load_inst);4948 try llvm_args.append(load_inst);
...@@ -4944,15 +4952,15 @@ pub const FuncGen = struct {...@@ -4944,15 +4952,15 @@ pub const FuncGen = struct {
4944 const arg = args[it.zig_index - 1];4952 const arg = args[it.zig_index - 1];
4945 const arg_ty = self.air.typeOf(arg);4953 const arg_ty = self.air.typeOf(arg);
4946 var llvm_arg = try self.resolveInst(arg);4954 var llvm_arg = try self.resolveInst(arg);
4947 if (!isByRef(arg_ty)) {4955 if (!isByRef(arg_ty, mod)) {
4948 const p = self.buildAlloca(llvm_arg.typeOf(), null);4956 const p = self.buildAlloca(llvm_arg.typeOf(), null);
4949 const store_inst = self.builder.buildStore(llvm_arg, p);4957 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));
4951 llvm_arg = store_inst;4959 llvm_arg = store_inst;
4952 }4960 }
49534961
4954 const array_llvm_ty = self.context.intType(elem_size).arrayType(arr_len);4962 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);
4956 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");4964 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");
4957 load_inst.setAlignment(alignment);4965 load_inst.setAlignment(alignment);
4958 try llvm_args.append(load_inst);4966 try llvm_args.append(load_inst);
...@@ -4969,7 +4977,7 @@ pub const FuncGen = struct {...@@ -4969,7 +4977,7 @@ pub const FuncGen = struct {
4969 "",4977 "",
4970 );4978 );
49714979
4972 if (callee_ty.zigTypeTag() == .Pointer) {4980 if (callee_ty.zigTypeTag(mod) == .Pointer) {
4973 // Add argument attributes for function pointer calls.4981 // Add argument attributes for function pointer calls.
4974 it = iterateParamTypes(self.dg, fn_info);4982 it = iterateParamTypes(self.dg, fn_info);
4975 it.llvm_index += @boolToInt(sret);4983 it.llvm_index += @boolToInt(sret);
...@@ -4978,7 +4986,7 @@ pub const FuncGen = struct {...@@ -4978,7 +4986,7 @@ pub const FuncGen = struct {
4978 .byval => {4986 .byval => {
4979 const param_index = it.zig_index - 1;4987 const param_index = it.zig_index - 1;
4980 const param_ty = fn_info.param_types[param_index];4988 const param_ty = fn_info.param_types[param_index];
4981 if (!isByRef(param_ty)) {4989 if (!isByRef(param_ty, mod)) {
4982 self.dg.addByValParamAttrs(call, param_ty, param_index, fn_info, it.llvm_index - 1);4990 self.dg.addByValParamAttrs(call, param_ty, param_index, fn_info, it.llvm_index - 1);
4983 }4991 }
4984 },4992 },
...@@ -4986,7 +4994,7 @@ pub const FuncGen = struct {...@@ -4986,7 +4994,7 @@ pub const FuncGen = struct {
4986 const param_index = it.zig_index - 1;4994 const param_index = it.zig_index - 1;
4987 const param_ty = fn_info.param_types[param_index];4995 const param_ty = fn_info.param_types[param_index];
4988 const param_llvm_ty = try self.dg.lowerType(param_ty);4996 const param_llvm_ty = try self.dg.lowerType(param_ty);
4989 const alignment = param_ty.abiAlignment(target);4997 const alignment = param_ty.abiAlignment(mod);
4990 self.dg.addByRefParamAttrs(call, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);4998 self.dg.addByRefParamAttrs(call, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
4991 },4999 },
4992 .byref_mut => {5000 .byref_mut => {
...@@ -5013,7 +5021,7 @@ pub const FuncGen = struct {...@@ -5013,7 +5021,7 @@ pub const FuncGen = struct {
5013 self.dg.addArgAttr(call, llvm_arg_i, "noalias");5021 self.dg.addArgAttr(call, llvm_arg_i, "noalias");
5014 }5022 }
5015 }5023 }
5016 if (param_ty.zigTypeTag() != .Optional) {5024 if (param_ty.zigTypeTag(mod) != .Optional) {
5017 self.dg.addArgAttr(call, llvm_arg_i, "nonnull");5025 self.dg.addArgAttr(call, llvm_arg_i, "nonnull");
5018 }5026 }
5019 if (!ptr_info.mutable) {5027 if (!ptr_info.mutable) {
...@@ -5022,7 +5030,7 @@ pub const FuncGen = struct {...@@ -5022,7 +5030,7 @@ pub const FuncGen = struct {
5022 if (ptr_info.@"align" != 0) {5030 if (ptr_info.@"align" != 0) {
5023 self.dg.addArgAttrInt(call, llvm_arg_i, "align", ptr_info.@"align");5031 self.dg.addArgAttrInt(call, llvm_arg_i, "align", ptr_info.@"align");
5024 } else {5032 } 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);
5026 self.dg.addArgAttrInt(call, llvm_arg_i, "align", elem_align);5034 self.dg.addArgAttrInt(call, llvm_arg_i, "align", elem_align);
5027 }5035 }
5028 },5036 },
...@@ -5033,7 +5041,7 @@ pub const FuncGen = struct {...@@ -5033,7 +5041,7 @@ pub const FuncGen = struct {
5033 return null;5041 return null;
5034 }5042 }
50355043
5036 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime()) {5044 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(mod)) {
5037 return null;5045 return null;
5038 }5046 }
50395047
...@@ -5041,12 +5049,12 @@ pub const FuncGen = struct {...@@ -5041,12 +5049,12 @@ pub const FuncGen = struct {
50415049
5042 if (ret_ptr) |rp| {5050 if (ret_ptr) |rp| {
5043 call.setCallSret(llvm_ret_ty);5051 call.setCallSret(llvm_ret_ty);
5044 if (isByRef(return_type)) {5052 if (isByRef(return_type, mod)) {
5045 return rp;5053 return rp;
5046 } else {5054 } else {
5047 // our by-ref status disagrees with sret so we must load.5055 // our by-ref status disagrees with sret so we must load.
5048 const loaded = self.builder.buildLoad(llvm_ret_ty, rp, "");5056 const loaded = self.builder.buildLoad(llvm_ret_ty, rp, "");
5049 loaded.setAlignment(return_type.abiAlignment(target));5057 loaded.setAlignment(return_type.abiAlignment(mod));
5050 return loaded;5058 return loaded;
5051 }5059 }
5052 }5060 }
...@@ -5061,7 +5069,7 @@ pub const FuncGen = struct {...@@ -5061,7 +5069,7 @@ pub const FuncGen = struct {
5061 const rp = self.buildAlloca(llvm_ret_ty, alignment);5069 const rp = self.buildAlloca(llvm_ret_ty, alignment);
5062 const store_inst = self.builder.buildStore(call, rp);5070 const store_inst = self.builder.buildStore(call, rp);
5063 store_inst.setAlignment(alignment);5071 store_inst.setAlignment(alignment);
5064 if (isByRef(return_type)) {5072 if (isByRef(return_type, mod)) {
5065 return rp;5073 return rp;
5066 } else {5074 } else {
5067 const load_inst = self.builder.buildLoad(llvm_ret_ty, rp, "");5075 const load_inst = self.builder.buildLoad(llvm_ret_ty, rp, "");
...@@ -5070,10 +5078,10 @@ pub const FuncGen = struct {...@@ -5070,10 +5078,10 @@ pub const FuncGen = struct {
5070 }5078 }
5071 }5079 }
50725080
5073 if (isByRef(return_type)) {5081 if (isByRef(return_type, mod)) {
5074 // our by-ref status disagrees with sret so we must allocate, store,5082 // our by-ref status disagrees with sret so we must allocate, store,
5075 // and return the allocation pointer.5083 // and return the allocation pointer.
5076 const alignment = return_type.abiAlignment(target);5084 const alignment = return_type.abiAlignment(mod);
5077 const rp = self.buildAlloca(llvm_ret_ty, alignment);5085 const rp = self.buildAlloca(llvm_ret_ty, alignment);
5078 const store_inst = self.builder.buildStore(call, rp);5086 const store_inst = self.builder.buildStore(call, rp);
5079 store_inst.setAlignment(alignment);5087 store_inst.setAlignment(alignment);
...@@ -5084,6 +5092,7 @@ pub const FuncGen = struct {...@@ -5084,6 +5092,7 @@ pub const FuncGen = struct {
5084 }5092 }
50855093
5086 fn airRet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5094 fn airRet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5095 const mod = self.dg.module;
5087 const un_op = self.air.instructions.items(.data)[inst].un_op;5096 const un_op = self.air.instructions.items(.data)[inst].un_op;
5088 const ret_ty = self.air.typeOf(un_op);5097 const ret_ty = self.air.typeOf(un_op);
5089 if (self.ret_ptr) |ret_ptr| {5098 if (self.ret_ptr) |ret_ptr| {
...@@ -5098,8 +5107,8 @@ pub const FuncGen = struct {...@@ -5098,8 +5107,8 @@ pub const FuncGen = struct {
5098 return null;5107 return null;
5099 }5108 }
5100 const fn_info = self.dg.decl.ty.fnInfo();5109 const fn_info = self.dg.decl.ty.fnInfo();
5101 if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {5110 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5102 if (fn_info.return_type.isError()) {5111 if (fn_info.return_type.isError(mod)) {
5103 // Functions with an empty error set are emitted with an error code5112 // Functions with an empty error set are emitted with an error code
5104 // return type and return zero so they can be function pointers coerced5113 // return type and return zero so they can be function pointers coerced
5105 // to functions that return anyerror.5114 // to functions that return anyerror.
...@@ -5113,10 +5122,9 @@ pub const FuncGen = struct {...@@ -5113,10 +5122,9 @@ pub const FuncGen = struct {
51135122
5114 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);5123 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
5115 const operand = try self.resolveInst(un_op);5124 const operand = try self.resolveInst(un_op);
5116 const target = self.dg.module.getTarget();5125 const alignment = ret_ty.abiAlignment(mod);
5117 const alignment = ret_ty.abiAlignment(target);
51185126
5119 if (isByRef(ret_ty)) {5127 if (isByRef(ret_ty, mod)) {
5120 // operand is a pointer however self.ret_ptr is null so that means5128 // operand is a pointer however self.ret_ptr is null so that means
5121 // we need to return a value.5129 // we need to return a value.
5122 const load_inst = self.builder.buildLoad(abi_ret_ty, operand, "");5130 const load_inst = self.builder.buildLoad(abi_ret_ty, operand, "");
...@@ -5145,8 +5153,9 @@ pub const FuncGen = struct {...@@ -5145,8 +5153,9 @@ pub const FuncGen = struct {
5145 const ptr_ty = self.air.typeOf(un_op);5153 const ptr_ty = self.air.typeOf(un_op);
5146 const ret_ty = ptr_ty.childType();5154 const ret_ty = ptr_ty.childType();
5147 const fn_info = self.dg.decl.ty.fnInfo();5155 const fn_info = self.dg.decl.ty.fnInfo();
5148 if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {5156 const mod = self.dg.module;
5149 if (fn_info.return_type.isError()) {5157 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5158 if (fn_info.return_type.isError(mod)) {
5150 // Functions with an empty error set are emitted with an error code5159 // Functions with an empty error set are emitted with an error code
5151 // return type and return zero so they can be function pointers coerced5160 // return type and return zero so they can be function pointers coerced
5152 // to functions that return anyerror.5161 // to functions that return anyerror.
...@@ -5162,10 +5171,9 @@ pub const FuncGen = struct {...@@ -5162,10 +5171,9 @@ pub const FuncGen = struct {
5162 return null;5171 return null;
5163 }5172 }
5164 const ptr = try self.resolveInst(un_op);5173 const ptr = try self.resolveInst(un_op);
5165 const target = self.dg.module.getTarget();
5166 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);5174 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
5167 const loaded = self.builder.buildLoad(abi_ret_ty, ptr, "");5175 const loaded = self.builder.buildLoad(abi_ret_ty, ptr, "");
5168 loaded.setAlignment(ret_ty.abiAlignment(target));5176 loaded.setAlignment(ret_ty.abiAlignment(mod));
5169 _ = self.builder.buildRet(loaded);5177 _ = self.builder.buildRet(loaded);
5170 return null;5178 return null;
5171 }5179 }
...@@ -5184,9 +5192,9 @@ pub const FuncGen = struct {...@@ -5184,9 +5192,9 @@ pub const FuncGen = struct {
5184 const src_list = try self.resolveInst(ty_op.operand);5192 const src_list = try self.resolveInst(ty_op.operand);
5185 const va_list_ty = self.air.getRefType(ty_op.ty);5193 const va_list_ty = self.air.getRefType(ty_op.ty);
5186 const llvm_va_list_ty = try self.dg.lowerType(va_list_ty);5194 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();5197 const result_alignment = va_list_ty.abiAlignment(mod);
5189 const result_alignment = va_list_ty.abiAlignment(target);
5190 const dest_list = self.buildAlloca(llvm_va_list_ty, result_alignment);5198 const dest_list = self.buildAlloca(llvm_va_list_ty, result_alignment);
51915199
5192 const llvm_fn_name = "llvm.va_copy";5200 const llvm_fn_name = "llvm.va_copy";
...@@ -5202,7 +5210,7 @@ pub const FuncGen = struct {...@@ -5202,7 +5210,7 @@ pub const FuncGen = struct {
5202 const args: [2]*llvm.Value = .{ dest_list, src_list };5210 const args: [2]*llvm.Value = .{ dest_list, src_list };
5203 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");5211 _ = 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)) {
5206 return dest_list;5214 return dest_list;
5207 } else {5215 } else {
5208 const loaded = self.builder.buildLoad(llvm_va_list_ty, dest_list, "");5216 const loaded = self.builder.buildLoad(llvm_va_list_ty, dest_list, "");
...@@ -5227,11 +5235,11 @@ pub const FuncGen = struct {...@@ -5227,11 +5235,11 @@ pub const FuncGen = struct {
5227 }5235 }
52285236
5229 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5237 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5238 const mod = self.dg.module;
5230 const va_list_ty = self.air.typeOfIndex(inst);5239 const va_list_ty = self.air.typeOfIndex(inst);
5231 const llvm_va_list_ty = try self.dg.lowerType(va_list_ty);5240 const llvm_va_list_ty = try self.dg.lowerType(va_list_ty);
52325241
5233 const target = self.dg.module.getTarget();5242 const result_alignment = va_list_ty.abiAlignment(mod);
5234 const result_alignment = va_list_ty.abiAlignment(target);
5235 const list = self.buildAlloca(llvm_va_list_ty, result_alignment);5243 const list = self.buildAlloca(llvm_va_list_ty, result_alignment);
52365244
5237 const llvm_fn_name = "llvm.va_start";5245 const llvm_fn_name = "llvm.va_start";
...@@ -5243,7 +5251,7 @@ pub const FuncGen = struct {...@@ -5243,7 +5251,7 @@ pub const FuncGen = struct {
5243 const args: [1]*llvm.Value = .{list};5251 const args: [1]*llvm.Value = .{list};
5244 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");5252 _ = 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)) {
5247 return list;5255 return list;
5248 } else {5256 } else {
5249 const loaded = self.builder.buildLoad(llvm_va_list_ty, list, "");5257 const loaded = self.builder.buildLoad(llvm_va_list_ty, list, "");
...@@ -5292,23 +5300,23 @@ pub const FuncGen = struct {...@@ -5292,23 +5300,23 @@ pub const FuncGen = struct {
5292 operand_ty: Type,5300 operand_ty: Type,
5293 op: math.CompareOperator,5301 op: math.CompareOperator,
5294 ) Allocator.Error!*llvm.Value {5302 ) Allocator.Error!*llvm.Value {
5295 var int_buffer: Type.Payload.Bits = undefined;
5296 var opt_buffer: Type.Payload.ElemType = undefined;5303 var opt_buffer: Type.Payload.ElemType = undefined;
52975304
5298 const scalar_ty = operand_ty.scalarType();5305 const mod = self.dg.module;
5299 const int_ty = switch (scalar_ty.zigTypeTag()) {5306 const scalar_ty = operand_ty.scalarType(mod);
5300 .Enum => scalar_ty.intTagType(&int_buffer),5307 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {
5308 .Enum => scalar_ty.intTagType(),
5301 .Int, .Bool, .Pointer, .ErrorSet => scalar_ty,5309 .Int, .Bool, .Pointer, .ErrorSet => scalar_ty,
5302 .Optional => blk: {5310 .Optional => blk: {
5303 const payload_ty = operand_ty.optionalChild(&opt_buffer);5311 const payload_ty = operand_ty.optionalChild(&opt_buffer);
5304 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or5312 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or
5305 operand_ty.optionalReprIsPayload())5313 operand_ty.optionalReprIsPayload(mod))
5306 {5314 {
5307 break :blk operand_ty;5315 break :blk operand_ty;
5308 }5316 }
5309 // We need to emit instructions to check for equality/inequality5317 // We need to emit instructions to check for equality/inequality
5310 // of optionals that are not pointers.5318 // of optionals that are not pointers.
5311 const is_by_ref = isByRef(scalar_ty);5319 const is_by_ref = isByRef(scalar_ty, mod);
5312 const opt_llvm_ty = try self.dg.lowerType(scalar_ty);5320 const opt_llvm_ty = try self.dg.lowerType(scalar_ty);
5313 const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);5321 const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);
5314 const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);5322 const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);
...@@ -5375,7 +5383,7 @@ pub const FuncGen = struct {...@@ -5375,7 +5383,7 @@ pub const FuncGen = struct {
5375 .Float => return self.buildFloatCmp(op, operand_ty, .{ lhs, rhs }),5383 .Float => return self.buildFloatCmp(op, operand_ty, .{ lhs, rhs }),
5376 else => unreachable,5384 else => unreachable,
5377 };5385 };
5378 const is_signed = int_ty.isSignedInt();5386 const is_signed = int_ty.isSignedInt(mod);
5379 const operation: llvm.IntPredicate = switch (op) {5387 const operation: llvm.IntPredicate = switch (op) {
5380 .eq => .EQ,5388 .eq => .EQ,
5381 .neq => .NE,5389 .neq => .NE,
...@@ -5393,6 +5401,7 @@ pub const FuncGen = struct {...@@ -5393,6 +5401,7 @@ pub const FuncGen = struct {
5393 const body = self.air.extra[extra.end..][0..extra.data.body_len];5401 const body = self.air.extra[extra.end..][0..extra.data.body_len];
5394 const inst_ty = self.air.typeOfIndex(inst);5402 const inst_ty = self.air.typeOfIndex(inst);
5395 const parent_bb = self.context.createBasicBlock("Block");5403 const parent_bb = self.context.createBasicBlock("Block");
5404 const mod = self.dg.module;
53965405
5397 if (inst_ty.isNoReturn()) {5406 if (inst_ty.isNoReturn()) {
5398 try self.genBody(body);5407 try self.genBody(body);
...@@ -5414,8 +5423,8 @@ pub const FuncGen = struct {...@@ -5414,8 +5423,8 @@ pub const FuncGen = struct {
5414 self.builder.positionBuilderAtEnd(parent_bb);5423 self.builder.positionBuilderAtEnd(parent_bb);
54155424
5416 // Create a phi node only if the block returns a value.5425 // Create a phi node only if the block returns a value.
5417 const is_body = inst_ty.zigTypeTag() == .Fn;5426 const is_body = inst_ty.zigTypeTag(mod) == .Fn;
5418 if (!is_body and !inst_ty.hasRuntimeBitsIgnoreComptime()) return null;5427 if (!is_body and !inst_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
54195428
5420 const raw_llvm_ty = try self.dg.lowerType(inst_ty);5429 const raw_llvm_ty = try self.dg.lowerType(inst_ty);
54215430
...@@ -5424,7 +5433,7 @@ pub const FuncGen = struct {...@@ -5424,7 +5433,7 @@ pub const FuncGen = struct {
5424 // a pointer to it. LLVM IR allows the call instruction to use function bodies instead5433 // a pointer to it. LLVM IR allows the call instruction to use function bodies instead
5425 // of function pointers, however the phi makes it a runtime value and therefore5434 // of function pointers, however the phi makes it a runtime value and therefore
5426 // the LLVM type has to be wrapped in a pointer.5435 // 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)) {
5428 break :ty self.context.pointerType(0);5437 break :ty self.context.pointerType(0);
5429 }5438 }
5430 break :ty raw_llvm_ty;5439 break :ty raw_llvm_ty;
...@@ -5445,7 +5454,8 @@ pub const FuncGen = struct {...@@ -5445,7 +5454,8 @@ pub const FuncGen = struct {
54455454
5446 // Add the values to the lists only if the break provides a value.5455 // Add the values to the lists only if the break provides a value.
5447 const operand_ty = self.air.typeOf(branch.operand);5456 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) {
5449 const val = try self.resolveInst(branch.operand);5459 const val = try self.resolveInst(branch.operand);
54505460
5451 // For the phi node, we need the basic blocks and the values of the5461 // For the phi node, we need the basic blocks and the values of the
...@@ -5481,6 +5491,7 @@ pub const FuncGen = struct {...@@ -5481,6 +5491,7 @@ pub const FuncGen = struct {
5481 }5491 }
54825492
5483 fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {5493 fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5494 const mod = self.dg.module;
5484 const inst = body_tail[0];5495 const inst = body_tail[0];
5485 const pl_op = self.air.instructions.items(.data)[inst].pl_op;5496 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
5486 const err_union = try self.resolveInst(pl_op.operand);5497 const err_union = try self.resolveInst(pl_op.operand);
...@@ -5488,7 +5499,7 @@ pub const FuncGen = struct {...@@ -5488,7 +5499,7 @@ pub const FuncGen = struct {
5488 const body = self.air.extra[extra.end..][0..extra.data.body_len];5499 const body = self.air.extra[extra.end..][0..extra.data.body_len];
5489 const err_union_ty = self.air.typeOf(pl_op.operand);5500 const err_union_ty = self.air.typeOf(pl_op.operand);
5490 const payload_ty = self.air.typeOfIndex(inst);5501 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;
5492 const is_unused = self.liveness.isUnused(inst);5503 const is_unused = self.liveness.isUnused(inst);
5493 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);5504 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);
5494 }5505 }
...@@ -5512,9 +5523,9 @@ pub const FuncGen = struct {...@@ -5512,9 +5523,9 @@ pub const FuncGen = struct {
5512 can_elide_load: bool,5523 can_elide_load: bool,
5513 is_unused: bool,5524 is_unused: bool,
5514 ) !?*llvm.Value {5525 ) !?*llvm.Value {
5526 const mod = fg.dg.module;
5515 const payload_ty = err_union_ty.errorUnionPayload();5527 const payload_ty = err_union_ty.errorUnionPayload();
5516 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();5528 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
5517 const target = fg.dg.module.getTarget();
5518 const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty);5529 const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty);
55195530
5520 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {5531 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
...@@ -5529,8 +5540,8 @@ pub const FuncGen = struct {...@@ -5529,8 +5540,8 @@ pub const FuncGen = struct {
5529 err_union;5540 err_union;
5530 break :err fg.builder.buildICmp(.NE, loaded, zero, "");5541 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
5531 }5542 }
5532 const err_field_index = errUnionErrorOffset(payload_ty, target);5543 const err_field_index = errUnionErrorOffset(payload_ty, mod);
5533 if (operand_is_ptr or isByRef(err_union_ty)) {5544 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
5534 const err_field_ptr = fg.builder.buildStructGEP(err_union_llvm_ty, err_union, err_field_index, "");5545 const err_field_ptr = fg.builder.buildStructGEP(err_union_llvm_ty, err_union, err_field_index, "");
5535 // TODO add alignment to this load5546 // TODO add alignment to this load
5536 const loaded = fg.builder.buildLoad(err_set_ty, err_field_ptr, "");5547 const loaded = fg.builder.buildLoad(err_set_ty, err_field_ptr, "");
...@@ -5555,30 +5566,31 @@ pub const FuncGen = struct {...@@ -5555,30 +5566,31 @@ pub const FuncGen = struct {
5555 if (!payload_has_bits) {5566 if (!payload_has_bits) {
5556 return if (operand_is_ptr) err_union else null;5567 return if (operand_is_ptr) err_union else null;
5557 }5568 }
5558 const offset = errUnionPayloadOffset(payload_ty, target);5569 const offset = errUnionPayloadOffset(payload_ty, mod);
5559 if (operand_is_ptr) {5570 if (operand_is_ptr) {
5560 return fg.builder.buildStructGEP(err_union_llvm_ty, err_union, offset, "");5571 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)) {
5562 const payload_ptr = fg.builder.buildStructGEP(err_union_llvm_ty, err_union, offset, "");5573 const payload_ptr = fg.builder.buildStructGEP(err_union_llvm_ty, err_union, offset, "");
5563 if (isByRef(payload_ty)) {5574 if (isByRef(payload_ty, mod)) {
5564 if (can_elide_load)5575 if (can_elide_load)
5565 return payload_ptr;5576 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);
5568 }5579 }
5569 const load_inst = fg.builder.buildLoad(err_union_llvm_ty.structGetTypeAtIndex(offset), payload_ptr, "");5580 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));
5571 return load_inst;5582 return load_inst;
5572 }5583 }
5573 return fg.builder.buildExtractValue(err_union, offset, "");5584 return fg.builder.buildExtractValue(err_union, offset, "");
5574 }5585 }
55755586
5576 fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5587 fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5588 const mod = self.dg.module;
5577 const pl_op = self.air.instructions.items(.data)[inst].pl_op;5589 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
5578 const cond = try self.resolveInst(pl_op.operand);5590 const cond = try self.resolveInst(pl_op.operand);
5579 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);5591 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
5580 const else_block = self.context.appendBasicBlock(self.llvm_func, "Else");5592 const else_block = self.context.appendBasicBlock(self.llvm_func, "Else");
5581 const target = self.dg.module.getTarget();5593 const target = mod.getTarget();
5582 const llvm_usize = self.context.intType(target.ptrBitWidth());5594 const llvm_usize = self.context.intType(target.ptrBitWidth());
5583 const cond_int = if (cond.typeOf().getTypeKind() == .Pointer)5595 const cond_int = if (cond.typeOf().getTypeKind() == .Pointer)
5584 self.builder.buildPtrToInt(cond, llvm_usize, "")5596 self.builder.buildPtrToInt(cond, llvm_usize, "")
...@@ -5645,6 +5657,7 @@ pub const FuncGen = struct {...@@ -5645,6 +5657,7 @@ pub const FuncGen = struct {
5645 }5657 }
56465658
5647 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5659 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5660 const mod = self.dg.module;
5648 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5661 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5649 const operand_ty = self.air.typeOf(ty_op.operand);5662 const operand_ty = self.air.typeOf(ty_op.operand);
5650 const array_ty = operand_ty.childType();5663 const array_ty = operand_ty.childType();
...@@ -5652,7 +5665,7 @@ pub const FuncGen = struct {...@@ -5652,7 +5665,7 @@ pub const FuncGen = struct {
5652 const len = llvm_usize.constInt(array_ty.arrayLen(), .False);5665 const len = llvm_usize.constInt(array_ty.arrayLen(), .False);
5653 const slice_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));5666 const slice_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));
5654 const operand = try self.resolveInst(ty_op.operand);5667 const operand = try self.resolveInst(ty_op.operand);
5655 if (!array_ty.hasRuntimeBitsIgnoreComptime()) {5668 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5656 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, "");5669 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, "");
5657 return self.builder.buildInsertValue(partial, len, 1, "");5670 return self.builder.buildInsertValue(partial, len, 1, "");
5658 }5671 }
...@@ -5666,30 +5679,31 @@ pub const FuncGen = struct {...@@ -5666,30 +5679,31 @@ pub const FuncGen = struct {
5666 }5679 }
56675680
5668 fn airIntToFloat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5681 fn airIntToFloat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5682 const mod = self.dg.module;
5669 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5683 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
56705684
5671 const operand = try self.resolveInst(ty_op.operand);5685 const operand = try self.resolveInst(ty_op.operand);
5672 const operand_ty = self.air.typeOf(ty_op.operand);5686 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
5675 const dest_ty = self.air.typeOfIndex(inst);5689 const dest_ty = self.air.typeOfIndex(inst);
5676 const dest_scalar_ty = dest_ty.scalarType();5690 const dest_scalar_ty = dest_ty.scalarType(mod);
5677 const dest_llvm_ty = try self.dg.lowerType(dest_ty);5691 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
5678 const target = self.dg.module.getTarget();5692 const target = mod.getTarget();
56795693
5680 if (intrinsicsAllowed(dest_scalar_ty, target)) {5694 if (intrinsicsAllowed(dest_scalar_ty, target)) {
5681 if (operand_scalar_ty.isSignedInt()) {5695 if (operand_scalar_ty.isSignedInt(mod)) {
5682 return self.builder.buildSIToFP(operand, dest_llvm_ty, "");5696 return self.builder.buildSIToFP(operand, dest_llvm_ty, "");
5683 } else {5697 } else {
5684 return self.builder.buildUIToFP(operand, dest_llvm_ty, "");5698 return self.builder.buildUIToFP(operand, dest_llvm_ty, "");
5685 }5699 }
5686 }5700 }
56875701
5688 const operand_bits = @intCast(u16, operand_scalar_ty.bitSize(target));5702 const operand_bits = @intCast(u16, operand_scalar_ty.bitSize(mod));
5689 const rt_int_bits = compilerRtIntBits(operand_bits);5703 const rt_int_bits = compilerRtIntBits(operand_bits);
5690 const rt_int_ty = self.context.intType(rt_int_bits);5704 const rt_int_ty = self.context.intType(rt_int_bits);
5691 var extended = e: {5705 var extended = e: {
5692 if (operand_scalar_ty.isSignedInt()) {5706 if (operand_scalar_ty.isSignedInt(mod)) {
5693 break :e self.builder.buildSExtOrBitCast(operand, rt_int_ty, "");5707 break :e self.builder.buildSExtOrBitCast(operand, rt_int_ty, "");
5694 } else {5708 } else {
5695 break :e self.builder.buildZExtOrBitCast(operand, rt_int_ty, "");5709 break :e self.builder.buildZExtOrBitCast(operand, rt_int_ty, "");
...@@ -5698,7 +5712,7 @@ pub const FuncGen = struct {...@@ -5698,7 +5712,7 @@ pub const FuncGen = struct {
5698 const dest_bits = dest_scalar_ty.floatBits(target);5712 const dest_bits = dest_scalar_ty.floatBits(target);
5699 const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits);5713 const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits);
5700 const compiler_rt_dest_abbrev = compilerRtFloatAbbrev(dest_bits);5714 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";
5702 var fn_name_buf: [64]u8 = undefined;5716 var fn_name_buf: [64]u8 = undefined;
5703 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__float{s}{s}i{s}f", .{5717 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__float{s}{s}i{s}f", .{
5704 sign_prefix,5718 sign_prefix,
...@@ -5724,27 +5738,28 @@ pub const FuncGen = struct {...@@ -5724,27 +5738,28 @@ pub const FuncGen = struct {
5724 fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {5738 fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
5725 self.builder.setFastMath(want_fast_math);5739 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();
5728 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5743 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
57295744
5730 const operand = try self.resolveInst(ty_op.operand);5745 const operand = try self.resolveInst(ty_op.operand);
5731 const operand_ty = self.air.typeOf(ty_op.operand);5746 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
5734 const dest_ty = self.air.typeOfIndex(inst);5749 const dest_ty = self.air.typeOfIndex(inst);
5735 const dest_scalar_ty = dest_ty.scalarType();5750 const dest_scalar_ty = dest_ty.scalarType(mod);
5736 const dest_llvm_ty = try self.dg.lowerType(dest_ty);5751 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
57375752
5738 if (intrinsicsAllowed(operand_scalar_ty, target)) {5753 if (intrinsicsAllowed(operand_scalar_ty, target)) {
5739 // TODO set fast math flag5754 // TODO set fast math flag
5740 if (dest_scalar_ty.isSignedInt()) {5755 if (dest_scalar_ty.isSignedInt(mod)) {
5741 return self.builder.buildFPToSI(operand, dest_llvm_ty, "");5756 return self.builder.buildFPToSI(operand, dest_llvm_ty, "");
5742 } else {5757 } else {
5743 return self.builder.buildFPToUI(operand, dest_llvm_ty, "");5758 return self.builder.buildFPToUI(operand, dest_llvm_ty, "");
5744 }5759 }
5745 }5760 }
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)));
5748 const ret_ty = self.context.intType(rt_int_bits);5763 const ret_ty = self.context.intType(rt_int_bits);
5749 const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: {5764 const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: {
5750 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard5765 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard
...@@ -5756,7 +5771,7 @@ pub const FuncGen = struct {...@@ -5756,7 +5771,7 @@ pub const FuncGen = struct {
5756 const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits);5771 const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits);
57575772
5758 const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits);5773 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
5761 var fn_name_buf: [64]u8 = undefined;5776 var fn_name_buf: [64]u8 = undefined;
5762 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__fix{s}{s}f{s}i", .{5777 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__fix{s}{s}f{s}i", .{
...@@ -5786,13 +5801,14 @@ pub const FuncGen = struct {...@@ -5786,13 +5801,14 @@ pub const FuncGen = struct {
5786 }5801 }
57875802
5788 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: *llvm.Value, ty: Type) *llvm.Value {5803 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();
5790 const llvm_usize_ty = fg.context.intType(target.ptrBitWidth());5806 const llvm_usize_ty = fg.context.intType(target.ptrBitWidth());
5791 switch (ty.ptrSize()) {5807 switch (ty.ptrSize()) {
5792 .Slice => {5808 .Slice => {
5793 const len = fg.builder.buildExtractValue(ptr, 1, "");5809 const len = fg.builder.buildExtractValue(ptr, 1, "");
5794 const elem_ty = ty.childType();5810 const elem_ty = ty.childType();
5795 const abi_size = elem_ty.abiSize(target);5811 const abi_size = elem_ty.abiSize(mod);
5796 if (abi_size == 1) return len;5812 if (abi_size == 1) return len;
5797 const abi_size_llvm_val = llvm_usize_ty.constInt(abi_size, .False);5813 const abi_size_llvm_val = llvm_usize_ty.constInt(abi_size, .False);
5798 return fg.builder.buildMul(len, abi_size_llvm_val, "");5814 return fg.builder.buildMul(len, abi_size_llvm_val, "");
...@@ -5800,7 +5816,7 @@ pub const FuncGen = struct {...@@ -5800,7 +5816,7 @@ pub const FuncGen = struct {
5800 .One => {5816 .One => {
5801 const array_ty = ty.childType();5817 const array_ty = ty.childType();
5802 const elem_ty = array_ty.childType();5818 const elem_ty = array_ty.childType();
5803 const abi_size = elem_ty.abiSize(target);5819 const abi_size = elem_ty.abiSize(mod);
5804 return llvm_usize_ty.constInt(array_ty.arrayLen() * abi_size, .False);5820 return llvm_usize_ty.constInt(array_ty.arrayLen() * abi_size, .False);
5805 },5821 },
5806 .Many, .C => unreachable,5822 .Many, .C => unreachable,
...@@ -5823,6 +5839,7 @@ pub const FuncGen = struct {...@@ -5823,6 +5839,7 @@ pub const FuncGen = struct {
5823 }5839 }
58245840
5825 fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {5841 fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5842 const mod = self.dg.module;
5826 const inst = body_tail[0];5843 const inst = body_tail[0];
5827 const bin_op = self.air.instructions.items(.data)[inst].bin_op;5844 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5828 const slice_ty = self.air.typeOf(bin_op.lhs);5845 const slice_ty = self.air.typeOf(bin_op.lhs);
...@@ -5833,12 +5850,11 @@ pub const FuncGen = struct {...@@ -5833,12 +5850,11 @@ pub const FuncGen = struct {
5833 const base_ptr = self.builder.buildExtractValue(slice, 0, "");5850 const base_ptr = self.builder.buildExtractValue(slice, 0, "");
5834 const indices: [1]*llvm.Value = .{index};5851 const indices: [1]*llvm.Value = .{index};
5835 const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");5852 const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
5836 if (isByRef(elem_ty)) {5853 if (isByRef(elem_ty, mod)) {
5837 if (self.canElideLoad(body_tail))5854 if (self.canElideLoad(body_tail))
5838 return ptr;5855 return ptr;
58395856
5840 const target = self.dg.module.getTarget();5857 return self.loadByRef(ptr, elem_ty, elem_ty.abiAlignment(mod), false);
5841 return self.loadByRef(ptr, elem_ty, elem_ty.abiAlignment(target), false);
5842 }5858 }
58435859
5844 return self.load(ptr, slice_ty);5860 return self.load(ptr, slice_ty);
...@@ -5858,6 +5874,7 @@ pub const FuncGen = struct {...@@ -5858,6 +5874,7 @@ pub const FuncGen = struct {
5858 }5874 }
58595875
5860 fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {5876 fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5877 const mod = self.dg.module;
5861 const inst = body_tail[0];5878 const inst = body_tail[0];
58625879
5863 const bin_op = self.air.instructions.items(.data)[inst].bin_op;5880 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
...@@ -5866,15 +5883,14 @@ pub const FuncGen = struct {...@@ -5866,15 +5883,14 @@ pub const FuncGen = struct {
5866 const rhs = try self.resolveInst(bin_op.rhs);5883 const rhs = try self.resolveInst(bin_op.rhs);
5867 const array_llvm_ty = try self.dg.lowerType(array_ty);5884 const array_llvm_ty = try self.dg.lowerType(array_ty);
5868 const elem_ty = array_ty.childType();5885 const elem_ty = array_ty.childType();
5869 if (isByRef(array_ty)) {5886 if (isByRef(array_ty, mod)) {
5870 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };5887 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
5871 if (isByRef(elem_ty)) {5888 if (isByRef(elem_ty, mod)) {
5872 const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, "");5889 const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, "");
5873 if (canElideLoad(self, body_tail))5890 if (canElideLoad(self, body_tail))
5874 return elem_ptr;5891 return elem_ptr;
58755892
5876 const target = self.dg.module.getTarget();5893 return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(mod), false);
5877 return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(target), false);
5878 } else {5894 } else {
5879 const lhs_index = Air.refToIndex(bin_op.lhs).?;5895 const lhs_index = Air.refToIndex(bin_op.lhs).?;
5880 const elem_llvm_ty = try self.dg.lowerType(elem_ty);5896 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
...@@ -5901,6 +5917,7 @@ pub const FuncGen = struct {...@@ -5901,6 +5917,7 @@ pub const FuncGen = struct {
5901 }5917 }
59025918
5903 fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {5919 fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5920 const mod = self.dg.module;
5904 const inst = body_tail[0];5921 const inst = body_tail[0];
5905 const bin_op = self.air.instructions.items(.data)[inst].bin_op;5922 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5906 const ptr_ty = self.air.typeOf(bin_op.lhs);5923 const ptr_ty = self.air.typeOf(bin_op.lhs);
...@@ -5917,23 +5934,23 @@ pub const FuncGen = struct {...@@ -5917,23 +5934,23 @@ pub const FuncGen = struct {
5917 const indices: [1]*llvm.Value = .{rhs};5934 const indices: [1]*llvm.Value = .{rhs};
5918 break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");5935 break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
5919 };5936 };
5920 if (isByRef(elem_ty)) {5937 if (isByRef(elem_ty, mod)) {
5921 if (self.canElideLoad(body_tail))5938 if (self.canElideLoad(body_tail))
5922 return ptr;5939 return ptr;
59235940
5924 const target = self.dg.module.getTarget();5941 return self.loadByRef(ptr, elem_ty, elem_ty.abiAlignment(mod), false);
5925 return self.loadByRef(ptr, elem_ty, elem_ty.abiAlignment(target), false);
5926 }5942 }
59275943
5928 return self.load(ptr, ptr_ty);5944 return self.load(ptr, ptr_ty);
5929 }5945 }
59305946
5931 fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5947 fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5948 const mod = self.dg.module;
5932 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5949 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5933 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;5950 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
5934 const ptr_ty = self.air.typeOf(bin_op.lhs);5951 const ptr_ty = self.air.typeOf(bin_op.lhs);
5935 const elem_ty = ptr_ty.childType();5952 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
5938 const base_ptr = try self.resolveInst(bin_op.lhs);5955 const base_ptr = try self.resolveInst(bin_op.lhs);
5939 const rhs = try self.resolveInst(bin_op.rhs);5956 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -5972,6 +5989,7 @@ pub const FuncGen = struct {...@@ -5972,6 +5989,7 @@ pub const FuncGen = struct {
5972 }5989 }
59735990
5974 fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {5991 fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5992 const mod = self.dg.module;
5975 const inst = body_tail[0];5993 const inst = body_tail[0];
5976 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5994 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5977 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;5995 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
...@@ -5979,29 +5997,28 @@ pub const FuncGen = struct {...@@ -5979,29 +5997,28 @@ pub const FuncGen = struct {
5979 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);5997 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);
5980 const field_index = struct_field.field_index;5998 const field_index = struct_field.field_index;
5981 const field_ty = struct_ty.structFieldType(field_index);5999 const field_ty = struct_ty.structFieldType(field_index);
5982 if (!field_ty.hasRuntimeBitsIgnoreComptime()) {6000 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5983 return null;6001 return null;
5984 }6002 }
5985 const target = self.dg.module.getTarget();
59866003
5987 if (!isByRef(struct_ty)) {6004 if (!isByRef(struct_ty, mod)) {
5988 assert(!isByRef(field_ty));6005 assert(!isByRef(field_ty, mod));
5989 switch (struct_ty.zigTypeTag()) {6006 switch (struct_ty.zigTypeTag(mod)) {
5990 .Struct => switch (struct_ty.containerLayout()) {6007 .Struct => switch (struct_ty.containerLayout()) {
5991 .Packed => {6008 .Packed => {
5992 const struct_obj = struct_ty.castTag(.@"struct").?.data;6009 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);
5994 const containing_int = struct_llvm_val;6011 const containing_int = struct_llvm_val;
5995 const shift_amt = containing_int.typeOf().constInt(bit_offset, .False);6012 const shift_amt = containing_int.typeOf().constInt(bit_offset, .False);
5996 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");6013 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");
5997 const elem_llvm_ty = try self.dg.lowerType(field_ty);6014 const elem_llvm_ty = try self.dg.lowerType(field_ty);
5998 if (field_ty.zigTypeTag() == .Float or field_ty.zigTypeTag() == .Vector) {6015 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
5999 const elem_bits = @intCast(c_uint, field_ty.bitSize(target));6016 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));
6000 const same_size_int = self.context.intType(elem_bits);6017 const same_size_int = self.context.intType(elem_bits);
6001 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");6018 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
6002 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");6019 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
6003 } else if (field_ty.isPtrAtRuntime()) {6020 } else if (field_ty.isPtrAtRuntime(mod)) {
6004 const elem_bits = @intCast(c_uint, field_ty.bitSize(target));6021 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));
6005 const same_size_int = self.context.intType(elem_bits);6022 const same_size_int = self.context.intType(elem_bits);
6006 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");6023 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
6007 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");6024 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
...@@ -6010,7 +6027,7 @@ pub const FuncGen = struct {...@@ -6010,7 +6027,7 @@ pub const FuncGen = struct {
6010 },6027 },
6011 else => {6028 else => {
6012 var ptr_ty_buf: Type.Payload.Pointer = undefined;6029 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).?;
6014 return self.builder.buildExtractValue(struct_llvm_val, llvm_field_index, "");6031 return self.builder.buildExtractValue(struct_llvm_val, llvm_field_index, "");
6015 },6032 },
6016 },6033 },
...@@ -6018,13 +6035,13 @@ pub const FuncGen = struct {...@@ -6018,13 +6035,13 @@ pub const FuncGen = struct {
6018 assert(struct_ty.containerLayout() == .Packed);6035 assert(struct_ty.containerLayout() == .Packed);
6019 const containing_int = struct_llvm_val;6036 const containing_int = struct_llvm_val;
6020 const elem_llvm_ty = try self.dg.lowerType(field_ty);6037 const elem_llvm_ty = try self.dg.lowerType(field_ty);
6021 if (field_ty.zigTypeTag() == .Float or field_ty.zigTypeTag() == .Vector) {6038 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
6022 const elem_bits = @intCast(c_uint, field_ty.bitSize(target));6039 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));
6023 const same_size_int = self.context.intType(elem_bits);6040 const same_size_int = self.context.intType(elem_bits);
6024 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");6041 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");
6025 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");6042 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
6026 } else if (field_ty.isPtrAtRuntime()) {6043 } else if (field_ty.isPtrAtRuntime(mod)) {
6027 const elem_bits = @intCast(c_uint, field_ty.bitSize(target));6044 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));
6028 const same_size_int = self.context.intType(elem_bits);6045 const same_size_int = self.context.intType(elem_bits);
6029 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");6046 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");
6030 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");6047 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
...@@ -6035,30 +6052,30 @@ pub const FuncGen = struct {...@@ -6035,30 +6052,30 @@ pub const FuncGen = struct {
6035 }6052 }
6036 }6053 }
60376054
6038 switch (struct_ty.zigTypeTag()) {6055 switch (struct_ty.zigTypeTag(mod)) {
6039 .Struct => {6056 .Struct => {
6040 assert(struct_ty.containerLayout() != .Packed);6057 assert(struct_ty.containerLayout() != .Packed);
6041 var ptr_ty_buf: Type.Payload.Pointer = undefined;6058 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).?;
6043 const struct_llvm_ty = try self.dg.lowerType(struct_ty);6060 const struct_llvm_ty = try self.dg.lowerType(struct_ty);
6044 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");6061 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");
6045 const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base);6062 const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base);
6046 if (isByRef(field_ty)) {6063 if (isByRef(field_ty, mod)) {
6047 if (canElideLoad(self, body_tail))6064 if (canElideLoad(self, body_tail))
6048 return field_ptr;6065 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);
6051 } else {6068 } else {
6052 return self.load(field_ptr, field_ptr_ty);6069 return self.load(field_ptr, field_ptr_ty);
6053 }6070 }
6054 },6071 },
6055 .Union => {6072 .Union => {
6056 const union_llvm_ty = try self.dg.lowerType(struct_ty);6073 const union_llvm_ty = try self.dg.lowerType(struct_ty);
6057 const layout = struct_ty.unionGetLayout(target);6074 const layout = struct_ty.unionGetLayout(mod);
6058 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);6075 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
6059 const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, "");6076 const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, "");
6060 const llvm_field_ty = try self.dg.lowerType(field_ty);6077 const llvm_field_ty = try self.dg.lowerType(field_ty);
6061 if (isByRef(field_ty)) {6078 if (isByRef(field_ty, mod)) {
6062 if (canElideLoad(self, body_tail))6079 if (canElideLoad(self, body_tail))
6063 return field_ptr;6080 return field_ptr;
60646081
...@@ -6072,6 +6089,7 @@ pub const FuncGen = struct {...@@ -6072,6 +6089,7 @@ pub const FuncGen = struct {
6072 }6089 }
60736090
6074 fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6091 fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6092 const mod = self.dg.module;
6075 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;6093 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
6076 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;6094 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
60776095
...@@ -6079,7 +6097,7 @@ pub const FuncGen = struct {...@@ -6079,7 +6097,7 @@ pub const FuncGen = struct {
60796097
6080 const target = self.dg.module.getTarget();6098 const target = self.dg.module.getTarget();
6081 const parent_ty = self.air.getRefType(ty_pl.ty).childType();6099 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
6084 const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty));6102 const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty));
6085 if (field_offset == 0) {6103 if (field_offset == 0) {
...@@ -6119,12 +6137,13 @@ pub const FuncGen = struct {...@@ -6119,12 +6137,13 @@ pub const FuncGen = struct {
6119 }6137 }
61206138
6121 fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6139 fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6140 const mod = self.dg.module;
6122 const dib = self.dg.object.di_builder orelse return null;6141 const dib = self.dg.object.di_builder orelse return null;
6123 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;6142 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
61246143
6125 const func = self.air.values[ty_pl.payload].castTag(.function).?.data;6144 const func = self.air.values[ty_pl.payload].castTag(.function).?.data;
6126 const decl_index = func.owner_decl;6145 const decl_index = func.owner_decl;
6127 const decl = self.dg.module.declPtr(decl_index);6146 const decl = mod.declPtr(decl_index);
6128 const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope);6147 const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope);
6129 self.di_file = di_file;6148 self.di_file = di_file;
6130 const line_number = decl.src_line + 1;6149 const line_number = decl.src_line + 1;
...@@ -6136,22 +6155,41 @@ pub const FuncGen = struct {...@@ -6136,22 +6155,41 @@ pub const FuncGen = struct {
6136 .base_line = self.base_line,6155 .base_line = self.base_line,
6137 });6156 });
61386157
6139 const fqn = try decl.getFullyQualifiedName(self.dg.module);6158 const fqn = try decl.getFullyQualifiedName(mod);
6140 defer self.gpa.free(fqn);6159 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);
6143 const subprogram = dib.createFunction(6181 const subprogram = dib.createFunction(
6144 di_file.toScope(),6182 di_file.toScope(),
6145 decl.name,6183 decl.name,
6146 fqn,6184 fqn,
6147 di_file,6185 di_file,
6148 line_number,6186 line_number,
6149 try self.dg.object.lowerDebugType(Type.initTag(.fn_void_no_args), .full),6187 try self.dg.object.lowerDebugType(fn_ty, .full),
6150 is_internal_linkage,6188 is_internal_linkage,
6151 true, // is definition6189 true, // is definition
6152 line_number + func.lbrace_line, // scope line6190 line_number + func.lbrace_line, // scope line
6153 llvm.DIFlags.StaticMember,6191 llvm.DIFlags.StaticMember,
6154 self.dg.module.comp.bin_file.options.optimize_mode != .Debug,6192 mod.comp.bin_file.options.optimize_mode != .Debug,
6155 null, // decl_subprogram6193 null, // decl_subprogram
6156 );6194 );
61576195
...@@ -6243,10 +6281,11 @@ pub const FuncGen = struct {...@@ -6243,10 +6281,11 @@ pub const FuncGen = struct {
6243 null;6281 null;
6244 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);6282 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);
6245 const insert_block = self.builder.getInsertBlock();6283 const insert_block = self.builder.getInsertBlock();
6246 if (isByRef(operand_ty)) {6284 const mod = self.dg.module;
6285 if (isByRef(operand_ty, mod)) {
6247 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);6286 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);
6248 } else if (self.dg.module.comp.bin_file.options.optimize_mode == .Debug) {6287 } 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);
6250 const alloca = self.buildAlloca(operand.typeOf(), alignment);6289 const alloca = self.buildAlloca(operand.typeOf(), alignment);
6251 const store_inst = self.builder.buildStore(operand, alloca);6290 const store_inst = self.builder.buildStore(operand, alloca);
6252 store_inst.setAlignment(alignment);6291 store_inst.setAlignment(alignment);
...@@ -6294,7 +6333,8 @@ pub const FuncGen = struct {...@@ -6294,7 +6333,8 @@ pub const FuncGen = struct {
6294 // This stores whether we need to add an elementtype attribute and6333 // This stores whether we need to add an elementtype attribute and
6295 // if so, the element type itself.6334 // if so, the element type itself.
6296 const llvm_param_attrs = try arena.alloc(?*llvm.Type, max_param_count);6335 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
6299 var llvm_ret_i: usize = 0;6339 var llvm_ret_i: usize = 0;
6300 var llvm_param_i: usize = 0;6340 var llvm_param_i: usize = 0;
...@@ -6322,7 +6362,7 @@ pub const FuncGen = struct {...@@ -6322,7 +6362,7 @@ pub const FuncGen = struct {
6322 if (output != .none) {6362 if (output != .none) {
6323 const output_inst = try self.resolveInst(output);6363 const output_inst = try self.resolveInst(output);
6324 const output_ty = self.air.typeOf(output);6364 const output_ty = self.air.typeOf(output);
6325 assert(output_ty.zigTypeTag() == .Pointer);6365 assert(output_ty.zigTypeTag(mod) == .Pointer);
6326 const elem_llvm_ty = try self.dg.lowerPtrElemTy(output_ty.childType());6366 const elem_llvm_ty = try self.dg.lowerPtrElemTy(output_ty.childType());
63276367
6328 if (llvm_ret_indirect[i]) {6368 if (llvm_ret_indirect[i]) {
...@@ -6376,13 +6416,13 @@ pub const FuncGen = struct {...@@ -6376,13 +6416,13 @@ pub const FuncGen = struct {
6376 const arg_llvm_value = try self.resolveInst(input);6416 const arg_llvm_value = try self.resolveInst(input);
6377 const arg_ty = self.air.typeOf(input);6417 const arg_ty = self.air.typeOf(input);
6378 var llvm_elem_ty: ?*llvm.Type = null;6418 var llvm_elem_ty: ?*llvm.Type = null;
6379 if (isByRef(arg_ty)) {6419 if (isByRef(arg_ty, mod)) {
6380 llvm_elem_ty = try self.dg.lowerPtrElemTy(arg_ty);6420 llvm_elem_ty = try self.dg.lowerPtrElemTy(arg_ty);
6381 if (constraintAllowsMemory(constraint)) {6421 if (constraintAllowsMemory(constraint)) {
6382 llvm_param_values[llvm_param_i] = arg_llvm_value;6422 llvm_param_values[llvm_param_i] = arg_llvm_value;
6383 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();6423 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
6384 } else {6424 } else {
6385 const alignment = arg_ty.abiAlignment(target);6425 const alignment = arg_ty.abiAlignment(mod);
6386 const arg_llvm_ty = try self.dg.lowerType(arg_ty);6426 const arg_llvm_ty = try self.dg.lowerType(arg_ty);
6387 const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, "");6427 const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, "");
6388 load_inst.setAlignment(alignment);6428 load_inst.setAlignment(alignment);
...@@ -6394,7 +6434,7 @@ pub const FuncGen = struct {...@@ -6394,7 +6434,7 @@ pub const FuncGen = struct {
6394 llvm_param_values[llvm_param_i] = arg_llvm_value;6434 llvm_param_values[llvm_param_i] = arg_llvm_value;
6395 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();6435 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
6396 } else {6436 } else {
6397 const alignment = arg_ty.abiAlignment(target);6437 const alignment = arg_ty.abiAlignment(mod);
6398 const arg_ptr = self.buildAlloca(arg_llvm_value.typeOf(), alignment);6438 const arg_ptr = self.buildAlloca(arg_llvm_value.typeOf(), alignment);
6399 const store_inst = self.builder.buildStore(arg_llvm_value, arg_ptr);6439 const store_inst = self.builder.buildStore(arg_llvm_value, arg_ptr);
6400 store_inst.setAlignment(alignment);6440 store_inst.setAlignment(alignment);
...@@ -6599,7 +6639,7 @@ pub const FuncGen = struct {...@@ -6599,7 +6639,7 @@ pub const FuncGen = struct {
6599 const output_ptr_ty = self.air.typeOf(output);6639 const output_ptr_ty = self.air.typeOf(output);
66006640
6601 const store_inst = self.builder.buildStore(output_value, output_ptr);6641 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));
6603 } else {6643 } else {
6604 ret_val = output_value;6644 ret_val = output_value;
6605 }6645 }
...@@ -6622,7 +6662,8 @@ pub const FuncGen = struct {...@@ -6622,7 +6662,8 @@ pub const FuncGen = struct {
6622 const optional_llvm_ty = try self.dg.lowerType(optional_ty);6662 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
6623 var buf: Type.Payload.ElemType = undefined;6663 var buf: Type.Payload.ElemType = undefined;
6624 const payload_ty = optional_ty.optionalChild(&buf);6664 const payload_ty = optional_ty.optionalChild(&buf);
6625 if (optional_ty.optionalReprIsPayload()) {6665 const mod = self.dg.module;
6666 if (optional_ty.optionalReprIsPayload(mod)) {
6626 const loaded = if (operand_is_ptr)6667 const loaded = if (operand_is_ptr)
6627 self.builder.buildLoad(optional_llvm_ty, operand, "")6668 self.builder.buildLoad(optional_llvm_ty, operand, "")
6628 else6669 else
...@@ -6638,7 +6679,7 @@ pub const FuncGen = struct {...@@ -6638,7 +6679,7 @@ pub const FuncGen = struct {
66386679
6639 comptime assert(optional_layout_version == 3);6680 comptime assert(optional_layout_version == 3);
66406681
6641 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6682 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6642 const loaded = if (operand_is_ptr)6683 const loaded = if (operand_is_ptr)
6643 self.builder.buildLoad(optional_llvm_ty, operand, "")6684 self.builder.buildLoad(optional_llvm_ty, operand, "")
6644 else6685 else
...@@ -6647,7 +6688,7 @@ pub const FuncGen = struct {...@@ -6647,7 +6688,7 @@ pub const FuncGen = struct {
6647 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");6688 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");
6648 }6689 }
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);
6651 const non_null_bit = self.optIsNonNull(optional_llvm_ty, operand, is_by_ref);6692 const non_null_bit = self.optIsNonNull(optional_llvm_ty, operand, is_by_ref);
6652 if (pred == .EQ) {6693 if (pred == .EQ) {
6653 return self.builder.buildNot(non_null_bit, "");6694 return self.builder.buildNot(non_null_bit, "");
...@@ -6662,6 +6703,7 @@ pub const FuncGen = struct {...@@ -6662,6 +6703,7 @@ pub const FuncGen = struct {
6662 op: llvm.IntPredicate,6703 op: llvm.IntPredicate,
6663 operand_is_ptr: bool,6704 operand_is_ptr: bool,
6664 ) !?*llvm.Value {6705 ) !?*llvm.Value {
6706 const mod = self.dg.module;
6665 const un_op = self.air.instructions.items(.data)[inst].un_op;6707 const un_op = self.air.instructions.items(.data)[inst].un_op;
6666 const operand = try self.resolveInst(un_op);6708 const operand = try self.resolveInst(un_op);
6667 const operand_ty = self.air.typeOf(un_op);6709 const operand_ty = self.air.typeOf(un_op);
...@@ -6679,7 +6721,7 @@ pub const FuncGen = struct {...@@ -6679,7 +6721,7 @@ pub const FuncGen = struct {
6679 }6721 }
6680 }6722 }
66816723
6682 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6724 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6683 const loaded = if (operand_is_ptr)6725 const loaded = if (operand_is_ptr)
6684 self.builder.buildLoad(try self.dg.lowerType(err_union_ty), operand, "")6726 self.builder.buildLoad(try self.dg.lowerType(err_union_ty), operand, "")
6685 else6727 else
...@@ -6687,10 +6729,9 @@ pub const FuncGen = struct {...@@ -6687,10 +6729,9 @@ pub const FuncGen = struct {
6687 return self.builder.buildICmp(op, loaded, zero, "");6729 return self.builder.buildICmp(op, loaded, zero, "");
6688 }6730 }
66896731
6690 const target = self.dg.module.getTarget();6732 const err_field_index = errUnionErrorOffset(payload_ty, mod);
6691 const err_field_index = errUnionErrorOffset(payload_ty, target);
66926733
6693 if (operand_is_ptr or isByRef(err_union_ty)) {6734 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
6694 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);6735 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
6695 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, "");6736 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, "");
6696 const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, "");6737 const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, "");
...@@ -6702,17 +6743,18 @@ pub const FuncGen = struct {...@@ -6702,17 +6743,18 @@ pub const FuncGen = struct {
6702 }6743 }
67036744
6704 fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6745 fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6746 const mod = self.dg.module;
6705 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6747 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6706 const operand = try self.resolveInst(ty_op.operand);6748 const operand = try self.resolveInst(ty_op.operand);
6707 const optional_ty = self.air.typeOf(ty_op.operand).childType();6749 const optional_ty = self.air.typeOf(ty_op.operand).childType();
6708 var buf: Type.Payload.ElemType = undefined;6750 var buf: Type.Payload.ElemType = undefined;
6709 const payload_ty = optional_ty.optionalChild(&buf);6751 const payload_ty = optional_ty.optionalChild(&buf);
6710 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6752 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6711 // We have a pointer to a zero-bit value and we need to return6753 // We have a pointer to a zero-bit value and we need to return
6712 // a pointer to a zero-bit value.6754 // a pointer to a zero-bit value.
6713 return operand;6755 return operand;
6714 }6756 }
6715 if (optional_ty.optionalReprIsPayload()) {6757 if (optional_ty.optionalReprIsPayload(mod)) {
6716 // The payload and the optional are the same value.6758 // The payload and the optional are the same value.
6717 return operand;6759 return operand;
6718 }6760 }
...@@ -6723,18 +6765,19 @@ pub const FuncGen = struct {...@@ -6723,18 +6765,19 @@ pub const FuncGen = struct {
6723 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6765 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6724 comptime assert(optional_layout_version == 3);6766 comptime assert(optional_layout_version == 3);
67256767
6768 const mod = self.dg.module;
6726 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6769 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6727 const operand = try self.resolveInst(ty_op.operand);6770 const operand = try self.resolveInst(ty_op.operand);
6728 const optional_ty = self.air.typeOf(ty_op.operand).childType();6771 const optional_ty = self.air.typeOf(ty_op.operand).childType();
6729 var buf: Type.Payload.ElemType = undefined;6772 var buf: Type.Payload.ElemType = undefined;
6730 const payload_ty = optional_ty.optionalChild(&buf);6773 const payload_ty = optional_ty.optionalChild(&buf);
6731 const non_null_bit = self.context.intType(8).constInt(1, .False);6774 const non_null_bit = self.context.intType(8).constInt(1, .False);
6732 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6775 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6733 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.6776 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
6734 _ = self.builder.buildStore(non_null_bit, operand);6777 _ = self.builder.buildStore(non_null_bit, operand);
6735 return operand;6778 return operand;
6736 }6779 }
6737 if (optional_ty.optionalReprIsPayload()) {6780 if (optional_ty.optionalReprIsPayload(mod)) {
6738 // The payload and the optional are the same value.6781 // The payload and the optional are the same value.
6739 // Setting to non-null will be done when the payload is set.6782 // Setting to non-null will be done when the payload is set.
6740 return operand;6783 return operand;
...@@ -6754,20 +6797,21 @@ pub const FuncGen = struct {...@@ -6754,20 +6797,21 @@ pub const FuncGen = struct {
6754 }6797 }
67556798
6756 fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {6799 fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
6800 const mod = self.dg.module;
6757 const inst = body_tail[0];6801 const inst = body_tail[0];
6758 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6802 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6759 const operand = try self.resolveInst(ty_op.operand);6803 const operand = try self.resolveInst(ty_op.operand);
6760 const optional_ty = self.air.typeOf(ty_op.operand);6804 const optional_ty = self.air.typeOf(ty_op.operand);
6761 const payload_ty = self.air.typeOfIndex(inst);6805 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)) {
6765 // Payload value is the same as the optional value.6809 // Payload value is the same as the optional value.
6766 return operand;6810 return operand;
6767 }6811 }
67686812
6769 const opt_llvm_ty = try self.dg.lowerType(optional_ty);6813 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;
6771 return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load);6815 return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load);
6772 }6816 }
67736817
...@@ -6776,6 +6820,7 @@ pub const FuncGen = struct {...@@ -6776,6 +6820,7 @@ pub const FuncGen = struct {
6776 body_tail: []const Air.Inst.Index,6820 body_tail: []const Air.Inst.Index,
6777 operand_is_ptr: bool,6821 operand_is_ptr: bool,
6778 ) !?*llvm.Value {6822 ) !?*llvm.Value {
6823 const mod = self.dg.module;
6779 const inst = body_tail[0];6824 const inst = body_tail[0];
6780 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6825 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6781 const operand = try self.resolveInst(ty_op.operand);6826 const operand = try self.resolveInst(ty_op.operand);
...@@ -6783,25 +6828,24 @@ pub const FuncGen = struct {...@@ -6783,25 +6828,24 @@ pub const FuncGen = struct {
6783 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;6828 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
6784 const result_ty = self.air.typeOfIndex(inst);6829 const result_ty = self.air.typeOfIndex(inst);
6785 const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty;6830 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)) {
6789 return if (operand_is_ptr) operand else null;6833 return if (operand_is_ptr) operand else null;
6790 }6834 }
6791 const offset = errUnionPayloadOffset(payload_ty, target);6835 const offset = errUnionPayloadOffset(payload_ty, mod);
6792 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);6836 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
6793 if (operand_is_ptr) {6837 if (operand_is_ptr) {
6794 return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");6838 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)) {
6796 const payload_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");6840 const payload_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
6797 if (isByRef(payload_ty)) {6841 if (isByRef(payload_ty, mod)) {
6798 if (self.canElideLoad(body_tail))6842 if (self.canElideLoad(body_tail))
6799 return payload_ptr;6843 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);
6802 }6846 }
6803 const load_inst = self.builder.buildLoad(err_union_llvm_ty.structGetTypeAtIndex(offset), payload_ptr, "");6847 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));
6805 return load_inst;6849 return load_inst;
6806 }6850 }
6807 return self.builder.buildExtractValue(operand, offset, "");6851 return self.builder.buildExtractValue(operand, offset, "");
...@@ -6812,6 +6856,7 @@ pub const FuncGen = struct {...@@ -6812,6 +6856,7 @@ pub const FuncGen = struct {
6812 inst: Air.Inst.Index,6856 inst: Air.Inst.Index,
6813 operand_is_ptr: bool,6857 operand_is_ptr: bool,
6814 ) !?*llvm.Value {6858 ) !?*llvm.Value {
6859 const mod = self.dg.module;
6815 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6860 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6816 const operand = try self.resolveInst(ty_op.operand);6861 const operand = try self.resolveInst(ty_op.operand);
6817 const operand_ty = self.air.typeOf(ty_op.operand);6862 const operand_ty = self.air.typeOf(ty_op.operand);
...@@ -6828,15 +6873,14 @@ pub const FuncGen = struct {...@@ -6828,15 +6873,14 @@ pub const FuncGen = struct {
6828 const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror);6873 const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror);
68296874
6830 const payload_ty = err_union_ty.errorUnionPayload();6875 const payload_ty = err_union_ty.errorUnionPayload();
6831 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6876 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6832 if (!operand_is_ptr) return operand;6877 if (!operand_is_ptr) return operand;
6833 return self.builder.buildLoad(err_set_llvm_ty, operand, "");6878 return self.builder.buildLoad(err_set_llvm_ty, operand, "");
6834 }6879 }
68356880
6836 const target = self.dg.module.getTarget();6881 const offset = errUnionErrorOffset(payload_ty, mod);
6837 const offset = errUnionErrorOffset(payload_ty, target);
68386882
6839 if (operand_is_ptr or isByRef(err_union_ty)) {6883 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
6840 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);6884 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
6841 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");6885 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
6842 return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, "");6886 return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, "");
...@@ -6846,30 +6890,30 @@ pub const FuncGen = struct {...@@ -6846,30 +6890,30 @@ pub const FuncGen = struct {
6846 }6890 }
68476891
6848 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6892 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6893 const mod = self.dg.module;
6849 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6894 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6850 const operand = try self.resolveInst(ty_op.operand);6895 const operand = try self.resolveInst(ty_op.operand);
6851 const err_union_ty = self.air.typeOf(ty_op.operand).childType();6896 const err_union_ty = self.air.typeOf(ty_op.operand).childType();
68526897
6853 const payload_ty = err_union_ty.errorUnionPayload();6898 const payload_ty = err_union_ty.errorUnionPayload();
6854 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero });6899 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)) {
6856 _ = self.builder.buildStore(non_error_val, operand);6901 _ = self.builder.buildStore(non_error_val, operand);
6857 return operand;6902 return operand;
6858 }6903 }
6859 const target = self.dg.module.getTarget();
6860 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);6904 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
6861 {6905 {
6862 const error_offset = errUnionErrorOffset(payload_ty, target);6906 const error_offset = errUnionErrorOffset(payload_ty, mod);
6863 // First set the non-error value.6907 // First set the non-error value.
6864 const non_null_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, error_offset, "");6908 const non_null_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, error_offset, "");
6865 const store_inst = self.builder.buildStore(non_error_val, non_null_ptr);6909 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));
6867 }6911 }
6868 // Then return the payload pointer (only if it is used).6912 // Then return the payload pointer (only if it is used).
6869 if (self.liveness.isUnused(inst))6913 if (self.liveness.isUnused(inst))
6870 return null;6914 return null;
68716915
6872 const payload_offset = errUnionPayloadOffset(payload_ty, target);6916 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
6873 return self.builder.buildStructGEP(err_union_llvm_ty, operand, payload_offset, "");6917 return self.builder.buildStructGEP(err_union_llvm_ty, operand, payload_offset, "");
6874 }6918 }
68756919
...@@ -6885,15 +6929,14 @@ pub const FuncGen = struct {...@@ -6885,15 +6929,14 @@ pub const FuncGen = struct {
6885 }6929 }
68866930
6887 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6931 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6888 const target = self.dg.module.getTarget();
6889
6890 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;6932 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
6891 //const struct_ty = try self.resolveInst(ty_pl.ty);6933 //const struct_ty = try self.resolveInst(ty_pl.ty);
6892 const struct_ty = self.air.getRefType(ty_pl.ty);6934 const struct_ty = self.air.getRefType(ty_pl.ty);
6893 const field_index = ty_pl.payload;6935 const field_index = ty_pl.payload;
68946936
6895 var ptr_ty_buf: Type.Payload.Pointer = undefined;6937 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).?;
6897 const struct_llvm_ty = try self.dg.lowerType(struct_ty);6940 const struct_llvm_ty = try self.dg.lowerType(struct_ty);
6898 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field_index, "");6941 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field_index, "");
6899 const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base);6942 const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base);
...@@ -6901,20 +6944,20 @@ pub const FuncGen = struct {...@@ -6901,20 +6944,20 @@ pub const FuncGen = struct {
6901 }6944 }
69026945
6903 fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6946 fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6947 const mod = self.dg.module;
6904 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6948 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6905 const payload_ty = self.air.typeOf(ty_op.operand);6949 const payload_ty = self.air.typeOf(ty_op.operand);
6906 const non_null_bit = self.context.intType(8).constInt(1, .False);6950 const non_null_bit = self.context.intType(8).constInt(1, .False);
6907 comptime assert(optional_layout_version == 3);6951 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;
6909 const operand = try self.resolveInst(ty_op.operand);6953 const operand = try self.resolveInst(ty_op.operand);
6910 const optional_ty = self.air.typeOfIndex(inst);6954 const optional_ty = self.air.typeOfIndex(inst);
6911 if (optional_ty.optionalReprIsPayload()) {6955 if (optional_ty.optionalReprIsPayload(mod)) {
6912 return operand;6956 return operand;
6913 }6957 }
6914 const llvm_optional_ty = try self.dg.lowerType(optional_ty);6958 const llvm_optional_ty = try self.dg.lowerType(optional_ty);
6915 if (isByRef(optional_ty)) {6959 if (isByRef(optional_ty, mod)) {
6916 const target = self.dg.module.getTarget();6960 const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod));
6917 const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(target));
6918 const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, "");6961 const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, "");
6919 var ptr_ty_payload: Type.Payload.ElemType = .{6962 var ptr_ty_payload: Type.Payload.ElemType = .{
6920 .base = .{ .tag = .single_mut_pointer },6963 .base = .{ .tag = .single_mut_pointer },
...@@ -6931,24 +6974,24 @@ pub const FuncGen = struct {...@@ -6931,24 +6974,24 @@ pub const FuncGen = struct {
6931 }6974 }
69326975
6933 fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6976 fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6977 const mod = self.dg.module;
6934 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6978 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6935 const err_un_ty = self.air.typeOfIndex(inst);6979 const err_un_ty = self.air.typeOfIndex(inst);
6936 const operand = try self.resolveInst(ty_op.operand);6980 const operand = try self.resolveInst(ty_op.operand);
6937 const payload_ty = self.air.typeOf(ty_op.operand);6981 const payload_ty = self.air.typeOf(ty_op.operand);
6938 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6982 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6939 return operand;6983 return operand;
6940 }6984 }
6941 const ok_err_code = (try self.dg.lowerType(Type.anyerror)).constNull();6985 const ok_err_code = (try self.dg.lowerType(Type.anyerror)).constNull();
6942 const err_un_llvm_ty = try self.dg.lowerType(err_un_ty);6986 const err_un_llvm_ty = try self.dg.lowerType(err_un_ty);
69436987
6944 const target = self.dg.module.getTarget();6988 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
6945 const payload_offset = errUnionPayloadOffset(payload_ty, target);6989 const error_offset = errUnionErrorOffset(payload_ty, mod);
6946 const error_offset = errUnionErrorOffset(payload_ty, target);6990 if (isByRef(err_un_ty, mod)) {
6947 if (isByRef(err_un_ty)) {6991 const result_ptr = self.buildAlloca(err_un_llvm_ty, err_un_ty.abiAlignment(mod));
6948 const result_ptr = self.buildAlloca(err_un_llvm_ty, err_un_ty.abiAlignment(target));
6949 const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");6992 const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");
6950 const store_inst = self.builder.buildStore(ok_err_code, err_ptr);6993 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));
6952 const payload_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, payload_offset, "");6995 const payload_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, payload_offset, "");
6953 var ptr_ty_payload: Type.Payload.ElemType = .{6996 var ptr_ty_payload: Type.Payload.ElemType = .{
6954 .base = .{ .tag = .single_mut_pointer },6997 .base = .{ .tag = .single_mut_pointer },
...@@ -6964,23 +7007,23 @@ pub const FuncGen = struct {...@@ -6964,23 +7007,23 @@ pub const FuncGen = struct {
6964 }7007 }
69657008
6966 fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7009 fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7010 const mod = self.dg.module;
6967 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7011 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6968 const err_un_ty = self.air.typeOfIndex(inst);7012 const err_un_ty = self.air.typeOfIndex(inst);
6969 const payload_ty = err_un_ty.errorUnionPayload();7013 const payload_ty = err_un_ty.errorUnionPayload();
6970 const operand = try self.resolveInst(ty_op.operand);7014 const operand = try self.resolveInst(ty_op.operand);
6971 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {7015 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6972 return operand;7016 return operand;
6973 }7017 }
6974 const err_un_llvm_ty = try self.dg.lowerType(err_un_ty);7018 const err_un_llvm_ty = try self.dg.lowerType(err_un_ty);
69757019
6976 const target = self.dg.module.getTarget();7020 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
6977 const payload_offset = errUnionPayloadOffset(payload_ty, target);7021 const error_offset = errUnionErrorOffset(payload_ty, mod);
6978 const error_offset = errUnionErrorOffset(payload_ty, target);7022 if (isByRef(err_un_ty, mod)) {
6979 if (isByRef(err_un_ty)) {7023 const result_ptr = self.buildAlloca(err_un_llvm_ty, err_un_ty.abiAlignment(mod));
6980 const result_ptr = self.buildAlloca(err_un_llvm_ty, err_un_ty.abiAlignment(target));
6981 const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");7024 const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");
6982 const store_inst = self.builder.buildStore(operand, err_ptr);7025 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));
6984 const payload_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, payload_offset, "");7027 const payload_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, payload_offset, "");
6985 var ptr_ty_payload: Type.Payload.ElemType = .{7028 var ptr_ty_payload: Type.Payload.ElemType = .{
6986 .base = .{ .tag = .single_mut_pointer },7029 .base = .{ .tag = .single_mut_pointer },
...@@ -7021,6 +7064,7 @@ pub const FuncGen = struct {...@@ -7021,6 +7064,7 @@ pub const FuncGen = struct {
7021 }7064 }
70227065
7023 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7066 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7067 const mod = self.dg.module;
7024 const data = self.air.instructions.items(.data)[inst].vector_store_elem;7068 const data = self.air.instructions.items(.data)[inst].vector_store_elem;
7025 const extra = self.air.extraData(Air.Bin, data.payload).data;7069 const extra = self.air.extraData(Air.Bin, data.payload).data;
70267070
...@@ -7032,8 +7076,7 @@ pub const FuncGen = struct {...@@ -7032,8 +7076,7 @@ pub const FuncGen = struct {
7032 const loaded_vector = blk: {7076 const loaded_vector = blk: {
7033 const elem_llvm_ty = try self.dg.lowerType(vector_ptr_ty.childType());7077 const elem_llvm_ty = try self.dg.lowerType(vector_ptr_ty.childType());
7034 const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, "");7078 const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, "");
7035 const target = self.dg.module.getTarget();7079 load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod));
7036 load_inst.setAlignment(vector_ptr_ty.ptrAlignment(target));
7037 load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr()));7080 load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr()));
7038 break :blk load_inst;7081 break :blk load_inst;
7039 };7082 };
...@@ -7043,24 +7086,26 @@ pub const FuncGen = struct {...@@ -7043,24 +7086,26 @@ pub const FuncGen = struct {
7043 }7086 }
70447087
7045 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7088 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7089 const mod = self.dg.module;
7046 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7090 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7047 const lhs = try self.resolveInst(bin_op.lhs);7091 const lhs = try self.resolveInst(bin_op.lhs);
7048 const rhs = try self.resolveInst(bin_op.rhs);7092 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
7051 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmin, scalar_ty, 2, .{ lhs, rhs });7095 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, "");
7053 return self.builder.buildUMin(lhs, rhs, "");7097 return self.builder.buildUMin(lhs, rhs, "");
7054 }7098 }
70557099
7056 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7100 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7101 const mod = self.dg.module;
7057 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7102 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7058 const lhs = try self.resolveInst(bin_op.lhs);7103 const lhs = try self.resolveInst(bin_op.lhs);
7059 const rhs = try self.resolveInst(bin_op.rhs);7104 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
7062 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmax, scalar_ty, 2, .{ lhs, rhs });7107 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, "");
7064 return self.builder.buildUMax(lhs, rhs, "");7109 return self.builder.buildUMax(lhs, rhs, "");
7065 }7110 }
70667111
...@@ -7081,14 +7126,15 @@ pub const FuncGen = struct {...@@ -7081,14 +7126,15 @@ pub const FuncGen = struct {
7081 fn airAdd(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7126 fn airAdd(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7082 self.builder.setFastMath(want_fast_math);7127 self.builder.setFastMath(want_fast_math);
70837128
7129 const mod = self.dg.module;
7084 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7130 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7085 const lhs = try self.resolveInst(bin_op.lhs);7131 const lhs = try self.resolveInst(bin_op.lhs);
7086 const rhs = try self.resolveInst(bin_op.rhs);7132 const rhs = try self.resolveInst(bin_op.rhs);
7087 const inst_ty = self.air.typeOfIndex(inst);7133 const inst_ty = self.air.typeOfIndex(inst);
7088 const scalar_ty = inst_ty.scalarType();7134 const scalar_ty = inst_ty.scalarType(mod);
70897135
7090 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.add, inst_ty, 2, .{ lhs, rhs });7136 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, "");
7092 return self.builder.buildNUWAdd(lhs, rhs, "");7138 return self.builder.buildNUWAdd(lhs, rhs, "");
7093 }7139 }
70947140
...@@ -7103,14 +7149,15 @@ pub const FuncGen = struct {...@@ -7103,14 +7149,15 @@ pub const FuncGen = struct {
7103 }7149 }
71047150
7105 fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7151 fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7152 const mod = self.dg.module;
7106 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7153 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7107 const lhs = try self.resolveInst(bin_op.lhs);7154 const lhs = try self.resolveInst(bin_op.lhs);
7108 const rhs = try self.resolveInst(bin_op.rhs);7155 const rhs = try self.resolveInst(bin_op.rhs);
7109 const inst_ty = self.air.typeOfIndex(inst);7156 const inst_ty = self.air.typeOfIndex(inst);
7110 const scalar_ty = inst_ty.scalarType();7157 const scalar_ty = inst_ty.scalarType(mod);
71117158
7112 if (scalar_ty.isAnyFloat()) return self.todo("saturating float add", .{});7159 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
7115 return self.builder.buildUAddSat(lhs, rhs, "");7162 return self.builder.buildUAddSat(lhs, rhs, "");
7116 }7163 }
...@@ -7118,14 +7165,15 @@ pub const FuncGen = struct {...@@ -7118,14 +7165,15 @@ pub const FuncGen = struct {
7118 fn airSub(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7165 fn airSub(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7119 self.builder.setFastMath(want_fast_math);7166 self.builder.setFastMath(want_fast_math);
71207167
7168 const mod = self.dg.module;
7121 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7169 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7122 const lhs = try self.resolveInst(bin_op.lhs);7170 const lhs = try self.resolveInst(bin_op.lhs);
7123 const rhs = try self.resolveInst(bin_op.rhs);7171 const rhs = try self.resolveInst(bin_op.rhs);
7124 const inst_ty = self.air.typeOfIndex(inst);7172 const inst_ty = self.air.typeOfIndex(inst);
7125 const scalar_ty = inst_ty.scalarType();7173 const scalar_ty = inst_ty.scalarType(mod);
71267174
7127 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.sub, inst_ty, 2, .{ lhs, rhs });7175 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, "");
7129 return self.builder.buildNUWSub(lhs, rhs, "");7177 return self.builder.buildNUWSub(lhs, rhs, "");
7130 }7178 }
71317179
...@@ -7140,28 +7188,30 @@ pub const FuncGen = struct {...@@ -7140,28 +7188,30 @@ pub const FuncGen = struct {
7140 }7188 }
71417189
7142 fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7190 fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7191 const mod = self.dg.module;
7143 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7192 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7144 const lhs = try self.resolveInst(bin_op.lhs);7193 const lhs = try self.resolveInst(bin_op.lhs);
7145 const rhs = try self.resolveInst(bin_op.rhs);7194 const rhs = try self.resolveInst(bin_op.rhs);
7146 const inst_ty = self.air.typeOfIndex(inst);7195 const inst_ty = self.air.typeOfIndex(inst);
7147 const scalar_ty = inst_ty.scalarType();7196 const scalar_ty = inst_ty.scalarType(mod);
71487197
7149 if (scalar_ty.isAnyFloat()) return self.todo("saturating float sub", .{});7198 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, "");
7151 return self.builder.buildUSubSat(lhs, rhs, "");7200 return self.builder.buildUSubSat(lhs, rhs, "");
7152 }7201 }
71537202
7154 fn airMul(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7203 fn airMul(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7155 self.builder.setFastMath(want_fast_math);7204 self.builder.setFastMath(want_fast_math);
71567205
7206 const mod = self.dg.module;
7157 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7207 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7158 const lhs = try self.resolveInst(bin_op.lhs);7208 const lhs = try self.resolveInst(bin_op.lhs);
7159 const rhs = try self.resolveInst(bin_op.rhs);7209 const rhs = try self.resolveInst(bin_op.rhs);
7160 const inst_ty = self.air.typeOfIndex(inst);7210 const inst_ty = self.air.typeOfIndex(inst);
7161 const scalar_ty = inst_ty.scalarType();7211 const scalar_ty = inst_ty.scalarType(mod);
71627212
7163 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.mul, inst_ty, 2, .{ lhs, rhs });7213 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, "");
7165 return self.builder.buildNUWMul(lhs, rhs, "");7215 return self.builder.buildNUWMul(lhs, rhs, "");
7166 }7216 }
71677217
...@@ -7176,14 +7226,15 @@ pub const FuncGen = struct {...@@ -7176,14 +7226,15 @@ pub const FuncGen = struct {
7176 }7226 }
71777227
7178 fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7228 fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7229 const mod = self.dg.module;
7179 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7230 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7180 const lhs = try self.resolveInst(bin_op.lhs);7231 const lhs = try self.resolveInst(bin_op.lhs);
7181 const rhs = try self.resolveInst(bin_op.rhs);7232 const rhs = try self.resolveInst(bin_op.rhs);
7182 const inst_ty = self.air.typeOfIndex(inst);7233 const inst_ty = self.air.typeOfIndex(inst);
7183 const scalar_ty = inst_ty.scalarType();7234 const scalar_ty = inst_ty.scalarType(mod);
71847235
7185 if (scalar_ty.isAnyFloat()) return self.todo("saturating float mul", .{});7236 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, "");
7187 return self.builder.buildUMulFixSat(lhs, rhs, "");7238 return self.builder.buildUMulFixSat(lhs, rhs, "");
7188 }7239 }
71897240
...@@ -7201,38 +7252,39 @@ pub const FuncGen = struct {...@@ -7201,38 +7252,39 @@ pub const FuncGen = struct {
7201 fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7252 fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7202 self.builder.setFastMath(want_fast_math);7253 self.builder.setFastMath(want_fast_math);
72037254
7255 const mod = self.dg.module;
7204 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7256 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7205 const lhs = try self.resolveInst(bin_op.lhs);7257 const lhs = try self.resolveInst(bin_op.lhs);
7206 const rhs = try self.resolveInst(bin_op.rhs);7258 const rhs = try self.resolveInst(bin_op.rhs);
7207 const inst_ty = self.air.typeOfIndex(inst);7259 const inst_ty = self.air.typeOfIndex(inst);
7208 const scalar_ty = inst_ty.scalarType();7260 const scalar_ty = inst_ty.scalarType(mod);
72097261
7210 if (scalar_ty.isRuntimeFloat()) {7262 if (scalar_ty.isRuntimeFloat()) {
7211 const result = try self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });7263 const result = try self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });
7212 return self.buildFloatOp(.trunc, inst_ty, 1, .{result});7264 return self.buildFloatOp(.trunc, inst_ty, 1, .{result});
7213 }7265 }
7214 if (scalar_ty.isSignedInt()) return self.builder.buildSDiv(lhs, rhs, "");7266 if (scalar_ty.isSignedInt(mod)) return self.builder.buildSDiv(lhs, rhs, "");
7215 return self.builder.buildUDiv(lhs, rhs, "");7267 return self.builder.buildUDiv(lhs, rhs, "");
7216 }7268 }
72177269
7218 fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7270 fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7219 self.builder.setFastMath(want_fast_math);7271 self.builder.setFastMath(want_fast_math);
72207272
7273 const mod = self.dg.module;
7221 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7274 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7222 const lhs = try self.resolveInst(bin_op.lhs);7275 const lhs = try self.resolveInst(bin_op.lhs);
7223 const rhs = try self.resolveInst(bin_op.rhs);7276 const rhs = try self.resolveInst(bin_op.rhs);
7224 const inst_ty = self.air.typeOfIndex(inst);7277 const inst_ty = self.air.typeOfIndex(inst);
7225 const scalar_ty = inst_ty.scalarType();7278 const scalar_ty = inst_ty.scalarType(mod);
72267279
7227 if (scalar_ty.isRuntimeFloat()) {7280 if (scalar_ty.isRuntimeFloat()) {
7228 const result = try self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });7281 const result = try self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });
7229 return self.buildFloatOp(.floor, inst_ty, 1, .{result});7282 return self.buildFloatOp(.floor, inst_ty, 1, .{result});
7230 }7283 }
7231 if (scalar_ty.isSignedInt()) {7284 if (scalar_ty.isSignedInt(mod)) {
7232 const target = self.dg.module.getTarget();
7233 const inst_llvm_ty = try self.dg.lowerType(inst_ty);7285 const inst_llvm_ty = try self.dg.lowerType(inst_ty);
7234 const scalar_bit_size_minus_one = scalar_ty.bitSize(target) - 1;7286 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;
7235 const bit_size_minus_one = if (inst_ty.zigTypeTag() == .Vector) const_vector: {7287 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {
7236 const vec_len = inst_ty.vectorLen();7288 const vec_len = inst_ty.vectorLen();
7237 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);7289 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
72387290
...@@ -7258,40 +7310,43 @@ pub const FuncGen = struct {...@@ -7258,40 +7310,43 @@ pub const FuncGen = struct {
7258 fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7310 fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7259 self.builder.setFastMath(want_fast_math);7311 self.builder.setFastMath(want_fast_math);
72607312
7313 const mod = self.dg.module;
7261 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7314 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7262 const lhs = try self.resolveInst(bin_op.lhs);7315 const lhs = try self.resolveInst(bin_op.lhs);
7263 const rhs = try self.resolveInst(bin_op.rhs);7316 const rhs = try self.resolveInst(bin_op.rhs);
7264 const inst_ty = self.air.typeOfIndex(inst);7317 const inst_ty = self.air.typeOfIndex(inst);
7265 const scalar_ty = inst_ty.scalarType();7318 const scalar_ty = inst_ty.scalarType(mod);
72667319
7267 if (scalar_ty.isRuntimeFloat()) return self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });7320 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, "");
7269 return self.builder.buildExactUDiv(lhs, rhs, "");7322 return self.builder.buildExactUDiv(lhs, rhs, "");
7270 }7323 }
72717324
7272 fn airRem(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7325 fn airRem(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7273 self.builder.setFastMath(want_fast_math);7326 self.builder.setFastMath(want_fast_math);
72747327
7328 const mod = self.dg.module;
7275 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7329 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7276 const lhs = try self.resolveInst(bin_op.lhs);7330 const lhs = try self.resolveInst(bin_op.lhs);
7277 const rhs = try self.resolveInst(bin_op.rhs);7331 const rhs = try self.resolveInst(bin_op.rhs);
7278 const inst_ty = self.air.typeOfIndex(inst);7332 const inst_ty = self.air.typeOfIndex(inst);
7279 const scalar_ty = inst_ty.scalarType();7333 const scalar_ty = inst_ty.scalarType(mod);
72807334
7281 if (scalar_ty.isRuntimeFloat()) return self.buildFloatOp(.fmod, inst_ty, 2, .{ lhs, rhs });7335 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, "");
7283 return self.builder.buildURem(lhs, rhs, "");7337 return self.builder.buildURem(lhs, rhs, "");
7284 }7338 }
72857339
7286 fn airMod(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7340 fn airMod(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7287 self.builder.setFastMath(want_fast_math);7341 self.builder.setFastMath(want_fast_math);
72887342
7343 const mod = self.dg.module;
7289 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7344 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7290 const lhs = try self.resolveInst(bin_op.lhs);7345 const lhs = try self.resolveInst(bin_op.lhs);
7291 const rhs = try self.resolveInst(bin_op.rhs);7346 const rhs = try self.resolveInst(bin_op.rhs);
7292 const inst_ty = self.air.typeOfIndex(inst);7347 const inst_ty = self.air.typeOfIndex(inst);
7293 const inst_llvm_ty = try self.dg.lowerType(inst_ty);7348 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
7296 if (scalar_ty.isRuntimeFloat()) {7351 if (scalar_ty.isRuntimeFloat()) {
7297 const a = try self.buildFloatOp(.fmod, inst_ty, 2, .{ lhs, rhs });7352 const a = try self.buildFloatOp(.fmod, inst_ty, 2, .{ lhs, rhs });
...@@ -7301,10 +7356,9 @@ pub const FuncGen = struct {...@@ -7301,10 +7356,9 @@ pub const FuncGen = struct {
7301 const ltz = try self.buildFloatCmp(.lt, inst_ty, .{ lhs, zero });7356 const ltz = try self.buildFloatCmp(.lt, inst_ty, .{ lhs, zero });
7302 return self.builder.buildSelect(ltz, c, a, "");7357 return self.builder.buildSelect(ltz, c, a, "");
7303 }7358 }
7304 if (scalar_ty.isSignedInt()) {7359 if (scalar_ty.isSignedInt(mod)) {
7305 const target = self.dg.module.getTarget();7360 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;
7306 const scalar_bit_size_minus_one = scalar_ty.bitSize(target) - 1;7361 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {
7307 const bit_size_minus_one = if (inst_ty.zigTypeTag() == .Vector) const_vector: {
7308 const vec_len = inst_ty.vectorLen();7362 const vec_len = inst_ty.vectorLen();
7309 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);7363 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
73107364
...@@ -7386,6 +7440,7 @@ pub const FuncGen = struct {...@@ -7386,6 +7440,7 @@ pub const FuncGen = struct {
7386 signed_intrinsic: []const u8,7440 signed_intrinsic: []const u8,
7387 unsigned_intrinsic: []const u8,7441 unsigned_intrinsic: []const u8,
7388 ) !?*llvm.Value {7442 ) !?*llvm.Value {
7443 const mod = self.dg.module;
7389 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;7444 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
7390 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;7445 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
73917446
...@@ -7393,16 +7448,14 @@ pub const FuncGen = struct {...@@ -7393,16 +7448,14 @@ pub const FuncGen = struct {
7393 const rhs = try self.resolveInst(extra.rhs);7448 const rhs = try self.resolveInst(extra.rhs);
73947449
7395 const lhs_ty = self.air.typeOf(extra.lhs);7450 const lhs_ty = self.air.typeOf(extra.lhs);
7396 const scalar_ty = lhs_ty.scalarType();7451 const scalar_ty = lhs_ty.scalarType(mod);
7397 const dest_ty = self.air.typeOfIndex(inst);7452 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
7401 const llvm_lhs_ty = try self.dg.lowerType(lhs_ty);7456 const llvm_lhs_ty = try self.dg.lowerType(lhs_ty);
7402 const llvm_dest_ty = try self.dg.lowerType(dest_ty);7457 const llvm_dest_ty = try self.dg.lowerType(dest_ty);
74037458
7404 const tg = self.dg.module.getTarget();
7405
7406 const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty});7459 const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty});
7407 const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, "");7460 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 {...@@ -7410,12 +7463,11 @@ pub const FuncGen = struct {
7410 const overflow_bit = self.builder.buildExtractValue(result_struct, 1, "");7463 const overflow_bit = self.builder.buildExtractValue(result_struct, 1, "");
74117464
7412 var ty_buf: Type.Payload.Pointer = undefined;7465 var ty_buf: Type.Payload.Pointer = undefined;
7413 const result_index = llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?;7466 const result_index = llvmFieldIndex(dest_ty, 0, mod, &ty_buf).?;
7414 const overflow_index = llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?;7467 const overflow_index = llvmFieldIndex(dest_ty, 1, mod, &ty_buf).?;
74157468
7416 if (isByRef(dest_ty)) {7469 if (isByRef(dest_ty, mod)) {
7417 const target = self.dg.module.getTarget();7470 const result_alignment = dest_ty.abiAlignment(mod);
7418 const result_alignment = dest_ty.abiAlignment(target);
7419 const alloca_inst = self.buildAlloca(llvm_dest_ty, result_alignment);7471 const alloca_inst = self.buildAlloca(llvm_dest_ty, result_alignment);
7420 {7472 {
7421 const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");7473 const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");
...@@ -7486,8 +7538,9 @@ pub const FuncGen = struct {...@@ -7486,8 +7538,9 @@ pub const FuncGen = struct {
7486 ty: Type,7538 ty: Type,
7487 params: [2]*llvm.Value,7539 params: [2]*llvm.Value,
7488 ) !*llvm.Value {7540 ) !*llvm.Value {
7541 const mod = self.dg.module;
7489 const target = self.dg.module.getTarget();7542 const target = self.dg.module.getTarget();
7490 const scalar_ty = ty.scalarType();7543 const scalar_ty = ty.scalarType(mod);
7491 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);7544 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
74927545
7493 if (intrinsicsAllowed(scalar_ty, target)) {7546 if (intrinsicsAllowed(scalar_ty, target)) {
...@@ -7531,7 +7584,7 @@ pub const FuncGen = struct {...@@ -7531,7 +7584,7 @@ pub const FuncGen = struct {
7531 .gte => .SGE,7584 .gte => .SGE,
7532 };7585 };
75337586
7534 if (ty.zigTypeTag() == .Vector) {7587 if (ty.zigTypeTag(mod) == .Vector) {
7535 const vec_len = ty.vectorLen();7588 const vec_len = ty.vectorLen();
7536 const vector_result_ty = llvm_i32.vectorType(vec_len);7589 const vector_result_ty = llvm_i32.vectorType(vec_len);
75377590
...@@ -7587,8 +7640,9 @@ pub const FuncGen = struct {...@@ -7587,8 +7640,9 @@ pub const FuncGen = struct {
7587 comptime params_len: usize,7640 comptime params_len: usize,
7588 params: [params_len]*llvm.Value,7641 params: [params_len]*llvm.Value,
7589 ) !*llvm.Value {7642 ) !*llvm.Value {
7590 const target = self.dg.module.getTarget();7643 const mod = self.dg.module;
7591 const scalar_ty = ty.scalarType();7644 const target = mod.getTarget();
7645 const scalar_ty = ty.scalarType(mod);
7592 const llvm_ty = try self.dg.lowerType(ty);7646 const llvm_ty = try self.dg.lowerType(ty);
7593 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);7647 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
75947648
...@@ -7615,7 +7669,7 @@ pub const FuncGen = struct {...@@ -7615,7 +7669,7 @@ pub const FuncGen = struct {
7615 const one = int_llvm_ty.constInt(1, .False);7669 const one = int_llvm_ty.constInt(1, .False);
7616 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);7670 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);
7617 const sign_mask = one.constShl(shift_amt);7671 const sign_mask = one.constShl(shift_amt);
7618 const result = if (ty.zigTypeTag() == .Vector) blk: {7672 const result = if (ty.zigTypeTag(mod) == .Vector) blk: {
7619 const splat_sign_mask = self.builder.buildVectorSplat(ty.vectorLen(), sign_mask, "");7673 const splat_sign_mask = self.builder.buildVectorSplat(ty.vectorLen(), sign_mask, "");
7620 const cast_ty = int_llvm_ty.vectorType(ty.vectorLen());7674 const cast_ty = int_llvm_ty.vectorType(ty.vectorLen());
7621 const bitcasted_operand = self.builder.buildBitCast(params[0], cast_ty, "");7675 const bitcasted_operand = self.builder.buildBitCast(params[0], cast_ty, "");
...@@ -7662,7 +7716,7 @@ pub const FuncGen = struct {...@@ -7662,7 +7716,7 @@ pub const FuncGen = struct {
7662 .libc => |fn_name| b: {7716 .libc => |fn_name| b: {
7663 const param_types = [3]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty, scalar_llvm_ty };7717 const param_types = [3]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty, scalar_llvm_ty };
7664 const libc_fn = self.getLibcFunction(fn_name, param_types[0..params.len], scalar_llvm_ty);7718 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) {
7666 const result = llvm_ty.getUndef();7720 const result = llvm_ty.getUndef();
7667 return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen());7721 return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen());
7668 }7722 }
...@@ -7686,6 +7740,7 @@ pub const FuncGen = struct {...@@ -7686,6 +7740,7 @@ pub const FuncGen = struct {
7686 }7740 }
76877741
7688 fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7742 fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7743 const mod = self.dg.module;
7689 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;7744 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
7690 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;7745 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
76917746
...@@ -7694,21 +7749,19 @@ pub const FuncGen = struct {...@@ -7694,21 +7749,19 @@ pub const FuncGen = struct {
76947749
7695 const lhs_ty = self.air.typeOf(extra.lhs);7750 const lhs_ty = self.air.typeOf(extra.lhs);
7696 const rhs_ty = self.air.typeOf(extra.rhs);7751 const rhs_ty = self.air.typeOf(extra.rhs);
7697 const lhs_scalar_ty = lhs_ty.scalarType();7752 const lhs_scalar_ty = lhs_ty.scalarType(mod);
7698 const rhs_scalar_ty = rhs_ty.scalarType();7753 const rhs_scalar_ty = rhs_ty.scalarType(mod);
76997754
7700 const dest_ty = self.air.typeOfIndex(inst);7755 const dest_ty = self.air.typeOfIndex(inst);
7701 const llvm_dest_ty = try self.dg.lowerType(dest_ty);7756 const llvm_dest_ty = try self.dg.lowerType(dest_ty);
77027757
7703 const tg = self.dg.module.getTarget();7758 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
7704
7705 const casted_rhs = if (rhs_scalar_ty.bitSize(tg) < lhs_scalar_ty.bitSize(tg))
7706 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_ty), "")7759 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_ty), "")
7707 else7760 else
7708 rhs;7761 rhs;
77097762
7710 const result = self.builder.buildShl(lhs, casted_rhs, "");7763 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))
7712 self.builder.buildAShr(result, casted_rhs, "")7765 self.builder.buildAShr(result, casted_rhs, "")
7713 else7766 else
7714 self.builder.buildLShr(result, casted_rhs, "");7767 self.builder.buildLShr(result, casted_rhs, "");
...@@ -7716,12 +7769,11 @@ pub const FuncGen = struct {...@@ -7716,12 +7769,11 @@ pub const FuncGen = struct {
7716 const overflow_bit = self.builder.buildICmp(.NE, lhs, reconstructed, "");7769 const overflow_bit = self.builder.buildICmp(.NE, lhs, reconstructed, "");
77177770
7718 var ty_buf: Type.Payload.Pointer = undefined;7771 var ty_buf: Type.Payload.Pointer = undefined;
7719 const result_index = llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?;7772 const result_index = llvmFieldIndex(dest_ty, 0, mod, &ty_buf).?;
7720 const overflow_index = llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?;7773 const overflow_index = llvmFieldIndex(dest_ty, 1, mod, &ty_buf).?;
77217774
7722 if (isByRef(dest_ty)) {7775 if (isByRef(dest_ty, mod)) {
7723 const target = self.dg.module.getTarget();7776 const result_alignment = dest_ty.abiAlignment(mod);
7724 const result_alignment = dest_ty.abiAlignment(target);
7725 const alloca_inst = self.buildAlloca(llvm_dest_ty, result_alignment);7777 const alloca_inst = self.buildAlloca(llvm_dest_ty, result_alignment);
7726 {7778 {
7727 const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");7779 const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");
...@@ -7763,6 +7815,7 @@ pub const FuncGen = struct {...@@ -7763,6 +7815,7 @@ pub const FuncGen = struct {
7763 }7815 }
77647816
7765 fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7817 fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7818 const mod = self.dg.module;
7766 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7819 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
77677820
7768 const lhs = try self.resolveInst(bin_op.lhs);7821 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7770,20 +7823,19 @@ pub const FuncGen = struct {...@@ -7770,20 +7823,19 @@ pub const FuncGen = struct {
77707823
7771 const lhs_ty = self.air.typeOf(bin_op.lhs);7824 const lhs_ty = self.air.typeOf(bin_op.lhs);
7772 const rhs_ty = self.air.typeOf(bin_op.rhs);7825 const rhs_ty = self.air.typeOf(bin_op.rhs);
7773 const lhs_scalar_ty = lhs_ty.scalarType();7826 const lhs_scalar_ty = lhs_ty.scalarType(mod);
7774 const rhs_scalar_ty = rhs_ty.scalarType();7827 const rhs_scalar_ty = rhs_ty.scalarType(mod);
77757828
7776 const tg = self.dg.module.getTarget();7829 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
7777
7778 const casted_rhs = if (rhs_scalar_ty.bitSize(tg) < lhs_scalar_ty.bitSize(tg))
7779 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_ty), "")7830 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_ty), "")
7780 else7831 else
7781 rhs;7832 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, "");
7783 return self.builder.buildNUWShl(lhs, casted_rhs, "");7834 return self.builder.buildNUWShl(lhs, casted_rhs, "");
7784 }7835 }
77857836
7786 fn airShl(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7837 fn airShl(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7838 const mod = self.dg.module;
7787 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7839 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
77887840
7789 const lhs = try self.resolveInst(bin_op.lhs);7841 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7791,12 +7843,10 @@ pub const FuncGen = struct {...@@ -7791,12 +7843,10 @@ pub const FuncGen = struct {
77917843
7792 const lhs_type = self.air.typeOf(bin_op.lhs);7844 const lhs_type = self.air.typeOf(bin_op.lhs);
7793 const rhs_type = self.air.typeOf(bin_op.rhs);7845 const rhs_type = self.air.typeOf(bin_op.rhs);
7794 const lhs_scalar_ty = lhs_type.scalarType();7846 const lhs_scalar_ty = lhs_type.scalarType(mod);
7795 const rhs_scalar_ty = rhs_type.scalarType();7847 const rhs_scalar_ty = rhs_type.scalarType(mod);
7796
7797 const tg = self.dg.module.getTarget();
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))
7800 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_type), "")7850 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_type), "")
7801 else7851 else
7802 rhs;7852 rhs;
...@@ -7804,6 +7854,7 @@ pub const FuncGen = struct {...@@ -7804,6 +7854,7 @@ pub const FuncGen = struct {
7804 }7854 }
78057855
7806 fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7856 fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7857 const mod = self.dg.module;
7807 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7858 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
78087859
7809 const lhs = try self.resolveInst(bin_op.lhs);7860 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7811,17 +7862,16 @@ pub const FuncGen = struct {...@@ -7811,17 +7862,16 @@ pub const FuncGen = struct {
78117862
7812 const lhs_ty = self.air.typeOf(bin_op.lhs);7863 const lhs_ty = self.air.typeOf(bin_op.lhs);
7813 const rhs_ty = self.air.typeOf(bin_op.rhs);7864 const rhs_ty = self.air.typeOf(bin_op.rhs);
7814 const lhs_scalar_ty = lhs_ty.scalarType();7865 const lhs_scalar_ty = lhs_ty.scalarType(mod);
7815 const rhs_scalar_ty = rhs_ty.scalarType();7866 const rhs_scalar_ty = rhs_ty.scalarType(mod);
7816 const tg = self.dg.module.getTarget();7867 const lhs_bits = lhs_scalar_ty.bitSize(mod);
7817 const lhs_bits = lhs_scalar_ty.bitSize(tg);
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)
7820 self.builder.buildZExt(rhs, lhs.typeOf(), "")7870 self.builder.buildZExt(rhs, lhs.typeOf(), "")
7821 else7871 else
7822 rhs;7872 rhs;
78237873
7824 const result = if (lhs_scalar_ty.isSignedInt())7874 const result = if (lhs_scalar_ty.isSignedInt(mod))
7825 self.builder.buildSShlSat(lhs, casted_rhs, "")7875 self.builder.buildSShlSat(lhs, casted_rhs, "")
7826 else7876 else
7827 self.builder.buildUShlSat(lhs, casted_rhs, "");7877 self.builder.buildUShlSat(lhs, casted_rhs, "");
...@@ -7834,7 +7884,7 @@ pub const FuncGen = struct {...@@ -7834,7 +7884,7 @@ pub const FuncGen = struct {
7834 const lhs_scalar_llvm_ty = try self.dg.lowerType(lhs_scalar_ty);7884 const lhs_scalar_llvm_ty = try self.dg.lowerType(lhs_scalar_ty);
7835 const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False);7885 const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False);
7836 const lhs_max = lhs_scalar_llvm_ty.constAllOnes();7886 const lhs_max = lhs_scalar_llvm_ty.constAllOnes();
7837 if (rhs_ty.zigTypeTag() == .Vector) {7887 if (rhs_ty.zigTypeTag(mod) == .Vector) {
7838 const vec_len = rhs_ty.vectorLen();7888 const vec_len = rhs_ty.vectorLen();
7839 const bits_vec = self.builder.buildVectorSplat(vec_len, bits, "");7889 const bits_vec = self.builder.buildVectorSplat(vec_len, bits, "");
7840 const lhs_max_vec = self.builder.buildVectorSplat(vec_len, lhs_max, "");7890 const lhs_max_vec = self.builder.buildVectorSplat(vec_len, lhs_max, "");
...@@ -7847,6 +7897,7 @@ pub const FuncGen = struct {...@@ -7847,6 +7897,7 @@ pub const FuncGen = struct {
7847 }7897 }
78487898
7849 fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !?*llvm.Value {7899 fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !?*llvm.Value {
7900 const mod = self.dg.module;
7850 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7901 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
78517902
7852 const lhs = try self.resolveInst(bin_op.lhs);7903 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7854,16 +7905,14 @@ pub const FuncGen = struct {...@@ -7854,16 +7905,14 @@ pub const FuncGen = struct {
78547905
7855 const lhs_ty = self.air.typeOf(bin_op.lhs);7906 const lhs_ty = self.air.typeOf(bin_op.lhs);
7856 const rhs_ty = self.air.typeOf(bin_op.rhs);7907 const rhs_ty = self.air.typeOf(bin_op.rhs);
7857 const lhs_scalar_ty = lhs_ty.scalarType();7908 const lhs_scalar_ty = lhs_ty.scalarType(mod);
7858 const rhs_scalar_ty = rhs_ty.scalarType();7909 const rhs_scalar_ty = rhs_ty.scalarType(mod);
7859
7860 const tg = self.dg.module.getTarget();
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))
7863 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_ty), "")7912 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_ty), "")
7864 else7913 else
7865 rhs;7914 rhs;
7866 const is_signed_int = lhs_scalar_ty.isSignedInt();7915 const is_signed_int = lhs_scalar_ty.isSignedInt(mod);
78677916
7868 if (is_exact) {7917 if (is_exact) {
7869 if (is_signed_int) {7918 if (is_signed_int) {
...@@ -7881,14 +7930,14 @@ pub const FuncGen = struct {...@@ -7881,14 +7930,14 @@ pub const FuncGen = struct {
7881 }7930 }
78827931
7883 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7932 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7884 const target = self.dg.module.getTarget();7933 const mod = self.dg.module;
7885 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7934 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7886 const dest_ty = self.air.typeOfIndex(inst);7935 const dest_ty = self.air.typeOfIndex(inst);
7887 const dest_info = dest_ty.intInfo(target);7936 const dest_info = dest_ty.intInfo(mod);
7888 const dest_llvm_ty = try self.dg.lowerType(dest_ty);7937 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
7889 const operand = try self.resolveInst(ty_op.operand);7938 const operand = try self.resolveInst(ty_op.operand);
7890 const operand_ty = self.air.typeOf(ty_op.operand);7939 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
7893 if (operand_info.bits < dest_info.bits) {7942 if (operand_info.bits < dest_info.bits) {
7894 switch (operand_info.signedness) {7943 switch (operand_info.signedness) {
...@@ -7910,11 +7959,12 @@ pub const FuncGen = struct {...@@ -7910,11 +7959,12 @@ pub const FuncGen = struct {
7910 }7959 }
79117960
7912 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7961 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7962 const mod = self.dg.module;
7913 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7963 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7914 const operand = try self.resolveInst(ty_op.operand);7964 const operand = try self.resolveInst(ty_op.operand);
7915 const operand_ty = self.air.typeOf(ty_op.operand);7965 const operand_ty = self.air.typeOf(ty_op.operand);
7916 const dest_ty = self.air.typeOfIndex(inst);7966 const dest_ty = self.air.typeOfIndex(inst);
7917 const target = self.dg.module.getTarget();7967 const target = mod.getTarget();
7918 const dest_bits = dest_ty.floatBits(target);7968 const dest_bits = dest_ty.floatBits(target);
7919 const src_bits = operand_ty.floatBits(target);7969 const src_bits = operand_ty.floatBits(target);
79207970
...@@ -7939,11 +7989,12 @@ pub const FuncGen = struct {...@@ -7939,11 +7989,12 @@ pub const FuncGen = struct {
7939 }7989 }
79407990
7941 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7991 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7992 const mod = self.dg.module;
7942 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7993 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7943 const operand = try self.resolveInst(ty_op.operand);7994 const operand = try self.resolveInst(ty_op.operand);
7944 const operand_ty = self.air.typeOf(ty_op.operand);7995 const operand_ty = self.air.typeOf(ty_op.operand);
7945 const dest_ty = self.air.typeOfIndex(inst);7996 const dest_ty = self.air.typeOfIndex(inst);
7946 const target = self.dg.module.getTarget();7997 const target = mod.getTarget();
7947 const dest_bits = dest_ty.floatBits(target);7998 const dest_bits = dest_ty.floatBits(target);
7948 const src_bits = operand_ty.floatBits(target);7999 const src_bits = operand_ty.floatBits(target);
79498000
...@@ -7985,10 +8036,10 @@ pub const FuncGen = struct {...@@ -7985,10 +8036,10 @@ pub const FuncGen = struct {
7985 }8036 }
79868037
7987 fn bitCast(self: *FuncGen, operand: *llvm.Value, operand_ty: Type, inst_ty: Type) !*llvm.Value {8038 fn bitCast(self: *FuncGen, operand: *llvm.Value, operand_ty: Type, inst_ty: Type) !*llvm.Value {
7988 const operand_is_ref = isByRef(operand_ty);8039 const mod = self.dg.module;
7989 const result_is_ref = isByRef(inst_ty);8040 const operand_is_ref = isByRef(operand_ty, mod);
8041 const result_is_ref = isByRef(inst_ty, mod);
7990 const llvm_dest_ty = try self.dg.lowerType(inst_ty);8042 const llvm_dest_ty = try self.dg.lowerType(inst_ty);
7991 const target = self.dg.module.getTarget();
79928043
7993 if (operand_is_ref and result_is_ref) {8044 if (operand_is_ref and result_is_ref) {
7994 // They are both pointers, so just return the same opaque pointer :)8045 // They are both pointers, so just return the same opaque pointer :)
...@@ -8001,20 +8052,20 @@ pub const FuncGen = struct {...@@ -8001,20 +8052,20 @@ pub const FuncGen = struct {
8001 return self.builder.buildZExtOrBitCast(operand, llvm_dest_ty, "");8052 return self.builder.buildZExtOrBitCast(operand, llvm_dest_ty, "");
8002 }8053 }
80038054
8004 if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) {8055 if (operand_ty.zigTypeTag(mod) == .Int and inst_ty.isPtrAtRuntime(mod)) {
8005 return self.builder.buildIntToPtr(operand, llvm_dest_ty, "");8056 return self.builder.buildIntToPtr(operand, llvm_dest_ty, "");
8006 }8057 }
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) {
8009 const elem_ty = operand_ty.childType();8060 const elem_ty = operand_ty.childType();
8010 if (!result_is_ref) {8061 if (!result_is_ref) {
8011 return self.dg.todo("implement bitcast vector to non-ref array", .{});8062 return self.dg.todo("implement bitcast vector to non-ref array", .{});
8012 }8063 }
8013 const array_ptr = self.buildAlloca(llvm_dest_ty, null);8064 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;
8015 if (bitcast_ok) {8066 if (bitcast_ok) {
8016 const llvm_store = self.builder.buildStore(operand, array_ptr);8067 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));
8018 } else {8069 } else {
8019 // If the ABI size of the element type is not evenly divisible by size in bits;8070 // If the ABI size of the element type is not evenly divisible by size in bits;
8020 // a simple bitcast will not work, and we fall back to extractelement.8071 // a simple bitcast will not work, and we fall back to extractelement.
...@@ -8033,19 +8084,19 @@ pub const FuncGen = struct {...@@ -8033,19 +8084,19 @@ pub const FuncGen = struct {
8033 }8084 }
8034 }8085 }
8035 return array_ptr;8086 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) {
8037 const elem_ty = operand_ty.childType();8088 const elem_ty = operand_ty.childType();
8038 const llvm_vector_ty = try self.dg.lowerType(inst_ty);8089 const llvm_vector_ty = try self.dg.lowerType(inst_ty);
8039 if (!operand_is_ref) {8090 if (!operand_is_ref) {
8040 return self.dg.todo("implement bitcast non-ref array to vector", .{});8091 return self.dg.todo("implement bitcast non-ref array to vector", .{});
8041 }8092 }
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;
8044 if (bitcast_ok) {8095 if (bitcast_ok) {
8045 const vector = self.builder.buildLoad(llvm_vector_ty, operand, "");8096 const vector = self.builder.buildLoad(llvm_vector_ty, operand, "");
8046 // The array is aligned to the element's alignment, while the vector might have a completely8097 // The array is aligned to the element's alignment, while the vector might have a completely
8047 // different alignment. This means we need to enforce the alignment of this load.8098 // 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));
8049 return vector;8100 return vector;
8050 } else {8101 } else {
8051 // If the ABI size of the element type is not evenly divisible by size in bits;8102 // If the ABI size of the element type is not evenly divisible by size in bits;
...@@ -8073,12 +8124,12 @@ pub const FuncGen = struct {...@@ -8073,12 +8124,12 @@ pub const FuncGen = struct {
80738124
8074 if (operand_is_ref) {8125 if (operand_is_ref) {
8075 const load_inst = self.builder.buildLoad(llvm_dest_ty, operand, "");8126 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));
8077 return load_inst;8128 return load_inst;
8078 }8129 }
80798130
8080 if (result_is_ref) {8131 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));
8082 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);8133 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);
8083 const store_inst = self.builder.buildStore(operand, result_ptr);8134 const store_inst = self.builder.buildStore(operand, result_ptr);
8084 store_inst.setAlignment(alignment);8135 store_inst.setAlignment(alignment);
...@@ -8089,7 +8140,7 @@ pub const FuncGen = struct {...@@ -8089,7 +8140,7 @@ pub const FuncGen = struct {
8089 // Both our operand and our result are values, not pointers,8140 // Both our operand and our result are values, not pointers,
8090 // but LLVM won't let us bitcast struct values.8141 // but LLVM won't let us bitcast struct values.
8091 // Therefore, we store operand to alloca, then load for result.8142 // 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));
8093 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);8144 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);
8094 const store_inst = self.builder.buildStore(operand, result_ptr);8145 const store_inst = self.builder.buildStore(operand, result_ptr);
8095 store_inst.setAlignment(alignment);8146 store_inst.setAlignment(alignment);
...@@ -8118,12 +8169,13 @@ pub const FuncGen = struct {...@@ -8118,12 +8169,13 @@ pub const FuncGen = struct {
8118 }8169 }
81198170
8120 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;8171 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
8172 const mod = self.dg.module;
8121 const func = self.dg.decl.getFunction().?;8173 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;
8123 const lbrace_col = func.lbrace_column + 1;8175 const lbrace_col = func.lbrace_column + 1;
8124 const di_local_var = dib.createParameterVariable(8176 const di_local_var = dib.createParameterVariable(
8125 self.di_scope.?,8177 self.di_scope.?,
8126 func.getParamName(self.dg.module, src_index).ptr, // TODO test 0 bit args8178 func.getParamName(mod, src_index).ptr, // TODO test 0 bit args
8127 self.di_file.?,8179 self.di_file.?,
8128 lbrace_line,8180 lbrace_line,
8129 try self.dg.object.lowerDebugType(inst_ty, .full),8181 try self.dg.object.lowerDebugType(inst_ty, .full),
...@@ -8134,10 +8186,10 @@ pub const FuncGen = struct {...@@ -8134,10 +8186,10 @@ pub const FuncGen = struct {
81348186
8135 const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?, null);8187 const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?, null);
8136 const insert_block = self.builder.getInsertBlock();8188 const insert_block = self.builder.getInsertBlock();
8137 if (isByRef(inst_ty)) {8189 if (isByRef(inst_ty, mod)) {
8138 _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block);8190 _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block);
8139 } else if (self.dg.module.comp.bin_file.options.optimize_mode == .Debug) {8191 } 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);
8141 const alloca = self.buildAlloca(arg_val.typeOf(), alignment);8193 const alloca = self.buildAlloca(arg_val.typeOf(), alignment);
8142 const store_inst = self.builder.buildStore(arg_val, alloca);8194 const store_inst = self.builder.buildStore(arg_val, alloca);
8143 store_inst.setAlignment(alignment);8195 store_inst.setAlignment(alignment);
...@@ -8153,22 +8205,22 @@ pub const FuncGen = struct {...@@ -8153,22 +8205,22 @@ pub const FuncGen = struct {
8153 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8205 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8154 const ptr_ty = self.air.typeOfIndex(inst);8206 const ptr_ty = self.air.typeOfIndex(inst);
8155 const pointee_type = ptr_ty.childType();8207 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
8158 const pointee_llvm_ty = try self.dg.lowerType(pointee_type);8211 const pointee_llvm_ty = try self.dg.lowerType(pointee_type);
8159 const target = self.dg.module.getTarget();8212 const alignment = ptr_ty.ptrAlignment(mod);
8160 const alignment = ptr_ty.ptrAlignment(target);
8161 return self.buildAlloca(pointee_llvm_ty, alignment);8213 return self.buildAlloca(pointee_llvm_ty, alignment);
8162 }8214 }
81638215
8164 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8216 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8165 const ptr_ty = self.air.typeOfIndex(inst);8217 const ptr_ty = self.air.typeOfIndex(inst);
8166 const ret_ty = ptr_ty.childType();8218 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);
8168 if (self.ret_ptr) |ret_ptr| return ret_ptr;8221 if (self.ret_ptr) |ret_ptr| return ret_ptr;
8169 const ret_llvm_ty = try self.dg.lowerType(ret_ty);8222 const ret_llvm_ty = try self.dg.lowerType(ret_ty);
8170 const target = self.dg.module.getTarget();8223 return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(mod));
8171 return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(target));
8172 }8224 }
81738225
8174 /// Use this instead of builder.buildAlloca, because this function makes sure to8226 /// Use this instead of builder.buildAlloca, because this function makes sure to
...@@ -8182,8 +8234,9 @@ pub const FuncGen = struct {...@@ -8182,8 +8234,9 @@ pub const FuncGen = struct {
8182 const dest_ptr = try self.resolveInst(bin_op.lhs);8234 const dest_ptr = try self.resolveInst(bin_op.lhs);
8183 const ptr_ty = self.air.typeOf(bin_op.lhs);8235 const ptr_ty = self.air.typeOf(bin_op.lhs);
8184 const operand_ty = ptr_ty.childType();8236 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;
8187 if (val_is_undef) {8240 if (val_is_undef) {
8188 // Even if safety is disabled, we still emit a memset to undefined since it conveys8241 // Even if safety is disabled, we still emit a memset to undefined since it conveys
8189 // extra information to LLVM. However, safety makes the difference between using8242 // extra information to LLVM. However, safety makes the difference between using
...@@ -8193,13 +8246,12 @@ pub const FuncGen = struct {...@@ -8193,13 +8246,12 @@ pub const FuncGen = struct {
8193 u8_llvm_ty.constInt(0xaa, .False)8246 u8_llvm_ty.constInt(0xaa, .False)
8194 else8247 else
8195 u8_llvm_ty.getUndef();8248 u8_llvm_ty.getUndef();
8196 const target = self.dg.module.getTarget();8249 const operand_size = operand_ty.abiSize(mod);
8197 const operand_size = operand_ty.abiSize(target);
8198 const usize_llvm_ty = try self.dg.lowerType(Type.usize);8250 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
8199 const len = usize_llvm_ty.constInt(operand_size, .False);8251 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);
8201 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr());8253 _ = 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) {
8203 self.valgrindMarkUndef(dest_ptr, len);8255 self.valgrindMarkUndef(dest_ptr, len);
8204 }8256 }
8205 return null;8257 return null;
...@@ -8230,6 +8282,7 @@ pub const FuncGen = struct {...@@ -8230,6 +8282,7 @@ pub const FuncGen = struct {
8230 }8282 }
82318283
8232 fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {8284 fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
8285 const mod = fg.dg.module;
8233 const inst = body_tail[0];8286 const inst = body_tail[0];
8234 const ty_op = fg.air.instructions.items(.data)[inst].ty_op;8287 const ty_op = fg.air.instructions.items(.data)[inst].ty_op;
8235 const ptr_ty = fg.air.typeOf(ty_op.operand);8288 const ptr_ty = fg.air.typeOf(ty_op.operand);
...@@ -8237,7 +8290,7 @@ pub const FuncGen = struct {...@@ -8237,7 +8290,7 @@ pub const FuncGen = struct {
8237 const ptr = try fg.resolveInst(ty_op.operand);8290 const ptr = try fg.resolveInst(ty_op.operand);
82388291
8239 elide: {8292 elide: {
8240 if (!isByRef(ptr_info.pointee_type)) break :elide;8293 if (!isByRef(ptr_info.pointee_type, mod)) break :elide;
8241 if (!canElideLoad(fg, body_tail)) break :elide;8294 if (!canElideLoad(fg, body_tail)) break :elide;
8242 return ptr;8295 return ptr;
8243 }8296 }
...@@ -8261,8 +8314,9 @@ pub const FuncGen = struct {...@@ -8261,8 +8314,9 @@ pub const FuncGen = struct {
82618314
8262 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8315 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8263 _ = inst;8316 _ = inst;
8317 const mod = self.dg.module;
8264 const llvm_usize = try self.dg.lowerType(Type.usize);8318 const llvm_usize = try self.dg.lowerType(Type.usize);
8265 const target = self.dg.module.getTarget();8319 const target = mod.getTarget();
8266 if (!target_util.supportsReturnAddress(target)) {8320 if (!target_util.supportsReturnAddress(target)) {
8267 // https://github.com/ziglang/zig/issues/119468321 // https://github.com/ziglang/zig/issues/11946
8268 return llvm_usize.constNull();8322 return llvm_usize.constNull();
...@@ -8301,6 +8355,7 @@ pub const FuncGen = struct {...@@ -8301,6 +8355,7 @@ pub const FuncGen = struct {
8301 }8355 }
83028356
8303 fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value {8357 fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value {
8358 const mod = self.dg.module;
8304 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;8359 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
8305 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;8360 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
8306 const ptr = try self.resolveInst(extra.ptr);8361 const ptr = try self.resolveInst(extra.ptr);
...@@ -8310,7 +8365,7 @@ pub const FuncGen = struct {...@@ -8310,7 +8365,7 @@ pub const FuncGen = struct {
8310 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);8365 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
8311 if (opt_abi_ty) |abi_ty| {8366 if (opt_abi_ty) |abi_ty| {
8312 // operand needs widening and truncating8367 // operand needs widening and truncating
8313 if (operand_ty.isSignedInt()) {8368 if (operand_ty.isSignedInt(mod)) {
8314 expected_value = self.builder.buildSExt(expected_value, abi_ty, "");8369 expected_value = self.builder.buildSExt(expected_value, abi_ty, "");
8315 new_value = self.builder.buildSExt(new_value, abi_ty, "");8370 new_value = self.builder.buildSExt(new_value, abi_ty, "");
8316 } else {8371 } else {
...@@ -8336,7 +8391,7 @@ pub const FuncGen = struct {...@@ -8336,7 +8391,7 @@ pub const FuncGen = struct {
8336 }8391 }
8337 const success_bit = self.builder.buildExtractValue(result, 1, "");8392 const success_bit = self.builder.buildExtractValue(result, 1, "");
83388393
8339 if (optional_ty.optionalReprIsPayload()) {8394 if (optional_ty.optionalReprIsPayload(mod)) {
8340 return self.builder.buildSelect(success_bit, payload.typeOf().constNull(), payload, "");8395 return self.builder.buildSelect(success_bit, payload.typeOf().constNull(), payload, "");
8341 }8396 }
83428397
...@@ -8347,13 +8402,14 @@ pub const FuncGen = struct {...@@ -8347,13 +8402,14 @@ pub const FuncGen = struct {
8347 }8402 }
83488403
8349 fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8404 fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8405 const mod = self.dg.module;
8350 const pl_op = self.air.instructions.items(.data)[inst].pl_op;8406 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
8351 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;8407 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;
8352 const ptr = try self.resolveInst(pl_op.operand);8408 const ptr = try self.resolveInst(pl_op.operand);
8353 const ptr_ty = self.air.typeOf(pl_op.operand);8409 const ptr_ty = self.air.typeOf(pl_op.operand);
8354 const operand_ty = ptr_ty.elemType();8410 const operand_ty = ptr_ty.elemType();
8355 const operand = try self.resolveInst(extra.operand);8411 const operand = try self.resolveInst(extra.operand);
8356 const is_signed_int = operand_ty.isSignedInt();8412 const is_signed_int = operand_ty.isSignedInt(mod);
8357 const is_float = operand_ty.isRuntimeFloat();8413 const is_float = operand_ty.isRuntimeFloat();
8358 const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);8414 const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);
8359 const ordering = toLlvmAtomicOrdering(extra.ordering());8415 const ordering = toLlvmAtomicOrdering(extra.ordering());
...@@ -8402,17 +8458,17 @@ pub const FuncGen = struct {...@@ -8402,17 +8458,17 @@ pub const FuncGen = struct {
8402 }8458 }
84038459
8404 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8460 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8461 const mod = self.dg.module;
8405 const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;8462 const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;
8406 const ptr = try self.resolveInst(atomic_load.ptr);8463 const ptr = try self.resolveInst(atomic_load.ptr);
8407 const ptr_ty = self.air.typeOf(atomic_load.ptr);8464 const ptr_ty = self.air.typeOf(atomic_load.ptr);
8408 const ptr_info = ptr_ty.ptrInfo().data;8465 const ptr_info = ptr_ty.ptrInfo().data;
8409 const elem_ty = ptr_info.pointee_type;8466 const elem_ty = ptr_info.pointee_type;
8410 if (!elem_ty.hasRuntimeBitsIgnoreComptime())8467 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))
8411 return null;8468 return null;
8412 const ordering = toLlvmAtomicOrdering(atomic_load.order);8469 const ordering = toLlvmAtomicOrdering(atomic_load.order);
8413 const opt_abi_llvm_ty = self.dg.getAtomicAbiType(elem_ty, false);8470 const opt_abi_llvm_ty = self.dg.getAtomicAbiType(elem_ty, false);
8414 const target = self.dg.module.getTarget();8471 const ptr_alignment = ptr_info.alignment(mod);
8415 const ptr_alignment = ptr_info.alignment(target);
8416 const ptr_volatile = llvm.Bool.fromBool(ptr_info.@"volatile");8472 const ptr_volatile = llvm.Bool.fromBool(ptr_info.@"volatile");
8417 const elem_llvm_ty = try self.dg.lowerType(elem_ty);8473 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
84188474
...@@ -8436,17 +8492,18 @@ pub const FuncGen = struct {...@@ -8436,17 +8492,18 @@ pub const FuncGen = struct {
8436 inst: Air.Inst.Index,8492 inst: Air.Inst.Index,
8437 ordering: llvm.AtomicOrdering,8493 ordering: llvm.AtomicOrdering,
8438 ) !?*llvm.Value {8494 ) !?*llvm.Value {
8495 const mod = self.dg.module;
8439 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8496 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8440 const ptr_ty = self.air.typeOf(bin_op.lhs);8497 const ptr_ty = self.air.typeOf(bin_op.lhs);
8441 const operand_ty = ptr_ty.childType();8498 const operand_ty = ptr_ty.childType();
8442 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null;8499 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return null;
8443 const ptr = try self.resolveInst(bin_op.lhs);8500 const ptr = try self.resolveInst(bin_op.lhs);
8444 var element = try self.resolveInst(bin_op.rhs);8501 var element = try self.resolveInst(bin_op.rhs);
8445 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);8502 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
84468503
8447 if (opt_abi_ty) |abi_ty| {8504 if (opt_abi_ty) |abi_ty| {
8448 // operand needs widening8505 // operand needs widening
8449 if (operand_ty.isSignedInt()) {8506 if (operand_ty.isSignedInt(mod)) {
8450 element = self.builder.buildSExt(element, abi_ty, "");8507 element = self.builder.buildSExt(element, abi_ty, "");
8451 } else {8508 } else {
8452 element = self.builder.buildZExt(element, abi_ty, "");8509 element = self.builder.buildZExt(element, abi_ty, "");
...@@ -8457,18 +8514,19 @@ pub const FuncGen = struct {...@@ -8457,18 +8514,19 @@ pub const FuncGen = struct {
8457 }8514 }
84588515
8459 fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {8516 fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {
8517 const mod = self.dg.module;
8460 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8518 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8461 const dest_slice = try self.resolveInst(bin_op.lhs);8519 const dest_slice = try self.resolveInst(bin_op.lhs);
8462 const ptr_ty = self.air.typeOf(bin_op.lhs);8520 const ptr_ty = self.air.typeOf(bin_op.lhs);
8463 const elem_ty = self.air.typeOf(bin_op.rhs);8521 const elem_ty = self.air.typeOf(bin_op.rhs);
8464 const module = self.dg.module;8522 const module = self.dg.module;
8465 const target = module.getTarget();8523 const target = module.getTarget();
8466 const dest_ptr_align = ptr_ty.ptrAlignment(target);8524 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
8467 const u8_llvm_ty = self.context.intType(8);8525 const u8_llvm_ty = self.context.intType(8);
8468 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);8526 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);
8469 const is_volatile = ptr_ty.isVolatilePtr();8527 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| {
8472 if (elem_val.isUndefDeep()) {8530 if (elem_val.isUndefDeep()) {
8473 // Even if safety is disabled, we still emit a memset to undefined since it conveys8531 // Even if safety is disabled, we still emit a memset to undefined since it conveys
8474 // extra information to LLVM. However, safety makes the difference between using8532 // extra information to LLVM. However, safety makes the difference between using
...@@ -8503,7 +8561,7 @@ pub const FuncGen = struct {...@@ -8503,7 +8561,7 @@ pub const FuncGen = struct {
8503 }8561 }
85048562
8505 const value = try self.resolveInst(bin_op.rhs);8563 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
8508 if (elem_abi_size == 1) {8566 if (elem_abi_size == 1) {
8509 // In this case we can take advantage of LLVM's intrinsic.8567 // In this case we can take advantage of LLVM's intrinsic.
...@@ -8551,9 +8609,9 @@ pub const FuncGen = struct {...@@ -8551,9 +8609,9 @@ pub const FuncGen = struct {
8551 _ = self.builder.buildCondBr(end, body_block, end_block);8609 _ = self.builder.buildCondBr(end, body_block, end_block);
85528610
8553 self.builder.positionBuilderAtEnd(body_block);8611 self.builder.positionBuilderAtEnd(body_block);
8554 const elem_abi_alignment = elem_ty.abiAlignment(target);8612 const elem_abi_alignment = elem_ty.abiAlignment(mod);
8555 const it_ptr_alignment = @min(elem_abi_alignment, dest_ptr_align);8613 const it_ptr_alignment = @min(elem_abi_alignment, dest_ptr_align);
8556 if (isByRef(elem_ty)) {8614 if (isByRef(elem_ty, mod)) {
8557 _ = self.builder.buildMemCpy(8615 _ = self.builder.buildMemCpy(
8558 it_ptr,8616 it_ptr,
8559 it_ptr_alignment,8617 it_ptr_alignment,
...@@ -8589,13 +8647,13 @@ pub const FuncGen = struct {...@@ -8589,13 +8647,13 @@ pub const FuncGen = struct {
8589 const src_ptr = self.sliceOrArrayPtr(src_slice, src_ptr_ty);8647 const src_ptr = self.sliceOrArrayPtr(src_slice, src_ptr_ty);
8590 const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);8648 const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);
8591 const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);8649 const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);
8650 const mod = self.dg.module;
8592 const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr();8651 const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr();
8593 const target = self.dg.module.getTarget();
8594 _ = self.builder.buildMemCpy(8652 _ = self.builder.buildMemCpy(
8595 dest_ptr,8653 dest_ptr,
8596 dest_ptr_ty.ptrAlignment(target),8654 dest_ptr_ty.ptrAlignment(mod),
8597 src_ptr,8655 src_ptr,
8598 src_ptr_ty.ptrAlignment(target),8656 src_ptr_ty.ptrAlignment(mod),
8599 len,8657 len,
8600 is_volatile,8658 is_volatile,
8601 );8659 );
...@@ -8603,10 +8661,10 @@ pub const FuncGen = struct {...@@ -8603,10 +8661,10 @@ pub const FuncGen = struct {
8603 }8661 }
86048662
8605 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8663 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8664 const mod = self.dg.module;
8606 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8665 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8607 const un_ty = self.air.typeOf(bin_op.lhs).childType();8666 const un_ty = self.air.typeOf(bin_op.lhs).childType();
8608 const target = self.dg.module.getTarget();8667 const layout = un_ty.unionGetLayout(mod);
8609 const layout = un_ty.unionGetLayout(target);
8610 if (layout.tag_size == 0) return null;8668 if (layout.tag_size == 0) return null;
8611 const union_ptr = try self.resolveInst(bin_op.lhs);8669 const union_ptr = try self.resolveInst(bin_op.lhs);
8612 const new_tag = try self.resolveInst(bin_op.rhs);8670 const new_tag = try self.resolveInst(bin_op.rhs);
...@@ -8624,13 +8682,13 @@ pub const FuncGen = struct {...@@ -8624,13 +8682,13 @@ pub const FuncGen = struct {
8624 }8682 }
86258683
8626 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8684 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8685 const mod = self.dg.module;
8627 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8686 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8628 const un_ty = self.air.typeOf(ty_op.operand);8687 const un_ty = self.air.typeOf(ty_op.operand);
8629 const target = self.dg.module.getTarget();8688 const layout = un_ty.unionGetLayout(mod);
8630 const layout = un_ty.unionGetLayout(target);
8631 if (layout.tag_size == 0) return null;8689 if (layout.tag_size == 0) return null;
8632 const union_handle = try self.resolveInst(ty_op.operand);8690 const union_handle = try self.resolveInst(ty_op.operand);
8633 if (isByRef(un_ty)) {8691 if (isByRef(un_ty, mod)) {
8634 const llvm_un_ty = try self.dg.lowerType(un_ty);8692 const llvm_un_ty = try self.dg.lowerType(un_ty);
8635 if (layout.payload_size == 0) {8693 if (layout.payload_size == 0) {
8636 return self.builder.buildLoad(llvm_un_ty, union_handle, "");8694 return self.builder.buildLoad(llvm_un_ty, union_handle, "");
...@@ -8666,6 +8724,7 @@ pub const FuncGen = struct {...@@ -8666,6 +8724,7 @@ pub const FuncGen = struct {
8666 }8724 }
86678725
8668 fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {8726 fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
8727 const mod = self.dg.module;
8669 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8728 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8670 const operand_ty = self.air.typeOf(ty_op.operand);8729 const operand_ty = self.air.typeOf(ty_op.operand);
8671 const operand = try self.resolveInst(ty_op.operand);8730 const operand = try self.resolveInst(ty_op.operand);
...@@ -8679,9 +8738,8 @@ pub const FuncGen = struct {...@@ -8679,9 +8738,8 @@ pub const FuncGen = struct {
8679 const result_ty = self.air.typeOfIndex(inst);8738 const result_ty = self.air.typeOfIndex(inst);
8680 const result_llvm_ty = try self.dg.lowerType(result_ty);8739 const result_llvm_ty = try self.dg.lowerType(result_ty);
86818740
8682 const target = self.dg.module.getTarget();8741 const bits = operand_ty.intInfo(mod).bits;
8683 const bits = operand_ty.intInfo(target).bits;8742 const result_bits = result_ty.intInfo(mod).bits;
8684 const result_bits = result_ty.intInfo(target).bits;
8685 if (bits > result_bits) {8743 if (bits > result_bits) {
8686 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");8744 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");
8687 } else if (bits < result_bits) {8745 } else if (bits < result_bits) {
...@@ -8692,6 +8750,7 @@ pub const FuncGen = struct {...@@ -8692,6 +8750,7 @@ pub const FuncGen = struct {
8692 }8750 }
86938751
8694 fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {8752 fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
8753 const mod = self.dg.module;
8695 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8754 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8696 const operand_ty = self.air.typeOf(ty_op.operand);8755 const operand_ty = self.air.typeOf(ty_op.operand);
8697 const operand = try self.resolveInst(ty_op.operand);8756 const operand = try self.resolveInst(ty_op.operand);
...@@ -8704,9 +8763,8 @@ pub const FuncGen = struct {...@@ -8704,9 +8763,8 @@ pub const FuncGen = struct {
8704 const result_ty = self.air.typeOfIndex(inst);8763 const result_ty = self.air.typeOfIndex(inst);
8705 const result_llvm_ty = try self.dg.lowerType(result_ty);8764 const result_llvm_ty = try self.dg.lowerType(result_ty);
87068765
8707 const target = self.dg.module.getTarget();8766 const bits = operand_ty.intInfo(mod).bits;
8708 const bits = operand_ty.intInfo(target).bits;8767 const result_bits = result_ty.intInfo(mod).bits;
8709 const result_bits = result_ty.intInfo(target).bits;
8710 if (bits > result_bits) {8768 if (bits > result_bits) {
8711 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");8769 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");
8712 } else if (bits < result_bits) {8770 } else if (bits < result_bits) {
...@@ -8717,10 +8775,10 @@ pub const FuncGen = struct {...@@ -8717,10 +8775,10 @@ pub const FuncGen = struct {
8717 }8775 }
87188776
8719 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {8777 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;
8721 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8779 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8722 const operand_ty = self.air.typeOf(ty_op.operand);8780 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;
8724 assert(bits % 8 == 0);8782 assert(bits % 8 == 0);
87258783
8726 var operand = try self.resolveInst(ty_op.operand);8784 var operand = try self.resolveInst(ty_op.operand);
...@@ -8730,7 +8788,7 @@ pub const FuncGen = struct {...@@ -8730,7 +8788,7 @@ pub const FuncGen = struct {
8730 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte8788 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte
8731 // The truncated result at the end will be the correct bswap8789 // The truncated result at the end will be the correct bswap
8732 const scalar_llvm_ty = self.context.intType(bits + 8);8790 const scalar_llvm_ty = self.context.intType(bits + 8);
8733 if (operand_ty.zigTypeTag() == .Vector) {8791 if (operand_ty.zigTypeTag(mod) == .Vector) {
8734 const vec_len = operand_ty.vectorLen();8792 const vec_len = operand_ty.vectorLen();
8735 operand_llvm_ty = scalar_llvm_ty.vectorType(vec_len);8793 operand_llvm_ty = scalar_llvm_ty.vectorType(vec_len);
87368794
...@@ -8759,7 +8817,7 @@ pub const FuncGen = struct {...@@ -8759,7 +8817,7 @@ pub const FuncGen = struct {
87598817
8760 const result_ty = self.air.typeOfIndex(inst);8818 const result_ty = self.air.typeOfIndex(inst);
8761 const result_llvm_ty = try self.dg.lowerType(result_ty);8819 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;
8763 if (bits > result_bits) {8821 if (bits > result_bits) {
8764 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");8822 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");
8765 } else if (bits < result_bits) {8823 } else if (bits < result_bits) {
...@@ -8770,6 +8828,7 @@ pub const FuncGen = struct {...@@ -8770,6 +8828,7 @@ pub const FuncGen = struct {
8770 }8828 }
87718829
8772 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8830 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8831 const mod = self.dg.module;
8773 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8832 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8774 const operand = try self.resolveInst(ty_op.operand);8833 const operand = try self.resolveInst(ty_op.operand);
8775 const error_set_ty = self.air.getRefType(ty_op.ty);8834 const error_set_ty = self.air.getRefType(ty_op.ty);
...@@ -8781,7 +8840,7 @@ pub const FuncGen = struct {...@@ -8781,7 +8840,7 @@ pub const FuncGen = struct {
8781 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));8840 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));
87828841
8783 for (names) |name| {8842 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).?;
8785 const this_tag_int_value = int: {8844 const this_tag_int_value = int: {
8786 var tag_val_payload: Value.Payload.U64 = .{8845 var tag_val_payload: Value.Payload.U64 = .{
8787 .base = .{ .tag = .int_u64 },8846 .base = .{ .tag = .int_u64 },
...@@ -8841,8 +8900,7 @@ pub const FuncGen = struct {...@@ -8841,8 +8900,7 @@ pub const FuncGen = struct {
8841 defer self.gpa.free(fqn);8900 defer self.gpa.free(fqn);
8842 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{s}", .{fqn});8901 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;8903 const int_tag_ty = enum_ty.intTagType();
8845 const int_tag_ty = enum_ty.intTagType(&int_tag_type_buffer);
8846 const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)};8904 const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)};
88478905
8848 const llvm_ret_ty = try self.dg.lowerType(Type.bool);8906 const llvm_ret_ty = try self.dg.lowerType(Type.bool);
...@@ -8923,11 +8981,9 @@ pub const FuncGen = struct {...@@ -8923,11 +8981,9 @@ pub const FuncGen = struct {
8923 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);8981 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);
8924 const llvm_ret_ty = try self.dg.lowerType(slice_ty);8982 const llvm_ret_ty = try self.dg.lowerType(slice_ty);
8925 const usize_llvm_ty = try self.dg.lowerType(Type.usize);8983 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
8926 const target = self.dg.module.getTarget();8984 const slice_alignment = slice_ty.abiAlignment(mod);
8927 const slice_alignment = slice_ty.abiAlignment(target);
89288985
8929 var int_tag_type_buffer: Type.Payload.Bits = undefined;8986 const int_tag_ty = enum_ty.intTagType();
8930 const int_tag_ty = enum_ty.intTagType(&int_tag_type_buffer);
8931 const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)};8987 const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)};
89328988
8933 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);8989 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);
...@@ -9057,6 +9113,7 @@ pub const FuncGen = struct {...@@ -9057,6 +9113,7 @@ pub const FuncGen = struct {
9057 }9113 }
90589114
9059 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9115 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9116 const mod = self.dg.module;
9060 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;9117 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
9061 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;9118 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
9062 const a = try self.resolveInst(extra.a);9119 const a = try self.resolveInst(extra.a);
...@@ -9077,11 +9134,11 @@ pub const FuncGen = struct {...@@ -9077,11 +9134,11 @@ pub const FuncGen = struct {
90779134
9078 for (values, 0..) |*val, i| {9135 for (values, 0..) |*val, i| {
9079 var buf: Value.ElemValueBuffer = undefined;9136 var buf: Value.ElemValueBuffer = undefined;
9080 const elem = mask.elemValueBuffer(self.dg.module, i, &buf);9137 const elem = mask.elemValueBuffer(mod, i, &buf);
9081 if (elem.isUndef()) {9138 if (elem.isUndef()) {
9082 val.* = llvm_i32.getUndef();9139 val.* = llvm_i32.getUndef();
9083 } else {9140 } else {
9084 const int = elem.toSignedInt(self.dg.module.getTarget());9141 const int = elem.toSignedInt(mod);
9085 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int + a_len);9142 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int + a_len);
9086 val.* = llvm_i32.constInt(unsigned, .False);9143 val.* = llvm_i32.constInt(unsigned, .False);
9087 }9144 }
...@@ -9157,7 +9214,8 @@ pub const FuncGen = struct {...@@ -9157,7 +9214,8 @@ pub const FuncGen = struct {
91579214
9158 fn airReduce(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {9215 fn airReduce(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
9159 self.builder.setFastMath(want_fast_math);9216 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
9162 const reduce = self.air.instructions.items(.data)[inst].reduce;9220 const reduce = self.air.instructions.items(.data)[inst].reduce;
9163 const operand = try self.resolveInst(reduce.operand);9221 const operand = try self.resolveInst(reduce.operand);
...@@ -9168,21 +9226,21 @@ pub const FuncGen = struct {...@@ -9168,21 +9226,21 @@ pub const FuncGen = struct {
9168 .And => return self.builder.buildAndReduce(operand),9226 .And => return self.builder.buildAndReduce(operand),
9169 .Or => return self.builder.buildOrReduce(operand),9227 .Or => return self.builder.buildOrReduce(operand),
9170 .Xor => return self.builder.buildXorReduce(operand),9228 .Xor => return self.builder.buildXorReduce(operand),
9171 .Min => switch (scalar_ty.zigTypeTag()) {9229 .Min => switch (scalar_ty.zigTypeTag(mod)) {
9172 .Int => return self.builder.buildIntMinReduce(operand, scalar_ty.isSignedInt()),9230 .Int => return self.builder.buildIntMinReduce(operand, scalar_ty.isSignedInt(mod)),
9173 .Float => if (intrinsicsAllowed(scalar_ty, target)) {9231 .Float => if (intrinsicsAllowed(scalar_ty, target)) {
9174 return self.builder.buildFPMinReduce(operand);9232 return self.builder.buildFPMinReduce(operand);
9175 },9233 },
9176 else => unreachable,9234 else => unreachable,
9177 },9235 },
9178 .Max => switch (scalar_ty.zigTypeTag()) {9236 .Max => switch (scalar_ty.zigTypeTag(mod)) {
9179 .Int => return self.builder.buildIntMaxReduce(operand, scalar_ty.isSignedInt()),9237 .Int => return self.builder.buildIntMaxReduce(operand, scalar_ty.isSignedInt(mod)),
9180 .Float => if (intrinsicsAllowed(scalar_ty, target)) {9238 .Float => if (intrinsicsAllowed(scalar_ty, target)) {
9181 return self.builder.buildFPMaxReduce(operand);9239 return self.builder.buildFPMaxReduce(operand);
9182 },9240 },
9183 else => unreachable,9241 else => unreachable,
9184 },9242 },
9185 .Add => switch (scalar_ty.zigTypeTag()) {9243 .Add => switch (scalar_ty.zigTypeTag(mod)) {
9186 .Int => return self.builder.buildAddReduce(operand),9244 .Int => return self.builder.buildAddReduce(operand),
9187 .Float => if (intrinsicsAllowed(scalar_ty, target)) {9245 .Float => if (intrinsicsAllowed(scalar_ty, target)) {
9188 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);9246 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
...@@ -9191,7 +9249,7 @@ pub const FuncGen = struct {...@@ -9191,7 +9249,7 @@ pub const FuncGen = struct {
9191 },9249 },
9192 else => unreachable,9250 else => unreachable,
9193 },9251 },
9194 .Mul => switch (scalar_ty.zigTypeTag()) {9252 .Mul => switch (scalar_ty.zigTypeTag(mod)) {
9195 .Int => return self.builder.buildMulReduce(operand),9253 .Int => return self.builder.buildMulReduce(operand),
9196 .Float => if (intrinsicsAllowed(scalar_ty, target)) {9254 .Float => if (intrinsicsAllowed(scalar_ty, target)) {
9197 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);9255 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
...@@ -9247,9 +9305,9 @@ pub const FuncGen = struct {...@@ -9247,9 +9305,9 @@ pub const FuncGen = struct {
9247 const len = @intCast(usize, result_ty.arrayLen());9305 const len = @intCast(usize, result_ty.arrayLen());
9248 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);9306 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
9249 const llvm_result_ty = try self.dg.lowerType(result_ty);9307 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)) {
9253 .Vector => {9311 .Vector => {
9254 const llvm_u32 = self.context.intType(32);9312 const llvm_u32 = self.context.intType(32);
92559313
...@@ -9265,7 +9323,7 @@ pub const FuncGen = struct {...@@ -9265,7 +9323,7 @@ pub const FuncGen = struct {
9265 if (result_ty.containerLayout() == .Packed) {9323 if (result_ty.containerLayout() == .Packed) {
9266 const struct_obj = result_ty.castTag(.@"struct").?.data;9324 const struct_obj = result_ty.castTag(.@"struct").?.data;
9267 assert(struct_obj.haveLayout());9325 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);
9269 const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits));9327 const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits));
9270 const fields = struct_obj.fields.values();9328 const fields = struct_obj.fields.values();
9271 comptime assert(Type.packed_struct_layout_version == 2);9329 comptime assert(Type.packed_struct_layout_version == 2);
...@@ -9273,12 +9331,12 @@ pub const FuncGen = struct {...@@ -9273,12 +9331,12 @@ pub const FuncGen = struct {
9273 var running_bits: u16 = 0;9331 var running_bits: u16 = 0;
9274 for (elements, 0..) |elem, i| {9332 for (elements, 0..) |elem, i| {
9275 const field = fields[i];9333 const field = fields[i];
9276 if (!field.ty.hasRuntimeBitsIgnoreComptime()) continue;9334 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
92779335
9278 const non_int_val = try self.resolveInst(elem);9336 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));
9280 const small_int_ty = self.context.intType(ty_bit_size);9338 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))
9282 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")9340 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
9283 else9341 else
9284 self.builder.buildBitCast(non_int_val, small_int_ty, "");9342 self.builder.buildBitCast(non_int_val, small_int_ty, "");
...@@ -9296,24 +9354,24 @@ pub const FuncGen = struct {...@@ -9296,24 +9354,24 @@ pub const FuncGen = struct {
92969354
9297 var ptr_ty_buf: Type.Payload.Pointer = undefined;9355 var ptr_ty_buf: Type.Payload.Pointer = undefined;
92989356
9299 if (isByRef(result_ty)) {9357 if (isByRef(result_ty, mod)) {
9300 const llvm_u32 = self.context.intType(32);9358 const llvm_u32 = self.context.intType(32);
9301 // TODO in debug builds init to undef so that the padding will be 0xaa9359 // TODO in debug builds init to undef so that the padding will be 0xaa
9302 // even if we fully populate the fields.9360 // 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
9305 var indices: [2]*llvm.Value = .{ llvm_u32.constNull(), undefined };9363 var indices: [2]*llvm.Value = .{ llvm_u32.constNull(), undefined };
9306 for (elements, 0..) |elem, i| {9364 for (elements, 0..) |elem, i| {
9307 if (result_ty.structFieldValueComptime(i) != null) continue;9365 if (result_ty.structFieldValueComptime(mod, i) != null) continue;
93089366
9309 const llvm_elem = try self.resolveInst(elem);9367 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).?;
9311 indices[1] = llvm_u32.constInt(llvm_i, .False);9369 indices[1] = llvm_u32.constInt(llvm_i, .False);
9312 const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");9370 const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");
9313 var field_ptr_payload: Type.Payload.Pointer = .{9371 var field_ptr_payload: Type.Payload.Pointer = .{
9314 .data = .{9372 .data = .{
9315 .pointee_type = self.air.typeOf(elem),9373 .pointee_type = self.air.typeOf(elem),
9316 .@"align" = result_ty.structFieldAlign(i, target),9374 .@"align" = result_ty.structFieldAlign(i, mod),
9317 .@"addrspace" = .generic,9375 .@"addrspace" = .generic,
9318 },9376 },
9319 };9377 };
...@@ -9325,20 +9383,20 @@ pub const FuncGen = struct {...@@ -9325,20 +9383,20 @@ pub const FuncGen = struct {
9325 } else {9383 } else {
9326 var result = llvm_result_ty.getUndef();9384 var result = llvm_result_ty.getUndef();
9327 for (elements, 0..) |elem, i| {9385 for (elements, 0..) |elem, i| {
9328 if (result_ty.structFieldValueComptime(i) != null) continue;9386 if (result_ty.structFieldValueComptime(mod, i) != null) continue;
93299387
9330 const llvm_elem = try self.resolveInst(elem);9388 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).?;
9332 result = self.builder.buildInsertValue(result, llvm_elem, llvm_i, "");9390 result = self.builder.buildInsertValue(result, llvm_elem, llvm_i, "");
9333 }9391 }
9334 return result;9392 return result;
9335 }9393 }
9336 },9394 },
9337 .Array => {9395 .Array => {
9338 assert(isByRef(result_ty));9396 assert(isByRef(result_ty, mod));
93399397
9340 const llvm_usize = try self.dg.lowerType(Type.usize);9398 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
9343 const array_info = result_ty.arrayInfo();9401 const array_info = result_ty.arrayInfo();
9344 var elem_ptr_payload: Type.Payload.Pointer = .{9402 var elem_ptr_payload: Type.Payload.Pointer = .{
...@@ -9379,22 +9437,22 @@ pub const FuncGen = struct {...@@ -9379,22 +9437,22 @@ pub const FuncGen = struct {
9379 }9437 }
93809438
9381 fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9439 fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9440 const mod = self.dg.module;
9382 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;9441 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
9383 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;9442 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
9384 const union_ty = self.air.typeOfIndex(inst);9443 const union_ty = self.air.typeOfIndex(inst);
9385 const union_llvm_ty = try self.dg.lowerType(union_ty);9444 const union_llvm_ty = try self.dg.lowerType(union_ty);
9386 const target = self.dg.module.getTarget();9445 const layout = union_ty.unionGetLayout(mod);
9387 const layout = union_ty.unionGetLayout(target);
9388 const union_obj = union_ty.cast(Type.Payload.Union).?.data;9446 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
93899447
9390 if (union_obj.layout == .Packed) {9448 if (union_obj.layout == .Packed) {
9391 const big_bits = union_ty.bitSize(target);9449 const big_bits = union_ty.bitSize(mod);
9392 const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits));9450 const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits));
9393 const field = union_obj.fields.values()[extra.field_index];9451 const field = union_obj.fields.values()[extra.field_index];
9394 const non_int_val = try self.resolveInst(extra.init);9452 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));
9396 const small_int_ty = self.context.intType(ty_bit_size);9454 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))
9398 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")9456 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
9399 else9457 else
9400 self.builder.buildBitCast(non_int_val, small_int_ty, "");9458 self.builder.buildBitCast(non_int_val, small_int_ty, "");
...@@ -9412,16 +9470,16 @@ pub const FuncGen = struct {...@@ -9412,16 +9470,16 @@ pub const FuncGen = struct {
9412 const tag_val = Value.initPayload(&tag_val_payload.base);9470 const tag_val = Value.initPayload(&tag_val_payload.base);
9413 var int_payload: Value.Payload.U64 = undefined;9471 var int_payload: Value.Payload.U64 = undefined;
9414 const tag_int_val = tag_val.enumToInt(tag_ty, &int_payload);9472 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);
9416 };9474 };
9417 if (layout.payload_size == 0) {9475 if (layout.payload_size == 0) {
9418 if (layout.tag_size == 0) {9476 if (layout.tag_size == 0) {
9419 return null;9477 return null;
9420 }9478 }
9421 assert(!isByRef(union_ty));9479 assert(!isByRef(union_ty, mod));
9422 return union_llvm_ty.constInt(tag_int, .False);9480 return union_llvm_ty.constInt(tag_int, .False);
9423 }9481 }
9424 assert(isByRef(union_ty));9482 assert(isByRef(union_ty, mod));
9425 // The llvm type of the alloca will be the named LLVM union type, and will not9483 // The llvm type of the alloca will be the named LLVM union type, and will not
9426 // necessarily match the format that we need, depending on which tag is active.9484 // necessarily match the format that we need, depending on which tag is active.
9427 // We must construct the correct unnamed struct type here, in order to then set9485 // We must construct the correct unnamed struct type here, in order to then set
...@@ -9431,12 +9489,12 @@ pub const FuncGen = struct {...@@ -9431,12 +9489,12 @@ pub const FuncGen = struct {
9431 assert(union_obj.haveFieldTypes());9489 assert(union_obj.haveFieldTypes());
9432 const field = union_obj.fields.values()[extra.field_index];9490 const field = union_obj.fields.values()[extra.field_index];
9433 const field_llvm_ty = try self.dg.lowerType(field.ty);9491 const field_llvm_ty = try self.dg.lowerType(field.ty);
9434 const field_size = field.ty.abiSize(target);9492 const field_size = field.ty.abiSize(mod);
9435 const field_align = field.normalAlignment(target);9493 const field_align = field.normalAlignment(mod);
94369494
9437 const llvm_union_ty = t: {9495 const llvm_union_ty = t: {
9438 const payload = p: {9496 const payload = p: {
9439 if (!field.ty.hasRuntimeBitsIgnoreComptime()) {9497 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) {
9440 const padding_len = @intCast(c_uint, layout.payload_size);9498 const padding_len = @intCast(c_uint, layout.payload_size);
9441 break :p self.context.intType(8).arrayType(padding_len);9499 break :p self.context.intType(8).arrayType(padding_len);
9442 }9500 }
...@@ -9511,7 +9569,7 @@ pub const FuncGen = struct {...@@ -9511,7 +9569,7 @@ pub const FuncGen = struct {
9511 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);9569 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
9512 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);9570 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);
9513 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);9571 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));
9515 }9573 }
95169574
9517 return result_ptr;9575 return result_ptr;
...@@ -9535,7 +9593,8 @@ pub const FuncGen = struct {...@@ -9535,7 +9593,8 @@ pub const FuncGen = struct {
9535 // by the target.9593 // by the target.
9536 // To work around this, don't emit llvm.prefetch in this case.9594 // To work around this, don't emit llvm.prefetch in this case.
9537 // See https://bugs.llvm.org/show_bug.cgi?id=210379595 // 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();
9539 switch (prefetch.cache) {9598 switch (prefetch.cache) {
9540 .instruction => switch (target.cpu.arch) {9599 .instruction => switch (target.cpu.arch) {
9541 .x86_64,9600 .x86_64,
...@@ -9658,8 +9717,9 @@ pub const FuncGen = struct {...@@ -9658,8 +9717,9 @@ pub const FuncGen = struct {
9658 return table;9717 return table;
9659 }9718 }
96609719
9720 const mod = self.dg.module;
9661 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);9721 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);
9663 const llvm_slice_ptr_ty = self.context.pointerType(0); // TODO: Address space9723 const llvm_slice_ptr_ty = self.context.pointerType(0); // TODO: Address space
96649724
9665 const error_name_table_global = self.dg.object.llvm_module.addGlobal(llvm_slice_ptr_ty, "__zig_err_name_table");9725 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 {...@@ -9703,14 +9763,14 @@ pub const FuncGen = struct {
9703 ) !*llvm.Value {9763 ) !*llvm.Value {
9704 var buf: Type.Payload.ElemType = undefined;9764 var buf: Type.Payload.ElemType = undefined;
9705 const payload_ty = opt_ty.optionalChild(&buf);9765 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)) {
9708 // We have a pointer and we need to return a pointer to the first field.9769 // We have a pointer and we need to return a pointer to the first field.
9709 const payload_ptr = fg.builder.buildStructGEP(opt_llvm_ty, opt_handle, 0, "");9770 const payload_ptr = fg.builder.buildStructGEP(opt_llvm_ty, opt_handle, 0, "");
97109771
9711 const target = fg.dg.module.getTarget();9772 const payload_alignment = payload_ty.abiAlignment(mod);
9712 const payload_alignment = payload_ty.abiAlignment(target);9773 if (isByRef(payload_ty, mod)) {
9713 if (isByRef(payload_ty)) {
9714 if (can_elide_load)9774 if (can_elide_load)
9715 return payload_ptr;9775 return payload_ptr;
97169776
...@@ -9722,7 +9782,7 @@ pub const FuncGen = struct {...@@ -9722,7 +9782,7 @@ pub const FuncGen = struct {
9722 return load_inst;9782 return load_inst;
9723 }9783 }
97249784
9725 assert(!isByRef(payload_ty));9785 assert(!isByRef(payload_ty, mod));
9726 return fg.builder.buildExtractValue(opt_handle, 0, "");9786 return fg.builder.buildExtractValue(opt_handle, 0, "");
9727 }9787 }
97289788
...@@ -9734,10 +9794,10 @@ pub const FuncGen = struct {...@@ -9734,10 +9794,10 @@ pub const FuncGen = struct {
9734 ) !?*llvm.Value {9794 ) !?*llvm.Value {
9735 const optional_llvm_ty = try self.dg.lowerType(optional_ty);9795 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
9736 const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), "");9796 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)) {9799 if (isByRef(optional_ty, mod)) {
9739 const target = self.dg.module.getTarget();9800 const payload_alignment = optional_ty.abiAlignment(mod);
9740 const payload_alignment = optional_ty.abiAlignment(target);
9741 const alloca_inst = self.buildAlloca(optional_llvm_ty, payload_alignment);9801 const alloca_inst = self.buildAlloca(optional_llvm_ty, payload_alignment);
97429802
9743 {9803 {
...@@ -9765,9 +9825,9 @@ pub const FuncGen = struct {...@@ -9765,9 +9825,9 @@ pub const FuncGen = struct {
9765 struct_ptr_ty: Type,9825 struct_ptr_ty: Type,
9766 field_index: u32,9826 field_index: u32,
9767 ) !?*llvm.Value {9827 ) !?*llvm.Value {
9768 const target = self.dg.object.target;
9769 const struct_ty = struct_ptr_ty.childType();9828 const struct_ty = struct_ptr_ty.childType();
9770 switch (struct_ty.zigTypeTag()) {9829 const mod = self.dg.module;
9830 switch (struct_ty.zigTypeTag(mod)) {
9771 .Struct => switch (struct_ty.containerLayout()) {9831 .Struct => switch (struct_ty.containerLayout()) {
9772 .Packed => {9832 .Packed => {
9773 const result_ty = self.air.typeOfIndex(inst);9833 const result_ty = self.air.typeOfIndex(inst);
...@@ -9783,7 +9843,7 @@ pub const FuncGen = struct {...@@ -9783,7 +9843,7 @@ pub const FuncGen = struct {
97839843
9784 // We have a pointer to a packed struct field that happens to be byte-aligned.9844 // We have a pointer to a packed struct field that happens to be byte-aligned.
9785 // Offset our operand pointer by the correct number of bytes.9845 // 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);
9787 if (byte_offset == 0) return struct_ptr;9847 if (byte_offset == 0) return struct_ptr;
9788 const byte_llvm_ty = self.context.intType(8);9848 const byte_llvm_ty = self.context.intType(8);
9789 const llvm_usize = try self.dg.lowerType(Type.usize);9849 const llvm_usize = try self.dg.lowerType(Type.usize);
...@@ -9795,7 +9855,7 @@ pub const FuncGen = struct {...@@ -9795,7 +9855,7 @@ pub const FuncGen = struct {
9795 const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);9855 const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);
97969856
9797 var ty_buf: Type.Payload.Pointer = undefined;9857 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| {
9799 return self.builder.buildStructGEP(struct_llvm_ty, struct_ptr, llvm_field_index, "");9859 return self.builder.buildStructGEP(struct_llvm_ty, struct_ptr, llvm_field_index, "");
9800 } else {9860 } else {
9801 // If we found no index then this means this is a zero sized field at the9861 // If we found no index then this means this is a zero sized field at the
...@@ -9803,14 +9863,14 @@ pub const FuncGen = struct {...@@ -9803,14 +9863,14 @@ pub const FuncGen = struct {
9803 // the index to the element at index `1` to get a pointer to the end of9863 // the index to the element at index `1` to get a pointer to the end of
9804 // the struct.9864 // the struct.
9805 const llvm_u32 = self.context.intType(32);9865 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);
9807 const indices: [1]*llvm.Value = .{llvm_index};9867 const indices: [1]*llvm.Value = .{llvm_index};
9808 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");9868 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");
9809 }9869 }
9810 },9870 },
9811 },9871 },
9812 .Union => {9872 .Union => {
9813 const layout = struct_ty.unionGetLayout(target);9873 const layout = struct_ty.unionGetLayout(mod);
9814 if (layout.payload_size == 0 or struct_ty.containerLayout() == .Packed) return struct_ptr;9874 if (layout.payload_size == 0 or struct_ty.containerLayout() == .Packed) return struct_ptr;
9815 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);9875 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
9816 const union_llvm_ty = try self.dg.lowerType(struct_ty);9876 const union_llvm_ty = try self.dg.lowerType(struct_ty);
...@@ -9835,12 +9895,12 @@ pub const FuncGen = struct {...@@ -9835,12 +9895,12 @@ pub const FuncGen = struct {
9835 ptr_alignment: u32,9895 ptr_alignment: u32,
9836 is_volatile: bool,9896 is_volatile: bool,
9837 ) !*llvm.Value {9897 ) !*llvm.Value {
9898 const mod = fg.dg.module;
9838 const pointee_llvm_ty = try fg.dg.lowerType(pointee_type);9899 const pointee_llvm_ty = try fg.dg.lowerType(pointee_type);
9839 const target = fg.dg.module.getTarget();9900 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod));
9840 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(target));
9841 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);9901 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);
9842 const llvm_usize = fg.context.intType(Type.usize.intInfo(target).bits);9902 const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits);
9843 const size_bytes = pointee_type.abiSize(target);9903 const size_bytes = pointee_type.abiSize(mod);
9844 _ = fg.builder.buildMemCpy(9904 _ = fg.builder.buildMemCpy(
9845 result_ptr,9905 result_ptr,
9846 result_align,9906 result_align,
...@@ -9856,11 +9916,11 @@ pub const FuncGen = struct {...@@ -9856,11 +9916,11 @@ pub const FuncGen = struct {
9856 /// alloca and copies the value into it, then returns the alloca instruction.9916 /// alloca and copies the value into it, then returns the alloca instruction.
9857 /// For isByRef=false types, it creates a load instruction and returns it.9917 /// For isByRef=false types, it creates a load instruction and returns it.
9858 fn load(self: *FuncGen, ptr: *llvm.Value, ptr_ty: Type) !?*llvm.Value {9918 fn load(self: *FuncGen, ptr: *llvm.Value, ptr_ty: Type) !?*llvm.Value {
9919 const mod = self.dg.module;
9859 const info = ptr_ty.ptrInfo().data;9920 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();9923 const ptr_alignment = info.alignment(mod);
9863 const ptr_alignment = info.alignment(target);
9864 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr());9924 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr());
98659925
9866 assert(info.vector_index != .runtime);9926 assert(info.vector_index != .runtime);
...@@ -9877,7 +9937,7 @@ pub const FuncGen = struct {...@@ -9877,7 +9937,7 @@ pub const FuncGen = struct {
9877 }9937 }
98789938
9879 if (info.host_size == 0) {9939 if (info.host_size == 0) {
9880 if (isByRef(info.pointee_type)) {9940 if (isByRef(info.pointee_type, mod)) {
9881 return self.loadByRef(ptr, info.pointee_type, ptr_alignment, info.@"volatile");9941 return self.loadByRef(ptr, info.pointee_type, ptr_alignment, info.@"volatile");
9882 }9942 }
9883 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);9943 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
...@@ -9892,13 +9952,13 @@ pub const FuncGen = struct {...@@ -9892,13 +9952,13 @@ pub const FuncGen = struct {
9892 containing_int.setAlignment(ptr_alignment);9952 containing_int.setAlignment(ptr_alignment);
9893 containing_int.setVolatile(ptr_volatile);9953 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));
9896 const shift_amt = containing_int.typeOf().constInt(info.bit_offset, .False);9956 const shift_amt = containing_int.typeOf().constInt(info.bit_offset, .False);
9897 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");9957 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");
9898 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);9958 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
98999959
9900 if (isByRef(info.pointee_type)) {9960 if (isByRef(info.pointee_type, mod)) {
9901 const result_align = info.pointee_type.abiAlignment(target);9961 const result_align = info.pointee_type.abiAlignment(mod);
9902 const result_ptr = self.buildAlloca(elem_llvm_ty, result_align);9962 const result_ptr = self.buildAlloca(elem_llvm_ty, result_align);
99039963
9904 const same_size_int = self.context.intType(elem_bits);9964 const same_size_int = self.context.intType(elem_bits);
...@@ -9908,13 +9968,13 @@ pub const FuncGen = struct {...@@ -9908,13 +9968,13 @@ pub const FuncGen = struct {
9908 return result_ptr;9968 return result_ptr;
9909 }9969 }
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) {
9912 const same_size_int = self.context.intType(elem_bits);9972 const same_size_int = self.context.intType(elem_bits);
9913 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");9973 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
9914 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");9974 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
9915 }9975 }
99169976
9917 if (info.pointee_type.isPtrAtRuntime()) {9977 if (info.pointee_type.isPtrAtRuntime(mod)) {
9918 const same_size_int = self.context.intType(elem_bits);9978 const same_size_int = self.context.intType(elem_bits);
9919 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");9979 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
9920 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");9980 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
...@@ -9932,11 +9992,11 @@ pub const FuncGen = struct {...@@ -9932,11 +9992,11 @@ pub const FuncGen = struct {
9932 ) !void {9992 ) !void {
9933 const info = ptr_ty.ptrInfo().data;9993 const info = ptr_ty.ptrInfo().data;
9934 const elem_ty = info.pointee_type;9994 const elem_ty = info.pointee_type;
9935 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime()) {9995 const mod = self.dg.module;
9996 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
9936 return;9997 return;
9937 }9998 }
9938 const target = self.dg.module.getTarget();9999 const ptr_alignment = ptr_ty.ptrAlignment(mod);
9939 const ptr_alignment = ptr_ty.ptrAlignment(target);
9940 const ptr_volatile = llvm.Bool.fromBool(info.@"volatile");10000 const ptr_volatile = llvm.Bool.fromBool(info.@"volatile");
994110001
9942 assert(info.vector_index != .runtime);10002 assert(info.vector_index != .runtime);
...@@ -9964,13 +10024,13 @@ pub const FuncGen = struct {...@@ -9964,13 +10024,13 @@ pub const FuncGen = struct {
9964 assert(ordering == .NotAtomic);10024 assert(ordering == .NotAtomic);
9965 containing_int.setAlignment(ptr_alignment);10025 containing_int.setAlignment(ptr_alignment);
9966 containing_int.setVolatile(ptr_volatile);10026 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));
9968 const containing_int_ty = containing_int.typeOf();10028 const containing_int_ty = containing_int.typeOf();
9969 const shift_amt = containing_int_ty.constInt(info.bit_offset, .False);10029 const shift_amt = containing_int_ty.constInt(info.bit_offset, .False);
9970 // Convert to equally-sized integer type in order to perform the bit10030 // Convert to equally-sized integer type in order to perform the bit
9971 // operations on the value to store10031 // operations on the value to store
9972 const value_bits_type = self.context.intType(elem_bits);10032 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))
9974 self.builder.buildPtrToInt(elem, value_bits_type, "")10034 self.builder.buildPtrToInt(elem, value_bits_type, "")
9975 else10035 else
9976 self.builder.buildBitCast(elem, value_bits_type, "");10036 self.builder.buildBitCast(elem, value_bits_type, "");
...@@ -9991,7 +10051,7 @@ pub const FuncGen = struct {...@@ -9991,7 +10051,7 @@ pub const FuncGen = struct {
9991 store_inst.setVolatile(ptr_volatile);10051 store_inst.setVolatile(ptr_volatile);
9992 return;10052 return;
9993 }10053 }
9994 if (!isByRef(elem_ty)) {10054 if (!isByRef(elem_ty, mod)) {
9995 const store_inst = self.builder.buildStore(elem, ptr);10055 const store_inst = self.builder.buildStore(elem, ptr);
9996 store_inst.setOrdering(ordering);10056 store_inst.setOrdering(ordering);
9997 store_inst.setAlignment(ptr_alignment);10057 store_inst.setAlignment(ptr_alignment);
...@@ -9999,13 +10059,13 @@ pub const FuncGen = struct {...@@ -9999,13 +10059,13 @@ pub const FuncGen = struct {
9999 return;10059 return;
10000 }10060 }
10001 assert(ordering == .NotAtomic);10061 assert(ordering == .NotAtomic);
10002 const size_bytes = elem_ty.abiSize(target);10062 const size_bytes = elem_ty.abiSize(mod);
10003 _ = self.builder.buildMemCpy(10063 _ = self.builder.buildMemCpy(
10004 ptr,10064 ptr,
10005 ptr_alignment,10065 ptr_alignment,
10006 elem,10066 elem,
10007 elem_ty.abiAlignment(target),10067 elem_ty.abiAlignment(mod),
10008 self.context.intType(Type.usize.intInfo(target).bits).constInt(size_bytes, .False),10068 self.context.intType(Type.usize.intInfo(mod).bits).constInt(size_bytes, .False),
10009 info.@"volatile",10069 info.@"volatile",
10010 );10070 );
10011 }10071 }
...@@ -10030,11 +10090,12 @@ pub const FuncGen = struct {...@@ -10030,11 +10090,12 @@ pub const FuncGen = struct {
10030 a4: *llvm.Value,10090 a4: *llvm.Value,
10031 a5: *llvm.Value,10091 a5: *llvm.Value,
10032 ) *llvm.Value {10092 ) *llvm.Value {
10033 const target = fg.dg.module.getTarget();10093 const mod = fg.dg.module;
10094 const target = mod.getTarget();
10034 if (!target_util.hasValgrindSupport(target)) return default_value;10095 if (!target_util.hasValgrindSupport(target)) return default_value;
1003510096
10036 const usize_llvm_ty = fg.context.intType(target.ptrBitWidth());10097 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
10039 const array_llvm_ty = usize_llvm_ty.arrayType(6);10100 const array_llvm_ty = usize_llvm_ty.arrayType(6);
10040 const array_ptr = fg.valgrind_client_request_array orelse a: {10101 const array_ptr = fg.valgrind_client_request_array orelse a: {
...@@ -10451,7 +10512,7 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ...@@ -10451,7 +10512,7 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ
10451fn llvmFieldIndex(10512fn llvmFieldIndex(
10452 ty: Type,10513 ty: Type,
10453 field_index: usize,10514 field_index: usize,
10454 target: std.Target,10515 mod: *const Module,
10455 ptr_pl_buf: *Type.Payload.Pointer,10516 ptr_pl_buf: *Type.Payload.Pointer,
10456) ?c_uint {10517) ?c_uint {
10457 // Detects where we inserted extra padding fields so that we can skip10518 // Detects where we inserted extra padding fields so that we can skip
...@@ -10464,9 +10525,9 @@ fn llvmFieldIndex(...@@ -10464,9 +10525,9 @@ fn llvmFieldIndex(
10464 const tuple = ty.tupleFields();10525 const tuple = ty.tupleFields();
10465 var llvm_field_index: c_uint = 0;10526 var llvm_field_index: c_uint = 0;
10466 for (tuple.types, 0..) |field_ty, i| {10527 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);
10470 big_align = @max(big_align, field_align);10531 big_align = @max(big_align, field_align);
10471 const prev_offset = offset;10532 const prev_offset = offset;
10472 offset = std.mem.alignForwardGeneric(u64, offset, field_align);10533 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
...@@ -10488,7 +10549,7 @@ fn llvmFieldIndex(...@@ -10488,7 +10549,7 @@ fn llvmFieldIndex(
10488 }10549 }
1048910550
10490 llvm_field_index += 1;10551 llvm_field_index += 1;
10491 offset += field_ty.abiSize(target);10552 offset += field_ty.abiSize(mod);
10492 }10553 }
10493 return null;10554 return null;
10494 }10555 }
...@@ -10496,10 +10557,10 @@ fn llvmFieldIndex(...@@ -10496,10 +10557,10 @@ fn llvmFieldIndex(
10496 assert(layout != .Packed);10557 assert(layout != .Packed);
1049710558
10498 var llvm_field_index: c_uint = 0;10559 var llvm_field_index: c_uint = 0;
10499 var it = ty.castTag(.@"struct").?.data.runtimeFieldIterator();10560 var it = ty.castTag(.@"struct").?.data.runtimeFieldIterator(mod);
10500 while (it.next()) |field_and_index| {10561 while (it.next()) |field_and_index| {
10501 const field = field_and_index.field;10562 const field = field_and_index.field;
10502 const field_align = field.alignment(target, layout);10563 const field_align = field.alignment(mod, layout);
10503 big_align = @max(big_align, field_align);10564 big_align = @max(big_align, field_align);
10504 const prev_offset = offset;10565 const prev_offset = offset;
10505 offset = std.mem.alignForwardGeneric(u64, offset, field_align);10566 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
...@@ -10521,43 +10582,44 @@ fn llvmFieldIndex(...@@ -10521,43 +10582,44 @@ fn llvmFieldIndex(
10521 }10582 }
1052210583
10523 llvm_field_index += 1;10584 llvm_field_index += 1;
10524 offset += field.ty.abiSize(target);10585 offset += field.ty.abiSize(mod);
10525 } else {10586 } else {
10526 // We did not find an llvm field that corresponds to this zig field.10587 // We did not find an llvm field that corresponds to this zig field.
10527 return null;10588 return null;
10528 }10589 }
10529}10590}
1053010591
10531fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool {10592fn firstParamSRet(fn_info: Type.Payload.Function.Data, mod: *const Module) bool {
10532 if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime()) return false;10593 if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime(mod)) return false;
1053310594
10595 const target = mod.getTarget();
10534 switch (fn_info.cc) {10596 switch (fn_info.cc) {
10535 .Unspecified, .Inline => return isByRef(fn_info.return_type),10597 .Unspecified, .Inline => return isByRef(fn_info.return_type, mod),
10536 .C => switch (target.cpu.arch) {10598 .C => switch (target.cpu.arch) {
10537 .mips, .mipsel => return false,10599 .mips, .mipsel => return false,
10538 .x86_64 => switch (target.os.tag) {10600 .x86_64 => switch (target.os.tag) {
10539 .windows => return x86_64_abi.classifyWindows(fn_info.return_type, target) == .memory,10601 .windows => return x86_64_abi.classifyWindows(fn_info.return_type, mod) == .memory,
10540 else => return firstParamSRetSystemV(fn_info.return_type, target),10602 else => return firstParamSRetSystemV(fn_info.return_type, mod),
10541 },10603 },
10542 .wasm32 => return wasm_c_abi.classifyType(fn_info.return_type, target)[0] == .indirect,10604 .wasm32 => return wasm_c_abi.classifyType(fn_info.return_type, mod)[0] == .indirect,
10543 .aarch64, .aarch64_be => return aarch64_c_abi.classifyType(fn_info.return_type, target) == .memory,10605 .aarch64, .aarch64_be => return aarch64_c_abi.classifyType(fn_info.return_type, mod) == .memory,
10544 .arm, .armeb => switch (arm_c_abi.classifyType(fn_info.return_type, target, .ret)) {10606 .arm, .armeb => switch (arm_c_abi.classifyType(fn_info.return_type, mod, .ret)) {
10545 .memory, .i64_array => return true,10607 .memory, .i64_array => return true,
10546 .i32_array => |size| return size != 1,10608 .i32_array => |size| return size != 1,
10547 .byval => return false,10609 .byval => return false,
10548 },10610 },
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,
10550 else => return false, // TODO investigate C ABI for other architectures10612 else => return false, // TODO investigate C ABI for other architectures
10551 },10613 },
10552 .SysV => return firstParamSRetSystemV(fn_info.return_type, target),10614 .SysV => return firstParamSRetSystemV(fn_info.return_type, mod),
10553 .Win64 => return x86_64_abi.classifyWindows(fn_info.return_type, target) == .memory,10615 .Win64 => return x86_64_abi.classifyWindows(fn_info.return_type, mod) == .memory,
10554 .Stdcall => return !isScalar(fn_info.return_type),10616 .Stdcall => return !isScalar(mod, fn_info.return_type),
10555 else => return false,10617 else => return false,
10556 }10618 }
10557}10619}
1055810620
10559fn firstParamSRetSystemV(ty: Type, target: std.Target) bool {10621fn firstParamSRetSystemV(ty: Type, mod: *const Module) bool {
10560 const class = x86_64_abi.classifySystemV(ty, target, .ret);10622 const class = x86_64_abi.classifySystemV(ty, mod, .ret);
10561 if (class[0] == .memory) return true;10623 if (class[0] == .memory) return true;
10562 if (class[0] == .x87 and class[2] != .none) return true;10624 if (class[0] == .x87 and class[2] != .none) return true;
10563 return false;10625 return false;
...@@ -10567,20 +10629,21 @@ fn firstParamSRetSystemV(ty: Type, target: std.Target) bool {...@@ -10567,20 +10629,21 @@ fn firstParamSRetSystemV(ty: Type, target: std.Target) bool {
10567/// completely differently in the function prototype to honor the C ABI, and then10629/// completely differently in the function prototype to honor the C ABI, and then
10568/// be effectively bitcasted to the actual return type.10630/// be effectively bitcasted to the actual return type.
10569fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {10631fn 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)) {
10571 // If the return type is an error set or an error union, then we make this10634 // If the return type is an error set or an error union, then we make this
10572 // anyerror return type instead, so that it can be coerced into a function10635 // anyerror return type instead, so that it can be coerced into a function
10573 // pointer type which has anyerror as the return type.10636 // pointer type which has anyerror as the return type.
10574 if (fn_info.return_type.isError()) {10637 if (fn_info.return_type.isError(mod)) {
10575 return dg.lowerType(Type.anyerror);10638 return dg.lowerType(Type.anyerror);
10576 } else {10639 } else {
10577 return dg.context.voidType();10640 return dg.context.voidType();
10578 }10641 }
10579 }10642 }
10580 const target = dg.module.getTarget();10643 const target = mod.getTarget();
10581 switch (fn_info.cc) {10644 switch (fn_info.cc) {
10582 .Unspecified, .Inline => {10645 .Unspecified, .Inline => {
10583 if (isByRef(fn_info.return_type)) {10646 if (isByRef(fn_info.return_type, mod)) {
10584 return dg.context.voidType();10647 return dg.context.voidType();
10585 } else {10648 } else {
10586 return dg.lowerType(fn_info.return_type);10649 return dg.lowerType(fn_info.return_type);
...@@ -10594,33 +10657,33 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {...@@ -10594,33 +10657,33 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
10594 else => return lowerSystemVFnRetTy(dg, fn_info),10657 else => return lowerSystemVFnRetTy(dg, fn_info),
10595 },10658 },
10596 .wasm32 => {10659 .wasm32 => {
10597 if (isScalar(fn_info.return_type)) {10660 if (isScalar(mod, fn_info.return_type)) {
10598 return dg.lowerType(fn_info.return_type);10661 return dg.lowerType(fn_info.return_type);
10599 }10662 }
10600 const classes = wasm_c_abi.classifyType(fn_info.return_type, target);10663 const classes = wasm_c_abi.classifyType(fn_info.return_type, mod);
10601 if (classes[0] == .indirect or classes[0] == .none) {10664 if (classes[0] == .indirect or classes[0] == .none) {
10602 return dg.context.voidType();10665 return dg.context.voidType();
10603 }10666 }
1060410667
10605 assert(classes[0] == .direct and classes[1] == .none);10668 assert(classes[0] == .direct and classes[1] == .none);
10606 const scalar_type = wasm_c_abi.scalarType(fn_info.return_type, target);10669 const scalar_type = wasm_c_abi.scalarType(fn_info.return_type, mod);
10607 const abi_size = scalar_type.abiSize(target);10670 const abi_size = scalar_type.abiSize(mod);
10608 return dg.context.intType(@intCast(c_uint, abi_size * 8));10671 return dg.context.intType(@intCast(c_uint, abi_size * 8));
10609 },10672 },
10610 .aarch64, .aarch64_be => {10673 .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)) {
10612 .memory => return dg.context.voidType(),10675 .memory => return dg.context.voidType(),
10613 .float_array => return dg.lowerType(fn_info.return_type),10676 .float_array => return dg.lowerType(fn_info.return_type),
10614 .byval => return dg.lowerType(fn_info.return_type),10677 .byval => return dg.lowerType(fn_info.return_type),
10615 .integer => {10678 .integer => {
10616 const bit_size = fn_info.return_type.bitSize(target);10679 const bit_size = fn_info.return_type.bitSize(mod);
10617 return dg.context.intType(@intCast(c_uint, bit_size));10680 return dg.context.intType(@intCast(c_uint, bit_size));
10618 },10681 },
10619 .double_integer => return dg.context.intType(64).arrayType(2),10682 .double_integer => return dg.context.intType(64).arrayType(2),
10620 }10683 }
10621 },10684 },
10622 .arm, .armeb => {10685 .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)) {
10624 .memory, .i64_array => return dg.context.voidType(),10687 .memory, .i64_array => return dg.context.voidType(),
10625 .i32_array => |len| if (len == 1) {10688 .i32_array => |len| if (len == 1) {
10626 return dg.context.intType(32);10689 return dg.context.intType(32);
...@@ -10631,10 +10694,10 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {...@@ -10631,10 +10694,10 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
10631 }10694 }
10632 },10695 },
10633 .riscv32, .riscv64 => {10696 .riscv32, .riscv64 => {
10634 switch (riscv_c_abi.classifyType(fn_info.return_type, target)) {10697 switch (riscv_c_abi.classifyType(fn_info.return_type, mod)) {
10635 .memory => return dg.context.voidType(),10698 .memory => return dg.context.voidType(),
10636 .integer => {10699 .integer => {
10637 const bit_size = fn_info.return_type.bitSize(target);10700 const bit_size = fn_info.return_type.bitSize(mod);
10638 return dg.context.intType(@intCast(c_uint, bit_size));10701 return dg.context.intType(@intCast(c_uint, bit_size));
10639 },10702 },
10640 .double_integer => {10703 .double_integer => {
...@@ -10654,7 +10717,7 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {...@@ -10654,7 +10717,7 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
10654 .Win64 => return lowerWin64FnRetTy(dg, fn_info),10717 .Win64 => return lowerWin64FnRetTy(dg, fn_info),
10655 .SysV => return lowerSystemVFnRetTy(dg, fn_info),10718 .SysV => return lowerSystemVFnRetTy(dg, fn_info),
10656 .Stdcall => {10719 .Stdcall => {
10657 if (isScalar(fn_info.return_type)) {10720 if (isScalar(mod, fn_info.return_type)) {
10658 return dg.lowerType(fn_info.return_type);10721 return dg.lowerType(fn_info.return_type);
10659 } else {10722 } else {
10660 return dg.context.voidType();10723 return dg.context.voidType();
...@@ -10665,13 +10728,13 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {...@@ -10665,13 +10728,13 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
10665}10728}
1066610729
10667fn lowerWin64FnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {10730fn lowerWin64FnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
10668 const target = dg.module.getTarget();10731 const mod = dg.module;
10669 switch (x86_64_abi.classifyWindows(fn_info.return_type, target)) {10732 switch (x86_64_abi.classifyWindows(fn_info.return_type, mod)) {
10670 .integer => {10733 .integer => {
10671 if (isScalar(fn_info.return_type)) {10734 if (isScalar(mod, fn_info.return_type)) {
10672 return dg.lowerType(fn_info.return_type);10735 return dg.lowerType(fn_info.return_type);
10673 } else {10736 } else {
10674 const abi_size = fn_info.return_type.abiSize(target);10737 const abi_size = fn_info.return_type.abiSize(mod);
10675 return dg.context.intType(@intCast(c_uint, abi_size * 8));10738 return dg.context.intType(@intCast(c_uint, abi_size * 8));
10676 }10739 }
10677 },10740 },
...@@ -10683,11 +10746,11 @@ fn lowerWin64FnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.T...@@ -10683,11 +10746,11 @@ fn lowerWin64FnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.T
10683}10746}
1068410747
10685fn lowerSystemVFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {10748fn 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)) {
10687 return dg.lowerType(fn_info.return_type);10751 return dg.lowerType(fn_info.return_type);
10688 }10752 }
10689 const target = dg.module.getTarget();10753 const classes = x86_64_abi.classifySystemV(fn_info.return_type, mod, .ret);
10690 const classes = x86_64_abi.classifySystemV(fn_info.return_type, target, .ret);
10691 if (classes[0] == .memory) {10754 if (classes[0] == .memory) {
10692 return dg.context.voidType();10755 return dg.context.voidType();
10693 }10756 }
...@@ -10728,7 +10791,7 @@ fn lowerSystemVFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm...@@ -10728,7 +10791,7 @@ fn lowerSystemVFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm
10728 }10791 }
10729 }10792 }
10730 if (classes[0] == .integer and classes[1] == .none) {10793 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);
10732 return dg.context.intType(@intCast(c_uint, abi_size * 8));10795 return dg.context.intType(@intCast(c_uint, abi_size * 8));
10733 }10796 }
10734 return dg.context.structType(&llvm_types_buffer, llvm_types_index, .False);10797 return dg.context.structType(&llvm_types_buffer, llvm_types_index, .False);
...@@ -10739,7 +10802,6 @@ const ParamTypeIterator = struct {...@@ -10739,7 +10802,6 @@ const ParamTypeIterator = struct {
10739 fn_info: Type.Payload.Function.Data,10802 fn_info: Type.Payload.Function.Data,
10740 zig_index: u32,10803 zig_index: u32,
10741 llvm_index: u32,10804 llvm_index: u32,
10742 target: std.Target,
10743 llvm_types_len: u32,10805 llvm_types_len: u32,
10744 llvm_types_buffer: [8]*llvm.Type,10806 llvm_types_buffer: [8]*llvm.Type,
10745 byval_attr: bool,10807 byval_attr: bool,
...@@ -10779,7 +10841,10 @@ const ParamTypeIterator = struct {...@@ -10779,7 +10841,10 @@ const ParamTypeIterator = struct {
10779 }10841 }
1078010842
10781 fn nextInner(it: *ParamTypeIterator, ty: Type) ?Lowering {10843 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)) {
10783 it.zig_index += 1;10848 it.zig_index += 1;
10784 return .no_bits;10849 return .no_bits;
10785 }10850 }
...@@ -10788,10 +10853,10 @@ const ParamTypeIterator = struct {...@@ -10788,10 +10853,10 @@ const ParamTypeIterator = struct {
10788 it.zig_index += 1;10853 it.zig_index += 1;
10789 it.llvm_index += 1;10854 it.llvm_index += 1;
10790 var buf: Type.Payload.ElemType = undefined;10855 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())) {
10792 it.llvm_index += 1;10857 it.llvm_index += 1;
10793 return .slice;10858 return .slice;
10794 } else if (isByRef(ty)) {10859 } else if (isByRef(ty, mod)) {
10795 return .byref;10860 return .byref;
10796 } else {10861 } else {
10797 return .byval;10862 return .byval;
...@@ -10801,23 +10866,23 @@ const ParamTypeIterator = struct {...@@ -10801,23 +10866,23 @@ const ParamTypeIterator = struct {
10801 @panic("TODO implement async function lowering in the LLVM backend");10866 @panic("TODO implement async function lowering in the LLVM backend");
10802 },10867 },
10803 .C => {10868 .C => {
10804 switch (it.target.cpu.arch) {10869 switch (target.cpu.arch) {
10805 .mips, .mipsel => {10870 .mips, .mipsel => {
10806 it.zig_index += 1;10871 it.zig_index += 1;
10807 it.llvm_index += 1;10872 it.llvm_index += 1;
10808 return .byval;10873 return .byval;
10809 },10874 },
10810 .x86_64 => switch (it.target.os.tag) {10875 .x86_64 => switch (target.os.tag) {
10811 .windows => return it.nextWin64(ty),10876 .windows => return it.nextWin64(ty),
10812 else => return it.nextSystemV(ty),10877 else => return it.nextSystemV(ty),
10813 },10878 },
10814 .wasm32 => {10879 .wasm32 => {
10815 it.zig_index += 1;10880 it.zig_index += 1;
10816 it.llvm_index += 1;10881 it.llvm_index += 1;
10817 if (isScalar(ty)) {10882 if (isScalar(mod, ty)) {
10818 return .byval;10883 return .byval;
10819 }10884 }
10820 const classes = wasm_c_abi.classifyType(ty, it.target);10885 const classes = wasm_c_abi.classifyType(ty, mod);
10821 if (classes[0] == .indirect) {10886 if (classes[0] == .indirect) {
10822 return .byref;10887 return .byref;
10823 }10888 }
...@@ -10826,7 +10891,7 @@ const ParamTypeIterator = struct {...@@ -10826,7 +10891,7 @@ const ParamTypeIterator = struct {
10826 .aarch64, .aarch64_be => {10891 .aarch64, .aarch64_be => {
10827 it.zig_index += 1;10892 it.zig_index += 1;
10828 it.llvm_index += 1;10893 it.llvm_index += 1;
10829 switch (aarch64_c_abi.classifyType(ty, it.target)) {10894 switch (aarch64_c_abi.classifyType(ty, mod)) {
10830 .memory => return .byref_mut,10895 .memory => return .byref_mut,
10831 .float_array => |len| return Lowering{ .float_array = len },10896 .float_array => |len| return Lowering{ .float_array = len },
10832 .byval => return .byval,10897 .byval => return .byval,
...@@ -10841,7 +10906,7 @@ const ParamTypeIterator = struct {...@@ -10841,7 +10906,7 @@ const ParamTypeIterator = struct {
10841 .arm, .armeb => {10906 .arm, .armeb => {
10842 it.zig_index += 1;10907 it.zig_index += 1;
10843 it.llvm_index += 1;10908 it.llvm_index += 1;
10844 switch (arm_c_abi.classifyType(ty, it.target, .arg)) {10909 switch (arm_c_abi.classifyType(ty, mod, .arg)) {
10845 .memory => {10910 .memory => {
10846 it.byval_attr = true;10911 it.byval_attr = true;
10847 return .byref;10912 return .byref;
...@@ -10857,7 +10922,7 @@ const ParamTypeIterator = struct {...@@ -10857,7 +10922,7 @@ const ParamTypeIterator = struct {
10857 if (ty.tag() == .f16) {10922 if (ty.tag() == .f16) {
10858 return .as_u16;10923 return .as_u16;
10859 }10924 }
10860 switch (riscv_c_abi.classifyType(ty, it.target)) {10925 switch (riscv_c_abi.classifyType(ty, mod)) {
10861 .memory => return .byref_mut,10926 .memory => return .byref_mut,
10862 .byval => return .byval,10927 .byval => return .byval,
10863 .integer => return .abi_sized_int,10928 .integer => return .abi_sized_int,
...@@ -10878,7 +10943,7 @@ const ParamTypeIterator = struct {...@@ -10878,7 +10943,7 @@ const ParamTypeIterator = struct {
10878 it.zig_index += 1;10943 it.zig_index += 1;
10879 it.llvm_index += 1;10944 it.llvm_index += 1;
1088010945
10881 if (isScalar(ty)) {10946 if (isScalar(mod, ty)) {
10882 return .byval;10947 return .byval;
10883 } else {10948 } else {
10884 it.byval_attr = true;10949 it.byval_attr = true;
...@@ -10894,9 +10959,10 @@ const ParamTypeIterator = struct {...@@ -10894,9 +10959,10 @@ const ParamTypeIterator = struct {
10894 }10959 }
1089510960
10896 fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering {10961 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)) {
10898 .integer => {10964 .integer => {
10899 if (isScalar(ty)) {10965 if (isScalar(mod, ty)) {
10900 it.zig_index += 1;10966 it.zig_index += 1;
10901 it.llvm_index += 1;10967 it.llvm_index += 1;
10902 return .byval;10968 return .byval;
...@@ -10926,14 +10992,15 @@ const ParamTypeIterator = struct {...@@ -10926,14 +10992,15 @@ const ParamTypeIterator = struct {
10926 }10992 }
1092710993
10928 fn nextSystemV(it: *ParamTypeIterator, ty: Type) ?Lowering {10994 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);
10930 if (classes[0] == .memory) {10997 if (classes[0] == .memory) {
10931 it.zig_index += 1;10998 it.zig_index += 1;
10932 it.llvm_index += 1;10999 it.llvm_index += 1;
10933 it.byval_attr = true;11000 it.byval_attr = true;
10934 return .byref;11001 return .byref;
10935 }11002 }
10936 if (isScalar(ty)) {11003 if (isScalar(mod, ty)) {
10937 it.zig_index += 1;11004 it.zig_index += 1;
10938 it.llvm_index += 1;11005 it.llvm_index += 1;
10939 return .byval;11006 return .byval;
...@@ -10992,7 +11059,6 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp...@@ -10992,7 +11059,6 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp
10992 .fn_info = fn_info,11059 .fn_info = fn_info,
10993 .zig_index = 0,11060 .zig_index = 0,
10994 .llvm_index = 0,11061 .llvm_index = 0,
10995 .target = dg.module.getTarget(),
10996 .llvm_types_buffer = undefined,11062 .llvm_types_buffer = undefined,
10997 .llvm_types_len = 0,11063 .llvm_types_len = 0,
10998 .byval_attr = false,11064 .byval_attr = false,
...@@ -11001,16 +11067,17 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp...@@ -11001,16 +11067,17 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp
1100111067
11002fn ccAbiPromoteInt(11068fn ccAbiPromoteInt(
11003 cc: std.builtin.CallingConvention,11069 cc: std.builtin.CallingConvention,
11004 target: std.Target,11070 mod: *const Module,
11005 ty: Type,11071 ty: Type,
11006) ?std.builtin.Signedness {11072) ?std.builtin.Signedness {
11073 const target = mod.getTarget();
11007 switch (cc) {11074 switch (cc) {
11008 .Unspecified, .Inline, .Async => return null,11075 .Unspecified, .Inline, .Async => return null,
11009 else => {},11076 else => {},
11010 }11077 }
11011 const int_info = switch (ty.zigTypeTag()) {11078 const int_info = switch (ty.zigTypeTag(mod)) {
11012 .Bool => Type.u1.intInfo(target),11079 .Bool => Type.u1.intInfo(mod),
11013 .Int, .Enum, .ErrorSet => ty.intInfo(target),11080 .Int, .Enum, .ErrorSet => ty.intInfo(mod),
11014 else => return null,11081 else => return null,
11015 };11082 };
11016 if (int_info.bits <= 16) return int_info.signedness;11083 if (int_info.bits <= 16) return int_info.signedness;
...@@ -11039,12 +11106,12 @@ fn ccAbiPromoteInt(...@@ -11039,12 +11106,12 @@ fn ccAbiPromoteInt(
1103911106
11040/// This is the one source of truth for whether a type is passed around as an LLVM pointer,11107/// This is the one source of truth for whether a type is passed around as an LLVM pointer,
11041/// or as an LLVM value.11108/// or as an LLVM value.
11042fn isByRef(ty: Type) bool {11109fn isByRef(ty: Type, mod: *const Module) bool {
11043 // For tuples and structs, if there are more than this many non-void11110 // For tuples and structs, if there are more than this many non-void
11044 // fields, then we make it byref, otherwise byval.11111 // fields, then we make it byref, otherwise byval.
11045 const max_fields_byval = 0;11112 const max_fields_byval = 0;
1104611113
11047 switch (ty.zigTypeTag()) {11114 switch (ty.zigTypeTag(mod)) {
11048 .Type,11115 .Type,
11049 .ComptimeInt,11116 .ComptimeInt,
11050 .ComptimeFloat,11117 .ComptimeFloat,
...@@ -11067,7 +11134,7 @@ fn isByRef(ty: Type) bool {...@@ -11067,7 +11134,7 @@ fn isByRef(ty: Type) bool {
11067 .AnyFrame,11134 .AnyFrame,
11068 => return false,11135 => return false,
1106911136
11070 .Array, .Frame => return ty.hasRuntimeBits(),11137 .Array, .Frame => return ty.hasRuntimeBits(mod),
11071 .Struct => {11138 .Struct => {
11072 // Packed structs are represented to LLVM as integers.11139 // Packed structs are represented to LLVM as integers.
11073 if (ty.containerLayout() == .Packed) return false;11140 if (ty.containerLayout() == .Packed) return false;
...@@ -11075,32 +11142,32 @@ fn isByRef(ty: Type) bool {...@@ -11075,32 +11142,32 @@ fn isByRef(ty: Type) bool {
11075 const tuple = ty.tupleFields();11142 const tuple = ty.tupleFields();
11076 var count: usize = 0;11143 var count: usize = 0;
11077 for (tuple.values, 0..) |field_val, i| {11144 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
11080 count += 1;11147 count += 1;
11081 if (count > max_fields_byval) return true;11148 if (count > max_fields_byval) return true;
11082 if (isByRef(tuple.types[i])) return true;11149 if (isByRef(tuple.types[i], mod)) return true;
11083 }11150 }
11084 return false;11151 return false;
11085 }11152 }
11086 var count: usize = 0;11153 var count: usize = 0;
11087 const fields = ty.structFields();11154 const fields = ty.structFields();
11088 for (fields.values()) |field| {11155 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
11091 count += 1;11158 count += 1;
11092 if (count > max_fields_byval) return true;11159 if (count > max_fields_byval) return true;
11093 if (isByRef(field.ty)) return true;11160 if (isByRef(field.ty, mod)) return true;
11094 }11161 }
11095 return false;11162 return false;
11096 },11163 },
11097 .Union => switch (ty.containerLayout()) {11164 .Union => switch (ty.containerLayout()) {
11098 .Packed => return false,11165 .Packed => return false,
11099 else => return ty.hasRuntimeBits(),11166 else => return ty.hasRuntimeBits(mod),
11100 },11167 },
11101 .ErrorUnion => {11168 .ErrorUnion => {
11102 const payload_ty = ty.errorUnionPayload();11169 const payload_ty = ty.errorUnionPayload();
11103 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {11170 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
11104 return false;11171 return false;
11105 }11172 }
11106 return true;11173 return true;
...@@ -11108,10 +11175,10 @@ fn isByRef(ty: Type) bool {...@@ -11108,10 +11175,10 @@ fn isByRef(ty: Type) bool {
11108 .Optional => {11175 .Optional => {
11109 var buf: Type.Payload.ElemType = undefined;11176 var buf: Type.Payload.ElemType = undefined;
11110 const payload_ty = ty.optionalChild(&buf);11177 const payload_ty = ty.optionalChild(&buf);
11111 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {11178 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
11112 return false;11179 return false;
11113 }11180 }
11114 if (ty.optionalReprIsPayload()) {11181 if (ty.optionalReprIsPayload(mod)) {
11115 return false;11182 return false;
11116 }11183 }
11117 return true;11184 return true;
...@@ -11119,8 +11186,8 @@ fn isByRef(ty: Type) bool {...@@ -11119,8 +11186,8 @@ fn isByRef(ty: Type) bool {
11119 }11186 }
11120}11187}
1112111188
11122fn isScalar(ty: Type) bool {11189fn isScalar(mod: *const Module, ty: Type) bool {
11123 return switch (ty.zigTypeTag()) {11190 return switch (ty.zigTypeTag(mod)) {
11124 .Void,11191 .Void,
11125 .Bool,11192 .Bool,
11126 .NoReturn,11193 .NoReturn,
...@@ -11304,12 +11371,12 @@ fn buildAllocaInner(...@@ -11304,12 +11371,12 @@ fn buildAllocaInner(
11304 return alloca;11371 return alloca;
11305}11372}
1130611373
11307fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u1 {11374fn errUnionPayloadOffset(payload_ty: Type, mod: *const Module) u1 {
11308 return @boolToInt(Type.anyerror.abiAlignment(target) > payload_ty.abiAlignment(target));11375 return @boolToInt(Type.anyerror.abiAlignment(mod) > payload_ty.abiAlignment(mod));
11309}11376}
1131011377
11311fn errUnionErrorOffset(payload_ty: Type, target: std.Target) u1 {11378fn errUnionErrorOffset(payload_ty: Type, mod: *const Module) u1 {
11312 return @boolToInt(Type.anyerror.abiAlignment(target) <= payload_ty.abiAlignment(target));11379 return @boolToInt(Type.anyerror.abiAlignment(mod) <= payload_ty.abiAlignment(mod));
11313}11380}
1131411381
11315/// Returns true for asm constraint (e.g. "=*m", "=r") if it accepts a memory location11382/// 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 {...@@ -231,9 +231,10 @@ pub const DeclGen = struct {
231231
232 /// Fetch the result-id for a previously generated instruction or constant.232 /// Fetch the result-id for a previously generated instruction or constant.
233 fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef {233 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| {
235 const ty = self.air.typeOf(inst);236 const ty = self.air.typeOf(inst);
236 if (ty.zigTypeTag() == .Fn) {237 if (ty.zigTypeTag(mod) == .Fn) {
237 const fn_decl_index = switch (val.tag()) {238 const fn_decl_index = switch (val.tag()) {
238 .extern_fn => val.castTag(.extern_fn).?.data.owner_decl,239 .extern_fn => val.castTag(.extern_fn).?.data.owner_decl,
239 .function => val.castTag(.function).?.data.owner_decl,240 .function => val.castTag(.function).?.data.owner_decl,
...@@ -340,8 +341,9 @@ pub const DeclGen = struct {...@@ -340,8 +341,9 @@ pub const DeclGen = struct {
340 }341 }
341342
342 fn arithmeticTypeInfo(self: *DeclGen, ty: Type) !ArithmeticTypeInfo {343 fn arithmeticTypeInfo(self: *DeclGen, ty: Type) !ArithmeticTypeInfo {
344 const mod = self.module;
343 const target = self.getTarget();345 const target = self.getTarget();
344 return switch (ty.zigTypeTag()) {346 return switch (ty.zigTypeTag(mod)) {
345 .Bool => ArithmeticTypeInfo{347 .Bool => ArithmeticTypeInfo{
346 .bits = 1, // Doesn't matter for this class.348 .bits = 1, // Doesn't matter for this class.
347 .is_vector = false,349 .is_vector = false,
...@@ -355,7 +357,7 @@ pub const DeclGen = struct {...@@ -355,7 +357,7 @@ pub const DeclGen = struct {
355 .class = .float,357 .class = .float,
356 },358 },
357 .Int => blk: {359 .Int => blk: {
358 const int_info = ty.intInfo(target);360 const int_info = ty.intInfo(mod);
359 // TODO: Maybe it's useful to also return this value.361 // TODO: Maybe it's useful to also return this value.
360 const maybe_backing_bits = self.backingIntBits(int_info.bits);362 const maybe_backing_bits = self.backingIntBits(int_info.bits);
361 break :blk ArithmeticTypeInfo{363 break :blk ArithmeticTypeInfo{
...@@ -533,21 +535,22 @@ pub const DeclGen = struct {...@@ -533,21 +535,22 @@ pub const DeclGen = struct {
533 }535 }
534536
535 fn addInt(self: *@This(), ty: Type, val: Value) !void {537 fn addInt(self: *@This(), ty: Type, val: Value) !void {
536 const target = self.dg.getTarget();538 const mod = self.dg.module;
537 const int_info = ty.intInfo(target);539 const int_info = ty.intInfo(mod);
538 const int_bits = switch (int_info.signedness) {540 const int_bits = switch (int_info.signedness) {
539 .signed => @bitCast(u64, val.toSignedInt(target)),541 .signed => @bitCast(u64, val.toSignedInt(mod)),
540 .unsigned => val.toUnsignedInt(target),542 .unsigned => val.toUnsignedInt(mod),
541 };543 };
542544
543 // TODO: Swap endianess if the compiler is big endian.545 // TODO: Swap endianess if the compiler is big endian.
544 const len = ty.abiSize(target);546 const len = ty.abiSize(mod);
545 try self.addBytes(std.mem.asBytes(&int_bits)[0..@intCast(usize, len)]);547 try self.addBytes(std.mem.asBytes(&int_bits)[0..@intCast(usize, len)]);
546 }548 }
547549
548 fn addFloat(self: *@This(), ty: Type, val: Value) !void {550 fn addFloat(self: *@This(), ty: Type, val: Value) !void {
551 const mod = self.dg.module;
549 const target = self.dg.getTarget();552 const target = self.dg.getTarget();
550 const len = ty.abiSize(target);553 const len = ty.abiSize(mod);
551554
552 // TODO: Swap endianess if the compiler is big endian.555 // TODO: Swap endianess if the compiler is big endian.
553 switch (ty.floatBits(target)) {556 switch (ty.floatBits(target)) {
...@@ -607,15 +610,15 @@ pub const DeclGen = struct {...@@ -607,15 +610,15 @@ pub const DeclGen = struct {
607 }610 }
608611
609 fn lower(self: *@This(), ty: Type, val: Value) !void {612 fn lower(self: *@This(), ty: Type, val: Value) !void {
610 const target = self.dg.getTarget();
611 const dg = self.dg;613 const dg = self.dg;
614 const mod = dg.module;
612615
613 if (val.isUndef()) {616 if (val.isUndef()) {
614 const size = ty.abiSize(target);617 const size = ty.abiSize(mod);
615 return try self.addUndef(size);618 return try self.addUndef(size);
616 }619 }
617620
618 switch (ty.zigTypeTag()) {621 switch (ty.zigTypeTag(mod)) {
619 .Int => try self.addInt(ty, val),622 .Int => try self.addInt(ty, val),
620 .Float => try self.addFloat(ty, val),623 .Float => try self.addFloat(ty, val),
621 .Bool => try self.addConstBool(val.toBool()),624 .Bool => try self.addConstBool(val.toBool()),
...@@ -644,7 +647,7 @@ pub const DeclGen = struct {...@@ -644,7 +647,7 @@ pub const DeclGen = struct {
644 const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len];647 const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
645 try self.addBytes(bytes);648 try self.addBytes(bytes);
646 if (ty.sentinel()) |sentinel| {649 if (ty.sentinel()) |sentinel| {
647 try self.addByte(@intCast(u8, sentinel.toUnsignedInt(target)));650 try self.addByte(@intCast(u8, sentinel.toUnsignedInt(mod)));
648 }651 }
649 },652 },
650 .bytes => {653 .bytes => {
...@@ -690,13 +693,13 @@ pub const DeclGen = struct {...@@ -690,13 +693,13 @@ pub const DeclGen = struct {
690 const struct_begin = self.size;693 const struct_begin = self.size;
691 const field_vals = val.castTag(.aggregate).?.data;694 const field_vals = val.castTag(.aggregate).?.data;
692 for (struct_ty.fields.values(), 0..) |field, i| {695 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;
694 try self.lower(field.ty, field_vals[i]);697 try self.lower(field.ty, field_vals[i]);
695698
696 // Add padding if required.699 // Add padding if required.
697 // TODO: Add to type generation as well?700 // TODO: Add to type generation as well?
698 const unpadded_field_end = self.size - struct_begin;701 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);
700 const padding = padded_field_end - unpadded_field_end;703 const padding = padded_field_end - unpadded_field_end;
701 try self.addUndef(padding);704 try self.addUndef(padding);
702 }705 }
...@@ -705,13 +708,13 @@ pub const DeclGen = struct {...@@ -705,13 +708,13 @@ pub const DeclGen = struct {
705 .Optional => {708 .Optional => {
706 var opt_buf: Type.Payload.ElemType = undefined;709 var opt_buf: Type.Payload.ElemType = undefined;
707 const payload_ty = ty.optionalChild(&opt_buf);710 const payload_ty = ty.optionalChild(&opt_buf);
708 const has_payload = !val.isNull();711 const has_payload = !val.isNull(mod);
709 const abi_size = ty.abiSize(target);712 const abi_size = ty.abiSize(mod);
710713
711 if (!payload_ty.hasRuntimeBits()) {714 if (!payload_ty.hasRuntimeBits(mod)) {
712 try self.addConstBool(has_payload);715 try self.addConstBool(has_payload);
713 return;716 return;
714 } else if (ty.optionalReprIsPayload()) {717 } else if (ty.optionalReprIsPayload(mod)) {
715 // Optional representation is a nullable pointer or slice.718 // Optional representation is a nullable pointer or slice.
716 if (val.castTag(.opt_payload)) |payload| {719 if (val.castTag(.opt_payload)) |payload| {
717 try self.lower(payload_ty, payload.data);720 try self.lower(payload_ty, payload.data);
...@@ -729,7 +732,7 @@ pub const DeclGen = struct {...@@ -729,7 +732,7 @@ pub const DeclGen = struct {
729732
730 // Subtract 1 for @sizeOf(bool).733 // Subtract 1 for @sizeOf(bool).
731 // TODO: Make this not hardcoded.734 // TODO: Make this not hardcoded.
732 const payload_size = payload_ty.abiSize(target);735 const payload_size = payload_ty.abiSize(mod);
733 const padding = abi_size - payload_size - 1;736 const padding = abi_size - payload_size - 1;
734737
735 if (val.castTag(.opt_payload)) |payload| {738 if (val.castTag(.opt_payload)) |payload| {
...@@ -744,14 +747,13 @@ pub const DeclGen = struct {...@@ -744,14 +747,13 @@ pub const DeclGen = struct {
744 var int_val_buffer: Value.Payload.U64 = undefined;747 var int_val_buffer: Value.Payload.U64 = undefined;
745 const int_val = val.enumToInt(ty, &int_val_buffer);748 const int_val = val.enumToInt(ty, &int_val_buffer);
746749
747 var int_ty_buffer: Type.Payload.Bits = undefined;750 const int_ty = ty.intTagType();
748 const int_ty = ty.intTagType(&int_ty_buffer);
749751
750 try self.lower(int_ty, int_val);752 try self.lower(int_ty, int_val);
751 },753 },
752 .Union => {754 .Union => {
753 const tag_and_val = val.castTag(.@"union").?.data;755 const tag_and_val = val.castTag(.@"union").?.data;
754 const layout = ty.unionGetLayout(target);756 const layout = ty.unionGetLayout(mod);
755757
756 if (layout.payload_size == 0) {758 if (layout.payload_size == 0) {
757 return try self.lower(ty.unionTagTypeSafety().?, tag_and_val.tag);759 return try self.lower(ty.unionTagTypeSafety().?, tag_and_val.tag);
...@@ -772,9 +774,9 @@ pub const DeclGen = struct {...@@ -772,9 +774,9 @@ pub const DeclGen = struct {
772 try self.lower(ty.unionTagTypeSafety().?, tag_and_val.tag);774 try self.lower(ty.unionTagTypeSafety().?, tag_and_val.tag);
773 }775 }
774776
775 const active_field_size = if (active_field_ty.hasRuntimeBitsIgnoreComptime()) blk: {777 const active_field_size = if (active_field_ty.hasRuntimeBitsIgnoreComptime(mod)) blk: {
776 try self.lower(active_field_ty, tag_and_val.val);778 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);
778 } else 0;780 } else 0;
779781
780 const payload_padding_len = layout.payload_size - active_field_size;782 const payload_padding_len = layout.payload_size - active_field_size;
...@@ -808,9 +810,9 @@ pub const DeclGen = struct {...@@ -808,9 +810,9 @@ pub const DeclGen = struct {
808 return try self.lower(Type.anyerror, error_val);810 return try self.lower(Type.anyerror, error_val);
809 }811 }
810812
811 const payload_size = payload_ty.abiSize(target);813 const payload_size = payload_ty.abiSize(mod);
812 const error_size = Type.anyerror.abiAlignment(target);814 const error_size = Type.anyerror.abiAlignment(mod);
813 const ty_size = ty.abiSize(target);815 const ty_size = ty.abiSize(mod);
814 const padding = ty_size - payload_size - error_size;816 const padding = ty_size - payload_size - error_size;
815 const payload_val = if (val.castTag(.eu_payload)) |pl| pl.data else Value.initTag(.undef);817 const payload_val = if (val.castTag(.eu_payload)) |pl| pl.data else Value.initTag(.undef);
816818
...@@ -886,7 +888,7 @@ pub const DeclGen = struct {...@@ -886,7 +888,7 @@ pub const DeclGen = struct {
886 // .id_result = result_id,888 // .id_result = result_id,
887 // .storage_class = storage_class,889 // .storage_class = storage_class,
888 // });890 // });
889 // } else if (ty.abiSize(target) == 0) {891 // } else if (ty.abiSize(mod) == 0) {
890 // // Special case: if the type has no size, then return an undefined pointer.892 // // Special case: if the type has no size, then return an undefined pointer.
891 // return try section.emit(self.spv.gpa, .OpUndef, .{893 // return try section.emit(self.spv.gpa, .OpUndef, .{
892 // .id_result_type = self.typeId(ptr_ty_ref),894 // .id_result_type = self.typeId(ptr_ty_ref),
...@@ -968,6 +970,7 @@ pub const DeclGen = struct {...@@ -968,6 +970,7 @@ pub const DeclGen = struct {
968 /// is then loaded using OpLoad. Such values are loaded into the UniformConstant storage class by default.970 /// is then loaded using OpLoad. Such values are loaded into the UniformConstant storage class by default.
969 /// This function should only be called during function code generation.971 /// This function should only be called during function code generation.
970 fn constant(self: *DeclGen, ty: Type, val: Value, repr: Repr) !IdRef {972 fn constant(self: *DeclGen, ty: Type, val: Value, repr: Repr) !IdRef {
973 const mod = self.module;
971 const target = self.getTarget();974 const target = self.getTarget();
972 const result_ty_ref = try self.resolveType(ty, repr);975 const result_ty_ref = try self.resolveType(ty, repr);
973976
...@@ -977,12 +980,12 @@ pub const DeclGen = struct {...@@ -977,12 +980,12 @@ pub const DeclGen = struct {
977 return self.spv.constUndef(result_ty_ref);980 return self.spv.constUndef(result_ty_ref);
978 }981 }
979982
980 switch (ty.zigTypeTag()) {983 switch (ty.zigTypeTag(mod)) {
981 .Int => {984 .Int => {
982 if (ty.isSignedInt()) {985 if (ty.isSignedInt(mod)) {
983 return try self.spv.constInt(result_ty_ref, val.toSignedInt(target));986 return try self.spv.constInt(result_ty_ref, val.toSignedInt(mod));
984 } else {987 } 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));
986 }989 }
987 },990 },
988 .Bool => switch (repr) {991 .Bool => switch (repr) {
...@@ -1037,7 +1040,7 @@ pub const DeclGen = struct {...@@ -1037,7 +1040,7 @@ pub const DeclGen = struct {
1037 // The value cannot be generated directly, so generate it as an indirect constant,1040 // The value cannot be generated directly, so generate it as an indirect constant,
1038 // and then perform an OpLoad.1041 // and then perform an OpLoad.
1039 const result_id = self.spv.allocId();1042 const result_id = self.spv.allocId();
1040 const alignment = ty.abiAlignment(target);1043 const alignment = ty.abiAlignment(mod);
1041 const spv_decl_index = try self.spv.allocDecl(.global);1044 const spv_decl_index = try self.spv.allocDecl(.global);
10421045
1043 try self.lowerIndirectConstant(1046 try self.lowerIndirectConstant(
...@@ -1114,8 +1117,8 @@ pub const DeclGen = struct {...@@ -1114,8 +1117,8 @@ pub const DeclGen = struct {
1114 /// NOTE: When the active field is set to something other than the most aligned field, the1117 /// NOTE: When the active field is set to something other than the most aligned field, the
1115 /// resulting struct will be *underaligned*.1118 /// resulting struct will be *underaligned*.
1116 fn resolveUnionType(self: *DeclGen, ty: Type, maybe_active_field: ?usize) !CacheRef {1119 fn resolveUnionType(self: *DeclGen, ty: Type, maybe_active_field: ?usize) !CacheRef {
1117 const target = self.getTarget();1120 const mod = self.module;
1118 const layout = ty.unionGetLayout(target);1121 const layout = ty.unionGetLayout(mod);
1119 const union_ty = ty.cast(Type.Payload.Union).?.data;1122 const union_ty = ty.cast(Type.Payload.Union).?.data;
11201123
1121 if (union_ty.layout == .Packed) {1124 if (union_ty.layout == .Packed) {
...@@ -1143,11 +1146,11 @@ pub const DeclGen = struct {...@@ -1143,11 +1146,11 @@ pub const DeclGen = struct {
1143 const active_field = maybe_active_field orelse layout.most_aligned_field;1146 const active_field = maybe_active_field orelse layout.most_aligned_field;
1144 const active_field_ty = union_ty.fields.values()[active_field].ty;1147 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: {
1147 const active_payload_ty_ref = try self.resolveType(active_field_ty, .indirect);1150 const active_payload_ty_ref = try self.resolveType(active_field_ty, .indirect);
1148 member_types.appendAssumeCapacity(active_payload_ty_ref);1151 member_types.appendAssumeCapacity(active_payload_ty_ref);
1149 member_names.appendAssumeCapacity(try self.spv.resolveString("payload"));1152 member_names.appendAssumeCapacity(try self.spv.resolveString("payload"));
1150 break :blk active_field_ty.abiSize(target);1153 break :blk active_field_ty.abiSize(mod);
1151 } else 0;1154 } else 0;
11521155
1153 const payload_padding_len = layout.payload_size - active_field_size;1156 const payload_padding_len = layout.payload_size - active_field_size;
...@@ -1177,21 +1180,21 @@ pub const DeclGen = struct {...@@ -1177,21 +1180,21 @@ pub const DeclGen = struct {
11771180
1178 /// Turn a Zig type into a SPIR-V Type, and return a reference to it.1181 /// Turn a Zig type into a SPIR-V Type, and return a reference to it.
1179 fn resolveType(self: *DeclGen, ty: Type, repr: Repr) Error!CacheRef {1182 fn resolveType(self: *DeclGen, ty: Type, repr: Repr) Error!CacheRef {
1183 const mod = self.module;
1180 log.debug("resolveType: ty = {}", .{ty.fmt(self.module)});1184 log.debug("resolveType: ty = {}", .{ty.fmt(self.module)});
1181 const target = self.getTarget();1185 const target = self.getTarget();
1182 switch (ty.zigTypeTag()) {1186 switch (ty.zigTypeTag(mod)) {
1183 .Void, .NoReturn => return try self.spv.resolve(.void_type),1187 .Void, .NoReturn => return try self.spv.resolve(.void_type),
1184 .Bool => switch (repr) {1188 .Bool => switch (repr) {
1185 .direct => return try self.spv.resolve(.bool_type),1189 .direct => return try self.spv.resolve(.bool_type),
1186 .indirect => return try self.intType(.unsigned, 1),1190 .indirect => return try self.intType(.unsigned, 1),
1187 },1191 },
1188 .Int => {1192 .Int => {
1189 const int_info = ty.intInfo(target);1193 const int_info = ty.intInfo(mod);
1190 return try self.intType(int_info.signedness, int_info.bits);1194 return try self.intType(int_info.signedness, int_info.bits);
1191 },1195 },
1192 .Enum => {1196 .Enum => {
1193 var buffer: Type.Payload.Bits = undefined;1197 const tag_ty = ty.intTagType();
1194 const tag_ty = ty.intTagType(&buffer);
1195 return self.resolveType(tag_ty, repr);1198 return self.resolveType(tag_ty, repr);
1196 },1199 },
1197 .Float => {1200 .Float => {
...@@ -1290,7 +1293,7 @@ pub const DeclGen = struct {...@@ -1290,7 +1293,7 @@ pub const DeclGen = struct {
1290 var member_index: usize = 0;1293 var member_index: usize = 0;
1291 for (tuple.types, 0..) |field_ty, i| {1294 for (tuple.types, 0..) |field_ty, i| {
1292 const field_val = tuple.values[i];1295 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
1295 member_types[member_index] = try self.resolveType(field_ty, .indirect);1298 member_types[member_index] = try self.resolveType(field_ty, .indirect);
1296 member_index += 1;1299 member_index += 1;
...@@ -1315,7 +1318,7 @@ pub const DeclGen = struct {...@@ -1315,7 +1318,7 @@ pub const DeclGen = struct {
13151318
1316 var member_index: usize = 0;1319 var member_index: usize = 0;
1317 for (struct_ty.fields.values(), 0..) |field, i| {1320 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
1320 member_types[member_index] = try self.resolveType(field.ty, .indirect);1323 member_types[member_index] = try self.resolveType(field.ty, .indirect);
1321 member_names[member_index] = try self.spv.resolveString(struct_ty.fields.keys()[i]);1324 member_names[member_index] = try self.spv.resolveString(struct_ty.fields.keys()[i]);
...@@ -1334,7 +1337,7 @@ pub const DeclGen = struct {...@@ -1334,7 +1337,7 @@ pub const DeclGen = struct {
1334 .Optional => {1337 .Optional => {
1335 var buf: Type.Payload.ElemType = undefined;1338 var buf: Type.Payload.ElemType = undefined;
1336 const payload_ty = ty.optionalChild(&buf);1339 const payload_ty = ty.optionalChild(&buf);
1337 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1340 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1338 // Just use a bool.1341 // Just use a bool.
1339 // Note: Always generate the bool with indirect format, to save on some sanity1342 // Note: Always generate the bool with indirect format, to save on some sanity
1340 // Perform the conversion to a direct bool when the field is extracted.1343 // Perform the conversion to a direct bool when the field is extracted.
...@@ -1342,7 +1345,7 @@ pub const DeclGen = struct {...@@ -1342,7 +1345,7 @@ pub const DeclGen = struct {
1342 }1345 }
13431346
1344 const payload_ty_ref = try self.resolveType(payload_ty, .indirect);1347 const payload_ty_ref = try self.resolveType(payload_ty, .indirect);
1345 if (ty.optionalReprIsPayload()) {1348 if (ty.optionalReprIsPayload(mod)) {
1346 // Optional is actually a pointer or a slice.1349 // Optional is actually a pointer or a slice.
1347 return payload_ty_ref;1350 return payload_ty_ref;
1348 }1351 }
...@@ -1445,14 +1448,14 @@ pub const DeclGen = struct {...@@ -1445,14 +1448,14 @@ pub const DeclGen = struct {
1445 };1448 };
14461449
1447 fn errorUnionLayout(self: *DeclGen, payload_ty: Type) ErrorUnionLayout {1450 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);1453 const error_align = Type.anyerror.abiAlignment(mod);
1451 const payload_align = payload_ty.abiAlignment(target);1454 const payload_align = payload_ty.abiAlignment(mod);
14521455
1453 const error_first = error_align > payload_align;1456 const error_first = error_align > payload_align;
1454 return .{1457 return .{
1455 .payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(),1458 .payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod),
1456 .error_first = error_first,1459 .error_first = error_first,
1457 };1460 };
1458 }1461 }
...@@ -1529,14 +1532,15 @@ pub const DeclGen = struct {...@@ -1529,14 +1532,15 @@ pub const DeclGen = struct {
1529 }1532 }
15301533
1531 fn genDecl(self: *DeclGen) !void {1534 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);
1533 const spv_decl_index = try self.resolveDecl(self.decl_index);1537 const spv_decl_index = try self.resolveDecl(self.decl_index);
15341538
1535 const decl_id = self.spv.declPtr(spv_decl_index).result_id;1539 const decl_id = self.spv.declPtr(spv_decl_index).result_id;
1536 log.debug("genDecl: id = {}, index = {}, name = {s}", .{ decl_id.id, @enumToInt(spv_decl_index), decl.name });1540 log.debug("genDecl: id = {}, index = {}, name = {s}", .{ decl_id.id, @enumToInt(spv_decl_index), decl.name });
15371541
1538 if (decl.val.castTag(.function)) |_| {1542 if (decl.val.castTag(.function)) |_| {
1539 assert(decl.ty.zigTypeTag() == .Fn);1543 assert(decl.ty.zigTypeTag(mod) == .Fn);
1540 const prototype_id = try self.resolveTypeId(decl.ty);1544 const prototype_id = try self.resolveTypeId(decl.ty);
1541 try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{1545 try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{
1542 .id_result_type = try self.resolveTypeId(decl.ty.fnReturnType()),1546 .id_result_type = try self.resolveTypeId(decl.ty.fnReturnType()),
...@@ -1634,7 +1638,8 @@ pub const DeclGen = struct {...@@ -1634,7 +1638,8 @@ pub const DeclGen = struct {
1634 /// Convert representation from indirect (in memory) to direct (in 'register')1638 /// Convert representation from indirect (in memory) to direct (in 'register')
1635 /// This converts the argument type from resolveType(ty, .indirect) to resolveType(ty, .direct).1639 /// This converts the argument type from resolveType(ty, .indirect) to resolveType(ty, .direct).
1636 fn convertToDirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef {1640 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)) {
1638 .Bool => blk: {1643 .Bool => blk: {
1639 const direct_bool_ty_ref = try self.resolveType(ty, .direct);1644 const direct_bool_ty_ref = try self.resolveType(ty, .direct);
1640 const indirect_bool_ty_ref = try self.resolveType(ty, .indirect);1645 const indirect_bool_ty_ref = try self.resolveType(ty, .indirect);
...@@ -1655,7 +1660,8 @@ pub const DeclGen = struct {...@@ -1655,7 +1660,8 @@ pub const DeclGen = struct {
1655 /// Convert representation from direct (in 'register) to direct (in memory)1660 /// Convert representation from direct (in 'register) to direct (in memory)
1656 /// This converts the argument type from resolveType(ty, .direct) to resolveType(ty, .indirect).1661 /// This converts the argument type from resolveType(ty, .direct) to resolveType(ty, .indirect).
1657 fn convertToIndirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef {1662 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)) {
1659 .Bool => blk: {1665 .Bool => blk: {
1660 const indirect_bool_ty_ref = try self.resolveType(ty, .indirect);1666 const indirect_bool_ty_ref = try self.resolveType(ty, .indirect);
1661 break :blk self.boolToInt(indirect_bool_ty_ref, operand_id);1667 break :blk self.boolToInt(indirect_bool_ty_ref, operand_id);
...@@ -2056,6 +2062,7 @@ pub const DeclGen = struct {...@@ -2056,6 +2062,7 @@ pub const DeclGen = struct {
2056 }2062 }
20572063
2058 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2064 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2065 const mod = self.module;
2059 if (self.liveness.isUnused(inst)) return null;2066 if (self.liveness.isUnused(inst)) return null;
2060 const ty = self.air.typeOfIndex(inst);2067 const ty = self.air.typeOfIndex(inst);
2061 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2068 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
...@@ -2083,7 +2090,7 @@ pub const DeclGen = struct {...@@ -2083,7 +2090,7 @@ pub const DeclGen = struct {
2083 if (elem.isUndef()) {2090 if (elem.isUndef()) {
2084 self.func.body.writeOperand(spec.LiteralInteger, 0xFFFF_FFFF);2091 self.func.body.writeOperand(spec.LiteralInteger, 0xFFFF_FFFF);
2085 } else {2092 } else {
2086 const int = elem.toSignedInt(self.getTarget());2093 const int = elem.toSignedInt(mod);
2087 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int + a_len);2094 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int + a_len);
2088 self.func.body.writeOperand(spec.LiteralInteger, unsigned);2095 self.func.body.writeOperand(spec.LiteralInteger, unsigned);
2089 }2096 }
...@@ -2189,13 +2196,13 @@ pub const DeclGen = struct {...@@ -2189,13 +2196,13 @@ pub const DeclGen = struct {
2189 lhs_id: IdRef,2196 lhs_id: IdRef,
2190 rhs_id: IdRef,2197 rhs_id: IdRef,
2191 ) !IdRef {2198 ) !IdRef {
2199 const mod = self.module;
2192 var cmp_lhs_id = lhs_id;2200 var cmp_lhs_id = lhs_id;
2193 var cmp_rhs_id = rhs_id;2201 var cmp_rhs_id = rhs_id;
2194 const opcode: Opcode = opcode: {2202 const opcode: Opcode = opcode: {
2195 var int_buffer: Type.Payload.Bits = undefined;2203 const op_ty = switch (ty.zigTypeTag(mod)) {
2196 const op_ty = switch (ty.zigTypeTag()) {
2197 .Int, .Bool, .Float => ty,2204 .Int, .Bool, .Float => ty,
2198 .Enum => ty.intTagType(&int_buffer),2205 .Enum => ty.intTagType(),
2199 .ErrorSet => Type.u16,2206 .ErrorSet => Type.u16,
2200 .Pointer => blk: {2207 .Pointer => blk: {
2201 // Note that while SPIR-V offers OpPtrEqual and OpPtrNotEqual, they are2208 // Note that while SPIR-V offers OpPtrEqual and OpPtrNotEqual, they are
...@@ -2303,13 +2310,14 @@ pub const DeclGen = struct {...@@ -2303,13 +2310,14 @@ pub const DeclGen = struct {
2303 src_ty: Type,2310 src_ty: Type,
2304 src_id: IdRef,2311 src_id: IdRef,
2305 ) !IdRef {2312 ) !IdRef {
2313 const mod = self.module;
2306 const dst_ty_ref = try self.resolveType(dst_ty, .direct);2314 const dst_ty_ref = try self.resolveType(dst_ty, .direct);
2307 const result_id = self.spv.allocId();2315 const result_id = self.spv.allocId();
23082316
2309 // TODO: Some more cases are missing here2317 // TODO: Some more cases are missing here
2310 // See fn bitCast in llvm.zig2318 // 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)) {
2313 try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{2321 try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{
2314 .id_result_type = self.typeId(dst_ty_ref),2322 .id_result_type = self.typeId(dst_ty_ref),
2315 .id_result = result_id,2323 .id_result = result_id,
...@@ -2342,8 +2350,8 @@ pub const DeclGen = struct {...@@ -2342,8 +2350,8 @@ pub const DeclGen = struct {
2342 const dest_ty = self.air.typeOfIndex(inst);2350 const dest_ty = self.air.typeOfIndex(inst);
2343 const dest_ty_id = try self.resolveTypeId(dest_ty);2351 const dest_ty_id = try self.resolveTypeId(dest_ty);
23442352
2345 const target = self.getTarget();2353 const mod = self.module;
2346 const dest_info = dest_ty.intInfo(target);2354 const dest_info = dest_ty.intInfo(mod);
23472355
2348 // TODO: Masking?2356 // TODO: Masking?
23492357
...@@ -2485,8 +2493,9 @@ pub const DeclGen = struct {...@@ -2485,8 +2493,9 @@ pub const DeclGen = struct {
2485 }2493 }
24862494
2487 fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef {2495 fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef {
2496 const mod = self.module;
2488 // Construct new pointer type for the resulting pointer2497 // 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.
2490 const elem_ty_ref = try self.resolveType(elem_ty, .direct);2499 const elem_ty_ref = try self.resolveType(elem_ty, .direct);
2491 const elem_ptr_ty_ref = try self.spv.ptrType(elem_ty_ref, spvStorageClass(ptr_ty.ptrAddressSpace()));2500 const elem_ptr_ty_ref = try self.spv.ptrType(elem_ty_ref, spvStorageClass(ptr_ty.ptrAddressSpace()));
2492 if (ptr_ty.isSinglePointer()) {2501 if (ptr_ty.isSinglePointer()) {
...@@ -2502,12 +2511,13 @@ pub const DeclGen = struct {...@@ -2502,12 +2511,13 @@ pub const DeclGen = struct {
2502 fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2511 fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2503 if (self.liveness.isUnused(inst)) return null;2512 if (self.liveness.isUnused(inst)) return null;
25042513
2514 const mod = self.module;
2505 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2515 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2506 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;2516 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
2507 const ptr_ty = self.air.typeOf(bin_op.lhs);2517 const ptr_ty = self.air.typeOf(bin_op.lhs);
2508 const elem_ty = ptr_ty.childType();2518 const elem_ty = ptr_ty.childType();
2509 // TODO: Make this return a null ptr or something2519 // 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
2512 const ptr_id = try self.resolve(bin_op.lhs);2522 const ptr_id = try self.resolve(bin_op.lhs);
2513 const index_id = try self.resolve(bin_op.rhs);2523 const index_id = try self.resolve(bin_op.rhs);
...@@ -2536,8 +2546,8 @@ pub const DeclGen = struct {...@@ -2536,8 +2546,8 @@ pub const DeclGen = struct {
2536 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2546 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2537 const un_ty = self.air.typeOf(ty_op.operand);2547 const un_ty = self.air.typeOf(ty_op.operand);
25382548
2539 const target = self.module.getTarget();2549 const mod = self.module;
2540 const layout = un_ty.unionGetLayout(target);2550 const layout = un_ty.unionGetLayout(mod);
2541 if (layout.tag_size == 0) return null;2551 if (layout.tag_size == 0) return null;
25422552
2543 const union_handle = try self.resolve(ty_op.operand);2553 const union_handle = try self.resolve(ty_op.operand);
...@@ -2551,6 +2561,7 @@ pub const DeclGen = struct {...@@ -2551,6 +2561,7 @@ pub const DeclGen = struct {
2551 fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2561 fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2552 if (self.liveness.isUnused(inst)) return null;2562 if (self.liveness.isUnused(inst)) return null;
25532563
2564 const mod = self.module;
2554 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2565 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2555 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;2566 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
25562567
...@@ -2559,9 +2570,9 @@ pub const DeclGen = struct {...@@ -2559,9 +2570,9 @@ pub const DeclGen = struct {
2559 const field_index = struct_field.field_index;2570 const field_index = struct_field.field_index;
2560 const field_ty = struct_ty.structFieldType(field_index);2571 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
2566 return try self.extractField(field_ty, object_id, field_index);2577 return try self.extractField(field_ty, object_id, field_index);
2567 }2578 }
...@@ -2573,8 +2584,9 @@ pub const DeclGen = struct {...@@ -2573,8 +2584,9 @@ pub const DeclGen = struct {
2573 object_ptr: IdRef,2584 object_ptr: IdRef,
2574 field_index: u32,2585 field_index: u32,
2575 ) !?IdRef {2586 ) !?IdRef {
2587 const mod = self.module;
2576 const object_ty = object_ptr_ty.childType();2588 const object_ty = object_ptr_ty.childType();
2577 switch (object_ty.zigTypeTag()) {2589 switch (object_ty.zigTypeTag(mod)) {
2578 .Struct => switch (object_ty.containerLayout()) {2590 .Struct => switch (object_ty.containerLayout()) {
2579 .Packed => unreachable, // TODO2591 .Packed => unreachable, // TODO
2580 else => {2592 else => {
...@@ -2667,6 +2679,7 @@ pub const DeclGen = struct {...@@ -2667,6 +2679,7 @@ pub const DeclGen = struct {
2667 // the current block by first generating the code of the block, then a label, and then generate the rest of the current2679 // the current block by first generating the code of the block, then a label, and then generate the rest of the current
2668 // ir.Block in a different SPIR-V block.2680 // ir.Block in a different SPIR-V block.
26692681
2682 const mod = self.module;
2670 const label_id = self.spv.allocId();2683 const label_id = self.spv.allocId();
26712684
2672 // 4 chosen as arbitrary initial capacity.2685 // 4 chosen as arbitrary initial capacity.
...@@ -2690,7 +2703,7 @@ pub const DeclGen = struct {...@@ -2690,7 +2703,7 @@ pub const DeclGen = struct {
2690 try self.beginSpvBlock(label_id);2703 try self.beginSpvBlock(label_id);
26912704
2692 // If this block didn't produce a value, simply return here.2705 // If this block didn't produce a value, simply return here.
2693 if (!ty.hasRuntimeBitsIgnoreComptime())2706 if (!ty.hasRuntimeBitsIgnoreComptime(mod))
2694 return null;2707 return null;
26952708
2696 // Combine the result from the blocks using the Phi instruction.2709 // Combine the result from the blocks using the Phi instruction.
...@@ -2716,7 +2729,8 @@ pub const DeclGen = struct {...@@ -2716,7 +2729,8 @@ pub const DeclGen = struct {
2716 const block = self.blocks.get(br.block_inst).?;2729 const block = self.blocks.get(br.block_inst).?;
2717 const operand_ty = self.air.typeOf(br.operand);2730 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)) {
2720 const operand_id = try self.resolve(br.operand);2734 const operand_id = try self.resolve(br.operand);
2721 // current_block_label_id should not be undefined here, lest there is a br or br_void in the function's body.2735 // current_block_label_id should not be undefined here, lest there is a br or br_void in the function's body.
2722 try block.incoming_blocks.append(self.gpa, .{ .src_label_id = self.current_block_label_id, .break_value_id = operand_id });2736 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 {...@@ -2771,13 +2785,14 @@ pub const DeclGen = struct {
2771 }2785 }
27722786
2773 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {2787 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
2788 const mod = self.module;
2774 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2789 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2775 const ptr_ty = self.air.typeOf(bin_op.lhs);2790 const ptr_ty = self.air.typeOf(bin_op.lhs);
2776 const ptr = try self.resolve(bin_op.lhs);2791 const ptr = try self.resolve(bin_op.lhs);
2777 const value = try self.resolve(bin_op.rhs);2792 const value = try self.resolve(bin_op.rhs);
2778 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);2793 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;
2781 if (val_is_undef) {2796 if (val_is_undef) {
2782 const undef = try self.spv.constUndef(ptr_ty_ref);2797 const undef = try self.spv.constUndef(ptr_ty_ref);
2783 try self.store(ptr_ty, ptr, undef);2798 try self.store(ptr_ty, ptr, undef);
...@@ -2805,7 +2820,8 @@ pub const DeclGen = struct {...@@ -2805,7 +2820,8 @@ pub const DeclGen = struct {
2805 fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void {2820 fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void {
2806 const operand = self.air.instructions.items(.data)[inst].un_op;2821 const operand = self.air.instructions.items(.data)[inst].un_op;
2807 const operand_ty = self.air.typeOf(operand);2822 const operand_ty = self.air.typeOf(operand);
2808 if (operand_ty.hasRuntimeBits()) {2823 const mod = self.module;
2824 if (operand_ty.hasRuntimeBits(mod)) {
2809 const operand_id = try self.resolve(operand);2825 const operand_id = try self.resolve(operand);
2810 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{ .value = operand_id });2826 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{ .value = operand_id });
2811 } else {2827 } else {
...@@ -2814,11 +2830,12 @@ pub const DeclGen = struct {...@@ -2814,11 +2830,12 @@ pub const DeclGen = struct {
2814 }2830 }
28152831
2816 fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void {2832 fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void {
2833 const mod = self.module;
2817 const un_op = self.air.instructions.items(.data)[inst].un_op;2834 const un_op = self.air.instructions.items(.data)[inst].un_op;
2818 const ptr_ty = self.air.typeOf(un_op);2835 const ptr_ty = self.air.typeOf(un_op);
2819 const ret_ty = ptr_ty.childType();2836 const ret_ty = ptr_ty.childType();
28202837
2821 if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {2838 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2822 try self.func.body.emit(self.spv.gpa, .OpReturn, {});2839 try self.func.body.emit(self.spv.gpa, .OpReturn, {});
2823 return;2840 return;
2824 }2841 }
...@@ -2946,6 +2963,7 @@ pub const DeclGen = struct {...@@ -2946,6 +2963,7 @@ pub const DeclGen = struct {
2946 fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_null, is_non_null }) !?IdRef {2963 fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_null, is_non_null }) !?IdRef {
2947 if (self.liveness.isUnused(inst)) return null;2964 if (self.liveness.isUnused(inst)) return null;
29482965
2966 const mod = self.module;
2949 const un_op = self.air.instructions.items(.data)[inst].un_op;2967 const un_op = self.air.instructions.items(.data)[inst].un_op;
2950 const operand_id = try self.resolve(un_op);2968 const operand_id = try self.resolve(un_op);
2951 const optional_ty = self.air.typeOf(un_op);2969 const optional_ty = self.air.typeOf(un_op);
...@@ -2955,7 +2973,7 @@ pub const DeclGen = struct {...@@ -2955,7 +2973,7 @@ pub const DeclGen = struct {
29552973
2956 const bool_ty_ref = try self.resolveType(Type.bool, .direct);2974 const bool_ty_ref = try self.resolveType(Type.bool, .direct);
29572975
2958 if (optional_ty.optionalReprIsPayload()) {2976 if (optional_ty.optionalReprIsPayload(mod)) {
2959 // Pointer payload represents nullability: pointer or slice.2977 // Pointer payload represents nullability: pointer or slice.
29602978
2961 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2979 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
...@@ -2985,7 +3003,7 @@ pub const DeclGen = struct {...@@ -2985,7 +3003,7 @@ pub const DeclGen = struct {
2985 return result_id;3003 return result_id;
2986 }3004 }
29873005
2988 const is_non_null_id = if (optional_ty.hasRuntimeBitsIgnoreComptime())3006 const is_non_null_id = if (optional_ty.hasRuntimeBitsIgnoreComptime(mod))
2989 try self.extractField(Type.bool, operand_id, 1)3007 try self.extractField(Type.bool, operand_id, 1)
2990 else3008 else
2991 // Optional representation is bool indicating whether the optional is set3009 // Optional representation is bool indicating whether the optional is set
...@@ -3009,14 +3027,15 @@ pub const DeclGen = struct {...@@ -3009,14 +3027,15 @@ pub const DeclGen = struct {
3009 fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3027 fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3010 if (self.liveness.isUnused(inst)) return null;3028 if (self.liveness.isUnused(inst)) return null;
30113029
3030 const mod = self.module;
3012 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3031 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3013 const operand_id = try self.resolve(ty_op.operand);3032 const operand_id = try self.resolve(ty_op.operand);
3014 const optional_ty = self.air.typeOf(ty_op.operand);3033 const optional_ty = self.air.typeOf(ty_op.operand);
3015 const payload_ty = self.air.typeOfIndex(inst);3034 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)) {
3020 return operand_id;3039 return operand_id;
3021 }3040 }
30223041
...@@ -3026,16 +3045,17 @@ pub const DeclGen = struct {...@@ -3026,16 +3045,17 @@ pub const DeclGen = struct {
3026 fn airWrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3045 fn airWrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3027 if (self.liveness.isUnused(inst)) return null;3046 if (self.liveness.isUnused(inst)) return null;
30283047
3048 const mod = self.module;
3029 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3049 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3030 const payload_ty = self.air.typeOf(ty_op.operand);3050 const payload_ty = self.air.typeOf(ty_op.operand);
30313051
3032 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3052 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3033 return try self.constBool(true, .direct);3053 return try self.constBool(true, .direct);
3034 }3054 }
30353055
3036 const operand_id = try self.resolve(ty_op.operand);3056 const operand_id = try self.resolve(ty_op.operand);
3037 const optional_ty = self.air.typeOfIndex(inst);3057 const optional_ty = self.air.typeOfIndex(inst);
3038 if (optional_ty.optionalReprIsPayload()) {3058 if (optional_ty.optionalReprIsPayload(mod)) {
3039 return operand_id;3059 return operand_id;
3040 }3060 }
30413061
...@@ -3045,30 +3065,29 @@ pub const DeclGen = struct {...@@ -3045,30 +3065,29 @@ pub const DeclGen = struct {
3045 }3065 }
30463066
3047 fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {3067 fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {
3048 const target = self.getTarget();3068 const mod = self.module;
3049 const pl_op = self.air.instructions.items(.data)[inst].pl_op;3069 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
3050 const cond = try self.resolve(pl_op.operand);3070 const cond = try self.resolve(pl_op.operand);
3051 const cond_ty = self.air.typeOf(pl_op.operand);3071 const cond_ty = self.air.typeOf(pl_op.operand);
3052 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);3072 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)) {
3055 .Int => blk: {3075 .Int => blk: {
3056 const bits = cond_ty.intInfo(target).bits;3076 const bits = cond_ty.intInfo(mod).bits;
3057 const backing_bits = self.backingIntBits(bits) orelse {3077 const backing_bits = self.backingIntBits(bits) orelse {
3058 return self.todo("implement composite int switch", .{});3078 return self.todo("implement composite int switch", .{});
3059 };3079 };
3060 break :blk if (backing_bits <= 32) @as(u32, 1) else 2;3080 break :blk if (backing_bits <= 32) @as(u32, 1) else 2;
3061 },3081 },
3062 .Enum => blk: {3082 .Enum => blk: {
3063 var buffer: Type.Payload.Bits = undefined;3083 const int_ty = cond_ty.intTagType();
3064 const int_ty = cond_ty.intTagType(&buffer);3084 const int_info = int_ty.intInfo(mod);
3065 const int_info = int_ty.intInfo(target);
3066 const backing_bits = self.backingIntBits(int_info.bits) orelse {3085 const backing_bits = self.backingIntBits(int_info.bits) orelse {
3067 return self.todo("implement composite int switch", .{});3086 return self.todo("implement composite int switch", .{});
3068 };3087 };
3069 break :blk if (backing_bits <= 32) @as(u32, 1) else 2;3088 break :blk if (backing_bits <= 32) @as(u32, 1) else 2;
3070 },3089 },
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.
3072 };3091 };
30733092
3074 const num_cases = switch_br.data.cases_len;3093 const num_cases = switch_br.data.cases_len;
...@@ -3112,15 +3131,15 @@ pub const DeclGen = struct {...@@ -3112,15 +3131,15 @@ pub const DeclGen = struct {
3112 const label = IdRef{ .id = first_case_label.id + case_i };3131 const label = IdRef{ .id = first_case_label.id + case_i };
31133132
3114 for (items) |item| {3133 for (items) |item| {
3115 const value = self.air.value(item) orelse {3134 const value = self.air.value(item, mod) orelse {
3116 return self.todo("switch on runtime value???", .{});3135 return self.todo("switch on runtime value???", .{});
3117 };3136 };
3118 const int_val = switch (cond_ty.zigTypeTag()) {3137 const int_val = switch (cond_ty.zigTypeTag(mod)) {
3119 .Int => if (cond_ty.isSignedInt()) @bitCast(u64, value.toSignedInt(target)) else value.toUnsignedInt(target),3138 .Int => if (cond_ty.isSignedInt(mod)) @bitCast(u64, value.toSignedInt(mod)) else value.toUnsignedInt(mod),
3120 .Enum => blk: {3139 .Enum => blk: {
3121 var int_buffer: Value.Payload.U64 = undefined;3140 var int_buffer: Value.Payload.U64 = undefined;
3122 // TODO: figure out of cond_ty is correct (something with enum literals)3141 // 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 constants3142 break :blk value.enumToInt(cond_ty, &int_buffer).toUnsignedInt(mod); // TODO: composite integer constants
3124 },3143 },
3125 else => unreachable,3144 else => unreachable,
3126 };3145 };
...@@ -3294,11 +3313,12 @@ pub const DeclGen = struct {...@@ -3294,11 +3313,12 @@ pub const DeclGen = struct {
3294 fn airCall(self: *DeclGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !?IdRef {3313 fn airCall(self: *DeclGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !?IdRef {
3295 _ = modifier;3314 _ = modifier;
32963315
3316 const mod = self.module;
3297 const pl_op = self.air.instructions.items(.data)[inst].pl_op;3317 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
3298 const extra = self.air.extraData(Air.Call, pl_op.payload);3318 const extra = self.air.extraData(Air.Call, pl_op.payload);
3299 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);3319 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
3300 const callee_ty = self.air.typeOf(pl_op.operand);3320 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)) {
3302 .Fn => callee_ty,3322 .Fn => callee_ty,
3303 .Pointer => return self.fail("cannot call function pointers", .{}),3323 .Pointer => return self.fail("cannot call function pointers", .{}),
3304 else => unreachable,3324 else => unreachable,
...@@ -3320,7 +3340,7 @@ pub const DeclGen = struct {...@@ -3320,7 +3340,7 @@ pub const DeclGen = struct {
3320 // temporary params buffer.3340 // temporary params buffer.
3321 const arg_id = try self.resolve(arg);3341 const arg_id = try self.resolve(arg);
3322 const arg_ty = self.air.typeOf(arg);3342 const arg_ty = self.air.typeOf(arg);
3323 if (!arg_ty.hasRuntimeBitsIgnoreComptime()) continue;3343 if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
33243344
3325 params[n_params] = arg_id;3345 params[n_params] = arg_id;
3326 n_params += 1;3346 n_params += 1;
...@@ -3337,7 +3357,7 @@ pub const DeclGen = struct {...@@ -3337,7 +3357,7 @@ pub const DeclGen = struct {
3337 try self.func.body.emit(self.spv.gpa, .OpUnreachable, {});3357 try self.func.body.emit(self.spv.gpa, .OpUnreachable, {});
3338 }3358 }
33393359
3340 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime()) {3360 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(mod)) {
3341 return null;3361 return null;
3342 }3362 }
33433363
src/link/Coff.zig+4-3
...@@ -1123,7 +1123,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In...@@ -1123,7 +1123,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
1123 },1123 },
1124 };1124 };
11251125
1126 const required_alignment = tv.ty.abiAlignment(self.base.options.target);1126 const required_alignment = tv.ty.abiAlignment(mod);
1127 const atom = self.getAtomPtr(atom_index);1127 const atom = self.getAtomPtr(atom_index);
1128 atom.size = @intCast(u32, code.len);1128 atom.size = @intCast(u32, code.len);
1129 atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, required_alignment);1129 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....@@ -1299,7 +1299,8 @@ pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.
1299fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 {1299fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 {
1300 const decl = self.base.options.module.?.declPtr(decl_index);1300 const decl = self.base.options.module.?.declPtr(decl_index);
1301 const ty = decl.ty;1301 const ty = decl.ty;
1302 const zig_ty = ty.zigTypeTag();1302 const mod = self.base.options.module.?;
1303 const zig_ty = ty.zigTypeTag(mod);
1303 const val = decl.val;1304 const val = decl.val;
1304 const index: u16 = blk: {1305 const index: u16 = blk: {
1305 if (val.isUndefDeep()) {1306 if (val.isUndefDeep()) {
...@@ -1330,7 +1331,7 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []u8, comple...@@ -1330,7 +1331,7 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []u8, comple
1330 defer gpa.free(decl_name);1331 defer gpa.free(decl_name);
13311332
1332 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });1333 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
1335 const decl_metadata = self.decls.get(decl_index).?;1336 const decl_metadata = self.decls.get(decl_index).?;
1336 const atom_index = decl_metadata.atom;1337 const atom_index = decl_metadata.atom;
src/link/Dwarf.zig+52-51
...@@ -169,16 +169,16 @@ pub const DeclState = struct {...@@ -169,16 +169,16 @@ pub const DeclState = struct {
169169
170 fn addDbgInfoType(170 fn addDbgInfoType(
171 self: *DeclState,171 self: *DeclState,
172 module: *Module,172 mod: *Module,
173 atom_index: Atom.Index,173 atom_index: Atom.Index,
174 ty: Type,174 ty: Type,
175 ) error{OutOfMemory}!void {175 ) error{OutOfMemory}!void {
176 const arena = self.abbrev_type_arena.allocator();176 const arena = self.abbrev_type_arena.allocator();
177 const dbg_info_buffer = &self.dbg_info;177 const dbg_info_buffer = &self.dbg_info;
178 const target = module.getTarget();178 const target = mod.getTarget();
179 const target_endian = target.cpu.arch.endian();179 const target_endian = target.cpu.arch.endian();
180180
181 switch (ty.zigTypeTag()) {181 switch (ty.zigTypeTag(mod)) {
182 .NoReturn => unreachable,182 .NoReturn => unreachable,
183 .Void => {183 .Void => {
184 try dbg_info_buffer.append(@enumToInt(AbbrevKind.pad1));184 try dbg_info_buffer.append(@enumToInt(AbbrevKind.pad1));
...@@ -189,12 +189,12 @@ pub const DeclState = struct {...@@ -189,12 +189,12 @@ pub const DeclState = struct {
189 // DW.AT.encoding, DW.FORM.data1189 // DW.AT.encoding, DW.FORM.data1
190 dbg_info_buffer.appendAssumeCapacity(DW.ATE.boolean);190 dbg_info_buffer.appendAssumeCapacity(DW.ATE.boolean);
191 // DW.AT.byte_size, DW.FORM.udata191 // 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));
193 // DW.AT.name, DW.FORM.string193 // 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)});
195 },195 },
196 .Int => {196 .Int => {
197 const info = ty.intInfo(target);197 const info = ty.intInfo(mod);
198 try dbg_info_buffer.ensureUnusedCapacity(12);198 try dbg_info_buffer.ensureUnusedCapacity(12);
199 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type));199 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type));
200 // DW.AT.encoding, DW.FORM.data1200 // DW.AT.encoding, DW.FORM.data1
...@@ -203,20 +203,20 @@ pub const DeclState = struct {...@@ -203,20 +203,20 @@ pub const DeclState = struct {
203 .unsigned => DW.ATE.unsigned,203 .unsigned => DW.ATE.unsigned,
204 });204 });
205 // DW.AT.byte_size, DW.FORM.udata205 // 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));
207 // DW.AT.name, DW.FORM.string207 // 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)});
209 },209 },
210 .Optional => {210 .Optional => {
211 if (ty.isPtrLikeOptional()) {211 if (ty.isPtrLikeOptional(mod)) {
212 try dbg_info_buffer.ensureUnusedCapacity(12);212 try dbg_info_buffer.ensureUnusedCapacity(12);
213 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type));213 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type));
214 // DW.AT.encoding, DW.FORM.data1214 // DW.AT.encoding, DW.FORM.data1
215 dbg_info_buffer.appendAssumeCapacity(DW.ATE.address);215 dbg_info_buffer.appendAssumeCapacity(DW.ATE.address);
216 // DW.AT.byte_size, DW.FORM.udata216 // 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));
218 // DW.AT.name, DW.FORM.string218 // 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)});
220 } else {220 } else {
221 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }221 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }
222 var buf = try arena.create(Type.Payload.ElemType);222 var buf = try arena.create(Type.Payload.ElemType);
...@@ -224,10 +224,10 @@ pub const DeclState = struct {...@@ -224,10 +224,10 @@ pub const DeclState = struct {
224 // DW.AT.structure_type224 // DW.AT.structure_type
225 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));225 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
226 // DW.AT.byte_size, DW.FORM.udata226 // DW.AT.byte_size, DW.FORM.udata
227 const abi_size = ty.abiSize(target);227 const abi_size = ty.abiSize(mod);
228 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);228 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
229 // DW.AT.name, DW.FORM.string229 // 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)});
231 // DW.AT.member231 // DW.AT.member
232 try dbg_info_buffer.ensureUnusedCapacity(7);232 try dbg_info_buffer.ensureUnusedCapacity(7);
233 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));233 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
...@@ -251,7 +251,7 @@ pub const DeclState = struct {...@@ -251,7 +251,7 @@ pub const DeclState = struct {
251 try dbg_info_buffer.resize(index + 4);251 try dbg_info_buffer.resize(index + 4);
252 try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(u32, index));252 try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(u32, index));
253 // DW.AT.data_member_location, DW.FORM.udata253 // 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);
255 try leb128.writeULEB128(dbg_info_buffer.writer(), offset);255 try leb128.writeULEB128(dbg_info_buffer.writer(), offset);
256 // DW.AT.structure_type delimit children256 // DW.AT.structure_type delimit children
257 try dbg_info_buffer.append(0);257 try dbg_info_buffer.append(0);
...@@ -266,9 +266,9 @@ pub const DeclState = struct {...@@ -266,9 +266,9 @@ pub const DeclState = struct {
266 try dbg_info_buffer.ensureUnusedCapacity(2);266 try dbg_info_buffer.ensureUnusedCapacity(2);
267 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_type));267 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_type));
268 // DW.AT.byte_size, DW.FORM.udata268 // 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));
270 // DW.AT.name, DW.FORM.string270 // 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)});
272 // DW.AT.member272 // DW.AT.member
273 try dbg_info_buffer.ensureUnusedCapacity(5);273 try dbg_info_buffer.ensureUnusedCapacity(5);
274 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));274 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
...@@ -311,7 +311,7 @@ pub const DeclState = struct {...@@ -311,7 +311,7 @@ pub const DeclState = struct {
311 // DW.AT.array_type311 // DW.AT.array_type
312 try dbg_info_buffer.append(@enumToInt(AbbrevKind.array_type));312 try dbg_info_buffer.append(@enumToInt(AbbrevKind.array_type));
313 // DW.AT.name, DW.FORM.string313 // 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)});
315 // DW.AT.type, DW.FORM.ref4315 // DW.AT.type, DW.FORM.ref4
316 var index = dbg_info_buffer.items.len;316 var index = dbg_info_buffer.items.len;
317 try dbg_info_buffer.resize(index + 4);317 try dbg_info_buffer.resize(index + 4);
...@@ -332,12 +332,12 @@ pub const DeclState = struct {...@@ -332,12 +332,12 @@ pub const DeclState = struct {
332 // DW.AT.structure_type332 // DW.AT.structure_type
333 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));333 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
334 // DW.AT.byte_size, DW.FORM.udata334 // 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
337 switch (ty.tag()) {337 switch (ty.tag()) {
338 .tuple, .anon_struct => {338 .tuple, .anon_struct => {
339 // DW.AT.name, DW.FORM.string339 // 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
342 const fields = ty.tupleFields();342 const fields = ty.tupleFields();
343 for (fields.types, 0..) |field, field_index| {343 for (fields.types, 0..) |field, field_index| {
...@@ -350,13 +350,13 @@ pub const DeclState = struct {...@@ -350,13 +350,13 @@ pub const DeclState = struct {
350 try dbg_info_buffer.resize(index + 4);350 try dbg_info_buffer.resize(index + 4);
351 try self.addTypeRelocGlobal(atom_index, field, @intCast(u32, index));351 try self.addTypeRelocGlobal(atom_index, field, @intCast(u32, index));
352 // DW.AT.data_member_location, DW.FORM.udata352 // 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);
354 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);354 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
355 }355 }
356 },356 },
357 else => {357 else => {
358 // DW.AT.name, DW.FORM.string358 // DW.AT.name, DW.FORM.string
359 const struct_name = try ty.nameAllocArena(arena, module);359 const struct_name = try ty.nameAllocArena(arena, mod);
360 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);360 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);
361 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);361 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);
362 dbg_info_buffer.appendAssumeCapacity(0);362 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -370,7 +370,7 @@ pub const DeclState = struct {...@@ -370,7 +370,7 @@ pub const DeclState = struct {
370 const fields = ty.structFields();370 const fields = ty.structFields();
371 for (fields.keys(), 0..) |field_name, field_index| {371 for (fields.keys(), 0..) |field_name, field_index| {
372 const field = fields.get(field_name).?;372 const field = fields.get(field_name).?;
373 if (!field.ty.hasRuntimeBits()) continue;373 if (!field.ty.hasRuntimeBits(mod)) continue;
374 // DW.AT.member374 // DW.AT.member
375 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);375 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
376 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));376 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
...@@ -382,7 +382,7 @@ pub const DeclState = struct {...@@ -382,7 +382,7 @@ pub const DeclState = struct {
382 try dbg_info_buffer.resize(index + 4);382 try dbg_info_buffer.resize(index + 4);
383 try self.addTypeRelocGlobal(atom_index, field.ty, @intCast(u32, index));383 try self.addTypeRelocGlobal(atom_index, field.ty, @intCast(u32, index));
384 // DW.AT.data_member_location, DW.FORM.udata384 // 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);
386 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);386 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
387 }387 }
388 },388 },
...@@ -395,9 +395,9 @@ pub const DeclState = struct {...@@ -395,9 +395,9 @@ pub const DeclState = struct {
395 // DW.AT.enumeration_type395 // DW.AT.enumeration_type
396 try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type));396 try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type));
397 // DW.AT.byte_size, DW.FORM.udata397 // 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));
399 // DW.AT.name, DW.FORM.string399 // DW.AT.name, DW.FORM.string
400 const enum_name = try ty.nameAllocArena(arena, module);400 const enum_name = try ty.nameAllocArena(arena, mod);
401 try dbg_info_buffer.ensureUnusedCapacity(enum_name.len + 1);401 try dbg_info_buffer.ensureUnusedCapacity(enum_name.len + 1);
402 dbg_info_buffer.appendSliceAssumeCapacity(enum_name);402 dbg_info_buffer.appendSliceAssumeCapacity(enum_name);
403 dbg_info_buffer.appendAssumeCapacity(0);403 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -424,7 +424,7 @@ pub const DeclState = struct {...@@ -424,7 +424,7 @@ pub const DeclState = struct {
424 // See https://github.com/ziglang/zig/issues/645424 // See https://github.com/ziglang/zig/issues/645
425 var int_buffer: Value.Payload.U64 = undefined;425 var int_buffer: Value.Payload.U64 = undefined;
426 const field_int_val = value.enumToInt(ty, &int_buffer);426 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));
428 } else @intCast(u64, field_i);428 } else @intCast(u64, field_i);
429 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian);429 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian);
430 }430 }
...@@ -433,12 +433,12 @@ pub const DeclState = struct {...@@ -433,12 +433,12 @@ pub const DeclState = struct {
433 try dbg_info_buffer.append(0);433 try dbg_info_buffer.append(0);
434 },434 },
435 .Union => {435 .Union => {
436 const layout = ty.unionGetLayout(target);436 const layout = ty.unionGetLayout(mod);
437 const union_obj = ty.cast(Type.Payload.Union).?.data;437 const union_obj = ty.cast(Type.Payload.Union).?.data;
438 const payload_offset = if (layout.tag_align >= layout.payload_align) layout.tag_size else 0;438 const payload_offset = if (layout.tag_align >= layout.payload_align) layout.tag_size else 0;
439 const tag_offset = if (layout.tag_align >= layout.payload_align) 0 else layout.payload_size;439 const tag_offset = if (layout.tag_align >= layout.payload_align) 0 else layout.payload_size;
440 const is_tagged = layout.tag_size > 0;440 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
443 // TODO this is temporary to match current state of unions in Zig - we don't yet have443 // TODO this is temporary to match current state of unions in Zig - we don't yet have
444 // safety checks implemented meaning the implicit tag is not yet stored and generated444 // safety checks implemented meaning the implicit tag is not yet stored and generated
...@@ -481,7 +481,7 @@ pub const DeclState = struct {...@@ -481,7 +481,7 @@ pub const DeclState = struct {
481 const fields = ty.unionFields();481 const fields = ty.unionFields();
482 for (fields.keys()) |field_name| {482 for (fields.keys()) |field_name| {
483 const field = fields.get(field_name).?;483 const field = fields.get(field_name).?;
484 if (!field.ty.hasRuntimeBits()) continue;484 if (!field.ty.hasRuntimeBits(mod)) continue;
485 // DW.AT.member485 // DW.AT.member
486 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_member));486 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_member));
487 // DW.AT.name, DW.FORM.string487 // DW.AT.name, DW.FORM.string
...@@ -517,7 +517,7 @@ pub const DeclState = struct {...@@ -517,7 +517,7 @@ pub const DeclState = struct {
517 .ErrorSet => {517 .ErrorSet => {
518 try addDbgInfoErrorSet(518 try addDbgInfoErrorSet(
519 self.abbrev_type_arena.allocator(),519 self.abbrev_type_arena.allocator(),
520 module,520 mod,
521 ty,521 ty,
522 target,522 target,
523 &self.dbg_info,523 &self.dbg_info,
...@@ -526,18 +526,18 @@ pub const DeclState = struct {...@@ -526,18 +526,18 @@ pub const DeclState = struct {
526 .ErrorUnion => {526 .ErrorUnion => {
527 const error_ty = ty.errorUnionSet();527 const error_ty = ty.errorUnionSet();
528 const payload_ty = ty.errorUnionPayload();528 const payload_ty = ty.errorUnionPayload();
529 const payload_align = if (payload_ty.isNoReturn()) 0 else payload_ty.abiAlignment(target);529 const payload_align = if (payload_ty.isNoReturn()) 0 else payload_ty.abiAlignment(mod);
530 const error_align = Type.anyerror.abiAlignment(target);530 const error_align = Type.anyerror.abiAlignment(mod);
531 const abi_size = ty.abiSize(target);531 const abi_size = ty.abiSize(mod);
532 const payload_off = if (error_align >= payload_align) Type.anyerror.abiSize(target) else 0;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(target);533 const error_off = if (error_align >= payload_align) 0 else payload_ty.abiSize(mod);
534534
535 // DW.AT.structure_type535 // DW.AT.structure_type
536 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));536 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
537 // DW.AT.byte_size, DW.FORM.udata537 // DW.AT.byte_size, DW.FORM.udata
538 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);538 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
539 // DW.AT.name, DW.FORM.string539 // DW.AT.name, DW.FORM.string
540 const name = try ty.nameAllocArena(arena, module);540 const name = try ty.nameAllocArena(arena, mod);
541 try dbg_info_buffer.writer().print("{s}\x00", .{name});541 try dbg_info_buffer.writer().print("{s}\x00", .{name});
542542
543 if (!payload_ty.isNoReturn()) {543 if (!payload_ty.isNoReturn()) {
...@@ -685,7 +685,8 @@ pub const DeclState = struct {...@@ -685,7 +685,8 @@ pub const DeclState = struct {
685 const atom_index = self.di_atom_decls.get(owner_decl).?;685 const atom_index = self.di_atom_decls.get(owner_decl).?;
686 const name_with_null = name.ptr[0 .. name.len + 1];686 const name_with_null = name.ptr[0 .. name.len + 1];
687 try dbg_info.append(@enumToInt(AbbrevKind.variable));687 try dbg_info.append(@enumToInt(AbbrevKind.variable));
688 const target = self.mod.getTarget();688 const mod = self.mod;
689 const target = mod.getTarget();
689 const endian = target.cpu.arch.endian();690 const endian = target.cpu.arch.endian();
690 const child_ty = if (is_ptr) ty.childType() else ty;691 const child_ty = if (is_ptr) ty.childType() else ty;
691692
...@@ -790,9 +791,9 @@ pub const DeclState = struct {...@@ -790,9 +791,9 @@ pub const DeclState = struct {
790 const fixup = dbg_info.items.len;791 const fixup = dbg_info.items.len;
791 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc792 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
792 1,793 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,
794 });795 });
795 if (child_ty.isSignedInt()) {796 if (child_ty.isSignedInt(mod)) {
796 try leb128.writeILEB128(dbg_info.writer(), @bitCast(i64, x));797 try leb128.writeILEB128(dbg_info.writer(), @bitCast(i64, x));
797 } else {798 } else {
798 try leb128.writeULEB128(dbg_info.writer(), x);799 try leb128.writeULEB128(dbg_info.writer(), x);
...@@ -805,7 +806,7 @@ pub const DeclState = struct {...@@ -805,7 +806,7 @@ pub const DeclState = struct {
805 // DW.AT.location, DW.FORM.exprloc806 // DW.AT.location, DW.FORM.exprloc
806 // uleb128(exprloc_len)807 // uleb128(exprloc_len)
807 // DW.OP.implicit_value uleb128(len_of_bytes) bytes808 // 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));
809 var implicit_value_len = std.ArrayList(u8).init(self.gpa);810 var implicit_value_len = std.ArrayList(u8).init(self.gpa);
810 defer implicit_value_len.deinit();811 defer implicit_value_len.deinit();
811 try leb128.writeULEB128(implicit_value_len.writer(), abi_size);812 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)...@@ -979,7 +980,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
979980
980 assert(decl.has_tv);981 assert(decl.has_tv);
981982
982 switch (decl.ty.zigTypeTag()) {983 switch (decl.ty.zigTypeTag(mod)) {
983 .Fn => {984 .Fn => {
984 _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index);985 _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index);
985986
...@@ -1027,7 +1028,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)...@@ -1027,7 +1028,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
1027 try dbg_info_buffer.ensureUnusedCapacity(25 + decl_name_with_null.len);1028 try dbg_info_buffer.ensureUnusedCapacity(25 + decl_name_with_null.len);
10281029
1029 const fn_ret_type = decl.ty.fnReturnType();1030 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);
1031 if (fn_ret_has_bits) {1032 if (fn_ret_has_bits) {
1032 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.subprogram));1033 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.subprogram));
1033 } else {1034 } else {
...@@ -1059,7 +1060,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)...@@ -1059,7 +1060,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
10591060
1060pub fn commitDeclState(1061pub fn commitDeclState(
1061 self: *Dwarf,1062 self: *Dwarf,
1062 module: *Module,1063 mod: *Module,
1063 decl_index: Module.Decl.Index,1064 decl_index: Module.Decl.Index,
1064 sym_addr: u64,1065 sym_addr: u64,
1065 sym_size: u64,1066 sym_size: u64,
...@@ -1071,12 +1072,12 @@ pub fn commitDeclState(...@@ -1071,12 +1072,12 @@ pub fn commitDeclState(
1071 const gpa = self.allocator;1072 const gpa = self.allocator;
1072 var dbg_line_buffer = &decl_state.dbg_line;1073 var dbg_line_buffer = &decl_state.dbg_line;
1073 var dbg_info_buffer = &decl_state.dbg_info;1074 var dbg_info_buffer = &decl_state.dbg_info;
1074 const decl = module.declPtr(decl_index);1075 const decl = mod.declPtr(decl_index);
10751076
1076 const target_endian = self.target.cpu.arch.endian();1077 const target_endian = self.target.cpu.arch.endian();
10771078
1078 assert(decl.has_tv);1079 assert(decl.has_tv);
1079 switch (decl.ty.zigTypeTag()) {1080 switch (decl.ty.zigTypeTag(mod)) {
1080 .Fn => {1081 .Fn => {
1081 // Since the Decl is a function, we need to update the .debug_line program.1082 // Since the Decl is a function, we need to update the .debug_line program.
1082 // Perform the relocations based on vaddr.1083 // Perform the relocations based on vaddr.
...@@ -1283,7 +1284,7 @@ pub fn commitDeclState(...@@ -1283,7 +1284,7 @@ pub fn commitDeclState(
1283 if (deferred) continue;1284 if (deferred) continue;
12841285
1285 symbol.offset = @intCast(u32, dbg_info_buffer.items.len);1286 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);
1287 }1288 }
1288 }1289 }
12891290
...@@ -1319,7 +1320,7 @@ pub fn commitDeclState(...@@ -1319,7 +1320,7 @@ pub fn commitDeclState(
1319 reloc.offset,1320 reloc.offset,
1320 value,1321 value,
1321 target,1322 target,
1322 ty.fmt(module),1323 ty.fmt(mod),
1323 });1324 });
1324 mem.writeInt(1325 mem.writeInt(
1325 u32,1326 u32,
...@@ -2663,7 +2664,7 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct {...@@ -2663,7 +2664,7 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct {
26632664
2664fn addDbgInfoErrorSet(2665fn addDbgInfoErrorSet(
2665 arena: Allocator,2666 arena: Allocator,
2666 module: *Module,2667 mod: *Module,
2667 ty: Type,2668 ty: Type,
2668 target: std.Target,2669 target: std.Target,
2669 dbg_info_buffer: *std.ArrayList(u8),2670 dbg_info_buffer: *std.ArrayList(u8),
...@@ -2673,10 +2674,10 @@ fn addDbgInfoErrorSet(...@@ -2673,10 +2674,10 @@ fn addDbgInfoErrorSet(
2673 // DW.AT.enumeration_type2674 // DW.AT.enumeration_type
2674 try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type));2675 try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type));
2675 // DW.AT.byte_size, DW.FORM.udata2676 // DW.AT.byte_size, DW.FORM.udata
2676 const abi_size = Type.anyerror.abiSize(target);2677 const abi_size = Type.anyerror.abiSize(mod);
2677 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);2678 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
2678 // DW.AT.name, DW.FORM.string2679 // DW.AT.name, DW.FORM.string
2679 const name = try ty.nameAllocArena(arena, module);2680 const name = try ty.nameAllocArena(arena, mod);
2680 try dbg_info_buffer.writer().print("{s}\x00", .{name});2681 try dbg_info_buffer.writer().print("{s}\x00", .{name});
26812682
2682 // DW.AT.enumerator2683 // DW.AT.enumerator
...@@ -2691,7 +2692,7 @@ fn addDbgInfoErrorSet(...@@ -2691,7 +2692,7 @@ fn addDbgInfoErrorSet(
26912692
2692 const error_names = ty.errorSetNames();2693 const error_names = ty.errorSetNames();
2693 for (error_names) |error_name| {2694 for (error_names) |error_name| {
2694 const kv = module.getErrorValue(error_name) catch unreachable;2695 const kv = mod.getErrorValue(error_name) catch unreachable;
2695 // DW.AT.enumerator2696 // DW.AT.enumerator
2696 try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));2697 try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));
2697 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));2698 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...@@ -2449,9 +2449,10 @@ pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.I
2449}2449}
24502450
2451fn getDeclShdrIndex(self: *Elf, decl_index: Module.Decl.Index) u16 {2451fn 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);
2453 const ty = decl.ty;2454 const ty = decl.ty;
2454 const zig_ty = ty.zigTypeTag();2455 const zig_ty = ty.zigTypeTag(mod);
2455 const val = decl.val;2456 const val = decl.val;
2456 const shdr_index: u16 = blk: {2457 const shdr_index: u16 = blk: {
2457 if (val.isUndefDeep()) {2458 if (val.isUndefDeep()) {
...@@ -2482,7 +2483,7 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s...@@ -2482,7 +2483,7 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s
2482 defer self.base.allocator.free(decl_name);2483 defer self.base.allocator.free(decl_name);
24832484
2484 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });2485 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
2487 const decl_metadata = self.decls.get(decl_index).?;2488 const decl_metadata = self.decls.get(decl_index).?;
2488 const atom_index = decl_metadata.atom;2489 const atom_index = decl_metadata.atom;
...@@ -2826,7 +2827,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module...@@ -2826,7 +2827,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
2826 },2827 },
2827 };2828 };
28282829
2829 const required_alignment = typed_value.ty.abiAlignment(self.base.options.target);2830 const required_alignment = typed_value.ty.abiAlignment(mod);
2830 const shdr_index = self.rodata_section_index.?;2831 const shdr_index = self.rodata_section_index.?;
2831 const phdr_index = self.sections.items(.phdr_index)[shdr_index];2832 const phdr_index = self.sections.items(.phdr_index)[shdr_index];
2832 const local_sym = self.getAtom(atom_index).getSymbolPtr(self);2833 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...@@ -1948,7 +1948,8 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
1948 },1948 },
1949 };1949 };
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);
1952 const atom = self.getAtomPtr(atom_index);1953 const atom = self.getAtomPtr(atom_index);
1953 atom.size = code.len;1954 atom.size = code.len;
1954 // TODO: work out logic for disambiguating functions from function pointers1955 // TODO: work out logic for disambiguating functions from function pointers
...@@ -2152,6 +2153,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.In...@@ -2152,6 +2153,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.In
2152}2153}
21532154
2154fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.Decl.Index) !void {2155fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.Decl.Index) !void {
2156 const mod = self.base.options.module.?;
2155 // Lowering a TLV on macOS involves two stages:2157 // Lowering a TLV on macOS involves two stages:
2156 // 1. first we lower the initializer into appopriate section (__thread_data or __thread_bss)2158 // 1. first we lower the initializer into appopriate section (__thread_data or __thread_bss)
2157 // 2. next, we create a corresponding threadlocal variable descriptor in __thread_vars2159 // 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...@@ -2202,7 +2204,7 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.D
2202 },2204 },
2203 };2205 };
22042206
2205 const required_alignment = decl.getAlignment(self.base.options.target);2207 const required_alignment = decl.getAlignment(mod);
22062208
2207 const decl_name = try decl.getFullyQualifiedName(module);2209 const decl_name = try decl.getFullyQualifiedName(module);
2208 defer gpa.free(decl_name);2210 defer gpa.free(decl_name);
...@@ -2262,7 +2264,8 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 {...@@ -2262,7 +2264,8 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 {
2262 const decl = self.base.options.module.?.declPtr(decl_index);2264 const decl = self.base.options.module.?.declPtr(decl_index);
2263 const ty = decl.ty;2265 const ty = decl.ty;
2264 const val = decl.val;2266 const val = decl.val;
2265 const zig_ty = ty.zigTypeTag();2267 const mod = self.base.options.module.?;
2268 const zig_ty = ty.zigTypeTag(mod);
2266 const mode = self.base.options.optimize_mode;2269 const mode = self.base.options.optimize_mode;
2267 const single_threaded = self.base.options.single_threaded;2270 const single_threaded = self.base.options.single_threaded;
2268 const sect_id: u8 = blk: {2271 const sect_id: u8 = blk: {
...@@ -2301,7 +2304,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64...@@ -2301,7 +2304,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64
2301 const mod = self.base.options.module.?;2304 const mod = self.base.options.module.?;
2302 const decl = mod.declPtr(decl_index);2305 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
2306 const decl_name = try decl.getFullyQualifiedName(mod);2309 const decl_name = try decl.getFullyQualifiedName(mod);
2307 defer gpa.free(decl_name);2310 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)...@@ -432,8 +432,9 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl_index: Module.Decl.Index)
432}432}
433/// called at the end of update{Decl,Func}433/// called at the end of update{Decl,Func}
434fn updateFinish(self: *Plan9, decl_index: Module.Decl.Index) !void {434fn updateFinish(self: *Plan9, decl_index: Module.Decl.Index) !void {
435 const decl = self.base.options.module.?.declPtr(decl_index);435 const mod = self.base.options.module.?;
436 const is_fn = (decl.ty.zigTypeTag() == .Fn);436 const decl = mod.declPtr(decl_index);
437 const is_fn = (decl.ty.zigTypeTag(mod) == .Fn);
437 log.debug("update the symbol table and got for decl {*} ({s})", .{ decl, decl.name });438 log.debug("update the symbol table and got for decl {*} ({s})", .{ decl, decl.name });
438 const sym_t: aout.Sym.Type = if (is_fn) .t else .d;439 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...@@ -704,7 +705,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
704 log.debug("relocating the address of '{s}' + {d} into '{s}' + {d}", .{ target_decl.name, addend, source_decl.name, offset });705 log.debug("relocating the address of '{s}' + {d} into '{s}' + {d}", .{ target_decl.name, addend, source_decl.name, offset });
705706
706 const code = blk: {707 const code = blk: {
707 const is_fn = source_decl.ty.zigTypeTag() == .Fn;708 const is_fn = source_decl.ty.zigTypeTag(mod) == .Fn;
708 if (is_fn) {709 if (is_fn) {
709 const table = self.fn_decl_table.get(source_decl.getFileScope()).?.functions;710 const table = self.fn_decl_table.get(source_decl.getFileScope()).?.functions;
710 const output = table.get(source_decl_index).?;711 const output = table.get(source_decl_index).?;
...@@ -1031,7 +1032,7 @@ pub fn getDeclVAddr(...@@ -1031,7 +1032,7 @@ pub fn getDeclVAddr(
1031) !u64 {1032) !u64 {
1032 const mod = self.base.options.module.?;1033 const mod = self.base.options.module.?;
1033 const decl = mod.declPtr(decl_index);1034 const decl = mod.declPtr(decl_index);
1034 if (decl.ty.zigTypeTag() == .Fn) {1035 if (decl.ty.zigTypeTag(mod) == .Fn) {
1035 var start = self.bases.text;1036 var start = self.bases.text;
1036 var it_file = self.fn_decl_table.iterator();1037 var it_file = self.fn_decl_table.iterator();
1037 while (it_file.next()) |fentry| {1038 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...@@ -1473,7 +1473,7 @@ fn finishUpdateDecl(wasm: *Wasm, decl_index: Module.Decl.Index, code: []const u8
14731473
1474 atom.size = @intCast(u32, code.len);1474 atom.size = @intCast(u32, code.len);
1475 if (code.len == 0) return;1475 if (code.len == 0) return;
1476 atom.alignment = decl.ty.abiAlignment(wasm.base.options.target);1476 atom.alignment = decl.ty.abiAlignment(mod);
1477}1477}
14781478
1479/// From a given symbol location, returns its `wasm.GlobalType`.1479/// From a given symbol location, returns its `wasm.GlobalType`.
...@@ -1523,9 +1523,8 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {...@@ -1523,9 +1523,8 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {
1523/// Returns the symbol index of the local1523/// Returns the symbol index of the local
1524/// The given `decl` is the parent decl whom owns the constant.1524/// The given `decl` is the parent decl whom owns the constant.
1525pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.Index) !u32 {1525pub 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
1528 const mod = wasm.base.options.module.?;1526 const mod = wasm.base.options.module.?;
1527 assert(tv.ty.zigTypeTag(mod) != .Fn); // cannot create local symbols for functions
1529 const decl = mod.declPtr(decl_index);1528 const decl = mod.declPtr(decl_index);
15301529
1531 // Create and initialize a new local symbol and atom1530 // 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...@@ -1543,7 +1542,7 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.In
15431542
1544 const code = code: {1543 const code = code: {
1545 const atom = wasm.getAtomPtr(atom_index);1544 const atom = wasm.getAtomPtr(atom_index);
1546 atom.alignment = tv.ty.abiAlignment(wasm.base.options.target);1545 atom.alignment = tv.ty.abiAlignment(mod);
1547 wasm.symbols.items[atom.sym_index] = .{1546 wasm.symbols.items[atom.sym_index] = .{
1548 .name = try wasm.string_table.put(wasm.base.allocator, name),1547 .name = try wasm.string_table.put(wasm.base.allocator, name),
1549 .flags = @enumToInt(Symbol.Flag.WASM_SYM_BINDING_LOCAL),1548 .flags = @enumToInt(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
...@@ -1632,7 +1631,7 @@ pub fn getDeclVAddr(...@@ -1632,7 +1631,7 @@ pub fn getDeclVAddr(
1632 const atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;1631 const atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;
1633 const atom = wasm.getAtomPtr(atom_index);1632 const atom = wasm.getAtomPtr(atom_index);
1634 const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32;1633 const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32;
1635 if (decl.ty.zigTypeTag() == .Fn) {1634 if (decl.ty.zigTypeTag(mod) == .Fn) {
1636 assert(reloc_info.addend == 0); // addend not allowed for function relocations1635 assert(reloc_info.addend == 0); // addend not allowed for function relocations
1637 // We found a function pointer, so add it to our table,1636 // We found a function pointer, so add it to our table,
1638 // as function pointers are not allowed to be stored inside the data section.1637 // as function pointers are not allowed to be stored inside the data section.
...@@ -2933,7 +2932,8 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 {...@@ -2933,7 +2932,8 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 {
2933 const atom_index = try wasm.createAtom();2932 const atom_index = try wasm.createAtom();
2934 const atom = wasm.getAtomPtr(atom_index);2933 const atom = wasm.getAtomPtr(atom_index);
2935 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);2934 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);
2937 const sym_index = atom.sym_index;2937 const sym_index = atom.sym_index;
29382938
2939 const sym_name = try wasm.string_table.put(wasm.base.allocator, "__zig_err_name_table");2939 const sym_name = try wasm.string_table.put(wasm.base.allocator, "__zig_err_name_table");
...@@ -3000,7 +3000,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void {...@@ -3000,7 +3000,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
3000 .offset = offset,3000 .offset = offset,
3001 .addend = @intCast(i32, addend),3001 .addend = @intCast(i32, addend),
3002 });3002 });
3003 atom.size += @intCast(u32, slice_ty.abiSize(wasm.base.options.target));3003 atom.size += @intCast(u32, slice_ty.abiSize(mod));
3004 addend += len;3004 addend += len;
30053005
3006 // as we updated the error name table, we now store the actual name within the names atom3006 // 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...@@ -3369,7 +3369,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
3369 if (decl.isExtern()) continue;3369 if (decl.isExtern()) continue;
3370 const atom_index = entry.value_ptr.*;3370 const atom_index = entry.value_ptr.*;
3371 const atom = wasm.getAtomPtr(atom_index);3371 const atom = wasm.getAtomPtr(atom_index);
3372 if (decl.ty.zigTypeTag() == .Fn) {3372 if (decl.ty.zigTypeTag(mod) == .Fn) {
3373 try wasm.parseAtom(atom_index, .function);3373 try wasm.parseAtom(atom_index, .function);
3374 } else if (decl.getVariable()) |variable| {3374 } else if (decl.getVariable()) |variable| {
3375 if (!variable.is_mutable) {3375 if (!variable.is_mutable) {
src/print_air.zig+4-4
...@@ -7,6 +7,7 @@ const Value = @import("value.zig").Value;...@@ -7,6 +7,7 @@ const Value = @import("value.zig").Value;
7const Type = @import("type.zig").Type;7const Type = @import("type.zig").Type;
8const Air = @import("Air.zig");8const Air = @import("Air.zig");
9const Liveness = @import("Liveness.zig");9const Liveness = @import("Liveness.zig");
10const InternPool = @import("InternPool.zig");
1011
11pub fn write(stream: anytype, module: *Module, air: Air, liveness: ?Liveness) void {12pub fn write(stream: anytype, module: *Module, air: Air, liveness: ?Liveness) void {
12 const instruction_bytes = air.instructions.len *13 const instruction_bytes = air.instructions.len *
...@@ -965,14 +966,13 @@ const Writer = struct {...@@ -965,14 +966,13 @@ const Writer = struct {
965 operand: Air.Inst.Ref,966 operand: Air.Inst.Ref,
966 dies: bool,967 dies: bool,
967 ) @TypeOf(s).Error!void {968 ) @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) {
971 return s.print("@{}", .{operand});972 return s.print("@{}", .{operand});
972 }973 }
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);
976 }976 }
977977
978 fn writeInstIndex(978 fn writeInstIndex(
src/print_zir.zig+4-8
...@@ -3,6 +3,7 @@ const mem = std.mem;...@@ -3,6 +3,7 @@ const mem = std.mem;
3const Allocator = std.mem.Allocator;3const Allocator = std.mem.Allocator;
4const assert = std.debug.assert;4const assert = std.debug.assert;
5const Ast = std.zig.Ast;5const Ast = std.zig.Ast;
6const InternPool = @import("InternPool.zig");
67
7const Zir = @import("Zir.zig");8const Zir = @import("Zir.zig");
8const Module = @import("Module.zig");9const Module = @import("Module.zig");
...@@ -2468,14 +2469,9 @@ const Writer = struct {...@@ -2468,14 +2469,9 @@ const Writer = struct {
2468 }2469 }
24692470
2470 fn writeInstRef(self: *Writer, stream: anytype, ref: Zir.Inst.Ref) !void {2471 fn writeInstRef(self: *Writer, stream: anytype, ref: Zir.Inst.Ref) !void {
2471 var i: usize = @enumToInt(ref);2472 const i = @enumToInt(ref);
24722473 if (i < InternPool.static_len) return stream.print("@{}", .{@intToEnum(InternPool.Index, i)});
2473 if (i < Zir.Inst.Ref.typed_value_map.len) {2474 return self.writeInstIndex(stream, i - InternPool.static_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));
2479 }2475 }
24802476
2481 fn writeInstIndex(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2477 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 {...@@ -512,134 +512,6 @@ pub fn needUnwindTables(target: std.Target) bool {
512 return target.os.tag == .windows;512 return target.os.tag == .windows;
513}513}
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
643pub fn defaultAddressSpace(515pub fn defaultAddressSpace(
644 target: std.Target,516 target: std.Target,
645 context: enum {517 context: enum {
src/type.zig+650-663
...@@ -9,27 +9,102 @@ const log = std.log.scoped(.Type);...@@ -9,27 +9,102 @@ const log = std.log.scoped(.Type);
9const target_util = @import("target.zig");9const target_util = @import("target.zig");
10const TypedValue = @import("TypedValue.zig");10const TypedValue = @import("TypedValue.zig");
11const Sema = @import("Sema.zig");11const Sema = @import("Sema.zig");
12const InternPool = @import("InternPool.zig");
1213
13const file_struct = @This();14const file_struct = @This();
1415
15/// This is the raw data, with no bookkeeping, no memory awareness, no de-duplication.16pub const Type = struct {
16/// It's important for this type to be small.17 /// We are migrating towards using this for every Type object. However, many
17/// Types are not de-duplicated, which helps with multi-threading since it obviates the requirement18 /// types are still represented the legacy way. This is indicated by using
18/// of obtaining a lock on a global type table, as well as making the19 /// InternPool.Index.none.
19/// garbage collection bookkeeping simpler.20 ip_index: InternPool.Index,
20/// This union takes advantage of the fact that the first page of memory21
21/// is unmapped, giving us 4096 possible enum tags that have no payload.22 /// This is the raw data, with no bookkeeping, no memory awareness, no de-duplication.
22pub const Type = extern union {23 /// This union takes advantage of the fact that the first page of memory
23 /// If the tag value is less than Tag.no_payload_count, then no pointer24 /// is unmapped, giving us 4096 possible enum tags that have no payload.
24 /// dereference is needed.25 legacy: extern union {
25 tag_if_small_enough: Tag,26 /// If the tag value is less than Tag.no_payload_count, then no pointer
26 ptr_otherwise: *Payload,27 /// dereference is needed.
2728 tag_if_small_enough: Tag,
28 pub fn zigTypeTag(ty: Type) std.builtin.TypeId {29 ptr_otherwise: *Payload,
29 return ty.zigTypeTagOrPoison() catch unreachable;30 },
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 }
33 switch (ty.tag()) {108 switch (ty.tag()) {
34 .generic_poison => return error.GenericPoison,109 .generic_poison => return error.GenericPoison,
35110
...@@ -56,8 +131,6 @@ pub const Type = extern union {...@@ -56,8 +131,6 @@ pub const Type = extern union {
56 .c_ulong,131 .c_ulong,
57 .c_longlong,132 .c_longlong,
58 .c_ulonglong,133 .c_ulonglong,
59 .int_signed,
60 .int_unsigned,
61 => return .Int,134 => return .Int,
62135
63 .f16,136 .f16,
...@@ -85,10 +158,6 @@ pub const Type = extern union {...@@ -85,10 +158,6 @@ pub const Type = extern union {
85 .null => return .Null,158 .null => return .Null,
86 .undefined => return .Undefined,159 .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,
92 .function => return .Fn,161 .function => return .Fn,
93162
94 .array,163 .array,
...@@ -159,26 +228,26 @@ pub const Type = extern union {...@@ -159,26 +228,26 @@ pub const Type = extern union {
159 }228 }
160 }229 }
161230
162 pub fn baseZigTypeTag(self: Type) std.builtin.TypeId {231 pub fn baseZigTypeTag(self: Type, mod: *const Module) std.builtin.TypeId {
163 return switch (self.zigTypeTag()) {232 return switch (self.zigTypeTag(mod)) {
164 .ErrorUnion => self.errorUnionPayload().baseZigTypeTag(),233 .ErrorUnion => self.errorUnionPayload().baseZigTypeTag(mod),
165 .Optional => {234 .Optional => {
166 var buf: Payload.ElemType = undefined;235 var buf: Payload.ElemType = undefined;
167 return self.optionalChild(&buf).baseZigTypeTag();236 return self.optionalChild(&buf).baseZigTypeTag(mod);
168 },237 },
169 else => |t| t,238 else => |t| t,
170 };239 };
171 }240 }
172241
173 pub fn isSelfComparable(ty: Type, is_equality_cmp: bool) bool {242 pub fn isSelfComparable(ty: Type, mod: *const Module, is_equality_cmp: bool) bool {
174 return switch (ty.zigTypeTag()) {243 return switch (ty.zigTypeTag(mod)) {
175 .Int,244 .Int,
176 .Float,245 .Float,
177 .ComptimeFloat,246 .ComptimeFloat,
178 .ComptimeInt,247 .ComptimeInt,
179 => true,248 => true,
180249
181 .Vector => ty.elemType2().isSelfComparable(is_equality_cmp),250 .Vector => ty.elemType2(mod).isSelfComparable(mod, is_equality_cmp),
182251
183 .Bool,252 .Bool,
184 .Type,253 .Type,
...@@ -205,44 +274,54 @@ pub const Type = extern union {...@@ -205,44 +274,54 @@ pub const Type = extern union {
205 .Optional => {274 .Optional => {
206 if (!is_equality_cmp) return false;275 if (!is_equality_cmp) return false;
207 var buf: Payload.ElemType = undefined;276 var buf: Payload.ElemType = undefined;
208 return ty.optionalChild(&buf).isSelfComparable(is_equality_cmp);277 return ty.optionalChild(&buf).isSelfComparable(mod, is_equality_cmp);
209 },278 },
210 };279 };
211 }280 }
212281
213 pub fn initTag(comptime small_tag: Tag) Type {282 pub fn initTag(comptime small_tag: Tag) Type {
214 comptime assert(@enumToInt(small_tag) < Tag.no_payload_count);283 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 };
216 }288 }
217289
218 pub fn initPayload(payload: *Payload) Type {290 pub fn initPayload(payload: *Payload) Type {
219 assert(@enumToInt(payload.tag) >= Tag.no_payload_count);291 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 };
221 }296 }
222297
223 pub fn tag(self: Type) Tag {298 pub fn tag(ty: Type) Tag {
224 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {299 assert(ty.ip_index == .none);
225 return self.tag_if_small_enough;300 if (@enumToInt(ty.legacy.tag_if_small_enough) < Tag.no_payload_count) {
301 return ty.legacy.tag_if_small_enough;
226 } else {302 } else {
227 return self.ptr_otherwise.tag;303 return ty.legacy.ptr_otherwise.tag;
228 }304 }
229 }305 }
230306
231 /// Prefer `castTag` to this.307 /// Prefer `castTag` to this.
232 pub fn cast(self: Type, comptime T: type) ?*T {308 pub fn cast(self: Type, comptime T: type) ?*T {
309 if (self.ip_index != .none) {
310 return null;
311 }
233 if (@hasField(T, "base_tag")) {312 if (@hasField(T, "base_tag")) {
234 return self.castTag(T.base_tag);313 return self.castTag(T.base_tag);
235 }314 }
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) {
237 return null;316 return null;
238 }317 }
239 inline for (@typeInfo(Tag).Enum.fields) |field| {318 inline for (@typeInfo(Tag).Enum.fields) |field| {
240 if (field.value < Tag.no_payload_count)319 if (field.value < Tag.no_payload_count)
241 continue;320 continue;
242 const t = @intToEnum(Tag, field.value);321 const t = @intToEnum(Tag, field.value);
243 if (self.ptr_otherwise.tag == t) {322 if (self.legacy.ptr_otherwise.tag == t) {
244 if (T == t.Type()) {323 if (T == t.Type()) {
245 return @fieldParentPtr(T, "base", self.ptr_otherwise);324 return @fieldParentPtr(T, "base", self.legacy.ptr_otherwise);
246 }325 }
247 return null;326 return null;
248 }327 }
...@@ -251,11 +330,14 @@ pub const Type = extern union {...@@ -251,11 +330,14 @@ pub const Type = extern union {
251 }330 }
252331
253 pub fn castTag(self: Type, comptime t: Tag) ?*t.Type() {332 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)
255 return null;337 return null;
256338
257 if (self.ptr_otherwise.tag == t)339 if (self.legacy.ptr_otherwise.tag == t)
258 return @fieldParentPtr(t.Type(), "base", self.ptr_otherwise);340 return @fieldParentPtr(t.Type(), "base", self.legacy.ptr_otherwise);
259341
260 return null;342 return null;
261 }343 }
...@@ -285,10 +367,10 @@ pub const Type = extern union {...@@ -285,10 +367,10 @@ pub const Type = extern union {
285 }367 }
286368
287 /// If it is a function pointer, returns the function type. Otherwise returns null.369 /// If it is a function pointer, returns the function type. Otherwise returns null.
288 pub fn castPtrToFn(ty: Type) ?Type {370 pub fn castPtrToFn(ty: Type, mod: *const Module) ?Type {
289 if (ty.zigTypeTag() != .Pointer) return null;371 if (ty.zigTypeTag(mod) != .Pointer) return null;
290 const elem_ty = ty.childType();372 const elem_ty = ty.childType();
291 if (elem_ty.zigTypeTag() != .Fn) return null;373 if (elem_ty.zigTypeTag(mod) != .Fn) return null;
292 return elem_ty;374 return elem_ty;
293 }375 }
294376
...@@ -536,7 +618,10 @@ pub const Type = extern union {...@@ -536,7 +618,10 @@ pub const Type = extern union {
536618
537 pub fn eql(a: Type, b: Type, mod: *Module) bool {619 pub fn eql(a: Type, b: Type, mod: *Module) bool {
538 // As a shortcut, if the small tags / addresses match, we're done.620 // 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
541 switch (a.tag()) {626 switch (a.tag()) {
542 .generic_poison => unreachable,627 .generic_poison => unreachable,
...@@ -589,16 +674,11 @@ pub const Type = extern union {...@@ -589,16 +674,11 @@ pub const Type = extern union {
589 .i64,674 .i64,
590 .u128,675 .u128,
591 .i128,676 .i128,
592 .int_signed,
593 .int_unsigned,
594 => {677 => {
595 if (b.zigTypeTag() != .Int) return false;678 if (b.zigTypeTag(mod) != .Int) return false;
596 if (b.isNamedInt()) return false;679 if (b.isNamedInt()) return false;
597680 const info_a = a.intInfo(mod);
598 // Arbitrary sized integers. The target will not be branched upon,681 const info_b = b.intInfo(mod);
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));
602 return info_a.signedness == info_b.signedness and info_a.bits == info_b.bits;682 return info_a.signedness == info_b.signedness and info_a.bits == info_b.bits;
603 },683 },
604684
...@@ -641,13 +721,8 @@ pub const Type = extern union {...@@ -641,13 +721,8 @@ pub const Type = extern union {
641 return opaque_obj_a == opaque_obj_b;721 return opaque_obj_a == opaque_obj_b;
642 },722 },
643723
644 .fn_noreturn_no_args,724 .function => {
645 .fn_void_no_args,725 if (b.zigTypeTag(mod) != .Fn) return false;
646 .fn_naked_noreturn_no_args,
647 .fn_ccc_void_no_args,
648 .function,
649 => {
650 if (b.zigTypeTag() != .Fn) return false;
651726
652 const a_info = a.fnInfo();727 const a_info = a.fnInfo();
653 const b_info = b.fnInfo();728 const b_info = b.fnInfo();
...@@ -699,7 +774,7 @@ pub const Type = extern union {...@@ -699,7 +774,7 @@ pub const Type = extern union {
699 .array_sentinel,774 .array_sentinel,
700 .vector,775 .vector,
701 => {776 => {
702 if (a.zigTypeTag() != b.zigTypeTag()) return false;777 if (a.zigTypeTag(mod) != b.zigTypeTag(mod)) return false;
703778
704 if (a.arrayLen() != b.arrayLen())779 if (a.arrayLen() != b.arrayLen())
705 return false;780 return false;
...@@ -737,7 +812,7 @@ pub const Type = extern union {...@@ -737,7 +812,7 @@ pub const Type = extern union {
737 .manyptr_const_u8,812 .manyptr_const_u8,
738 .manyptr_const_u8_sentinel_0,813 .manyptr_const_u8_sentinel_0,
739 => {814 => {
740 if (b.zigTypeTag() != .Pointer) return false;815 if (b.zigTypeTag(mod) != .Pointer) return false;
741816
742 const info_a = a.ptrInfo().data;817 const info_a = a.ptrInfo().data;
743 const info_b = b.ptrInfo().data;818 const info_b = b.ptrInfo().data;
...@@ -783,7 +858,7 @@ pub const Type = extern union {...@@ -783,7 +858,7 @@ pub const Type = extern union {
783 .optional_single_const_pointer,858 .optional_single_const_pointer,
784 .optional_single_mut_pointer,859 .optional_single_mut_pointer,
785 => {860 => {
786 if (b.zigTypeTag() != .Optional) return false;861 if (b.zigTypeTag(mod) != .Optional) return false;
787862
788 var buf_a: Payload.ElemType = undefined;863 var buf_a: Payload.ElemType = undefined;
789 var buf_b: Payload.ElemType = undefined;864 var buf_b: Payload.ElemType = undefined;
...@@ -791,7 +866,7 @@ pub const Type = extern union {...@@ -791,7 +866,7 @@ pub const Type = extern union {
791 },866 },
792867
793 .anyerror_void_error_union, .error_union => {868 .anyerror_void_error_union, .error_union => {
794 if (b.zigTypeTag() != .ErrorUnion) return false;869 if (b.zigTypeTag(mod) != .ErrorUnion) return false;
795870
796 const a_set = a.errorUnionSet();871 const a_set = a.errorUnionSet();
797 const b_set = b.errorUnionSet();872 const b_set = b.errorUnionSet();
...@@ -805,8 +880,8 @@ pub const Type = extern union {...@@ -805,8 +880,8 @@ pub const Type = extern union {
805 },880 },
806881
807 .anyframe_T => {882 .anyframe_T => {
808 if (b.zigTypeTag() != .AnyFrame) return false;883 if (b.zigTypeTag(mod) != .AnyFrame) return false;
809 return a.elemType2().eql(b.elemType2(), mod);884 return a.elemType2(mod).eql(b.elemType2(mod), mod);
810 },885 },
811886
812 .empty_struct => {887 .empty_struct => {
...@@ -941,6 +1016,9 @@ pub const Type = extern union {...@@ -941,6 +1016,9 @@ pub const Type = extern union {
941 }1016 }
9421017
943 pub fn hashWithHasher(ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {1018 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 }
944 switch (ty.tag()) {1022 switch (ty.tag()) {
945 .generic_poison => unreachable,1023 .generic_poison => unreachable,
9461024
...@@ -1007,13 +1085,10 @@ pub const Type = extern union {...@@ -1007,13 +1085,10 @@ pub const Type = extern union {
1007 .i64,1085 .i64,
1008 .u128,1086 .u128,
1009 .i128,1087 .i128,
1010 .int_signed,
1011 .int_unsigned,
1012 => {1088 => {
1013 // Arbitrary sized integers. The target will not be branched upon,1089 // Arbitrary sized integers.
1014 // because we handled target-dependent cases above.
1015 std.hash.autoHash(hasher, std.builtin.TypeId.Int);1090 std.hash.autoHash(hasher, std.builtin.TypeId.Int);
1016 const info = ty.intInfo(@as(Target, undefined));1091 const info = ty.intInfo(mod);
1017 std.hash.autoHash(hasher, info.signedness);1092 std.hash.autoHash(hasher, info.signedness);
1018 std.hash.autoHash(hasher, info.bits);1093 std.hash.autoHash(hasher, info.bits);
1019 },1094 },
...@@ -1052,12 +1127,7 @@ pub const Type = extern union {...@@ -1052,12 +1127,7 @@ pub const Type = extern union {
1052 std.hash.autoHash(hasher, opaque_obj);1127 std.hash.autoHash(hasher, opaque_obj);
1053 },1128 },
10541129
1055 .fn_noreturn_no_args,1130 .function => {
1056 .fn_void_no_args,
1057 .fn_naked_noreturn_no_args,
1058 .fn_ccc_void_no_args,
1059 .function,
1060 => {
1061 std.hash.autoHash(hasher, std.builtin.TypeId.Fn);1131 std.hash.autoHash(hasher, std.builtin.TypeId.Fn);
10621132
1063 const fn_info = ty.fnInfo();1133 const fn_info = ty.fnInfo();
...@@ -1275,9 +1345,15 @@ pub const Type = extern union {...@@ -1275,9 +1345,15 @@ pub const Type = extern union {
1275 };1345 };
12761346
1277 pub fn copy(self: Type, allocator: Allocator) error{OutOfMemory}!Type {1347 pub fn copy(self: Type, allocator: Allocator) error{OutOfMemory}!Type {
1278 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {1348 if (self.ip_index != .none) {
1279 return Type{ .tag_if_small_enough = self.tag_if_small_enough };1349 return Type{ .ip_index = self.ip_index, .legacy = undefined };
1280 } else switch (self.ptr_otherwise.tag) {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) {
1281 .u1,1357 .u1,
1282 .u8,1358 .u8,
1283 .i8,1359 .i8,
...@@ -1317,10 +1393,6 @@ pub const Type = extern union {...@@ -1317,10 +1393,6 @@ pub const Type = extern union {
1317 .noreturn,1393 .noreturn,
1318 .null,1394 .null,
1319 .undefined,1395 .undefined,
1320 .fn_noreturn_no_args,
1321 .fn_void_no_args,
1322 .fn_naked_noreturn_no_args,
1323 .fn_ccc_void_no_args,
1324 .single_const_pointer_to_comptime_int,1396 .single_const_pointer_to_comptime_int,
1325 .const_slice_u8,1397 .const_slice_u8,
1326 .const_slice_u8_sentinel_0,1398 .const_slice_u8_sentinel_0,
...@@ -1370,13 +1442,12 @@ pub const Type = extern union {...@@ -1370,13 +1442,12 @@ pub const Type = extern union {
1370 .base = .{ .tag = payload.base.tag },1442 .base = .{ .tag = payload.base.tag },
1371 .data = try payload.data.copy(allocator),1443 .data = try payload.data.copy(allocator),
1372 };1444 };
1373 return Type{ .ptr_otherwise = &new_payload.base };1445 return Type{
1446 .ip_index = .none,
1447 .legacy = .{ .ptr_otherwise = &new_payload.base },
1448 };
1374 },1449 },
13751450
1376 .int_signed,
1377 .int_unsigned,
1378 => return self.copyPayloadShallow(allocator, Payload.Bits),
1379
1380 .vector => {1451 .vector => {
1381 const payload = self.castTag(.vector).?.data;1452 const payload = self.castTag(.vector).?.data;
1382 return Tag.vector.create(allocator, .{1453 return Tag.vector.create(allocator, .{
...@@ -1511,7 +1582,10 @@ pub const Type = extern union {...@@ -1511,7 +1582,10 @@ pub const Type = extern union {
1511 const payload = self.cast(T).?;1582 const payload = self.cast(T).?;
1512 const new_payload = try allocator.create(T);1583 const new_payload = try allocator.create(T);
1513 new_payload.* = payload.*;1584 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 };
1515 }1589 }
15161590
1517 pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {1591 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 {...@@ -1550,7 +1624,7 @@ pub const Type = extern union {
1550 }1624 }
15511625
1552 /// This is a debug function. In order to print types in a meaningful way1626 /// 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.
1554 pub fn dump(1628 pub fn dump(
1555 start_type: Type,1629 start_type: Type,
1556 comptime unused_format_string: []const u8,1630 comptime unused_format_string: []const u8,
...@@ -1559,10 +1633,13 @@ pub const Type = extern union {...@@ -1559,10 +1633,13 @@ pub const Type = extern union {
1559 ) @TypeOf(writer).Error!void {1633 ) @TypeOf(writer).Error!void {
1560 _ = options;1634 _ = options;
1561 comptime assert(unused_format_string.len == 0);1635 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 }
1562 if (true) {1639 if (true) {
1563 // This is disabled to work around a bug where this function1640 // This is disabled to work around a stage2 bug where this function recursively
1564 // recursively causes more generic function instantiations1641 // causes more generic function instantiations resulting in an infinite loop
1565 // resulting in an infinite loop in the compiler.1642 // in the compiler.
1566 try writer.writeAll("[TODO fix internal compiler bug regarding dump]");1643 try writer.writeAll("[TODO fix internal compiler bug regarding dump]");
1567 return;1644 return;
1568 }1645 }
...@@ -1656,10 +1733,6 @@ pub const Type = extern union {...@@ -1656,10 +1733,6 @@ pub const Type = extern union {
1656 .anyerror_void_error_union => return writer.writeAll("anyerror!void"),1733 .anyerror_void_error_union => return writer.writeAll("anyerror!void"),
1657 .const_slice_u8 => return writer.writeAll("[]const u8"),1734 .const_slice_u8 => return writer.writeAll("[]const u8"),
1658 .const_slice_u8_sentinel_0 => return writer.writeAll("[:0]const u8"),1735 .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"),
1663 .single_const_pointer_to_comptime_int => return writer.writeAll("*const comptime_int"),1736 .single_const_pointer_to_comptime_int => return writer.writeAll("*const comptime_int"),
1664 .manyptr_u8 => return writer.writeAll("[*]u8"),1737 .manyptr_u8 => return writer.writeAll("[*]u8"),
1665 .manyptr_const_u8 => return writer.writeAll("[*]const u8"),1738 .manyptr_const_u8 => return writer.writeAll("[*]const u8"),
...@@ -1820,14 +1893,6 @@ pub const Type = extern union {...@@ -1820,14 +1893,6 @@ pub const Type = extern union {
1820 ty = pointee_type;1893 ty = pointee_type;
1821 continue;1894 continue;
1822 },1895 },
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 },
1831 .optional => {1896 .optional => {
1832 const child_type = ty.castTag(.optional).?.data;1897 const child_type = ty.castTag(.optional).?.data;
1833 try writer.writeByte('?');1898 try writer.writeByte('?');
...@@ -1938,6 +2003,26 @@ pub const Type = extern union {...@@ -1938,6 +2003,26 @@ pub const Type = extern union {
19382003
1939 /// Prints a name suitable for `@typeName`.2004 /// Prints a name suitable for `@typeName`.
1940 pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void {2005 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 };
1941 const t = ty.tag();2026 const t = ty.tag();
1942 switch (t) {2027 switch (t) {
1943 .inferred_alloc_const => unreachable,2028 .inferred_alloc_const => unreachable,
...@@ -2041,10 +2126,6 @@ pub const Type = extern union {...@@ -2041,10 +2126,6 @@ pub const Type = extern union {
2041 .anyerror_void_error_union => try writer.writeAll("anyerror!void"),2126 .anyerror_void_error_union => try writer.writeAll("anyerror!void"),
2042 .const_slice_u8 => try writer.writeAll("[]const u8"),2127 .const_slice_u8 => try writer.writeAll("[]const u8"),
2043 .const_slice_u8_sentinel_0 => try writer.writeAll("[:0]const u8"),2128 .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"),
2048 .single_const_pointer_to_comptime_int => try writer.writeAll("*const comptime_int"),2129 .single_const_pointer_to_comptime_int => try writer.writeAll("*const comptime_int"),
2049 .manyptr_u8 => try writer.writeAll("[*]u8"),2130 .manyptr_u8 => try writer.writeAll("[*]u8"),
2050 .manyptr_const_u8 => try writer.writeAll("[*]const u8"),2131 .manyptr_const_u8 => try writer.writeAll("[*]const u8"),
...@@ -2200,7 +2281,7 @@ pub const Type = extern union {...@@ -2200,7 +2281,7 @@ pub const Type = extern union {
2200 if (info.@"align" != 0) {2281 if (info.@"align" != 0) {
2201 try writer.print("align({d}", .{info.@"align"});2282 try writer.print("align({d}", .{info.@"align"});
2202 } else {2283 } else {
2203 const alignment = info.pointee_type.abiAlignment(mod.getTarget());2284 const alignment = info.pointee_type.abiAlignment(mod);
2204 try writer.print("align({d}", .{alignment});2285 try writer.print("align({d}", .{alignment});
2205 }2286 }
22062287
...@@ -2224,14 +2305,6 @@ pub const Type = extern union {...@@ -2224,14 +2305,6 @@ pub const Type = extern union {
2224 try print(info.pointee_type, writer, mod);2305 try print(info.pointee_type, writer, mod);
2225 },2306 },
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 },
2235 .optional => {2308 .optional => {
2236 const child_type = ty.castTag(.optional).?.data;2309 const child_type = ty.castTag(.optional).?.data;
2237 try writer.writeByte('?');2310 try writer.writeByte('?');
...@@ -2317,10 +2390,6 @@ pub const Type = extern union {...@@ -2317,10 +2390,6 @@ pub const Type = extern union {
2317 .noreturn => return Value.initTag(.noreturn_type),2390 .noreturn => return Value.initTag(.noreturn_type),
2318 .null => return Value.initTag(.null_type),2391 .null => return Value.initTag(.null_type),
2319 .undefined => return Value.initTag(.undefined_type),2392 .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),
2324 .single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),2393 .single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),
2325 .const_slice_u8 => return Value.initTag(.const_slice_u8_type),2394 .const_slice_u8 => return Value.initTag(.const_slice_u8_type),
2326 .const_slice_u8_sentinel_0 => return Value.initTag(.const_slice_u8_sentinel_0_type),2395 .const_slice_u8_sentinel_0 => return Value.initTag(.const_slice_u8_sentinel_0_type),
...@@ -2360,9 +2429,24 @@ pub const Type = extern union {...@@ -2360,9 +2429,24 @@ pub const Type = extern union {
2360 /// may return false positives.2429 /// may return false positives.
2361 pub fn hasRuntimeBitsAdvanced(2430 pub fn hasRuntimeBitsAdvanced(
2362 ty: Type,2431 ty: Type,
2432 mod: *const Module,
2363 ignore_comptime_only: bool,2433 ignore_comptime_only: bool,
2364 strat: AbiAlignmentAdvancedStrat,2434 strat: AbiAlignmentAdvancedStrat,
2365 ) RuntimeBitsError!bool {2435 ) 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 };
2366 switch (ty.tag()) {2450 switch (ty.tag()) {
2367 .u1,2451 .u1,
2368 .u8,2452 .u8,
...@@ -2440,12 +2524,12 @@ pub const Type = extern union {...@@ -2440,12 +2524,12 @@ pub const Type = extern union {
2440 => {2524 => {
2441 if (ignore_comptime_only) {2525 if (ignore_comptime_only) {
2442 return true;2526 return true;
2443 } else if (ty.childType().zigTypeTag() == .Fn) {2527 } else if (ty.childType().zigTypeTag(mod) == .Fn) {
2444 return !ty.childType().fnInfo().is_generic;2528 return !ty.childType().fnInfo().is_generic;
2445 } else if (strat == .sema) {2529 } else if (strat == .sema) {
2446 return !(try strat.sema.typeRequiresComptime(ty));2530 return !(try strat.sema.typeRequiresComptime(ty));
2447 } else {2531 } else {
2448 return !comptimeOnly(ty);2532 return !comptimeOnly(ty, mod);
2449 }2533 }
2450 },2534 },
24512535
...@@ -2465,10 +2549,6 @@ pub const Type = extern union {...@@ -2465,10 +2549,6 @@ pub const Type = extern union {
2465 // Special exceptions have to be made when emitting functions due to2549 // Special exceptions have to be made when emitting functions due to
2466 // this returning false.2550 // this returning false.
2467 .function,2551 .function,
2468 .fn_noreturn_no_args,
2469 .fn_void_no_args,
2470 .fn_naked_noreturn_no_args,
2471 .fn_ccc_void_no_args,
2472 => return false,2552 => return false,
24732553
2474 .optional => {2554 .optional => {
...@@ -2483,7 +2563,7 @@ pub const Type = extern union {...@@ -2483,7 +2563,7 @@ pub const Type = extern union {
2483 } else if (strat == .sema) {2563 } else if (strat == .sema) {
2484 return !(try strat.sema.typeRequiresComptime(child_ty));2564 return !(try strat.sema.typeRequiresComptime(child_ty));
2485 } else {2565 } else {
2486 return !comptimeOnly(child_ty);2566 return !comptimeOnly(child_ty, mod);
2487 }2567 }
2488 },2568 },
24892569
...@@ -2502,7 +2582,7 @@ pub const Type = extern union {...@@ -2502,7 +2582,7 @@ pub const Type = extern union {
2502 }2582 }
2503 for (struct_obj.fields.values()) |field| {2583 for (struct_obj.fields.values()) |field| {
2504 if (field.is_comptime) continue;2584 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))
2506 return true;2586 return true;
2507 } else {2587 } else {
2508 return false;2588 return false;
...@@ -2511,16 +2591,15 @@ pub const Type = extern union {...@@ -2511,16 +2591,15 @@ pub const Type = extern union {
25112591
2512 .enum_full => {2592 .enum_full => {
2513 const enum_full = ty.castTag(.enum_full).?.data;2593 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);
2515 },2595 },
2516 .enum_simple => {2596 .enum_simple => {
2517 const enum_simple = ty.castTag(.enum_simple).?.data;2597 const enum_simple = ty.castTag(.enum_simple).?.data;
2518 return enum_simple.fields.count() >= 2;2598 return enum_simple.fields.count() >= 2;
2519 },2599 },
2520 .enum_numbered, .enum_nonexhaustive => {2600 .enum_numbered, .enum_nonexhaustive => {
2521 var buffer: Payload.Bits = undefined;2601 const int_tag_ty = ty.intTagType();
2522 const int_tag_ty = ty.intTagType(&buffer);2602 return int_tag_ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat);
2523 return int_tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, strat);
2524 },2603 },
25252604
2526 .@"union" => {2605 .@"union" => {
...@@ -2537,7 +2616,7 @@ pub const Type = extern union {...@@ -2537,7 +2616,7 @@ pub const Type = extern union {
2537 .lazy => if (!union_obj.haveFieldTypes()) return error.NeedLazy,2616 .lazy => if (!union_obj.haveFieldTypes()) return error.NeedLazy,
2538 }2617 }
2539 for (union_obj.fields.values()) |value| {2618 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))
2541 return true;2620 return true;
2542 } else {2621 } else {
2543 return false;2622 return false;
...@@ -2545,7 +2624,7 @@ pub const Type = extern union {...@@ -2545,7 +2624,7 @@ pub const Type = extern union {
2545 },2624 },
2546 .union_safety_tagged, .union_tagged => {2625 .union_safety_tagged, .union_tagged => {
2547 const union_obj = ty.cast(Payload.Union).?.data;2626 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)) {
2549 return true;2628 return true;
2550 }2629 }
25512630
...@@ -2555,7 +2634,7 @@ pub const Type = extern union {...@@ -2555,7 +2634,7 @@ pub const Type = extern union {
2555 .lazy => if (!union_obj.haveFieldTypes()) return error.NeedLazy,2634 .lazy => if (!union_obj.haveFieldTypes()) return error.NeedLazy,
2556 }2635 }
2557 for (union_obj.fields.values()) |value| {2636 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))
2559 return true;2638 return true;
2560 } else {2639 } else {
2561 return false;2640 return false;
...@@ -2563,18 +2642,16 @@ pub const Type = extern union {...@@ -2563,18 +2642,16 @@ pub const Type = extern union {
2563 },2642 },
25642643
2565 .array, .vector => return ty.arrayLen() != 0 and2644 .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),
2567 .array_u8 => return ty.arrayLen() != 0,2646 .array_u8 => return ty.arrayLen() != 0,
2568 .array_sentinel => return ty.childType().hasRuntimeBitsAdvanced(ignore_comptime_only, strat),2647 .array_sentinel => return ty.childType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat),
2569
2570 .int_signed, .int_unsigned => return ty.cast(Payload.Bits).?.data != 0,
25712648
2572 .tuple, .anon_struct => {2649 .tuple, .anon_struct => {
2573 const tuple = ty.tupleFields();2650 const tuple = ty.tupleFields();
2574 for (tuple.types, 0..) |field_ty, i| {2651 for (tuple.types, 0..) |field_ty, i| {
2575 const val = tuple.values[i];2652 const val = tuple.values[i];
2576 if (val.tag() != .unreachable_value) continue; // comptime field2653 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;
2578 }2655 }
2579 return false;2656 return false;
2580 },2657 },
...@@ -2588,7 +2665,21 @@ pub const Type = extern union {...@@ -2588,7 +2665,21 @@ pub const Type = extern union {
2588 /// true if and only if the type has a well-defined memory layout2665 /// true if and only if the type has a well-defined memory layout
2589 /// readFrom/writeToMemory are supported only for types with a well-2666 /// readFrom/writeToMemory are supported only for types with a well-
2590 /// defined memory layout2667 /// 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 };
2592 return switch (ty.tag()) {2683 return switch (ty.tag()) {
2593 .u1,2684 .u1,
2594 .u8,2685 .u8,
...@@ -2626,8 +2717,6 @@ pub const Type = extern union {...@@ -2626,8 +2717,6 @@ pub const Type = extern union {
2626 .manyptr_const_u8_sentinel_0,2717 .manyptr_const_u8_sentinel_0,
2627 .array_u8,2718 .array_u8,
2628 .array_u8_sentinel_0,2719 .array_u8_sentinel_0,
2629 .int_signed,
2630 .int_unsigned,
2631 .pointer,2720 .pointer,
2632 .single_const_pointer,2721 .single_const_pointer,
2633 .single_mut_pointer,2722 .single_mut_pointer,
...@@ -2670,10 +2759,6 @@ pub const Type = extern union {...@@ -2670,10 +2759,6 @@ pub const Type = extern union {
2670 .enum_literal,2759 .enum_literal,
2671 .type_info,2760 .type_info,
2672 // These are function bodies, not function pointers.2761 // 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,
2677 .function,2762 .function,
2678 .const_slice_u8,2763 .const_slice_u8,
2679 .const_slice_u8_sentinel_0,2764 .const_slice_u8_sentinel_0,
...@@ -2698,25 +2783,25 @@ pub const Type = extern union {...@@ -2698,25 +2783,25 @@ pub const Type = extern union {
26982783
2699 .array,2784 .array,
2700 .array_sentinel,2785 .array_sentinel,
2701 => ty.childType().hasWellDefinedLayout(),2786 => ty.childType().hasWellDefinedLayout(mod),
27022787
2703 .optional => ty.isPtrLikeOptional(),2788 .optional => ty.isPtrLikeOptional(mod),
2704 .@"struct" => ty.castTag(.@"struct").?.data.layout != .Auto,2789 .@"struct" => ty.castTag(.@"struct").?.data.layout != .Auto,
2705 .@"union", .union_safety_tagged => ty.cast(Payload.Union).?.data.layout != .Auto,2790 .@"union", .union_safety_tagged => ty.cast(Payload.Union).?.data.layout != .Auto,
2706 .union_tagged => false,2791 .union_tagged => false,
2707 };2792 };
2708 }2793 }
27092794
2710 pub fn hasRuntimeBits(ty: Type) bool {2795 pub fn hasRuntimeBits(ty: Type, mod: *const Module) bool {
2711 return hasRuntimeBitsAdvanced(ty, false, .eager) catch unreachable;2796 return hasRuntimeBitsAdvanced(ty, mod, false, .eager) catch unreachable;
2712 }2797 }
27132798
2714 pub fn hasRuntimeBitsIgnoreComptime(ty: Type) bool {2799 pub fn hasRuntimeBitsIgnoreComptime(ty: Type, mod: *const Module) bool {
2715 return hasRuntimeBitsAdvanced(ty, true, .eager) catch unreachable;2800 return hasRuntimeBitsAdvanced(ty, mod, true, .eager) catch unreachable;
2716 }2801 }
27172802
2718 pub fn isFnOrHasRuntimeBits(ty: Type) bool {2803 pub fn isFnOrHasRuntimeBits(ty: Type, mod: *const Module) bool {
2719 switch (ty.zigTypeTag()) {2804 switch (ty.zigTypeTag(mod)) {
2720 .Fn => {2805 .Fn => {
2721 const fn_info = ty.fnInfo();2806 const fn_info = ty.fnInfo();
2722 if (fn_info.is_generic) return false;2807 if (fn_info.is_generic) return false;
...@@ -2727,18 +2812,18 @@ pub const Type = extern union {...@@ -2727,18 +2812,18 @@ pub const Type = extern union {
2727 .Inline => return false,2812 .Inline => return false,
2728 else => {},2813 else => {},
2729 }2814 }
2730 if (fn_info.return_type.comptimeOnly()) return false;2815 if (fn_info.return_type.comptimeOnly(mod)) return false;
2731 return true;2816 return true;
2732 },2817 },
2733 else => return ty.hasRuntimeBits(),2818 else => return ty.hasRuntimeBits(mod),
2734 }2819 }
2735 }2820 }
27362821
2737 /// Same as `isFnOrHasRuntimeBits` but comptime-only types may return a false positive.2822 /// Same as `isFnOrHasRuntimeBits` but comptime-only types may return a false positive.
2738 pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type) bool {2823 pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type, mod: *const Module) bool {
2739 return switch (ty.zigTypeTag()) {2824 return switch (ty.zigTypeTag(mod)) {
2740 .Fn => true,2825 .Fn => true,
2741 else => return ty.hasRuntimeBitsIgnoreComptime(),2826 else => return ty.hasRuntimeBitsIgnoreComptime(mod),
2742 };2827 };
2743 }2828 }
27442829
...@@ -2761,11 +2846,11 @@ pub const Type = extern union {...@@ -2761,11 +2846,11 @@ pub const Type = extern union {
2761 }2846 }
27622847
2763 /// Returns 0 if the pointer is naturally aligned and the element type is 0-bit.2848 /// Returns 0 if the pointer is naturally aligned and the element type is 0-bit.
2764 pub fn ptrAlignment(ty: Type, target: Target) u32 {2849 pub fn ptrAlignment(ty: Type, mod: *const Module) u32 {
2765 return ptrAlignmentAdvanced(ty, target, null) catch unreachable;2850 return ptrAlignmentAdvanced(ty, mod, null) catch unreachable;
2766 }2851 }
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 {
2769 switch (ty.tag()) {2854 switch (ty.tag()) {
2770 .single_const_pointer,2855 .single_const_pointer,
2771 .single_mut_pointer,2856 .single_mut_pointer,
...@@ -2780,10 +2865,10 @@ pub const Type = extern union {...@@ -2780,10 +2865,10 @@ pub const Type = extern union {
2780 => {2865 => {
2781 const child_type = ty.cast(Payload.ElemType).?.data;2866 const child_type = ty.cast(Payload.ElemType).?.data;
2782 if (opt_sema) |sema| {2867 if (opt_sema) |sema| {
2783 const res = try child_type.abiAlignmentAdvanced(target, .{ .sema = sema });2868 const res = try child_type.abiAlignmentAdvanced(mod, .{ .sema = sema });
2784 return res.scalar;2869 return res.scalar;
2785 }2870 }
2786 return (child_type.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar;2871 return (child_type.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
2787 },2872 },
27882873
2789 .manyptr_u8,2874 .manyptr_u8,
...@@ -2798,13 +2883,13 @@ pub const Type = extern union {...@@ -2798,13 +2883,13 @@ pub const Type = extern union {
2798 if (ptr_info.@"align" != 0) {2883 if (ptr_info.@"align" != 0) {
2799 return ptr_info.@"align";2884 return ptr_info.@"align";
2800 } else if (opt_sema) |sema| {2885 } 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 });
2802 return res.scalar;2887 return res.scalar;
2803 } else {2888 } 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;
2805 }2890 }
2806 },2891 },
2807 .optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(target, opt_sema),2892 .optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(mod, opt_sema),
28082893
2809 else => unreachable,2894 else => unreachable,
2810 }2895 }
...@@ -2843,13 +2928,13 @@ pub const Type = extern union {...@@ -2843,13 +2928,13 @@ pub const Type = extern union {
2843 }2928 }
28442929
2845 /// Returns 0 for 0-bit types.2930 /// Returns 0 for 0-bit types.
2846 pub fn abiAlignment(ty: Type, target: Target) u32 {2931 pub fn abiAlignment(ty: Type, mod: *const Module) u32 {
2847 return (ty.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar;2932 return (ty.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
2848 }2933 }
28492934
2850 /// May capture a reference to `ty`.2935 /// May capture a reference to `ty`.
2851 pub fn lazyAbiAlignment(ty: Type, target: Target, arena: Allocator) !Value {2936 pub fn lazyAbiAlignment(ty: Type, mod: *const Module, arena: Allocator) !Value {
2852 switch (try ty.abiAlignmentAdvanced(target, .{ .lazy = arena })) {2937 switch (try ty.abiAlignmentAdvanced(mod, .{ .lazy = arena })) {
2853 .val => |val| return val,2938 .val => |val| return val,
2854 .scalar => |x| return Value.Tag.int_u64.create(arena, x),2939 .scalar => |x| return Value.Tag.int_u64.create(arena, x),
2855 }2940 }
...@@ -2874,9 +2959,29 @@ pub const Type = extern union {...@@ -2874,9 +2959,29 @@ pub const Type = extern union {
2874 /// necessary, possibly returning a CompileError.2959 /// necessary, possibly returning a CompileError.
2875 pub fn abiAlignmentAdvanced(2960 pub fn abiAlignmentAdvanced(
2876 ty: Type,2961 ty: Type,
2877 target: Target,2962 mod: *const Module,
2878 strat: AbiAlignmentAdvancedStrat,2963 strat: AbiAlignmentAdvancedStrat,
2879 ) Module.CompileError!AbiAlignmentAdvanced {2964 ) 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
2880 const opt_sema = switch (strat) {2985 const opt_sema = switch (strat) {
2881 .sema => |sema| sema,2986 .sema => |sema| sema,
2882 else => null,2987 else => null,
...@@ -2902,12 +3007,6 @@ pub const Type = extern union {...@@ -2902,12 +3007,6 @@ pub const Type = extern union {
2902 .anyopaque,3007 .anyopaque,
2903 => return AbiAlignmentAdvanced{ .scalar = 1 },3008 => 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
2911 // represents machine code; not a pointer3010 // represents machine code; not a pointer
2912 .function => {3011 .function => {
2913 const alignment = ty.castTag(.function).?.data.alignment;3012 const alignment = ty.castTag(.function).?.data.alignment;
...@@ -2958,12 +3057,11 @@ pub const Type = extern union {...@@ -2958,12 +3057,11 @@ pub const Type = extern union {
2958 .f80 => switch (target.c_type_bit_size(.longdouble)) {3057 .f80 => switch (target.c_type_bit_size(.longdouble)) {
2959 80 => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.longdouble) },3058 80 => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.longdouble) },
2960 else => {3059 else => {
2961 var payload: Payload.Bits = .{3060 const u80_ty: Type = .{
2962 .base = .{ .tag = .int_unsigned },3061 .ip_index = .u80_type,
2963 .data = 80,3062 .legacy = undefined,
2964 };3063 };
2965 const u80_ty = initPayload(&payload.base);3064 return AbiAlignmentAdvanced{ .scalar = abiAlignment(u80_ty, mod) };
2966 return AbiAlignmentAdvanced{ .scalar = abiAlignment(u80_ty, target) };
2967 },3065 },
2968 },3066 },
2969 .f128 => switch (target.c_type_bit_size(.longdouble)) {3067 .f128 => switch (target.c_type_bit_size(.longdouble)) {
...@@ -2980,11 +3078,11 @@ pub const Type = extern union {...@@ -2980,11 +3078,11 @@ pub const Type = extern union {
2980 .error_set_merged,3078 .error_set_merged,
2981 => return AbiAlignmentAdvanced{ .scalar = 2 },3079 => 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
2985 .vector => {3083 .vector => {
2986 const len = ty.arrayLen();3084 const len = ty.arrayLen();
2987 const bits = try bitSizeAdvanced(ty.elemType(), target, opt_sema);3085 const bits = try bitSizeAdvanced(ty.elemType(), mod, opt_sema);
2988 const bytes = ((bits * len) + 7) / 8;3086 const bytes = ((bits * len) + 7) / 8;
2989 const alignment = std.math.ceilPowerOfTwoAssert(u64, bytes);3087 const alignment = std.math.ceilPowerOfTwoAssert(u64, bytes);
2990 return AbiAlignmentAdvanced{ .scalar = @intCast(u32, alignment) };3088 return AbiAlignmentAdvanced{ .scalar = @intCast(u32, alignment) };
...@@ -2996,34 +3094,28 @@ pub const Type = extern union {...@@ -2996,34 +3094,28 @@ pub const Type = extern union {
2996 .i64, .u64 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(64, target) },3094 .i64, .u64 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(64, target) },
2997 .u128, .i128 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(128, target) },3095 .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
3005 .optional => {3097 .optional => {
3006 var buf: Payload.ElemType = undefined;3098 var buf: Payload.ElemType = undefined;
3007 const child_type = ty.optionalChild(&buf);3099 const child_type = ty.optionalChild(&buf);
30083100
3009 switch (child_type.zigTypeTag()) {3101 switch (child_type.zigTypeTag(mod)) {
3010 .Pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) },3102 .Pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) },
3011 .ErrorSet => return abiAlignmentAdvanced(Type.anyerror, target, strat),3103 .ErrorSet => return abiAlignmentAdvanced(Type.anyerror, mod, strat),
3012 .NoReturn => return AbiAlignmentAdvanced{ .scalar = 0 },3104 .NoReturn => return AbiAlignmentAdvanced{ .scalar = 0 },
3013 else => {},3105 else => {},
3014 }3106 }
30153107
3016 switch (strat) {3108 switch (strat) {
3017 .eager, .sema => {3109 .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) {
3019 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },3111 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
3020 else => |e| return e,3112 else => |e| return e,
3021 })) {3113 })) {
3022 return AbiAlignmentAdvanced{ .scalar = 1 };3114 return AbiAlignmentAdvanced{ .scalar = 1 };
3023 }3115 }
3024 return child_type.abiAlignmentAdvanced(target, strat);3116 return child_type.abiAlignmentAdvanced(mod, strat);
3025 },3117 },
3026 .lazy => |arena| switch (try child_type.abiAlignmentAdvanced(target, strat)) {3118 .lazy => |arena| switch (try child_type.abiAlignmentAdvanced(mod, strat)) {
3027 .scalar => |x| return AbiAlignmentAdvanced{ .scalar = @max(x, 1) },3119 .scalar => |x| return AbiAlignmentAdvanced{ .scalar = @max(x, 1) },
3028 .val => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) },3120 .val => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) },
3029 },3121 },
...@@ -3034,10 +3126,10 @@ pub const Type = extern union {...@@ -3034,10 +3126,10 @@ pub const Type = extern union {
3034 // This code needs to be kept in sync with the equivalent switch prong3126 // This code needs to be kept in sync with the equivalent switch prong
3035 // in abiSizeAdvanced.3127 // in abiSizeAdvanced.
3036 const data = ty.castTag(.error_union).?.data;3128 const data = ty.castTag(.error_union).?.data;
3037 const code_align = abiAlignment(Type.anyerror, target);3129 const code_align = abiAlignment(Type.anyerror, mod);
3038 switch (strat) {3130 switch (strat) {
3039 .eager, .sema => {3131 .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) {
3041 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },3133 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
3042 else => |e| return e,3134 else => |e| return e,
3043 })) {3135 })) {
...@@ -3045,11 +3137,11 @@ pub const Type = extern union {...@@ -3045,11 +3137,11 @@ pub const Type = extern union {
3045 }3137 }
3046 return AbiAlignmentAdvanced{ .scalar = @max(3138 return AbiAlignmentAdvanced{ .scalar = @max(
3047 code_align,3139 code_align,
3048 (try data.payload.abiAlignmentAdvanced(target, strat)).scalar,3140 (try data.payload.abiAlignmentAdvanced(mod, strat)).scalar,
3049 ) };3141 ) };
3050 },3142 },
3051 .lazy => |arena| {3143 .lazy => |arena| {
3052 switch (try data.payload.abiAlignmentAdvanced(target, strat)) {3144 switch (try data.payload.abiAlignmentAdvanced(mod, strat)) {
3053 .scalar => |payload_align| {3145 .scalar => |payload_align| {
3054 return AbiAlignmentAdvanced{3146 return AbiAlignmentAdvanced{
3055 .scalar = @max(code_align, payload_align),3147 .scalar = @max(code_align, payload_align),
...@@ -3089,20 +3181,20 @@ pub const Type = extern union {...@@ -3089,20 +3181,20 @@ pub const Type = extern union {
3089 .eager => {},3181 .eager => {},
3090 }3182 }
3091 assert(struct_obj.haveLayout());3183 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) };
3093 }3185 }
30943186
3095 const fields = ty.structFields();3187 const fields = ty.structFields();
3096 var big_align: u32 = 0;3188 var big_align: u32 = 0;
3097 for (fields.values()) |field| {3189 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) {
3099 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },3191 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
3100 else => |e| return e,3192 else => |e| return e,
3101 })) continue;3193 })) continue;
31023194
3103 const field_align = if (field.abi_align != 0)3195 const field_align = if (field.abi_align != 0)
3104 field.abi_align3196 field.abi_align
3105 else switch (try field.ty.abiAlignmentAdvanced(target, strat)) {3197 else switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
3106 .scalar => |a| a,3198 .scalar => |a| a,
3107 .val => switch (strat) {3199 .val => switch (strat) {
3108 .eager => unreachable, // struct layout not resolved3200 .eager => unreachable, // struct layout not resolved
...@@ -3114,7 +3206,7 @@ pub const Type = extern union {...@@ -3114,7 +3206,7 @@ pub const Type = extern union {
31143206
3115 // This logic is duplicated in Module.Struct.Field.alignment.3207 // This logic is duplicated in Module.Struct.Field.alignment.
3116 if (struct_obj.layout == .Extern or target.ofmt == .c) {3208 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) {
3118 // The C ABI requires 128 bit integer fields of structs3210 // The C ABI requires 128 bit integer fields of structs
3119 // to be 16-bytes aligned.3211 // to be 16-bytes aligned.
3120 big_align = @max(big_align, 16);3212 big_align = @max(big_align, 16);
...@@ -3130,9 +3222,9 @@ pub const Type = extern union {...@@ -3130,9 +3222,9 @@ pub const Type = extern union {
3130 for (tuple.types, 0..) |field_ty, i| {3222 for (tuple.types, 0..) |field_ty, i| {
3131 const val = tuple.values[i];3223 const val = tuple.values[i];
3132 if (val.tag() != .unreachable_value) continue; // comptime field3224 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)) {
3136 .scalar => |field_align| big_align = @max(big_align, field_align),3228 .scalar => |field_align| big_align = @max(big_align, field_align),
3137 .val => switch (strat) {3229 .val => switch (strat) {
3138 .eager => unreachable, // field type alignment not resolved3230 .eager => unreachable, // field type alignment not resolved
...@@ -3145,17 +3237,16 @@ pub const Type = extern union {...@@ -3145,17 +3237,16 @@ pub const Type = extern union {
3145 },3237 },
31463238
3147 .enum_full, .enum_nonexhaustive, .enum_simple, .enum_numbered => {3239 .enum_full, .enum_nonexhaustive, .enum_simple, .enum_numbered => {
3148 var buffer: Payload.Bits = undefined;3240 const int_tag_ty = ty.intTagType();
3149 const int_tag_ty = ty.intTagType(&buffer);3241 return AbiAlignmentAdvanced{ .scalar = int_tag_ty.abiAlignment(mod) };
3150 return AbiAlignmentAdvanced{ .scalar = int_tag_ty.abiAlignment(target) };
3151 },3242 },
3152 .@"union" => {3243 .@"union" => {
3153 const union_obj = ty.castTag(.@"union").?.data;3244 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);
3155 },3246 },
3156 .union_safety_tagged, .union_tagged => {3247 .union_safety_tagged, .union_tagged => {
3157 const union_obj = ty.cast(Payload.Union).?.data;3248 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);
3159 },3250 },
31603251
3161 .empty_struct,3252 .empty_struct,
...@@ -3181,7 +3272,7 @@ pub const Type = extern union {...@@ -3181,7 +3272,7 @@ pub const Type = extern union {
31813272
3182 pub fn abiAlignmentAdvancedUnion(3273 pub fn abiAlignmentAdvancedUnion(
3183 ty: Type,3274 ty: Type,
3184 target: Target,3275 mod: *const Module,
3185 strat: AbiAlignmentAdvancedStrat,3276 strat: AbiAlignmentAdvancedStrat,
3186 union_obj: *Module.Union,3277 union_obj: *Module.Union,
3187 have_tag: bool,3278 have_tag: bool,
...@@ -3195,6 +3286,7 @@ pub const Type = extern union {...@@ -3195,6 +3286,7 @@ pub const Type = extern union {
3195 // We'll guess "pointer-aligned", if the union has an3286 // We'll guess "pointer-aligned", if the union has an
3196 // underaligned pointer field then some allocations3287 // underaligned pointer field then some allocations
3197 // might require explicit alignment.3288 // might require explicit alignment.
3289 const target = mod.getTarget();
3198 return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) };3290 return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) };
3199 }3291 }
3200 _ = try sema.resolveTypeFields(ty);3292 _ = try sema.resolveTypeFields(ty);
...@@ -3206,23 +3298,23 @@ pub const Type = extern union {...@@ -3206,23 +3298,23 @@ pub const Type = extern union {
3206 };3298 };
3207 if (union_obj.fields.count() == 0) {3299 if (union_obj.fields.count() == 0) {
3208 if (have_tag) {3300 if (have_tag) {
3209 return abiAlignmentAdvanced(union_obj.tag_ty, target, strat);3301 return abiAlignmentAdvanced(union_obj.tag_ty, mod, strat);
3210 } else {3302 } else {
3211 return AbiAlignmentAdvanced{ .scalar = @boolToInt(union_obj.layout == .Extern) };3303 return AbiAlignmentAdvanced{ .scalar = @boolToInt(union_obj.layout == .Extern) };
3212 }3304 }
3213 }3305 }
32143306
3215 var max_align: u32 = 0;3307 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);
3217 for (union_obj.fields.values()) |field| {3309 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) {
3219 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },3311 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
3220 else => |e| return e,3312 else => |e| return e,
3221 })) continue;3313 })) continue;
32223314
3223 const field_align = if (field.abi_align != 0)3315 const field_align = if (field.abi_align != 0)
3224 field.abi_align3316 field.abi_align
3225 else switch (try field.ty.abiAlignmentAdvanced(target, strat)) {3317 else switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
3226 .scalar => |a| a,3318 .scalar => |a| a,
3227 .val => switch (strat) {3319 .val => switch (strat) {
3228 .eager => unreachable, // struct layout not resolved3320 .eager => unreachable, // struct layout not resolved
...@@ -3236,8 +3328,8 @@ pub const Type = extern union {...@@ -3236,8 +3328,8 @@ pub const Type = extern union {
3236 }3328 }
32373329
3238 /// May capture a reference to `ty`.3330 /// May capture a reference to `ty`.
3239 pub fn lazyAbiSize(ty: Type, target: Target, arena: Allocator) !Value {3331 pub fn lazyAbiSize(ty: Type, mod: *const Module, arena: Allocator) !Value {
3240 switch (try ty.abiSizeAdvanced(target, .{ .lazy = arena })) {3332 switch (try ty.abiSizeAdvanced(mod, .{ .lazy = arena })) {
3241 .val => |val| return val,3333 .val => |val| return val,
3242 .scalar => |x| return Value.Tag.int_u64.create(arena, x),3334 .scalar => |x| return Value.Tag.int_u64.create(arena, x),
3243 }3335 }
...@@ -3245,8 +3337,8 @@ pub const Type = extern union {...@@ -3245,8 +3337,8 @@ pub const Type = extern union {
32453337
3246 /// Asserts the type has the ABI size already resolved.3338 /// Asserts the type has the ABI size already resolved.
3247 /// Types that return false for hasRuntimeBits() return 0.3339 /// Types that return false for hasRuntimeBits() return 0.
3248 pub fn abiSize(ty: Type, target: Target) u64 {3340 pub fn abiSize(ty: Type, mod: *const Module) u64 {
3249 return (abiSizeAdvanced(ty, target, .eager) catch unreachable).scalar;3341 return (abiSizeAdvanced(ty, mod, .eager) catch unreachable).scalar;
3250 }3342 }
32513343
3252 const AbiSizeAdvanced = union(enum) {3344 const AbiSizeAdvanced = union(enum) {
...@@ -3262,14 +3354,30 @@ pub const Type = extern union {...@@ -3262,14 +3354,30 @@ pub const Type = extern union {
3262 /// necessary, possibly returning a CompileError.3354 /// necessary, possibly returning a CompileError.
3263 pub fn abiSizeAdvanced(3355 pub fn abiSizeAdvanced(
3264 ty: Type,3356 ty: Type,
3265 target: Target,3357 mod: *const Module,
3266 strat: AbiAlignmentAdvancedStrat,3358 strat: AbiAlignmentAdvancedStrat,
3267 ) Module.CompileError!AbiSizeAdvanced {3359 ) 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
3268 switch (ty.tag()) {3380 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
3273 .function => unreachable, // represents machine code; not a pointer3381 .function => unreachable, // represents machine code; not a pointer
3274 .@"opaque" => unreachable, // no size available3382 .@"opaque" => unreachable, // no size available
3275 .noreturn => unreachable,3383 .noreturn => unreachable,
...@@ -3308,7 +3416,7 @@ pub const Type = extern union {...@@ -3308,7 +3416,7 @@ pub const Type = extern union {
3308 .eager => {},3416 .eager => {},
3309 }3417 }
3310 assert(struct_obj.haveLayout());3418 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) };
3312 },3420 },
3313 else => {3421 else => {
3314 switch (strat) {3422 switch (strat) {
...@@ -3327,22 +3435,21 @@ pub const Type = extern union {...@@ -3327,22 +3435,21 @@ pub const Type = extern union {
3327 if (field_count == 0) {3435 if (field_count == 0) {
3328 return AbiSizeAdvanced{ .scalar = 0 };3436 return AbiSizeAdvanced{ .scalar = 0 };
3329 }3437 }
3330 return AbiSizeAdvanced{ .scalar = ty.structFieldOffset(field_count, target) };3438 return AbiSizeAdvanced{ .scalar = ty.structFieldOffset(field_count, mod) };
3331 },3439 },
3332 },3440 },
33333441
3334 .enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => {3442 .enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => {
3335 var buffer: Payload.Bits = undefined;3443 const int_tag_ty = ty.intTagType();
3336 const int_tag_ty = ty.intTagType(&buffer);3444 return AbiSizeAdvanced{ .scalar = int_tag_ty.abiSize(mod) };
3337 return AbiSizeAdvanced{ .scalar = int_tag_ty.abiSize(target) };
3338 },3445 },
3339 .@"union" => {3446 .@"union" => {
3340 const union_obj = ty.castTag(.@"union").?.data;3447 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);
3342 },3449 },
3343 .union_safety_tagged, .union_tagged => {3450 .union_safety_tagged, .union_tagged => {
3344 const union_obj = ty.cast(Payload.Union).?.data;3451 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);
3346 },3453 },
33473454
3348 .u1,3455 .u1,
...@@ -3361,7 +3468,7 @@ pub const Type = extern union {...@@ -3361,7 +3468,7 @@ pub const Type = extern union {
3361 .array_u8_sentinel_0 => return AbiSizeAdvanced{ .scalar = ty.castTag(.array_u8_sentinel_0).?.data + 1 },3468 .array_u8_sentinel_0 => return AbiSizeAdvanced{ .scalar = ty.castTag(.array_u8_sentinel_0).?.data + 1 },
3362 .array => {3469 .array => {
3363 const payload = ty.castTag(.array).?.data;3470 const payload = ty.castTag(.array).?.data;
3364 switch (try payload.elem_type.abiSizeAdvanced(target, strat)) {3471 switch (try payload.elem_type.abiSizeAdvanced(mod, strat)) {
3365 .scalar => |elem_size| return AbiSizeAdvanced{ .scalar = payload.len * elem_size },3472 .scalar => |elem_size| return AbiSizeAdvanced{ .scalar = payload.len * elem_size },
3366 .val => switch (strat) {3473 .val => switch (strat) {
3367 .sema => unreachable,3474 .sema => unreachable,
...@@ -3372,7 +3479,7 @@ pub const Type = extern union {...@@ -3372,7 +3479,7 @@ pub const Type = extern union {
3372 },3479 },
3373 .array_sentinel => {3480 .array_sentinel => {
3374 const payload = ty.castTag(.array_sentinel).?.data;3481 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)) {
3376 .scalar => |elem_size| return AbiSizeAdvanced{ .scalar = (payload.len + 1) * elem_size },3483 .scalar => |elem_size| return AbiSizeAdvanced{ .scalar = (payload.len + 1) * elem_size },
3377 .val => switch (strat) {3484 .val => switch (strat) {
3378 .sema => unreachable,3485 .sema => unreachable,
...@@ -3391,10 +3498,10 @@ pub const Type = extern union {...@@ -3391,10 +3498,10 @@ pub const Type = extern union {
3391 .val = try Value.Tag.lazy_size.create(arena, ty),3498 .val = try Value.Tag.lazy_size.create(arena, ty),
3392 },3499 },
3393 };3500 };
3394 const elem_bits = try payload.elem_type.bitSizeAdvanced(target, opt_sema);3501 const elem_bits = try payload.elem_type.bitSizeAdvanced(mod, opt_sema);
3395 const total_bits = elem_bits * payload.len;3502 const total_bits = elem_bits * payload.len;
3396 const total_bytes = (total_bits + 7) / 8;3503 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)) {
3398 .scalar => |x| x,3505 .scalar => |x| x,
3399 .val => return AbiSizeAdvanced{3506 .val => return AbiSizeAdvanced{
3400 .val = try Value.Tag.lazy_size.create(strat.lazy, ty),3507 .val = try Value.Tag.lazy_size.create(strat.lazy, ty),
...@@ -3450,12 +3557,11 @@ pub const Type = extern union {...@@ -3450,12 +3557,11 @@ pub const Type = extern union {
3450 .f80 => switch (target.c_type_bit_size(.longdouble)) {3557 .f80 => switch (target.c_type_bit_size(.longdouble)) {
3451 80 => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longdouble) },3558 80 => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longdouble) },
3452 else => {3559 else => {
3453 var payload: Payload.Bits = .{3560 const u80_ty: Type = .{
3454 .base = .{ .tag = .int_unsigned },3561 .ip_index = .u80_type,
3455 .data = 80,3562 .legacy = undefined,
3456 };3563 };
3457 const u80_ty = initPayload(&payload.base);3564 return AbiSizeAdvanced{ .scalar = abiSize(u80_ty, mod) };
3458 return AbiSizeAdvanced{ .scalar = abiSize(u80_ty, target) };
3459 },3565 },
3460 },3566 },
34613567
...@@ -3473,11 +3579,6 @@ pub const Type = extern union {...@@ -3473,11 +3579,6 @@ pub const Type = extern union {
3473 .i32, .u32 => return AbiSizeAdvanced{ .scalar = intAbiSize(32, target) },3579 .i32, .u32 => return AbiSizeAdvanced{ .scalar = intAbiSize(32, target) },
3474 .i64, .u64 => return AbiSizeAdvanced{ .scalar = intAbiSize(64, target) },3580 .i64, .u64 => return AbiSizeAdvanced{ .scalar = intAbiSize(64, target) },
3475 .u128, .i128 => return AbiSizeAdvanced{ .scalar = intAbiSize(128, target) },3581 .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
3482 .optional => {3583 .optional => {
3483 var buf: Payload.ElemType = undefined;3584 var buf: Payload.ElemType = undefined;
...@@ -3487,16 +3588,16 @@ pub const Type = extern union {...@@ -3487,16 +3588,16 @@ pub const Type = extern union {
3487 return AbiSizeAdvanced{ .scalar = 0 };3588 return AbiSizeAdvanced{ .scalar = 0 };
3488 }3589 }
34893590
3490 if (!(child_type.hasRuntimeBitsAdvanced(false, strat) catch |err| switch (err) {3591 if (!(child_type.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
3491 error.NeedLazy => return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(strat.lazy, ty) },3592 error.NeedLazy => return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(strat.lazy, ty) },
3492 else => |e| return e,3593 else => |e| return e,
3493 })) return AbiSizeAdvanced{ .scalar = 1 };3594 })) return AbiSizeAdvanced{ .scalar = 1 };
34943595
3495 if (ty.optionalReprIsPayload()) {3596 if (ty.optionalReprIsPayload(mod)) {
3496 return abiSizeAdvanced(child_type, target, strat);3597 return abiSizeAdvanced(child_type, mod, strat);
3497 }3598 }
34983599
3499 const payload_size = switch (try child_type.abiSizeAdvanced(target, strat)) {3600 const payload_size = switch (try child_type.abiSizeAdvanced(mod, strat)) {
3500 .scalar => |elem_size| elem_size,3601 .scalar => |elem_size| elem_size,
3501 .val => switch (strat) {3602 .val => switch (strat) {
3502 .sema => unreachable,3603 .sema => unreachable,
...@@ -3510,7 +3611,7 @@ pub const Type = extern union {...@@ -3510,7 +3611,7 @@ pub const Type = extern union {
3510 // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal3611 // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal
3511 // to the child type's ABI alignment.3612 // to the child type's ABI alignment.
3512 return AbiSizeAdvanced{3613 return AbiSizeAdvanced{
3513 .scalar = child_type.abiAlignment(target) + payload_size,3614 .scalar = child_type.abiAlignment(mod) + payload_size,
3514 };3615 };
3515 },3616 },
35163617
...@@ -3518,17 +3619,17 @@ pub const Type = extern union {...@@ -3518,17 +3619,17 @@ pub const Type = extern union {
3518 // This code needs to be kept in sync with the equivalent switch prong3619 // This code needs to be kept in sync with the equivalent switch prong
3519 // in abiAlignmentAdvanced.3620 // in abiAlignmentAdvanced.
3520 const data = ty.castTag(.error_union).?.data;3621 const data = ty.castTag(.error_union).?.data;
3521 const code_size = abiSize(Type.anyerror, target);3622 const code_size = abiSize(Type.anyerror, mod);
3522 if (!(data.payload.hasRuntimeBitsAdvanced(false, strat) catch |err| switch (err) {3623 if (!(data.payload.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
3523 error.NeedLazy => return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(strat.lazy, ty) },3624 error.NeedLazy => return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(strat.lazy, ty) },
3524 else => |e| return e,3625 else => |e| return e,
3525 })) {3626 })) {
3526 // Same as anyerror.3627 // Same as anyerror.
3527 return AbiSizeAdvanced{ .scalar = code_size };3628 return AbiSizeAdvanced{ .scalar = code_size };
3528 }3629 }
3529 const code_align = abiAlignment(Type.anyerror, target);3630 const code_align = abiAlignment(Type.anyerror, mod);
3530 const payload_align = abiAlignment(data.payload, target);3631 const payload_align = abiAlignment(data.payload, mod);
3531 const payload_size = switch (try data.payload.abiSizeAdvanced(target, strat)) {3632 const payload_size = switch (try data.payload.abiSizeAdvanced(mod, strat)) {
3532 .scalar => |elem_size| elem_size,3633 .scalar => |elem_size| elem_size,
3533 .val => switch (strat) {3634 .val => switch (strat) {
3534 .sema => unreachable,3635 .sema => unreachable,
...@@ -3556,7 +3657,7 @@ pub const Type = extern union {...@@ -3556,7 +3657,7 @@ pub const Type = extern union {
35563657
3557 pub fn abiSizeAdvancedUnion(3658 pub fn abiSizeAdvancedUnion(
3558 ty: Type,3659 ty: Type,
3559 target: Target,3660 mod: *const Module,
3560 strat: AbiAlignmentAdvancedStrat,3661 strat: AbiAlignmentAdvancedStrat,
3561 union_obj: *Module.Union,3662 union_obj: *Module.Union,
3562 have_tag: bool,3663 have_tag: bool,
...@@ -3570,7 +3671,7 @@ pub const Type = extern union {...@@ -3570,7 +3671,7 @@ pub const Type = extern union {
3570 },3671 },
3571 .eager => {},3672 .eager => {},
3572 }3673 }
3573 return AbiSizeAdvanced{ .scalar = union_obj.abiSize(target, have_tag) };3674 return AbiSizeAdvanced{ .scalar = union_obj.abiSize(mod, have_tag) };
3574 }3675 }
35753676
3576 fn intAbiSize(bits: u16, target: Target) u64 {3677 fn intAbiSize(bits: u16, target: Target) u64 {
...@@ -3585,8 +3686,8 @@ pub const Type = extern union {...@@ -3585,8 +3686,8 @@ pub const Type = extern union {
3585 );3686 );
3586 }3687 }
35873688
3588 pub fn bitSize(ty: Type, target: Target) u64 {3689 pub fn bitSize(ty: Type, mod: *const Module) u64 {
3589 return bitSizeAdvanced(ty, target, null) catch unreachable;3690 return bitSizeAdvanced(ty, mod, null) catch unreachable;
3590 }3691 }
35913692
3592 /// If you pass `opt_sema`, any recursive type resolutions will happen if3693 /// If you pass `opt_sema`, any recursive type resolutions will happen if
...@@ -3594,15 +3695,29 @@ pub const Type = extern union {...@@ -3594,15 +3695,29 @@ pub const Type = extern union {
3594 /// the type is fully resolved, and there will be no error, guaranteed.3695 /// the type is fully resolved, and there will be no error, guaranteed.
3595 pub fn bitSizeAdvanced(3696 pub fn bitSizeAdvanced(
3596 ty: Type,3697 ty: Type,
3597 target: Target,3698 mod: *const Module,
3598 opt_sema: ?*Sema,3699 opt_sema: ?*Sema,
3599 ) Module.CompileError!u64 {3700 ) 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
3600 const strat: AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;3718 const strat: AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
3719
3601 switch (ty.tag()) {3720 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
3606 .function => unreachable, // represents machine code; not a pointer3721 .function => unreachable, // represents machine code; not a pointer
3607 .anyopaque => unreachable,3722 .anyopaque => unreachable,
3608 .type => unreachable,3723 .type => unreachable,
...@@ -3633,68 +3748,67 @@ pub const Type = extern union {...@@ -3633,68 +3748,67 @@ pub const Type = extern union {
3633 .@"struct" => {3748 .@"struct" => {
3634 const struct_obj = ty.castTag(.@"struct").?.data;3749 const struct_obj = ty.castTag(.@"struct").?.data;
3635 if (struct_obj.layout != .Packed) {3750 if (struct_obj.layout != .Packed) {
3636 return (try ty.abiSizeAdvanced(target, strat)).scalar * 8;3751 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
3637 }3752 }
3638 if (opt_sema) |sema| _ = try sema.resolveTypeLayout(ty);3753 if (opt_sema) |sema| _ = try sema.resolveTypeLayout(ty);
3639 assert(struct_obj.haveLayout());3754 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);
3641 },3756 },
36423757
3643 .tuple, .anon_struct => {3758 .tuple, .anon_struct => {
3644 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);3759 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
3645 if (ty.containerLayout() != .Packed) {3760 if (ty.containerLayout() != .Packed) {
3646 return (try ty.abiSizeAdvanced(target, strat)).scalar * 8;3761 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
3647 }3762 }
3648 var total: u64 = 0;3763 var total: u64 = 0;
3649 for (ty.tupleFields().types) |field_ty| {3764 for (ty.tupleFields().types) |field_ty| {
3650 total += try bitSizeAdvanced(field_ty, target, opt_sema);3765 total += try bitSizeAdvanced(field_ty, mod, opt_sema);
3651 }3766 }
3652 return total;3767 return total;
3653 },3768 },
36543769
3655 .enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => {3770 .enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => {
3656 var buffer: Payload.Bits = undefined;3771 const int_tag_ty = ty.intTagType();
3657 const int_tag_ty = ty.intTagType(&buffer);3772 return try bitSizeAdvanced(int_tag_ty, mod, opt_sema);
3658 return try bitSizeAdvanced(int_tag_ty, target, opt_sema);
3659 },3773 },
36603774
3661 .@"union", .union_safety_tagged, .union_tagged => {3775 .@"union", .union_safety_tagged, .union_tagged => {
3662 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);3776 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
3663 if (ty.containerLayout() != .Packed) {3777 if (ty.containerLayout() != .Packed) {
3664 return (try ty.abiSizeAdvanced(target, strat)).scalar * 8;3778 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
3665 }3779 }
3666 const union_obj = ty.cast(Payload.Union).?.data;3780 const union_obj = ty.cast(Payload.Union).?.data;
3667 assert(union_obj.haveFieldTypes());3781 assert(union_obj.haveFieldTypes());
36683782
3669 var size: u64 = 0;3783 var size: u64 = 0;
3670 for (union_obj.fields.values()) |field| {3784 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));
3672 }3786 }
3673 return size;3787 return size;
3674 },3788 },
36753789
3676 .vector => {3790 .vector => {
3677 const payload = ty.castTag(.vector).?.data;3791 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);
3679 return elem_bit_size * payload.len;3793 return elem_bit_size * payload.len;
3680 },3794 },
3681 .array_u8 => return 8 * ty.castTag(.array_u8).?.data,3795 .array_u8 => return 8 * ty.castTag(.array_u8).?.data,
3682 .array_u8_sentinel_0 => return 8 * (ty.castTag(.array_u8_sentinel_0).?.data + 1),3796 .array_u8_sentinel_0 => return 8 * (ty.castTag(.array_u8_sentinel_0).?.data + 1),
3683 .array => {3797 .array => {
3684 const payload = ty.castTag(.array).?.data;3798 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));
3686 if (elem_size == 0 or payload.len == 0)3800 if (elem_size == 0 or payload.len == 0)
3687 return @as(u64, 0);3801 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);
3689 return (payload.len - 1) * 8 * elem_size + elem_bit_size;3803 return (payload.len - 1) * 8 * elem_size + elem_bit_size;
3690 },3804 },
3691 .array_sentinel => {3805 .array_sentinel => {
3692 const payload = ty.castTag(.array_sentinel).?.data;3806 const payload = ty.castTag(.array_sentinel).?.data;
3693 const elem_size = std.math.max(3807 const elem_size = std.math.max(
3694 payload.elem_type.abiAlignment(target),3808 payload.elem_type.abiAlignment(mod),
3695 payload.elem_type.abiSize(target),3809 payload.elem_type.abiSize(mod),
3696 );3810 );
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);
3698 return payload.len * 8 * elem_size + elem_bit_size;3812 return payload.len * 8 * elem_size + elem_bit_size;
3699 },3813 },
37003814
...@@ -3757,12 +3871,10 @@ pub const Type = extern union {...@@ -3757,12 +3871,10 @@ pub const Type = extern union {
3757 .error_set_merged,3871 .error_set_merged,
3758 => return 16, // TODO revisit this when we have the concept of the error tag type3872 => 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
3762 .optional, .error_union => {3874 .optional, .error_union => {
3763 // Optionals and error unions are not packed so their bitsize3875 // Optionals and error unions are not packed so their bitsize
3764 // includes padding bits.3876 // includes padding bits.
3765 return (try abiSizeAdvanced(ty, target, strat)).scalar * 8;3877 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
3766 },3878 },
37673879
3768 .atomic_order,3880 .atomic_order,
...@@ -3782,8 +3894,8 @@ pub const Type = extern union {...@@ -3782,8 +3894,8 @@ pub const Type = extern union {
37823894
3783 /// Returns true if the type's layout is already resolved and it is safe3895 /// Returns true if the type's layout is already resolved and it is safe
3784 /// to use `abiSize`, `abiAlignment` and `bitSize` on it.3896 /// to use `abiSize`, `abiAlignment` and `bitSize` on it.
3785 pub fn layoutIsResolved(ty: Type) bool {3897 pub fn layoutIsResolved(ty: Type, mod: *const Module) bool {
3786 switch (ty.zigTypeTag()) {3898 switch (ty.zigTypeTag(mod)) {
3787 .Struct => {3899 .Struct => {
3788 if (ty.castTag(.@"struct")) |struct_ty| {3900 if (ty.castTag(.@"struct")) |struct_ty| {
3789 return struct_ty.data.haveLayout();3901 return struct_ty.data.haveLayout();
...@@ -3798,16 +3910,16 @@ pub const Type = extern union {...@@ -3798,16 +3910,16 @@ pub const Type = extern union {
3798 },3910 },
3799 .Array => {3911 .Array => {
3800 if (ty.arrayLenIncludingSentinel() == 0) return true;3912 if (ty.arrayLenIncludingSentinel() == 0) return true;
3801 return ty.childType().layoutIsResolved();3913 return ty.childType().layoutIsResolved(mod);
3802 },3914 },
3803 .Optional => {3915 .Optional => {
3804 var buf: Type.Payload.ElemType = undefined;3916 var buf: Type.Payload.ElemType = undefined;
3805 const payload_ty = ty.optionalChild(&buf);3917 const payload_ty = ty.optionalChild(&buf);
3806 return payload_ty.layoutIsResolved();3918 return payload_ty.layoutIsResolved(mod);
3807 },3919 },
3808 .ErrorUnion => {3920 .ErrorUnion => {
3809 const payload_ty = ty.errorUnionPayload();3921 const payload_ty = ty.errorUnionPayload();
3810 return payload_ty.layoutIsResolved();3922 return payload_ty.layoutIsResolved(mod);
3811 },3923 },
3812 else => return true,3924 else => return true,
3813 }3925 }
...@@ -3994,13 +4106,13 @@ pub const Type = extern union {...@@ -3994,13 +4106,13 @@ pub const Type = extern union {
3994 };4106 };
3995 }4107 }
39964108
3997 pub fn isAllowzeroPtr(self: Type) bool {4109 pub fn isAllowzeroPtr(self: Type, mod: *const Module) bool {
3998 return switch (self.tag()) {4110 return switch (self.tag()) {
3999 .pointer => {4111 .pointer => {
4000 const payload = self.castTag(.pointer).?.data;4112 const payload = self.castTag(.pointer).?.data;
4001 return payload.@"allowzero";4113 return payload.@"allowzero";
4002 },4114 },
4003 else => return self.zigTypeTag() == .Optional,4115 else => return self.zigTypeTag(mod) == .Optional,
4004 };4116 };
4005 }4117 }
40064118
...@@ -4016,7 +4128,7 @@ pub const Type = extern union {...@@ -4016,7 +4128,7 @@ pub const Type = extern union {
4016 };4128 };
4017 }4129 }
40184130
4019 pub fn isPtrAtRuntime(self: Type) bool {4131 pub fn isPtrAtRuntime(self: Type, mod: *const Module) bool {
4020 switch (self.tag()) {4132 switch (self.tag()) {
4021 .c_const_pointer,4133 .c_const_pointer,
4022 .c_mut_pointer,4134 .c_mut_pointer,
...@@ -4040,7 +4152,7 @@ pub const Type = extern union {...@@ -4040,7 +4152,7 @@ pub const Type = extern union {
4040 .optional => {4152 .optional => {
4041 var buf: Payload.ElemType = undefined;4153 var buf: Payload.ElemType = undefined;
4042 const child_type = self.optionalChild(&buf);4154 const child_type = self.optionalChild(&buf);
4043 if (child_type.zigTypeTag() != .Pointer) return false;4155 if (child_type.zigTypeTag(mod) != .Pointer) return false;
4044 const info = child_type.ptrInfo().data;4156 const info = child_type.ptrInfo().data;
4045 switch (info.size) {4157 switch (info.size) {
4046 .Slice, .C => return false,4158 .Slice, .C => return false,
...@@ -4054,15 +4166,15 @@ pub const Type = extern union {...@@ -4054,15 +4166,15 @@ pub const Type = extern union {
40544166
4055 /// For pointer-like optionals, returns true, otherwise returns the allowzero property4167 /// For pointer-like optionals, returns true, otherwise returns the allowzero property
4056 /// of pointers.4168 /// of pointers.
4057 pub fn ptrAllowsZero(ty: Type) bool {4169 pub fn ptrAllowsZero(ty: Type, mod: *const Module) bool {
4058 if (ty.isPtrLikeOptional()) {4170 if (ty.isPtrLikeOptional(mod)) {
4059 return true;4171 return true;
4060 }4172 }
4061 return ty.ptrInfo().data.@"allowzero";4173 return ty.ptrInfo().data.@"allowzero";
4062 }4174 }
40634175
4064 /// See also `isPtrLikeOptional`.4176 /// See also `isPtrLikeOptional`.
4065 pub fn optionalReprIsPayload(ty: Type) bool {4177 pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool {
4066 switch (ty.tag()) {4178 switch (ty.tag()) {
4067 .optional_single_const_pointer,4179 .optional_single_const_pointer,
4068 .optional_single_mut_pointer,4180 .optional_single_mut_pointer,
...@@ -4072,7 +4184,7 @@ pub const Type = extern union {...@@ -4072,7 +4184,7 @@ pub const Type = extern union {
40724184
4073 .optional => {4185 .optional => {
4074 const child_ty = ty.castTag(.optional).?.data;4186 const child_ty = ty.castTag(.optional).?.data;
4075 switch (child_ty.zigTypeTag()) {4187 switch (child_ty.zigTypeTag(mod)) {
4076 .Pointer => {4188 .Pointer => {
4077 const info = child_ty.ptrInfo().data;4189 const info = child_ty.ptrInfo().data;
4078 switch (info.size) {4190 switch (info.size) {
...@@ -4093,7 +4205,7 @@ pub const Type = extern union {...@@ -4093,7 +4205,7 @@ pub const Type = extern union {
40934205
4094 /// Returns true if the type is optional and would be lowered to a single pointer4206 /// Returns true if the type is optional and would be lowered to a single pointer
4095 /// address value, using 0 for null. Note that this returns true for C pointers.4207 /// 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 {
4097 switch (self.tag()) {4209 switch (self.tag()) {
4098 .optional_single_const_pointer,4210 .optional_single_const_pointer,
4099 .optional_single_mut_pointer,4211 .optional_single_mut_pointer,
...@@ -4103,7 +4215,7 @@ pub const Type = extern union {...@@ -4103,7 +4215,7 @@ pub const Type = extern union {
41034215
4104 .optional => {4216 .optional => {
4105 const child_ty = self.castTag(.optional).?.data;4217 const child_ty = self.castTag(.optional).?.data;
4106 if (child_ty.zigTypeTag() != .Pointer) return false;4218 if (child_ty.zigTypeTag(mod) != .Pointer) return false;
4107 const info = child_ty.ptrInfo().data;4219 const info = child_ty.ptrInfo().data;
4108 switch (info.size) {4220 switch (info.size) {
4109 .Slice, .C => return false,4221 .Slice, .C => return false,
...@@ -4166,7 +4278,7 @@ pub const Type = extern union {...@@ -4166,7 +4278,7 @@ pub const Type = extern union {
4166 /// For [N]T, returns T.4278 /// For [N]T, returns T.
4167 /// For []T, returns T.4279 /// For []T, returns T.
4168 /// For anyframe->T, returns T.4280 /// For anyframe->T, returns T.
4169 pub fn elemType2(ty: Type) Type {4281 pub fn elemType2(ty: Type, mod: *const Module) Type {
4170 return switch (ty.tag()) {4282 return switch (ty.tag()) {
4171 .vector => ty.castTag(.vector).?.data.elem_type,4283 .vector => ty.castTag(.vector).?.data.elem_type,
4172 .array => ty.castTag(.array).?.data.elem_type,4284 .array => ty.castTag(.array).?.data.elem_type,
...@@ -4181,7 +4293,7 @@ pub const Type = extern union {...@@ -4181,7 +4293,7 @@ pub const Type = extern union {
41814293
4182 .single_const_pointer,4294 .single_const_pointer,
4183 .single_mut_pointer,4295 .single_mut_pointer,
4184 => ty.castPointer().?.data.shallowElemType(),4296 => ty.castPointer().?.data.shallowElemType(mod),
41854297
4186 .array_u8,4298 .array_u8,
4187 .array_u8_sentinel_0,4299 .array_u8_sentinel_0,
...@@ -4197,7 +4309,7 @@ pub const Type = extern union {...@@ -4197,7 +4309,7 @@ pub const Type = extern union {
4197 const info = ty.castTag(.pointer).?.data;4309 const info = ty.castTag(.pointer).?.data;
4198 const child_ty = info.pointee_type;4310 const child_ty = info.pointee_type;
4199 if (info.size == .One) {4311 if (info.size == .One) {
4200 return child_ty.shallowElemType();4312 return child_ty.shallowElemType(mod);
4201 } else {4313 } else {
4202 return child_ty;4314 return child_ty;
4203 }4315 }
...@@ -4213,16 +4325,16 @@ pub const Type = extern union {...@@ -4213,16 +4325,16 @@ pub const Type = extern union {
4213 };4325 };
4214 }4326 }
42154327
4216 fn shallowElemType(child_ty: Type) Type {4328 fn shallowElemType(child_ty: Type, mod: *const Module) Type {
4217 return switch (child_ty.zigTypeTag()) {4329 return switch (child_ty.zigTypeTag(mod)) {
4218 .Array, .Vector => child_ty.childType(),4330 .Array, .Vector => child_ty.childType(),
4219 else => child_ty,4331 else => child_ty,
4220 };4332 };
4221 }4333 }
42224334
4223 /// For vectors, returns the element type. Otherwise returns self.4335 /// For vectors, returns the element type. Otherwise returns self.
4224 pub fn scalarType(ty: Type) Type {4336 pub fn scalarType(ty: Type, mod: *const Module) Type {
4225 return switch (ty.zigTypeTag()) {4337 return switch (ty.zigTypeTag(mod)) {
4226 .Vector => ty.childType(),4338 .Vector => ty.childType(),
4227 else => ty,4339 else => ty,
4228 };4340 };
...@@ -4360,19 +4472,19 @@ pub const Type = extern union {...@@ -4360,19 +4472,19 @@ pub const Type = extern union {
4360 return union_obj.fields.getIndex(name);4472 return union_obj.fields.getIndex(name);
4361 }4473 }
43624474
4363 pub fn unionHasAllZeroBitFieldTypes(ty: Type) bool {4475 pub fn unionHasAllZeroBitFieldTypes(ty: Type, mod: *const Module) bool {
4364 return ty.cast(Payload.Union).?.data.hasAllZeroBitFieldTypes();4476 return ty.cast(Payload.Union).?.data.hasAllZeroBitFieldTypes(mod);
4365 }4477 }
43664478
4367 pub fn unionGetLayout(ty: Type, target: Target) Module.Union.Layout {4479 pub fn unionGetLayout(ty: Type, mod: *const Module) Module.Union.Layout {
4368 switch (ty.tag()) {4480 switch (ty.tag()) {
4369 .@"union" => {4481 .@"union" => {
4370 const union_obj = ty.castTag(.@"union").?.data;4482 const union_obj = ty.castTag(.@"union").?.data;
4371 return union_obj.getLayout(target, false);4483 return union_obj.getLayout(mod, false);
4372 },4484 },
4373 .union_safety_tagged, .union_tagged => {4485 .union_safety_tagged, .union_tagged => {
4374 const union_obj = ty.cast(Payload.Union).?.data;4486 const union_obj = ty.cast(Payload.Union).?.data;
4375 return union_obj.getLayout(target, true);4487 return union_obj.getLayout(mod, true);
4376 },4488 },
4377 else => unreachable,4489 else => unreachable,
4378 }4490 }
...@@ -4441,8 +4553,8 @@ pub const Type = extern union {...@@ -4441,8 +4553,8 @@ pub const Type = extern union {
4441 };4553 };
4442 }4554 }
44434555
4444 pub fn isError(ty: Type) bool {4556 pub fn isError(ty: Type, mod: *const Module) bool {
4445 return switch (ty.zigTypeTag()) {4557 return switch (ty.zigTypeTag(mod)) {
4446 .ErrorUnion, .ErrorSet => true,4558 .ErrorUnion, .ErrorSet => true,
4447 else => false,4559 else => false,
4448 };4560 };
...@@ -4543,14 +4655,21 @@ pub const Type = extern union {...@@ -4543,14 +4655,21 @@ pub const Type = extern union {
4543 }4655 }
45444656
4545 /// Returns true if and only if the type is a fixed-width integer.4657 /// Returns true if and only if the type is a fixed-width integer.
4546 pub fn isInt(self: Type) bool {4658 pub fn isInt(self: Type, mod: *const Module) bool {
4547 return self.isSignedInt() or self.isUnsignedInt();4659 return self.isSignedInt(mod) or self.isUnsignedInt(mod);
4548 }4660 }
45494661
4550 /// Returns true if and only if the type is a fixed-width, signed integer.4662 /// Returns true if and only if the type is a fixed-width, signed integer.
4551 pub fn isSignedInt(self: Type) bool {4663 pub fn isSignedInt(ty: Type, mod: *const Module) bool {
4552 return switch (self.tag()) {4664 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
4553 .int_signed,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()) {
4554 .i8,4673 .i8,
4555 .isize,4674 .isize,
4556 .c_char,4675 .c_char,
...@@ -4569,9 +4688,16 @@ pub const Type = extern union {...@@ -4569,9 +4688,16 @@ pub const Type = extern union {
4569 }4688 }
45704689
4571 /// Returns true if and only if the type is a fixed-width, unsigned integer.4690 /// Returns true if and only if the type is a fixed-width, unsigned integer.
4572 pub fn isUnsignedInt(self: Type) bool {4691 pub fn isUnsignedInt(ty: Type, mod: *const Module) bool {
4573 return switch (self.tag()) {4692 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
4574 .int_unsigned,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()) {
4575 .usize,4701 .usize,
4576 .c_ushort,4702 .c_ushort,
4577 .c_uint,4703 .c_uint,
...@@ -4592,8 +4718,8 @@ pub const Type = extern union {...@@ -4592,8 +4718,8 @@ pub const Type = extern union {
45924718
4593 /// Returns true for integers, enums, error sets, and packed structs.4719 /// Returns true for integers, enums, error sets, and packed structs.
4594 /// If this function returns true, then intInfo() can be called on the type.4720 /// If this function returns true, then intInfo() can be called on the type.
4595 pub fn isAbiInt(ty: Type) bool {4721 pub fn isAbiInt(ty: Type, mod: *const Module) bool {
4596 return switch (ty.zigTypeTag()) {4722 return switch (ty.zigTypeTag(mod)) {
4597 .Int, .Enum, .ErrorSet => true,4723 .Int, .Enum, .ErrorSet => true,
4598 .Struct => ty.containerLayout() == .Packed,4724 .Struct => ty.containerLayout() == .Packed,
4599 else => false,4725 else => false,
...@@ -4601,17 +4727,26 @@ pub const Type = extern union {...@@ -4601,17 +4727,26 @@ pub const Type = extern union {
4601 }4727 }
46024728
4603 /// Asserts the type is an integer, enum, error set, or vector of one of them.4729 /// 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 {4730 pub fn intInfo(starting_ty: Type, mod: *const Module) InternPool.Key.IntType {
4605 var ty = self;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
4606 while (true) switch (ty.tag()) {4749 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 },
4615 .u1 => return .{ .signedness = .unsigned, .bits = 1 },4750 .u1 => return .{ .signedness = .unsigned, .bits = 1 },
4616 .u8 => return .{ .signedness = .unsigned, .bits = 8 },4751 .u8 => return .{ .signedness = .unsigned, .bits = 8 },
4617 .i8 => return .{ .signedness = .signed, .bits = 8 },4752 .i8 => return .{ .signedness = .signed, .bits = 8 },
...@@ -4729,32 +4864,14 @@ pub const Type = extern union {...@@ -4729,32 +4864,14 @@ pub const Type = extern union {
47294864
4730 /// Asserts the type is a function.4865 /// Asserts the type is a function.
4731 pub fn fnParamLen(self: Type) usize {4866 pub fn fnParamLen(self: Type) usize {
4732 return switch (self.tag()) {4867 return self.castTag(.function).?.data.param_types.len;
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 };
4741 }4868 }
47424869
4743 /// Asserts the type is a function. The length of the slice must be at least the length4870 /// Asserts the type is a function. The length of the slice must be at least the length
4744 /// given by `fnParamLen`.4871 /// given by `fnParamLen`.
4745 pub fn fnParamTypes(self: Type, types: []Type) void {4872 pub fn fnParamTypes(self: Type, types: []Type) void {
4746 switch (self.tag()) {4873 const payload = self.castTag(.function).?.data;
4747 .fn_noreturn_no_args => return,4874 @memcpy(types[0..payload.param_types.len], payload.param_types);
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 }
4758 }4875 }
47594876
4760 /// Asserts the type is a function.4877 /// Asserts the type is a function.
...@@ -4769,33 +4886,15 @@ pub const Type = extern union {...@@ -4769,33 +4886,15 @@ pub const Type = extern union {
4769 }4886 }
4770 }4887 }
47714888
4772 /// Asserts the type is a function.4889 /// Asserts the type is a function or a function pointer.
4773 pub fn fnReturnType(self: Type) Type {4890 pub fn fnReturnType(ty: Type) Type {
4774 return switch (self.tag()) {4891 const fn_ty = if (ty.castPointer()) |p| p.data else ty;
4775 .fn_noreturn_no_args => Type.initTag(.noreturn),4892 return fn_ty.castTag(.function).?.data.return_type;
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 };
4786 }4893 }
47874894
4788 /// Asserts the type is a function.4895 /// Asserts the type is a function.
4789 pub fn fnCallingConvention(self: Type) std.builtin.CallingConvention {4896 pub fn fnCallingConvention(self: Type) std.builtin.CallingConvention {
4790 return switch (self.tag()) {4897 return self.castTag(.function).?.data.cc;
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 };
4799 }4898 }
48004899
4801 /// Asserts the type is a function.4900 /// Asserts the type is a function.
...@@ -4809,15 +4908,15 @@ pub const Type = extern union {...@@ -4809,15 +4908,15 @@ pub const Type = extern union {
4809 };4908 };
4810 }4909 }
48114910
4812 pub fn isValidParamType(self: Type) bool {4911 pub fn isValidParamType(self: Type, mod: *const Module) bool {
4813 return switch (self.zigTypeTagOrPoison() catch return true) {4912 return switch (self.zigTypeTagOrPoison(mod) catch return true) {
4814 .Undefined, .Null, .Opaque, .NoReturn => false,4913 .Undefined, .Null, .Opaque, .NoReturn => false,
4815 else => true,4914 else => true,
4816 };4915 };
4817 }4916 }
48184917
4819 pub fn isValidReturnType(self: Type) bool {4918 pub fn isValidReturnType(self: Type, mod: *const Module) bool {
4820 return switch (self.zigTypeTagOrPoison() catch return true) {4919 return switch (self.zigTypeTagOrPoison(mod) catch return true) {
4821 .Undefined, .Null, .Opaque => false,4920 .Undefined, .Null, .Opaque => false,
4822 else => true,4921 else => true,
4823 };4922 };
...@@ -4825,87 +4924,43 @@ pub const Type = extern union {...@@ -4825,87 +4924,43 @@ pub const Type = extern union {
48254924
4826 /// Asserts the type is a function.4925 /// Asserts the type is a function.
4827 pub fn fnIsVarArgs(self: Type) bool {4926 pub fn fnIsVarArgs(self: Type) bool {
4828 return switch (self.tag()) {4927 return self.castTag(.function).?.data.is_var_args;
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 };
4837 }4928 }
48384929
4839 pub fn fnInfo(ty: Type) Payload.Function.Data {4930 pub fn fnInfo(ty: Type) Payload.Function.Data {
4840 return switch (ty.tag()) {4931 return ty.castTag(.function).?.data;
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 };
4905 }4932 }
49064933
4907 pub fn isNumeric(self: Type) bool {4934 pub fn isNumeric(ty: Type, mod: *const Module) bool {
4908 return switch (self.tag()) {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()) {
4909 .f16,4964 .f16,
4910 .f32,4965 .f32,
4911 .f64,4966 .f64,
...@@ -4937,8 +4992,6 @@ pub const Type = extern union {...@@ -4937,8 +4992,6 @@ pub const Type = extern union {
4937 .c_ulong,4992 .c_ulong,
4938 .c_longlong,4993 .c_longlong,
4939 .c_ulonglong,4994 .c_ulonglong,
4940 .int_unsigned,
4941 .int_signed,
4942 => true,4995 => true,
49434996
4944 else => false,4997 else => false,
...@@ -4947,8 +5000,30 @@ pub const Type = extern union {...@@ -4947,8 +5000,30 @@ pub const Type = extern union {
49475000
4948 /// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which5001 /// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which
4949 /// resolves field types rather than asserting they are already resolved.5002 /// 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 {
4951 var ty = starting_type;5004 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
4952 while (true) switch (ty.tag()) {5027 while (true) switch (ty.tag()) {
4953 .f16,5028 .f16,
4954 .f32,5029 .f32,
...@@ -4988,10 +5063,6 @@ pub const Type = extern union {...@@ -4988,10 +5063,6 @@ pub const Type = extern union {
4988 .error_set_single,5063 .error_set_single,
4989 .error_set,5064 .error_set,
4990 .error_set_merged,5065 .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,
4995 .function,5066 .function,
4996 .single_const_pointer_to_comptime_int,5067 .single_const_pointer_to_comptime_int,
4997 .array_sentinel,5068 .array_sentinel,
...@@ -5047,7 +5118,7 @@ pub const Type = extern union {...@@ -5047,7 +5118,7 @@ pub const Type = extern union {
5047 assert(s.haveFieldTypes());5118 assert(s.haveFieldTypes());
5048 for (s.fields.values()) |field| {5119 for (s.fields.values()) |field| {
5049 if (field.is_comptime) continue;5120 if (field.is_comptime) continue;
5050 if (field.ty.onePossibleValue() != null) continue;5121 if (field.ty.onePossibleValue(mod) != null) continue;
5051 return null;5122 return null;
5052 }5123 }
5053 return Value.initTag(.empty_struct_value);5124 return Value.initTag(.empty_struct_value);
...@@ -5058,7 +5129,7 @@ pub const Type = extern union {...@@ -5058,7 +5129,7 @@ pub const Type = extern union {
5058 for (tuple.values, 0..) |val, i| {5129 for (tuple.values, 0..) |val, i| {
5059 const is_comptime = val.tag() != .unreachable_value;5130 const is_comptime = val.tag() != .unreachable_value;
5060 if (is_comptime) continue;5131 if (is_comptime) continue;
5061 if (tuple.types[i].onePossibleValue() != null) continue;5132 if (tuple.types[i].onePossibleValue(mod) != null) continue;
5062 return null;5133 return null;
5063 }5134 }
5064 return Value.initTag(.empty_struct_value);5135 return Value.initTag(.empty_struct_value);
...@@ -5067,7 +5138,7 @@ pub const Type = extern union {...@@ -5067,7 +5138,7 @@ pub const Type = extern union {
5067 .enum_numbered => {5138 .enum_numbered => {
5068 const enum_numbered = ty.castTag(.enum_numbered).?.data;5139 const enum_numbered = ty.castTag(.enum_numbered).?.data;
5069 // An explicit tag type is always provided for enum_numbered.5140 // 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)) {
5071 return null;5142 return null;
5072 }5143 }
5073 assert(enum_numbered.fields.count() == 1);5144 assert(enum_numbered.fields.count() == 1);
...@@ -5075,7 +5146,7 @@ pub const Type = extern union {...@@ -5075,7 +5146,7 @@ pub const Type = extern union {
5075 },5146 },
5076 .enum_full => {5147 .enum_full => {
5077 const enum_full = ty.castTag(.enum_full).?.data;5148 const enum_full = ty.castTag(.enum_full).?.data;
5078 if (enum_full.tag_ty.hasRuntimeBits()) {5149 if (enum_full.tag_ty.hasRuntimeBits(mod)) {
5079 return null;5150 return null;
5080 }5151 }
5081 switch (enum_full.fields.count()) {5152 switch (enum_full.fields.count()) {
...@@ -5098,7 +5169,7 @@ pub const Type = extern union {...@@ -5098,7 +5169,7 @@ pub const Type = extern union {
5098 },5169 },
5099 .enum_nonexhaustive => {5170 .enum_nonexhaustive => {
5100 const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;5171 const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;
5101 if (!tag_ty.hasRuntimeBits()) {5172 if (!tag_ty.hasRuntimeBits(mod)) {
5102 return Value.zero;5173 return Value.zero;
5103 } else {5174 } else {
5104 return null;5175 return null;
...@@ -5106,10 +5177,10 @@ pub const Type = extern union {...@@ -5106,10 +5177,10 @@ pub const Type = extern union {
5106 },5177 },
5107 .@"union", .union_safety_tagged, .union_tagged => {5178 .@"union", .union_safety_tagged, .union_tagged => {
5108 const union_obj = ty.cast(Payload.Union).?.data;5179 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;
5110 if (union_obj.fields.count() == 0) return Value.initTag(.unreachable_value);5181 if (union_obj.fields.count() == 0) return Value.initTag(.unreachable_value);
5111 const only_field = union_obj.fields.values()[0];5182 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;
5113 _ = tag_val;5184 _ = tag_val;
5114 _ = val_val;5185 _ = val_val;
5115 return Value.initTag(.empty_struct_value);5186 return Value.initTag(.empty_struct_value);
...@@ -5121,17 +5192,10 @@ pub const Type = extern union {...@@ -5121,17 +5192,10 @@ pub const Type = extern union {
5121 .null => return Value.initTag(.null_value),5192 .null => return Value.initTag(.null_value),
5122 .undefined => return Value.initTag(.undef),5193 .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 },
5131 .vector, .array, .array_u8 => {5195 .vector, .array, .array_u8 => {
5132 if (ty.arrayLen() == 0)5196 if (ty.arrayLen() == 0)
5133 return Value.initTag(.empty_array);5197 return Value.initTag(.empty_array);
5134 if (ty.elemType().onePossibleValue() != null)5198 if (ty.elemType().onePossibleValue(mod) != null)
5135 return Value.initTag(.the_only_possible_value);5199 return Value.initTag(.the_only_possible_value);
5136 return null;5200 return null;
5137 },5201 },
...@@ -5146,7 +5210,22 @@ pub const Type = extern union {...@@ -5146,7 +5210,22 @@ pub const Type = extern union {
5146 /// resolves field types rather than asserting they are already resolved.5210 /// resolves field types rather than asserting they are already resolved.
5147 /// TODO merge these implementations together with the "advanced" pattern seen5211 /// TODO merge these implementations together with the "advanced" pattern seen
5148 /// elsewhere in this file.5212 /// 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
5150 return switch (ty.tag()) {5229 return switch (ty.tag()) {
5151 .u1,5230 .u1,
5152 .u8,5231 .u8,
...@@ -5211,8 +5290,6 @@ pub const Type = extern union {...@@ -5211,8 +5290,6 @@ pub const Type = extern union {
5211 .generic_poison,5290 .generic_poison,
5212 .array_u8,5291 .array_u8,
5213 .array_u8_sentinel_0,5292 .array_u8_sentinel_0,
5214 .int_signed,
5215 .int_unsigned,
5216 .enum_simple,5293 .enum_simple,
5217 => false,5294 => false,
52185295
...@@ -5223,10 +5300,6 @@ pub const Type = extern union {...@@ -5223,10 +5300,6 @@ pub const Type = extern union {
5223 .enum_literal,5300 .enum_literal,
5224 .type_info,5301 .type_info,
5225 // These are function bodies, not function pointers.5302 // 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,
5230 .function,5303 .function,
5231 => true,5304 => true,
52325305
...@@ -5236,7 +5309,7 @@ pub const Type = extern union {...@@ -5236,7 +5309,7 @@ pub const Type = extern union {
5236 .array,5309 .array,
5237 .array_sentinel,5310 .array_sentinel,
5238 .vector,5311 .vector,
5239 => return ty.childType().comptimeOnly(),5312 => return ty.childType().comptimeOnly(mod),
52405313
5241 .pointer,5314 .pointer,
5242 .single_const_pointer,5315 .single_const_pointer,
...@@ -5249,10 +5322,10 @@ pub const Type = extern union {...@@ -5249,10 +5322,10 @@ pub const Type = extern union {
5249 .mut_slice,5322 .mut_slice,
5250 => {5323 => {
5251 const child_ty = ty.childType();5324 const child_ty = ty.childType();
5252 if (child_ty.zigTypeTag() == .Fn) {5325 if (child_ty.zigTypeTag(mod) == .Fn) {
5253 return false;5326 return false;
5254 } else {5327 } else {
5255 return child_ty.comptimeOnly();5328 return child_ty.comptimeOnly(mod);
5256 }5329 }
5257 },5330 },
52585331
...@@ -5261,14 +5334,14 @@ pub const Type = extern union {...@@ -5261,14 +5334,14 @@ pub const Type = extern union {
5261 .optional_single_const_pointer,5334 .optional_single_const_pointer,
5262 => {5335 => {
5263 var buf: Type.Payload.ElemType = undefined;5336 var buf: Type.Payload.ElemType = undefined;
5264 return ty.optionalChild(&buf).comptimeOnly();5337 return ty.optionalChild(&buf).comptimeOnly(mod);
5265 },5338 },
52665339
5267 .tuple, .anon_struct => {5340 .tuple, .anon_struct => {
5268 const tuple = ty.tupleFields();5341 const tuple = ty.tupleFields();
5269 for (tuple.types, 0..) |field_ty, i| {5342 for (tuple.types, 0..) |field_ty, i| {
5270 const have_comptime_val = tuple.values[i].tag() != .unreachable_value;5343 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;
5272 }5345 }
5273 return false;5346 return false;
5274 },5347 },
...@@ -5301,48 +5374,48 @@ pub const Type = extern union {...@@ -5301,48 +5374,48 @@ pub const Type = extern union {
5301 }5374 }
5302 },5375 },
53035376
5304 .error_union => return ty.errorUnionPayload().comptimeOnly(),5377 .error_union => return ty.errorUnionPayload().comptimeOnly(mod),
5305 .anyframe_T => {5378 .anyframe_T => {
5306 const child_ty = ty.castTag(.anyframe_T).?.data;5379 const child_ty = ty.castTag(.anyframe_T).?.data;
5307 return child_ty.comptimeOnly();5380 return child_ty.comptimeOnly(mod);
5308 },5381 },
5309 .enum_numbered => {5382 .enum_numbered => {
5310 const tag_ty = ty.castTag(.enum_numbered).?.data.tag_ty;5383 const tag_ty = ty.castTag(.enum_numbered).?.data.tag_ty;
5311 return tag_ty.comptimeOnly();5384 return tag_ty.comptimeOnly(mod);
5312 },5385 },
5313 .enum_full, .enum_nonexhaustive => {5386 .enum_full, .enum_nonexhaustive => {
5314 const tag_ty = ty.cast(Type.Payload.EnumFull).?.data.tag_ty;5387 const tag_ty = ty.cast(Type.Payload.EnumFull).?.data.tag_ty;
5315 return tag_ty.comptimeOnly();5388 return tag_ty.comptimeOnly(mod);
5316 },5389 },
5317 };5390 };
5318 }5391 }
53195392
5320 pub fn isArrayOrVector(ty: Type) bool {5393 pub fn isArrayOrVector(ty: Type, mod: *const Module) bool {
5321 return switch (ty.zigTypeTag()) {5394 return switch (ty.zigTypeTag(mod)) {
5322 .Array, .Vector => true,5395 .Array, .Vector => true,
5323 else => false,5396 else => false,
5324 };5397 };
5325 }5398 }
53265399
5327 pub fn isIndexable(ty: Type) bool {5400 pub fn isIndexable(ty: Type, mod: *const Module) bool {
5328 return switch (ty.zigTypeTag()) {5401 return switch (ty.zigTypeTag(mod)) {
5329 .Array, .Vector => true,5402 .Array, .Vector => true,
5330 .Pointer => switch (ty.ptrSize()) {5403 .Pointer => switch (ty.ptrSize()) {
5331 .Slice, .Many, .C => true,5404 .Slice, .Many, .C => true,
5332 .One => ty.elemType().zigTypeTag() == .Array,5405 .One => ty.elemType().zigTypeTag(mod) == .Array,
5333 },5406 },
5334 .Struct => ty.isTuple(),5407 .Struct => ty.isTuple(),
5335 else => false,5408 else => false,
5336 };5409 };
5337 }5410 }
53385411
5339 pub fn indexableHasLen(ty: Type) bool {5412 pub fn indexableHasLen(ty: Type, mod: *const Module) bool {
5340 return switch (ty.zigTypeTag()) {5413 return switch (ty.zigTypeTag(mod)) {
5341 .Array, .Vector => true,5414 .Array, .Vector => true,
5342 .Pointer => switch (ty.ptrSize()) {5415 .Pointer => switch (ty.ptrSize()) {
5343 .Many, .C => false,5416 .Many, .C => false,
5344 .Slice => true,5417 .Slice => true,
5345 .One => ty.elemType().zigTypeTag() == .Array,5418 .One => ty.elemType().zigTypeTag(mod) == .Array,
5346 },5419 },
5347 .Struct => ty.isTuple(),5420 .Struct => ty.isTuple(),
5348 else => false,5421 else => false,
...@@ -5366,19 +5439,19 @@ pub const Type = extern union {...@@ -5366,19 +5439,19 @@ pub const Type = extern union {
5366 }5439 }
53675440
5368 // Works for vectors and vectors of integers.5441 // Works for vectors and vectors of integers.
5369 pub fn minInt(ty: Type, arena: Allocator, target: Target) !Value {5442 pub fn minInt(ty: Type, arena: Allocator, mod: *const Module) !Value {
5370 const scalar = try minIntScalar(ty.scalarType(), arena, target);5443 const scalar = try minIntScalar(ty.scalarType(mod), arena, mod);
5371 if (ty.zigTypeTag() == .Vector and scalar.tag() != .the_only_possible_value) {5444 if (ty.zigTypeTag(mod) == .Vector and scalar.tag() != .the_only_possible_value) {
5372 return Value.Tag.repeated.create(arena, scalar);5445 return Value.Tag.repeated.create(arena, scalar);
5373 } else {5446 } else {
5374 return scalar;5447 return scalar;
5375 }5448 }
5376 }5449 }
53775450
5378 /// Asserts that self.zigTypeTag() == .Int.5451 /// Asserts that self.zigTypeTag(mod) == .Int.
5379 pub fn minIntScalar(ty: Type, arena: Allocator, target: Target) !Value {5452 pub fn minIntScalar(ty: Type, arena: Allocator, mod: *const Module) !Value {
5380 assert(ty.zigTypeTag() == .Int);5453 assert(ty.zigTypeTag(mod) == .Int);
5381 const info = ty.intInfo(target);5454 const info = ty.intInfo(mod);
53825455
5383 if (info.bits == 0) {5456 if (info.bits == 0) {
5384 return Value.initTag(.the_only_possible_value);5457 return Value.initTag(.the_only_possible_value);
...@@ -5405,9 +5478,9 @@ pub const Type = extern union {...@@ -5405,9 +5478,9 @@ pub const Type = extern union {
5405 }5478 }
54065479
5407 // Works for vectors and vectors of integers.5480 // Works for vectors and vectors of integers.
5408 pub fn maxInt(ty: Type, arena: Allocator, target: Target) !Value {5481 pub fn maxInt(ty: Type, arena: Allocator, mod: *const Module) !Value {
5409 const scalar = try maxIntScalar(ty.scalarType(), arena, target);5482 const scalar = try maxIntScalar(ty.scalarType(mod), arena, mod);
5410 if (ty.zigTypeTag() == .Vector and scalar.tag() != .the_only_possible_value) {5483 if (ty.zigTypeTag(mod) == .Vector and scalar.tag() != .the_only_possible_value) {
5411 return Value.Tag.repeated.create(arena, scalar);5484 return Value.Tag.repeated.create(arena, scalar);
5412 } else {5485 } else {
5413 return scalar;5486 return scalar;
...@@ -5415,9 +5488,9 @@ pub const Type = extern union {...@@ -5415,9 +5488,9 @@ pub const Type = extern union {
5415 }5488 }
54165489
5417 /// Asserts that self.zigTypeTag() == .Int.5490 /// Asserts that self.zigTypeTag() == .Int.
5418 pub fn maxIntScalar(self: Type, arena: Allocator, target: Target) !Value {5491 pub fn maxIntScalar(self: Type, arena: Allocator, mod: *const Module) !Value {
5419 assert(self.zigTypeTag() == .Int);5492 assert(self.zigTypeTag(mod) == .Int);
5420 const info = self.intInfo(target);5493 const info = self.intInfo(mod);
54215494
5422 if (info.bits == 0) {5495 if (info.bits == 0) {
5423 return Value.initTag(.the_only_possible_value);5496 return Value.initTag(.the_only_possible_value);
...@@ -5452,21 +5525,25 @@ pub const Type = extern union {...@@ -5452,21 +5525,25 @@ pub const Type = extern union {
5452 }5525 }
54535526
5454 /// Asserts the type is an enum or a union.5527 /// 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 {
5456 switch (ty.tag()) {5529 switch (ty.tag()) {
5457 .enum_full, .enum_nonexhaustive => return ty.cast(Payload.EnumFull).?.data.tag_ty,5530 .enum_full, .enum_nonexhaustive => return ty.cast(Payload.EnumFull).?.data.tag_ty,
5458 .enum_numbered => return ty.castTag(.enum_numbered).?.data.tag_ty,5531 .enum_numbered => return ty.castTag(.enum_numbered).?.data.tag_ty,
5459 .enum_simple => {5532 .enum_simple => {
5460 const enum_simple = ty.castTag(.enum_simple).?.data;5533 @panic("TODO move enum_simple to use the intern pool");
5461 const field_count = enum_simple.fields.count();5534 //const enum_simple = ty.castTag(.enum_simple).?.data;
5462 const bits: u16 = if (field_count == 0) 0 else std.math.log2_int_ceil(usize, field_count);5535 //const field_count = enum_simple.fields.count();
5463 buffer.* = .{5536 //const bits: u16 = if (field_count == 0) 0 else std.math.log2_int_ceil(usize, field_count);
5464 .base = .{ .tag = .int_unsigned },5537 //buffer.* = .{
5465 .data = bits,5538 // .base = .{ .tag = .int_unsigned },
5466 };5539 // .data = bits,
5467 return Type.initPayload(&buffer.base);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),
5468 },5546 },
5469 .union_tagged => return ty.castTag(.union_tagged).?.data.tag_ty.intTagType(buffer),
5470 else => unreachable,5547 else => unreachable,
5471 }5548 }
5472 }5549 }
...@@ -5566,7 +5643,7 @@ pub const Type = extern union {...@@ -5566,7 +5643,7 @@ pub const Type = extern union {
5566 };5643 };
5567 const end_val = Value.initPayload(&end_payload.base);5644 const end_val = Value.initPayload(&end_payload.base);
5568 if (int_val.compareAll(.gte, end_val, int_ty, m)) return null;5645 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));
5570 }5647 }
5571 };5648 };
5572 switch (ty.tag()) {5649 switch (ty.tag()) {
...@@ -5598,11 +5675,7 @@ pub const Type = extern union {...@@ -5598,11 +5675,7 @@ pub const Type = extern union {
5598 const enum_simple = ty.castTag(.enum_simple).?.data;5675 const enum_simple = ty.castTag(.enum_simple).?.data;
5599 const fields_len = enum_simple.fields.count();5676 const fields_len = enum_simple.fields.count();
5600 const bits = std.math.log2_int_ceil(usize, fields_len);5677 const bits = std.math.log2_int_ceil(usize, fields_len);
5601 var buffer: Payload.Bits = .{5678 const tag_ty = mod.intType(.unsigned, bits) catch @panic("TODO: handle OOM here");
5602 .base = .{ .tag = .int_unsigned },
5603 .data = bits,
5604 };
5605 const tag_ty = Type.initPayload(&buffer.base);
5606 return S.fieldWithRange(tag_ty, enum_tag, fields_len, mod);5679 return S.fieldWithRange(tag_ty, enum_tag, fields_len, mod);
5607 },5680 },
5608 .atomic_order,5681 .atomic_order,
...@@ -5675,19 +5748,19 @@ pub const Type = extern union {...@@ -5675,19 +5748,19 @@ pub const Type = extern union {
5675 }5748 }
5676 }5749 }
56775750
5678 pub fn structFieldAlign(ty: Type, index: usize, target: Target) u32 {5751 pub fn structFieldAlign(ty: Type, index: usize, mod: *const Module) u32 {
5679 switch (ty.tag()) {5752 switch (ty.tag()) {
5680 .@"struct" => {5753 .@"struct" => {
5681 const struct_obj = ty.castTag(.@"struct").?.data;5754 const struct_obj = ty.castTag(.@"struct").?.data;
5682 assert(struct_obj.layout != .Packed);5755 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);
5684 },5757 },
5685 .@"union", .union_safety_tagged, .union_tagged => {5758 .@"union", .union_safety_tagged, .union_tagged => {
5686 const union_obj = ty.cast(Payload.Union).?.data;5759 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);
5688 },5761 },
5689 .tuple => return ty.castTag(.tuple).?.data.types[index].abiAlignment(target),5762 .tuple => return ty.castTag(.tuple).?.data.types[index].abiAlignment(mod),
5690 .anon_struct => return ty.castTag(.anon_struct).?.data.types[index].abiAlignment(target),5763 .anon_struct => return ty.castTag(.anon_struct).?.data.types[index].abiAlignment(mod),
5691 else => unreachable,5764 else => unreachable,
5692 }5765 }
5693 }5766 }
...@@ -5710,7 +5783,7 @@ pub const Type = extern union {...@@ -5710,7 +5783,7 @@ pub const Type = extern union {
5710 }5783 }
5711 }5784 }
57125785
5713 pub fn structFieldValueComptime(ty: Type, index: usize) ?Value {5786 pub fn structFieldValueComptime(ty: Type, mod: *const Module, index: usize) ?Value {
5714 switch (ty.tag()) {5787 switch (ty.tag()) {
5715 .@"struct" => {5788 .@"struct" => {
5716 const struct_obj = ty.castTag(.@"struct").?.data;5789 const struct_obj = ty.castTag(.@"struct").?.data;
...@@ -5718,14 +5791,14 @@ pub const Type = extern union {...@@ -5718,14 +5791,14 @@ pub const Type = extern union {
5718 if (field.is_comptime) {5791 if (field.is_comptime) {
5719 return field.default_val;5792 return field.default_val;
5720 } else {5793 } else {
5721 return field.ty.onePossibleValue();5794 return field.ty.onePossibleValue(mod);
5722 }5795 }
5723 },5796 },
5724 .tuple => {5797 .tuple => {
5725 const tuple = ty.castTag(.tuple).?.data;5798 const tuple = ty.castTag(.tuple).?.data;
5726 const val = tuple.values[index];5799 const val = tuple.values[index];
5727 if (val.tag() == .unreachable_value) {5800 if (val.tag() == .unreachable_value) {
5728 return tuple.types[index].onePossibleValue();5801 return tuple.types[index].onePossibleValue(mod);
5729 } else {5802 } else {
5730 return val;5803 return val;
5731 }5804 }
...@@ -5734,7 +5807,7 @@ pub const Type = extern union {...@@ -5734,7 +5807,7 @@ pub const Type = extern union {
5734 const anon_struct = ty.castTag(.anon_struct).?.data;5807 const anon_struct = ty.castTag(.anon_struct).?.data;
5735 const val = anon_struct.values[index];5808 const val = anon_struct.values[index];
5736 if (val.tag() == .unreachable_value) {5809 if (val.tag() == .unreachable_value) {
5737 return anon_struct.types[index].onePossibleValue();5810 return anon_struct.types[index].onePossibleValue(mod);
5738 } else {5811 } else {
5739 return val;5812 return val;
5740 }5813 }
...@@ -5765,7 +5838,7 @@ pub const Type = extern union {...@@ -5765,7 +5838,7 @@ pub const Type = extern union {
5765 }5838 }
5766 }5839 }
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 {
5769 const struct_obj = ty.castTag(.@"struct").?.data;5842 const struct_obj = ty.castTag(.@"struct").?.data;
5770 assert(struct_obj.layout == .Packed);5843 assert(struct_obj.layout == .Packed);
5771 comptime assert(Type.packed_struct_layout_version == 2);5844 comptime assert(Type.packed_struct_layout_version == 2);
...@@ -5774,9 +5847,9 @@ pub const Type = extern union {...@@ -5774,9 +5847,9 @@ pub const Type = extern union {
5774 var elem_size_bits: u16 = undefined;5847 var elem_size_bits: u16 = undefined;
5775 var running_bits: u16 = 0;5848 var running_bits: u16 = 0;
5776 for (struct_obj.fields.values(), 0..) |f, i| {5849 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));
5780 if (i == field_index) {5853 if (i == field_index) {
5781 bit_offset = running_bits;5854 bit_offset = running_bits;
5782 elem_size_bits = field_bits;5855 elem_size_bits = field_bits;
...@@ -5797,9 +5870,10 @@ pub const Type = extern union {...@@ -5797,9 +5870,10 @@ pub const Type = extern union {
5797 offset: u64 = 0,5870 offset: u64 = 0,
5798 big_align: u32 = 0,5871 big_align: u32 = 0,
5799 struct_obj: *Module.Struct,5872 struct_obj: *Module.Struct,
5800 target: Target,5873 module: *const Module,
58015874
5802 pub fn next(it: *StructOffsetIterator) ?FieldOffset {5875 pub fn next(it: *StructOffsetIterator) ?FieldOffset {
5876 const mod = it.module;
5803 var i = it.field;5877 var i = it.field;
5804 if (it.struct_obj.fields.count() <= i)5878 if (it.struct_obj.fields.count() <= i)
5805 return null;5879 return null;
...@@ -5811,35 +5885,35 @@ pub const Type = extern union {...@@ -5811,35 +5885,35 @@ pub const Type = extern union {
5811 const field = it.struct_obj.fields.values()[i];5885 const field = it.struct_obj.fields.values()[i];
5812 it.field += 1;5886 it.field += 1;
58135887
5814 if (field.is_comptime or !field.ty.hasRuntimeBits()) {5888 if (field.is_comptime or !field.ty.hasRuntimeBits(mod)) {
5815 return FieldOffset{ .field = i, .offset = it.offset };5889 return FieldOffset{ .field = i, .offset = it.offset };
5816 }5890 }
58175891
5818 const field_align = field.alignment(it.target, it.struct_obj.layout);5892 const field_align = field.alignment(mod, it.struct_obj.layout);
5819 it.big_align = @max(it.big_align, field_align);5893 it.big_align = @max(it.big_align, field_align);
5820 const field_offset = std.mem.alignForwardGeneric(u64, it.offset, field_align);5894 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);
5822 return FieldOffset{ .field = i, .offset = field_offset };5896 return FieldOffset{ .field = i, .offset = field_offset };
5823 }5897 }
5824 };5898 };
58255899
5826 /// Get an iterator that iterates over all the struct field, returning the field and5900 /// Get an iterator that iterates over all the struct field, returning the field and
5827 /// offset of that field. Asserts that the type is a non-packed struct.5901 /// 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 {
5829 const struct_obj = ty.castTag(.@"struct").?.data;5903 const struct_obj = ty.castTag(.@"struct").?.data;
5830 assert(struct_obj.haveLayout());5904 assert(struct_obj.haveLayout());
5831 assert(struct_obj.layout != .Packed);5905 assert(struct_obj.layout != .Packed);
5832 return .{ .struct_obj = struct_obj, .target = target };5906 return .{ .struct_obj = struct_obj, .module = mod };
5833 }5907 }
58345908
5835 /// Supports structs and unions.5909 /// 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 {
5837 switch (ty.tag()) {5911 switch (ty.tag()) {
5838 .@"struct" => {5912 .@"struct" => {
5839 const struct_obj = ty.castTag(.@"struct").?.data;5913 const struct_obj = ty.castTag(.@"struct").?.data;
5840 assert(struct_obj.haveLayout());5914 assert(struct_obj.haveLayout());
5841 assert(struct_obj.layout != .Packed);5915 assert(struct_obj.layout != .Packed);
5842 var it = ty.iterateStructOffsets(target);5916 var it = ty.iterateStructOffsets(mod);
5843 while (it.next()) |field_offset| {5917 while (it.next()) |field_offset| {
5844 if (index == field_offset.field)5918 if (index == field_offset.field)
5845 return field_offset.offset;5919 return field_offset.offset;
...@@ -5856,17 +5930,17 @@ pub const Type = extern union {...@@ -5856,17 +5930,17 @@ pub const Type = extern union {
58565930
5857 for (tuple.types, 0..) |field_ty, i| {5931 for (tuple.types, 0..) |field_ty, i| {
5858 const field_val = tuple.values[i];5932 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)) {
5860 // comptime field5934 // comptime field
5861 if (i == index) return offset;5935 if (i == index) return offset;
5862 continue;5936 continue;
5863 }5937 }
58645938
5865 const field_align = field_ty.abiAlignment(target);5939 const field_align = field_ty.abiAlignment(mod);
5866 big_align = @max(big_align, field_align);5940 big_align = @max(big_align, field_align);
5867 offset = std.mem.alignForwardGeneric(u64, offset, field_align);5941 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
5868 if (i == index) return offset;5942 if (i == index) return offset;
5869 offset += field_ty.abiSize(target);5943 offset += field_ty.abiSize(mod);
5870 }5944 }
5871 offset = std.mem.alignForwardGeneric(u64, offset, @max(big_align, 1));5945 offset = std.mem.alignForwardGeneric(u64, offset, @max(big_align, 1));
5872 return offset;5946 return offset;
...@@ -5875,7 +5949,7 @@ pub const Type = extern union {...@@ -5875,7 +5949,7 @@ pub const Type = extern union {
5875 .@"union" => return 0,5949 .@"union" => return 0,
5876 .union_safety_tagged, .union_tagged => {5950 .union_safety_tagged, .union_tagged => {
5877 const union_obj = ty.cast(Payload.Union).?.data;5951 const union_obj = ty.cast(Payload.Union).?.data;
5878 const layout = union_obj.getLayout(target, true);5952 const layout = union_obj.getLayout(mod, true);
5879 if (layout.tag_align >= layout.payload_align) {5953 if (layout.tag_align >= layout.payload_align) {
5880 // {Tag, Payload}5954 // {Tag, Payload}
5881 return std.mem.alignForwardGeneric(u64, layout.tag_size, layout.payload_align);5955 return std.mem.alignForwardGeneric(u64, layout.tag_size, layout.payload_align);
...@@ -6050,10 +6124,6 @@ pub const Type = extern union {...@@ -6050,10 +6124,6 @@ pub const Type = extern union {
6050 manyptr_u8,6124 manyptr_u8,
6051 manyptr_const_u8,6125 manyptr_const_u8,
6052 manyptr_const_u8_sentinel_0,6126 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,
6057 single_const_pointer_to_comptime_int,6127 single_const_pointer_to_comptime_int,
6058 const_slice_u8,6128 const_slice_u8,
6059 const_slice_u8_sentinel_0,6129 const_slice_u8_sentinel_0,
...@@ -6087,8 +6157,6 @@ pub const Type = extern union {...@@ -6087,8 +6157,6 @@ pub const Type = extern union {
6087 c_mut_pointer,6157 c_mut_pointer,
6088 const_slice,6158 const_slice,
6089 mut_slice,6159 mut_slice,
6090 int_signed,
6091 int_unsigned,
6092 function,6160 function,
6093 optional,6161 optional,
6094 optional_single_mut_pointer,6162 optional_single_mut_pointer,
...@@ -6157,10 +6225,6 @@ pub const Type = extern union {...@@ -6157,10 +6225,6 @@ pub const Type = extern union {
6157 .enum_literal,6225 .enum_literal,
6158 .null,6226 .null,
6159 .undefined,6227 .undefined,
6160 .fn_noreturn_no_args,
6161 .fn_void_no_args,
6162 .fn_naked_noreturn_no_args,
6163 .fn_ccc_void_no_args,
6164 .single_const_pointer_to_comptime_int,6228 .single_const_pointer_to_comptime_int,
6165 .anyerror_void_error_union,6229 .anyerror_void_error_union,
6166 .const_slice_u8,6230 .const_slice_u8,
...@@ -6204,10 +6268,6 @@ pub const Type = extern union {...@@ -6204,10 +6268,6 @@ pub const Type = extern union {
6204 .anyframe_T,6268 .anyframe_T,
6205 => Payload.ElemType,6269 => Payload.ElemType,
62066270
6207 .int_signed,
6208 .int_unsigned,
6209 => Payload.Bits,
6210
6211 .error_set => Payload.ErrorSet,6271 .error_set => Payload.ErrorSet,
6212 .error_set_inferred => Payload.ErrorSetInferred,6272 .error_set_inferred => Payload.ErrorSetInferred,
6213 .error_set_merged => Payload.ErrorSetMerged,6273 .error_set_merged => Payload.ErrorSetMerged,
...@@ -6232,7 +6292,10 @@ pub const Type = extern union {...@@ -6232,7 +6292,10 @@ pub const Type = extern union {
62326292
6233 pub fn init(comptime t: Tag) file_struct.Type {6293 pub fn init(comptime t: Tag) file_struct.Type {
6234 comptime std.debug.assert(@enumToInt(t) < Tag.no_payload_count);6294 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 };
6236 }6299 }
62376300
6238 pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!file_struct.Type {6301 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 {...@@ -6241,7 +6304,10 @@ pub const Type = extern union {
6241 .base = .{ .tag = t },6304 .base = .{ .tag = t },
6242 .data = data,6305 .data = data,
6243 };6306 };
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 };
6245 }6311 }
62466312
6247 pub fn Data(comptime t: Tag) type {6313 pub fn Data(comptime t: Tag) type {
...@@ -6422,10 +6488,9 @@ pub const Type = extern union {...@@ -6422,10 +6488,9 @@ pub const Type = extern union {
6422 runtime = std.math.maxInt(u32) - 1,6488 runtime = std.math.maxInt(u32) - 1,
6423 _,6489 _,
6424 };6490 };
64256491 pub fn alignment(data: Data, mod: *const Module) u32 {
6426 pub fn alignment(data: Data, target: Target) u32 {
6427 if (data.@"align" != 0) return data.@"align";6492 if (data.@"align" != 0) return data.@"align";
6428 return abiAlignment(data.pointee_type, target);6493 return abiAlignment(data.pointee_type, mod);
6429 }6494 }
6430 };6495 };
6431 };6496 };
...@@ -6537,12 +6602,11 @@ pub const Type = extern union {...@@ -6537,12 +6602,11 @@ pub const Type = extern union {
6537 pub const @"anyerror" = initTag(.anyerror);6602 pub const @"anyerror" = initTag(.anyerror);
6538 pub const @"anyopaque" = initTag(.anyopaque);6603 pub const @"anyopaque" = initTag(.anyopaque);
6539 pub const @"null" = initTag(.null);6604 pub const @"null" = initTag(.null);
6605 pub const @"noreturn" = initTag(.noreturn);
65406606
6541 pub const err_int = Type.u16;6607 pub const err_int = Type.u16;
65426608
6543 pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type {6609 pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type {
6544 const target = mod.getTarget();
6545
6546 var d = data;6610 var d = data;
65476611
6548 if (d.size == .C) {6612 if (d.size == .C) {
...@@ -6554,8 +6618,8 @@ pub const Type = extern union {...@@ -6554,8 +6618,8 @@ pub const Type = extern union {
6554 // pointee type needs to be resolved more, that needs to be done before calling6618 // pointee type needs to be resolved more, that needs to be done before calling
6555 // this ptr() function.6619 // this ptr() function.
6556 if (d.@"align" != 0) canonicalize: {6620 if (d.@"align" != 0) canonicalize: {
6557 if (!d.pointee_type.layoutIsResolved()) break :canonicalize;6621 if (!d.pointee_type.layoutIsResolved(mod)) break :canonicalize;
6558 if (d.@"align" == d.pointee_type.abiAlignment(target)) {6622 if (d.@"align" == d.pointee_type.abiAlignment(mod)) {
6559 d.@"align" = 0;6623 d.@"align" = 0;
6560 }6624 }
6561 }6625 }
...@@ -6565,7 +6629,7 @@ pub const Type = extern union {...@@ -6565,7 +6629,7 @@ pub const Type = extern union {
6565 // needs to be resolved before calling this ptr() function.6629 // needs to be resolved before calling this ptr() function.
6566 if (d.host_size != 0) {6630 if (d.host_size != 0) {
6567 assert(d.bit_offset < d.host_size * 8);6631 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)) {
6569 assert(d.bit_offset == 0);6633 assert(d.bit_offset == 0);
6570 d.host_size = 0;6634 d.host_size = 0;
6571 }6635 }
...@@ -6676,7 +6740,7 @@ pub const Type = extern union {...@@ -6676,7 +6740,7 @@ pub const Type = extern union {
6676 payload: Type,6740 payload: Type,
6677 mod: *Module,6741 mod: *Module,
6678 ) Allocator.Error!Type {6742 ) Allocator.Error!Type {
6679 assert(error_set.zigTypeTag() == .ErrorSet);6743 assert(error_set.zigTypeTag(mod) == .ErrorSet);
6680 if (error_set.eql(Type.anyerror, mod) and6744 if (error_set.eql(Type.anyerror, mod) and
6681 payload.eql(Type.void, mod))6745 payload.eql(Type.void, mod))
6682 {6746 {
...@@ -6696,83 +6760,6 @@ pub const Type = extern union {...@@ -6696,83 +6760,6 @@ pub const Type = extern union {
6696 return @intCast(u16, base + @boolToInt(upper < max));6760 return @intCast(u16, base + @boolToInt(upper < max));
6697 }6761 }
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
6776 /// This is only used for comptime asserts. Bump this number when you make a change6763 /// This is only used for comptime asserts. Bump this number when you make a change
6777 /// to packed struct layout to find out all the places in the codebase you need to edit!6764 /// to packed struct layout to find out all the places in the codebase you need to edit!
6778 pub const packed_struct_layout_version = 2;6765 pub const packed_struct_layout_version = 2;
src/value.zig+441-439
...@@ -11,17 +11,24 @@ const Module = @import("Module.zig");...@@ -11,17 +11,24 @@ const Module = @import("Module.zig");
11const Air = @import("Air.zig");11const Air = @import("Air.zig");
12const TypedValue = @import("TypedValue.zig");12const TypedValue = @import("TypedValue.zig");
13const Sema = @import("Sema.zig");13const Sema = @import("Sema.zig");
1414const InternPool = @import("InternPool.zig");
15/// This is the raw data, with no bookkeeping, no memory awareness,15
16/// no de-duplication, and no type system awareness.16pub const Value = struct {
17/// It's important for this type to be small.17 /// We are migrating towards using this for every Value object. However, many
18/// This union takes advantage of the fact that the first page of memory18 /// values are still represented the legacy way. This is indicated by using
19/// is unmapped, giving us 4096 possible enum tags that have no payload.19 /// InternPool.Index.none.
20pub const Value = extern union {20 ip_index: InternPool.Index,
21 /// If the tag value is less than Tag.no_payload_count, then no pointer21
22 /// dereference is needed.22 /// This is the raw data, with no bookkeeping, no memory awareness,
23 tag_if_small_enough: Tag,23 /// no de-duplication, and no type system awareness.
24 ptr_otherwise: *Payload,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
26 // Keep in sync with tools/stage2_pretty_printers_common.py33 // Keep in sync with tools/stage2_pretty_printers_common.py
27 pub const Tag = enum(usize) {34 pub const Tag = enum(usize) {
...@@ -81,10 +88,6 @@ pub const Value = extern union {...@@ -81,10 +88,6 @@ pub const Value = extern union {
81 manyptr_u8_type,88 manyptr_u8_type,
82 manyptr_const_u8_type,89 manyptr_const_u8_type,
83 manyptr_const_u8_sentinel_0_type,90 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,
88 single_const_pointer_to_comptime_int_type,91 single_const_pointer_to_comptime_int_type,
89 const_slice_u8_type,92 const_slice_u8_type,
90 const_slice_u8_sentinel_0_type,93 const_slice_u8_sentinel_0_type,
...@@ -108,7 +111,6 @@ pub const Value = extern union {...@@ -108,7 +111,6 @@ pub const Value = extern union {
108 // After this, the tag requires a payload.111 // After this, the tag requires a payload.
109112
110 ty,113 ty,
111 int_type,
112 int_u64,114 int_u64,
113 int_i64,115 int_i64,
114 int_big_positive,116 int_big_positive,
...@@ -232,10 +234,6 @@ pub const Value = extern union {...@@ -232,10 +234,6 @@ pub const Value = extern union {
232 .noreturn_type,234 .noreturn_type,
233 .null_type,235 .null_type,
234 .undefined_type,236 .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,
239 .single_const_pointer_to_comptime_int_type,237 .single_const_pointer_to_comptime_int_type,
240 .anyframe_type,238 .anyframe_type,
241 .const_slice_u8_type,239 .const_slice_u8_type,
...@@ -304,7 +302,6 @@ pub const Value = extern union {...@@ -304,7 +302,6 @@ pub const Value = extern union {
304 .lazy_size,302 .lazy_size,
305 => Payload.Ty,303 => Payload.Ty,
306304
307 .int_type => Payload.IntType,
308 .int_u64 => Payload.U64,305 .int_u64 => Payload.U64,
309 .int_i64 => Payload.I64,306 .int_i64 => Payload.I64,
310 .function => Payload.Function,307 .function => Payload.Function,
...@@ -332,7 +329,10 @@ pub const Value = extern union {...@@ -332,7 +329,10 @@ pub const Value = extern union {
332 .base = .{ .tag = t },329 .base = .{ .tag = t },
333 .data = data,330 .data = data,
334 };331 };
335 return Value{ .ptr_otherwise = &ptr.base };332 return Value{
333 .ip_index = .none,
334 .legacy = .{ .ptr_otherwise = &ptr.base },
335 };
336 }336 }
337337
338 pub fn Data(comptime t: Tag) type {338 pub fn Data(comptime t: Tag) type {
...@@ -342,37 +342,47 @@ pub const Value = extern union {...@@ -342,37 +342,47 @@ pub const Value = extern union {
342342
343 pub fn initTag(small_tag: Tag) Value {343 pub fn initTag(small_tag: Tag) Value {
344 assert(@enumToInt(small_tag) < Tag.no_payload_count);344 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 };
346 }349 }
347350
348 pub fn initPayload(payload: *Payload) Value {351 pub fn initPayload(payload: *Payload) Value {
349 assert(@enumToInt(payload.tag) >= Tag.no_payload_count);352 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 };
351 }357 }
352358
353 pub fn tag(self: Value) Tag {359 pub fn tag(self: Value) Tag {
354 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {360 assert(self.ip_index == .none);
355 return self.tag_if_small_enough;361 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
362 return self.legacy.tag_if_small_enough;
356 } else {363 } else {
357 return self.ptr_otherwise.tag;364 return self.legacy.ptr_otherwise.tag;
358 }365 }
359 }366 }
360367
361 /// Prefer `castTag` to this.368 /// Prefer `castTag` to this.
362 pub fn cast(self: Value, comptime T: type) ?*T {369 pub fn cast(self: Value, comptime T: type) ?*T {
370 if (self.ip_index != .none) {
371 return null;
372 }
363 if (@hasField(T, "base_tag")) {373 if (@hasField(T, "base_tag")) {
364 return self.castTag(T.base_tag);374 return self.castTag(T.base_tag);
365 }375 }
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) {
367 return null;377 return null;
368 }378 }
369 inline for (@typeInfo(Tag).Enum.fields) |field| {379 inline for (@typeInfo(Tag).Enum.fields) |field| {
370 if (field.value < Tag.no_payload_count)380 if (field.value < Tag.no_payload_count)
371 continue;381 continue;
372 const t = @intToEnum(Tag, field.value);382 const t = @intToEnum(Tag, field.value);
373 if (self.ptr_otherwise.tag == t) {383 if (self.legacy.ptr_otherwise.tag == t) {
374 if (T == t.Type()) {384 if (T == t.Type()) {
375 return @fieldParentPtr(T, "base", self.ptr_otherwise);385 return @fieldParentPtr(T, "base", self.legacy.ptr_otherwise);
376 }386 }
377 return null;387 return null;
378 }388 }
...@@ -381,11 +391,15 @@ pub const Value = extern union {...@@ -381,11 +391,15 @@ pub const Value = extern union {
381 }391 }
382392
383 pub fn castTag(self: Value, comptime t: Tag) ?*t.Type() {393 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)
385 return null;399 return null;
386400
387 if (self.ptr_otherwise.tag == t)401 if (self.legacy.ptr_otherwise.tag == t)
388 return @fieldParentPtr(t.Type(), "base", self.ptr_otherwise);402 return @fieldParentPtr(t.Type(), "base", self.legacy.ptr_otherwise);
389403
390 return null;404 return null;
391 }405 }
...@@ -393,9 +407,15 @@ pub const Value = extern union {...@@ -393,9 +407,15 @@ pub const Value = extern union {
393 /// It's intentional that this function is not passed a corresponding Type, so that407 /// It's intentional that this function is not passed a corresponding Type, so that
394 /// a Value can be copied from a Sema to a Decl prior to resolving struct/union field types.408 /// a Value can be copied from a Sema to a Decl prior to resolving struct/union field types.
395 pub fn copy(self: Value, arena: Allocator) error{OutOfMemory}!Value {409 pub fn copy(self: Value, arena: Allocator) error{OutOfMemory}!Value {
396 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {410 if (self.ip_index != .none) {
397 return Value{ .tag_if_small_enough = self.tag_if_small_enough };411 return Value{ .ip_index = self.ip_index, .legacy = undefined };
398 } else switch (self.ptr_otherwise.tag) {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) {
399 .u1_type,419 .u1_type,
400 .u8_type,420 .u8_type,
401 .i8_type,421 .i8_type,
...@@ -435,10 +455,6 @@ pub const Value = extern union {...@@ -435,10 +455,6 @@ pub const Value = extern union {
435 .noreturn_type,455 .noreturn_type,
436 .null_type,456 .null_type,
437 .undefined_type,457 .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,
442 .single_const_pointer_to_comptime_int_type,458 .single_const_pointer_to_comptime_int_type,
443 .anyframe_type,459 .anyframe_type,
444 .const_slice_u8_type,460 .const_slice_u8_type,
...@@ -481,19 +497,24 @@ pub const Value = extern union {...@@ -481,19 +497,24 @@ pub const Value = extern union {
481 .base = payload.base,497 .base = payload.base,
482 .data = try payload.data.copy(arena),498 .data = try payload.data.copy(arena),
483 };499 };
484 return Value{ .ptr_otherwise = &new_payload.base };500 return Value{
501 .ip_index = .none,
502 .legacy = .{ .ptr_otherwise = &new_payload.base },
503 };
485 },504 },
486 .int_type => return self.copyPayloadShallow(arena, Payload.IntType),
487 .int_u64 => return self.copyPayloadShallow(arena, Payload.U64),505 .int_u64 => return self.copyPayloadShallow(arena, Payload.U64),
488 .int_i64 => return self.copyPayloadShallow(arena, Payload.I64),506 .int_i64 => return self.copyPayloadShallow(arena, Payload.I64),
489 .int_big_positive, .int_big_negative => {507 .int_big_positive, .int_big_negative => {
490 const old_payload = self.cast(Payload.BigInt).?;508 const old_payload = self.cast(Payload.BigInt).?;
491 const new_payload = try arena.create(Payload.BigInt);509 const new_payload = try arena.create(Payload.BigInt);
492 new_payload.* = .{510 new_payload.* = .{
493 .base = .{ .tag = self.ptr_otherwise.tag },511 .base = .{ .tag = self.legacy.ptr_otherwise.tag },
494 .data = try arena.dupe(std.math.big.Limb, old_payload.data),512 .data = try arena.dupe(std.math.big.Limb, old_payload.data),
495 };513 };
496 return Value{ .ptr_otherwise = &new_payload.base };514 return Value{
515 .ip_index = .none,
516 .legacy = .{ .ptr_otherwise = &new_payload.base },
517 };
497 },518 },
498 .function => return self.copyPayloadShallow(arena, Payload.Function),519 .function => return self.copyPayloadShallow(arena, Payload.Function),
499 .extern_fn => return self.copyPayloadShallow(arena, Payload.ExternFn),520 .extern_fn => return self.copyPayloadShallow(arena, Payload.ExternFn),
...@@ -512,7 +533,10 @@ pub const Value = extern union {...@@ -512,7 +533,10 @@ pub const Value = extern union {
512 .container_ty = try payload.data.container_ty.copy(arena),533 .container_ty = try payload.data.container_ty.copy(arena),
513 },534 },
514 };535 };
515 return Value{ .ptr_otherwise = &new_payload.base };536 return Value{
537 .ip_index = .none,
538 .legacy = .{ .ptr_otherwise = &new_payload.base },
539 };
516 },540 },
517 .comptime_field_ptr => {541 .comptime_field_ptr => {
518 const payload = self.cast(Payload.ComptimeFieldPtr).?;542 const payload = self.cast(Payload.ComptimeFieldPtr).?;
...@@ -524,7 +548,10 @@ pub const Value = extern union {...@@ -524,7 +548,10 @@ pub const Value = extern union {
524 .field_ty = try payload.data.field_ty.copy(arena),548 .field_ty = try payload.data.field_ty.copy(arena),
525 },549 },
526 };550 };
527 return Value{ .ptr_otherwise = &new_payload.base };551 return Value{
552 .ip_index = .none,
553 .legacy = .{ .ptr_otherwise = &new_payload.base },
554 };
528 },555 },
529 .elem_ptr => {556 .elem_ptr => {
530 const payload = self.castTag(.elem_ptr).?;557 const payload = self.castTag(.elem_ptr).?;
...@@ -537,7 +564,10 @@ pub const Value = extern union {...@@ -537,7 +564,10 @@ pub const Value = extern union {
537 .index = payload.data.index,564 .index = payload.data.index,
538 },565 },
539 };566 };
540 return Value{ .ptr_otherwise = &new_payload.base };567 return Value{
568 .ip_index = .none,
569 .legacy = .{ .ptr_otherwise = &new_payload.base },
570 };
541 },571 },
542 .field_ptr => {572 .field_ptr => {
543 const payload = self.castTag(.field_ptr).?;573 const payload = self.castTag(.field_ptr).?;
...@@ -550,7 +580,10 @@ pub const Value = extern union {...@@ -550,7 +580,10 @@ pub const Value = extern union {
550 .field_index = payload.data.field_index,580 .field_index = payload.data.field_index,
551 },581 },
552 };582 };
553 return Value{ .ptr_otherwise = &new_payload.base };583 return Value{
584 .ip_index = .none,
585 .legacy = .{ .ptr_otherwise = &new_payload.base },
586 };
554 },587 },
555 .bytes => {588 .bytes => {
556 const bytes = self.castTag(.bytes).?.data;589 const bytes = self.castTag(.bytes).?.data;
...@@ -559,7 +592,10 @@ pub const Value = extern union {...@@ -559,7 +592,10 @@ pub const Value = extern union {
559 .base = .{ .tag = .bytes },592 .base = .{ .tag = .bytes },
560 .data = try arena.dupe(u8, bytes),593 .data = try arena.dupe(u8, bytes),
561 };594 };
562 return Value{ .ptr_otherwise = &new_payload.base };595 return Value{
596 .ip_index = .none,
597 .legacy = .{ .ptr_otherwise = &new_payload.base },
598 };
563 },599 },
564 .str_lit => return self.copyPayloadShallow(arena, Payload.StrLit),600 .str_lit => return self.copyPayloadShallow(arena, Payload.StrLit),
565 .repeated,601 .repeated,
...@@ -574,7 +610,10 @@ pub const Value = extern union {...@@ -574,7 +610,10 @@ pub const Value = extern union {
574 .base = payload.base,610 .base = payload.base,
575 .data = try payload.data.copy(arena),611 .data = try payload.data.copy(arena),
576 };612 };
577 return Value{ .ptr_otherwise = &new_payload.base };613 return Value{
614 .ip_index = .none,
615 .legacy = .{ .ptr_otherwise = &new_payload.base },
616 };
578 },617 },
579 .slice => {618 .slice => {
580 const payload = self.castTag(.slice).?;619 const payload = self.castTag(.slice).?;
...@@ -586,7 +625,10 @@ pub const Value = extern union {...@@ -586,7 +625,10 @@ pub const Value = extern union {
586 .len = try payload.data.len.copy(arena),625 .len = try payload.data.len.copy(arena),
587 },626 },
588 };627 };
589 return Value{ .ptr_otherwise = &new_payload.base };628 return Value{
629 .ip_index = .none,
630 .legacy = .{ .ptr_otherwise = &new_payload.base },
631 };
590 },632 },
591 .float_16 => return self.copyPayloadShallow(arena, Payload.Float_16),633 .float_16 => return self.copyPayloadShallow(arena, Payload.Float_16),
592 .float_32 => return self.copyPayloadShallow(arena, Payload.Float_32),634 .float_32 => return self.copyPayloadShallow(arena, Payload.Float_32),
...@@ -600,7 +642,10 @@ pub const Value = extern union {...@@ -600,7 +642,10 @@ pub const Value = extern union {
600 .base = payload.base,642 .base = payload.base,
601 .data = try arena.dupe(u8, payload.data),643 .data = try arena.dupe(u8, payload.data),
602 };644 };
603 return Value{ .ptr_otherwise = &new_payload.base };645 return Value{
646 .ip_index = .none,
647 .legacy = .{ .ptr_otherwise = &new_payload.base },
648 };
604 },649 },
605 .enum_field_index => return self.copyPayloadShallow(arena, Payload.U32),650 .enum_field_index => return self.copyPayloadShallow(arena, Payload.U32),
606 .@"error" => return self.copyPayloadShallow(arena, Payload.Error),651 .@"error" => return self.copyPayloadShallow(arena, Payload.Error),
...@@ -615,7 +660,10 @@ pub const Value = extern union {...@@ -615,7 +660,10 @@ pub const Value = extern union {
615 for (new_payload.data, 0..) |*elem, i| {660 for (new_payload.data, 0..) |*elem, i| {
616 elem.* = try payload.data[i].copy(arena);661 elem.* = try payload.data[i].copy(arena);
617 }662 }
618 return Value{ .ptr_otherwise = &new_payload.base };663 return Value{
664 .ip_index = .none,
665 .legacy = .{ .ptr_otherwise = &new_payload.base },
666 };
619 },667 },
620668
621 .@"union" => {669 .@"union" => {
...@@ -628,7 +676,10 @@ pub const Value = extern union {...@@ -628,7 +676,10 @@ pub const Value = extern union {
628 .val = try tag_and_val.val.copy(arena),676 .val = try tag_and_val.val.copy(arena),
629 },677 },
630 };678 };
631 return Value{ .ptr_otherwise = &new_payload.base };679 return Value{
680 .ip_index = .none,
681 .legacy = .{ .ptr_otherwise = &new_payload.base },
682 };
632 },683 },
633684
634 .inferred_alloc => unreachable,685 .inferred_alloc => unreachable,
...@@ -640,7 +691,10 @@ pub const Value = extern union {...@@ -640,7 +691,10 @@ pub const Value = extern union {
640 const payload = self.cast(T).?;691 const payload = self.cast(T).?;
641 const new_payload = try arena.create(T);692 const new_payload = try arena.create(T);
642 new_payload.* = payload.*;693 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 };
644 }698 }
645699
646 pub fn format(val: Value, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {700 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 {...@@ -660,6 +714,10 @@ pub const Value = extern union {
660 out_stream: anytype,714 out_stream: anytype,
661 ) !void {715 ) !void {
662 comptime assert(fmt.len == 0);716 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 }
663 var val = start_val;721 var val = start_val;
664 while (true) switch (val.tag()) {722 while (true) switch (val.tag()) {
665 .u1_type => return out_stream.writeAll("u1"),723 .u1_type => return out_stream.writeAll("u1"),
...@@ -701,10 +759,6 @@ pub const Value = extern union {...@@ -701,10 +759,6 @@ pub const Value = extern union {
701 .noreturn_type => return out_stream.writeAll("noreturn"),759 .noreturn_type => return out_stream.writeAll("noreturn"),
702 .null_type => return out_stream.writeAll("@Type(.Null)"),760 .null_type => return out_stream.writeAll("@Type(.Null)"),
703 .undefined_type => return out_stream.writeAll("@Type(.Undefined)"),761 .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"),
708 .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),762 .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),
709 .anyframe_type => return out_stream.writeAll("anyframe"),763 .anyframe_type => return out_stream.writeAll("anyframe"),
710 .const_slice_u8_type => return out_stream.writeAll("[]const u8"),764 .const_slice_u8_type => return out_stream.writeAll("[]const u8"),
...@@ -755,13 +809,6 @@ pub const Value = extern union {...@@ -755,13 +809,6 @@ pub const Value = extern union {
755 try val.castTag(.lazy_size).?.data.dump("", options, out_stream);809 try val.castTag(.lazy_size).?.data.dump("", options, out_stream);
756 return try out_stream.writeAll(")");810 return try out_stream.writeAll(")");
757 },811 },
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 },
765 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", options, out_stream),812 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", options, out_stream),
766 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, out_stream),813 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, out_stream),
767 .int_big_positive => return out_stream.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),814 .int_big_positive => return out_stream.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),
...@@ -848,7 +895,6 @@ pub const Value = extern union {...@@ -848,7 +895,6 @@ pub const Value = extern union {
848 /// Asserts that the value is representable as an array of bytes.895 /// Asserts that the value is representable as an array of bytes.
849 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.896 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.
850 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 {897 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 {
851 const target = mod.getTarget();
852 switch (val.tag()) {898 switch (val.tag()) {
853 .bytes => {899 .bytes => {
854 const bytes = val.castTag(.bytes).?.data;900 const bytes = val.castTag(.bytes).?.data;
...@@ -863,7 +909,7 @@ pub const Value = extern union {...@@ -863,7 +909,7 @@ pub const Value = extern union {
863 },909 },
864 .enum_literal => return allocator.dupe(u8, val.castTag(.enum_literal).?.data),910 .enum_literal => return allocator.dupe(u8, val.castTag(.enum_literal).?.data),
865 .repeated => {911 .repeated => {
866 const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt(target));912 const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt(mod));
867 const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen()));913 const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen()));
868 @memset(result, byte);914 @memset(result, byte);
869 return result;915 return result;
...@@ -877,7 +923,7 @@ pub const Value = extern union {...@@ -877,7 +923,7 @@ pub const Value = extern union {
877 .the_only_possible_value => return &[_]u8{},923 .the_only_possible_value => return &[_]u8{},
878 .slice => {924 .slice => {
879 const slice = val.castTag(.slice).?.data;925 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);
881 },927 },
882 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator, mod),928 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator, mod),
883 }929 }
...@@ -888,15 +934,19 @@ pub const Value = extern union {...@@ -888,15 +934,19 @@ pub const Value = extern union {
888 var elem_value_buf: ElemValueBuffer = undefined;934 var elem_value_buf: ElemValueBuffer = undefined;
889 for (result, 0..) |*elem, i| {935 for (result, 0..) |*elem, i| {
890 const elem_val = val.elemValueBuffer(mod, i, &elem_value_buf);936 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));
892 }938 }
893 return result;939 return result;
894 }940 }
895941
896 pub const ToTypeBuffer = Type.Payload.Bits;
897
898 /// Asserts that the value is representable as a type.942 /// 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 }
900 return switch (self.tag()) {950 return switch (self.tag()) {
901 .ty => self.castTag(.ty).?.data,951 .ty => self.castTag(.ty).?.data,
902 .u1_type => Type.initTag(.u1),952 .u1_type => Type.initTag(.u1),
...@@ -938,10 +988,6 @@ pub const Value = extern union {...@@ -938,10 +988,6 @@ pub const Value = extern union {
938 .noreturn_type => Type.initTag(.noreturn),988 .noreturn_type => Type.initTag(.noreturn),
939 .null_type => Type.initTag(.null),989 .null_type => Type.initTag(.null),
940 .undefined_type => Type.initTag(.undefined),990 .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),
945 .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),991 .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),
946 .anyframe_type => Type.initTag(.@"anyframe"),992 .anyframe_type => Type.initTag(.@"anyframe"),
947 .const_slice_u8_type => Type.initTag(.const_slice_u8),993 .const_slice_u8_type => Type.initTag(.const_slice_u8),
...@@ -964,17 +1010,6 @@ pub const Value = extern union {...@@ -964,17 +1010,6 @@ pub const Value = extern union {
964 .extern_options_type => Type.initTag(.extern_options),1010 .extern_options_type => Type.initTag(.extern_options),
965 .type_info_type => Type.initTag(.type_info),1011 .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
978 else => unreachable,1013 else => unreachable,
979 };1014 };
980 }1015 }
...@@ -1050,7 +1085,7 @@ pub const Value = extern union {...@@ -1050,7 +1085,7 @@ pub const Value = extern union {
1050 }1085 }
10511086
1052 pub fn tagName(val: Value, ty: Type, mod: *Module) []const u8 {1087 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
1055 const field_index = switch (val.tag()) {1090 const field_index = switch (val.tag()) {
1056 .enum_field_index => val.castTag(.enum_field_index).?.data,1091 .enum_field_index => val.castTag(.enum_field_index).?.data,
...@@ -1068,10 +1103,9 @@ pub const Value = extern union {...@@ -1068,10 +1103,9 @@ pub const Value = extern union {
1068 };1103 };
1069 if (values.entries.len == 0) {1104 if (values.entries.len == 0) {
1070 // auto-numbered enum1105 // auto-numbered enum
1071 break :field_index @intCast(u32, val.toUnsignedInt(mod.getTarget()));1106 break :field_index @intCast(u32, val.toUnsignedInt(mod));
1072 }1107 }
1073 var buffer: Type.Payload.Bits = undefined;1108 const int_tag_ty = ty.intTagType();
1074 const int_tag_ty = ty.intTagType(&buffer);
1075 break :field_index @intCast(u32, values.getIndexContext(val, .{ .ty = int_tag_ty, .mod = mod }).?);1109 break :field_index @intCast(u32, values.getIndexContext(val, .{ .ty = int_tag_ty, .mod = mod }).?);
1076 },1110 },
1077 };1111 };
...@@ -1086,15 +1120,15 @@ pub const Value = extern union {...@@ -1086,15 +1120,15 @@ pub const Value = extern union {
1086 }1120 }
10871121
1088 /// Asserts the value is an integer.1122 /// Asserts the value is an integer.
1089 pub fn toBigInt(val: Value, space: *BigIntSpace, target: Target) BigIntConst {1123 pub fn toBigInt(val: Value, space: *BigIntSpace, mod: *const Module) BigIntConst {
1090 return val.toBigIntAdvanced(space, target, null) catch unreachable;1124 return val.toBigIntAdvanced(space, mod, null) catch unreachable;
1091 }1125 }
10921126
1093 /// Asserts the value is an integer.1127 /// Asserts the value is an integer.
1094 pub fn toBigIntAdvanced(1128 pub fn toBigIntAdvanced(
1095 val: Value,1129 val: Value,
1096 space: *BigIntSpace,1130 space: *BigIntSpace,
1097 target: Target,1131 mod: *const Module,
1098 opt_sema: ?*Sema,1132 opt_sema: ?*Sema,
1099 ) Module.CompileError!BigIntConst {1133 ) Module.CompileError!BigIntConst {
1100 switch (val.tag()) {1134 switch (val.tag()) {
...@@ -1114,7 +1148,7 @@ pub const Value = extern union {...@@ -1114,7 +1148,7 @@ pub const Value = extern union {
1114 },1148 },
1115 .runtime_value => {1149 .runtime_value => {
1116 const sub_val = val.castTag(.runtime_value).?.data;1150 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);
1118 },1152 },
1119 .int_u64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(),1153 .int_u64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(),
1120 .int_i64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(),1154 .int_i64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(),
...@@ -1128,7 +1162,7 @@ pub const Value = extern union {...@@ -1128,7 +1162,7 @@ pub const Value = extern union {
1128 if (opt_sema) |sema| {1162 if (opt_sema) |sema| {
1129 try sema.resolveTypeLayout(ty);1163 try sema.resolveTypeLayout(ty);
1130 }1164 }
1131 const x = ty.abiAlignment(target);1165 const x = ty.abiAlignment(mod);
1132 return BigIntMutable.init(&space.limbs, x).toConst();1166 return BigIntMutable.init(&space.limbs, x).toConst();
1133 },1167 },
1134 .lazy_size => {1168 .lazy_size => {
...@@ -1136,14 +1170,14 @@ pub const Value = extern union {...@@ -1136,14 +1170,14 @@ pub const Value = extern union {
1136 if (opt_sema) |sema| {1170 if (opt_sema) |sema| {
1137 try sema.resolveTypeLayout(ty);1171 try sema.resolveTypeLayout(ty);
1138 }1172 }
1139 const x = ty.abiSize(target);1173 const x = ty.abiSize(mod);
1140 return BigIntMutable.init(&space.limbs, x).toConst();1174 return BigIntMutable.init(&space.limbs, x).toConst();
1141 },1175 },
11421176
1143 .elem_ptr => {1177 .elem_ptr => {
1144 const elem_ptr = val.castTag(.elem_ptr).?.data;1178 const elem_ptr = val.castTag(.elem_ptr).?.data;
1145 const array_addr = (try elem_ptr.array_ptr.getUnsignedIntAdvanced(target, opt_sema)).?;1179 const array_addr = (try elem_ptr.array_ptr.getUnsignedIntAdvanced(mod, opt_sema)).?;
1146 const elem_size = elem_ptr.elem_ty.abiSize(target);1180 const elem_size = elem_ptr.elem_ty.abiSize(mod);
1147 const new_addr = array_addr + elem_size * elem_ptr.index;1181 const new_addr = array_addr + elem_size * elem_ptr.index;
1148 return BigIntMutable.init(&space.limbs, new_addr).toConst();1182 return BigIntMutable.init(&space.limbs, new_addr).toConst();
1149 },1183 },
...@@ -1154,13 +1188,13 @@ pub const Value = extern union {...@@ -1154,13 +1188,13 @@ pub const Value = extern union {
11541188
1155 /// If the value fits in a u64, return it, otherwise null.1189 /// If the value fits in a u64, return it, otherwise null.
1156 /// Asserts not undefined.1190 /// Asserts not undefined.
1157 pub fn getUnsignedInt(val: Value, target: Target) ?u64 {1191 pub fn getUnsignedInt(val: Value, mod: *const Module) ?u64 {
1158 return getUnsignedIntAdvanced(val, target, null) catch unreachable;1192 return getUnsignedIntAdvanced(val, mod, null) catch unreachable;
1159 }1193 }
11601194
1161 /// If the value fits in a u64, return it, otherwise null.1195 /// If the value fits in a u64, return it, otherwise null.
1162 /// Asserts not undefined.1196 /// 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 {
1164 switch (val.tag()) {1198 switch (val.tag()) {
1165 .zero,1199 .zero,
1166 .bool_false,1200 .bool_false,
...@@ -1181,17 +1215,17 @@ pub const Value = extern union {...@@ -1181,17 +1215,17 @@ pub const Value = extern union {
1181 .lazy_align => {1215 .lazy_align => {
1182 const ty = val.castTag(.lazy_align).?.data;1216 const ty = val.castTag(.lazy_align).?.data;
1183 if (opt_sema) |sema| {1217 if (opt_sema) |sema| {
1184 return (try ty.abiAlignmentAdvanced(target, .{ .sema = sema })).scalar;1218 return (try ty.abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar;
1185 } else {1219 } else {
1186 return ty.abiAlignment(target);1220 return ty.abiAlignment(mod);
1187 }1221 }
1188 },1222 },
1189 .lazy_size => {1223 .lazy_size => {
1190 const ty = val.castTag(.lazy_size).?.data;1224 const ty = val.castTag(.lazy_size).?.data;
1191 if (opt_sema) |sema| {1225 if (opt_sema) |sema| {
1192 return (try ty.abiSizeAdvanced(target, .{ .sema = sema })).scalar;1226 return (try ty.abiSizeAdvanced(mod, .{ .sema = sema })).scalar;
1193 } else {1227 } else {
1194 return ty.abiSize(target);1228 return ty.abiSize(mod);
1195 }1229 }
1196 },1230 },
11971231
...@@ -1200,12 +1234,12 @@ pub const Value = extern union {...@@ -1200,12 +1234,12 @@ pub const Value = extern union {
1200 }1234 }
12011235
1202 /// Asserts the value is an integer and it fits in a u641236 /// Asserts the value is an integer and it fits in a u64
1203 pub fn toUnsignedInt(val: Value, target: Target) u64 {1237 pub fn toUnsignedInt(val: Value, mod: *const Module) u64 {
1204 return getUnsignedInt(val, target).?;1238 return getUnsignedInt(val, mod).?;
1205 }1239 }
12061240
1207 /// Asserts the value is an integer and it fits in a i641241 /// 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 {
1209 switch (val.tag()) {1243 switch (val.tag()) {
1210 .zero,1244 .zero,
1211 .bool_false,1245 .bool_false,
...@@ -1223,11 +1257,11 @@ pub const Value = extern union {...@@ -1223,11 +1257,11 @@ pub const Value = extern union {
12231257
1224 .lazy_align => {1258 .lazy_align => {
1225 const ty = val.castTag(.lazy_align).?.data;1259 const ty = val.castTag(.lazy_align).?.data;
1226 return @intCast(i64, ty.abiAlignment(target));1260 return @intCast(i64, ty.abiAlignment(mod));
1227 },1261 },
1228 .lazy_size => {1262 .lazy_size => {
1229 const ty = val.castTag(.lazy_size).?.data;1263 const ty = val.castTag(.lazy_size).?.data;
1230 return @intCast(i64, ty.abiSize(target));1264 return @intCast(i64, ty.abiSize(mod));
1231 },1265 },
12321266
1233 .undef => unreachable,1267 .undef => unreachable,
...@@ -1276,17 +1310,17 @@ pub const Value = extern union {...@@ -1276,17 +1310,17 @@ pub const Value = extern union {
1276 const target = mod.getTarget();1310 const target = mod.getTarget();
1277 const endian = target.cpu.arch.endian();1311 const endian = target.cpu.arch.endian();
1278 if (val.isUndef()) {1312 if (val.isUndef()) {
1279 const size = @intCast(usize, ty.abiSize(target));1313 const size = @intCast(usize, ty.abiSize(mod));
1280 @memset(buffer[0..size], 0xaa);1314 @memset(buffer[0..size], 0xaa);
1281 return;1315 return;
1282 }1316 }
1283 switch (ty.zigTypeTag()) {1317 switch (ty.zigTypeTag(mod)) {
1284 .Void => {},1318 .Void => {},
1285 .Bool => {1319 .Bool => {
1286 buffer[0] = @boolToInt(val.toBool());1320 buffer[0] = @boolToInt(val.toBool());
1287 },1321 },
1288 .Int, .Enum => {1322 .Int, .Enum => {
1289 const int_info = ty.intInfo(target);1323 const int_info = ty.intInfo(mod);
1290 const bits = int_info.bits;1324 const bits = int_info.bits;
1291 const byte_count = (bits + 7) / 8;1325 const byte_count = (bits + 7) / 8;
12921326
...@@ -1307,7 +1341,7 @@ pub const Value = extern union {...@@ -1307,7 +1341,7 @@ pub const Value = extern union {
1307 };1341 };
1308 } else {1342 } else {
1309 var bigint_buffer: BigIntSpace = undefined;1343 var bigint_buffer: BigIntSpace = undefined;
1310 const bigint = int_val.toBigInt(&bigint_buffer, target);1344 const bigint = int_val.toBigInt(&bigint_buffer, mod);
1311 bigint.writeTwosComplement(buffer[0..byte_count], endian);1345 bigint.writeTwosComplement(buffer[0..byte_count], endian);
1312 }1346 }
1313 },1347 },
...@@ -1322,7 +1356,7 @@ pub const Value = extern union {...@@ -1322,7 +1356,7 @@ pub const Value = extern union {
1322 .Array => {1356 .Array => {
1323 const len = ty.arrayLen();1357 const len = ty.arrayLen();
1324 const elem_ty = ty.childType();1358 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));
1326 var elem_i: usize = 0;1360 var elem_i: usize = 0;
1327 var elem_value_buf: ElemValueBuffer = undefined;1361 var elem_value_buf: ElemValueBuffer = undefined;
1328 var buf_off: usize = 0;1362 var buf_off: usize = 0;
...@@ -1335,7 +1369,7 @@ pub const Value = extern union {...@@ -1335,7 +1369,7 @@ pub const Value = extern union {
1335 .Vector => {1369 .Vector => {
1336 // We use byte_count instead of abi_size here, so that any padding bytes1370 // We use byte_count instead of abi_size here, so that any padding bytes
1337 // follow the data bytes, on both big- and little-endian systems.1371 // 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;
1339 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);1373 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);
1340 },1374 },
1341 .Struct => switch (ty.containerLayout()) {1375 .Struct => switch (ty.containerLayout()) {
...@@ -1344,12 +1378,12 @@ pub const Value = extern union {...@@ -1344,12 +1378,12 @@ pub const Value = extern union {
1344 const fields = ty.structFields().values();1378 const fields = ty.structFields().values();
1345 const field_vals = val.castTag(.aggregate).?.data;1379 const field_vals = val.castTag(.aggregate).?.data;
1346 for (fields, 0..) |field, i| {1380 for (fields, 0..) |field, i| {
1347 const off = @intCast(usize, ty.structFieldOffset(i, target));1381 const off = @intCast(usize, ty.structFieldOffset(i, mod));
1348 try writeToMemory(field_vals[i], field.ty, mod, buffer[off..]);1382 try writeToMemory(field_vals[i], field.ty, mod, buffer[off..]);
1349 }1383 }
1350 },1384 },
1351 .Packed => {1385 .Packed => {
1352 const byte_count = (@intCast(usize, ty.bitSize(target)) + 7) / 8;1386 const byte_count = (@intCast(usize, ty.bitSize(mod)) + 7) / 8;
1353 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);1387 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);
1354 },1388 },
1355 },1389 },
...@@ -1363,7 +1397,7 @@ pub const Value = extern union {...@@ -1363,7 +1397,7 @@ pub const Value = extern union {
1363 .Auto => return error.IllDefinedMemoryLayout,1397 .Auto => return error.IllDefinedMemoryLayout,
1364 .Extern => return error.Unimplemented,1398 .Extern => return error.Unimplemented,
1365 .Packed => {1399 .Packed => {
1366 const byte_count = (@intCast(usize, ty.bitSize(target)) + 7) / 8;1400 const byte_count = (@intCast(usize, ty.bitSize(mod)) + 7) / 8;
1367 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);1401 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);
1368 },1402 },
1369 },1403 },
...@@ -1373,10 +1407,10 @@ pub const Value = extern union {...@@ -1373,10 +1407,10 @@ pub const Value = extern union {
1373 return val.writeToMemory(Type.usize, mod, buffer);1407 return val.writeToMemory(Type.usize, mod, buffer);
1374 },1408 },
1375 .Optional => {1409 .Optional => {
1376 if (!ty.isPtrLikeOptional()) return error.IllDefinedMemoryLayout;1410 if (!ty.isPtrLikeOptional(mod)) return error.IllDefinedMemoryLayout;
1377 var buf: Type.Payload.ElemType = undefined;1411 var buf: Type.Payload.ElemType = undefined;
1378 const child = ty.optionalChild(&buf);1412 const child = ty.optionalChild(&buf);
1379 const opt_val = val.optionalValue();1413 const opt_val = val.optionalValue(mod);
1380 if (opt_val) |some| {1414 if (opt_val) |some| {
1381 return some.writeToMemory(child, mod, buffer);1415 return some.writeToMemory(child, mod, buffer);
1382 } else {1416 } else {
...@@ -1395,11 +1429,11 @@ pub const Value = extern union {...@@ -1395,11 +1429,11 @@ pub const Value = extern union {
1395 const target = mod.getTarget();1429 const target = mod.getTarget();
1396 const endian = target.cpu.arch.endian();1430 const endian = target.cpu.arch.endian();
1397 if (val.isUndef()) {1431 if (val.isUndef()) {
1398 const bit_size = @intCast(usize, ty.bitSize(target));1432 const bit_size = @intCast(usize, ty.bitSize(mod));
1399 std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian);1433 std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian);
1400 return;1434 return;
1401 }1435 }
1402 switch (ty.zigTypeTag()) {1436 switch (ty.zigTypeTag(mod)) {
1403 .Void => {},1437 .Void => {},
1404 .Bool => {1438 .Bool => {
1405 const byte_index = switch (endian) {1439 const byte_index = switch (endian) {
...@@ -1413,8 +1447,8 @@ pub const Value = extern union {...@@ -1413,8 +1447,8 @@ pub const Value = extern union {
1413 }1447 }
1414 },1448 },
1415 .Int, .Enum => {1449 .Int, .Enum => {
1416 const bits = ty.intInfo(target).bits;1450 const bits = ty.intInfo(mod).bits;
1417 const abi_size = @intCast(usize, ty.abiSize(target));1451 const abi_size = @intCast(usize, ty.abiSize(mod));
14181452
1419 var enum_buffer: Payload.U64 = undefined;1453 var enum_buffer: Payload.U64 = undefined;
1420 const int_val = val.enumToInt(ty, &enum_buffer);1454 const int_val = val.enumToInt(ty, &enum_buffer);
...@@ -1431,7 +1465,7 @@ pub const Value = extern union {...@@ -1431,7 +1465,7 @@ pub const Value = extern union {
1431 std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian);1465 std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian);
1432 } else {1466 } else {
1433 var bigint_buffer: BigIntSpace = undefined;1467 var bigint_buffer: BigIntSpace = undefined;
1434 const bigint = int_val.toBigInt(&bigint_buffer, target);1468 const bigint = int_val.toBigInt(&bigint_buffer, mod);
1435 bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian);1469 bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian);
1436 }1470 }
1437 },1471 },
...@@ -1445,7 +1479,7 @@ pub const Value = extern union {...@@ -1445,7 +1479,7 @@ pub const Value = extern union {
1445 },1479 },
1446 .Vector => {1480 .Vector => {
1447 const elem_ty = ty.childType();1481 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));
1449 const len = @intCast(usize, ty.arrayLen());1483 const len = @intCast(usize, ty.arrayLen());
14501484
1451 var bits: u16 = 0;1485 var bits: u16 = 0;
...@@ -1467,7 +1501,7 @@ pub const Value = extern union {...@@ -1467,7 +1501,7 @@ pub const Value = extern union {
1467 const fields = ty.structFields().values();1501 const fields = ty.structFields().values();
1468 const field_vals = val.castTag(.aggregate).?.data;1502 const field_vals = val.castTag(.aggregate).?.data;
1469 for (fields, 0..) |field, i| {1503 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));
1471 try field_vals[i].writeToPackedMemory(field.ty, mod, buffer, bit_offset + bits);1505 try field_vals[i].writeToPackedMemory(field.ty, mod, buffer, bit_offset + bits);
1472 bits += field_bits;1506 bits += field_bits;
1473 }1507 }
...@@ -1479,7 +1513,7 @@ pub const Value = extern union {...@@ -1479,7 +1513,7 @@ pub const Value = extern union {
1479 .Packed => {1513 .Packed => {
1480 const field_index = ty.unionTagFieldIndex(val.unionTag(), mod);1514 const field_index = ty.unionTagFieldIndex(val.unionTag(), mod);
1481 const field_type = ty.unionFields().values()[field_index.?].ty;1515 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
1484 return field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset);1518 return field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset);
1485 },1519 },
...@@ -1490,10 +1524,10 @@ pub const Value = extern union {...@@ -1490,10 +1524,10 @@ pub const Value = extern union {
1490 return val.writeToPackedMemory(Type.usize, mod, buffer, bit_offset);1524 return val.writeToPackedMemory(Type.usize, mod, buffer, bit_offset);
1491 },1525 },
1492 .Optional => {1526 .Optional => {
1493 assert(ty.isPtrLikeOptional());1527 assert(ty.isPtrLikeOptional(mod));
1494 var buf: Type.Payload.ElemType = undefined;1528 var buf: Type.Payload.ElemType = undefined;
1495 const child = ty.optionalChild(&buf);1529 const child = ty.optionalChild(&buf);
1496 const opt_val = val.optionalValue();1530 const opt_val = val.optionalValue(mod);
1497 if (opt_val) |some| {1531 if (opt_val) |some| {
1498 return some.writeToPackedMemory(child, mod, buffer, bit_offset);1532 return some.writeToPackedMemory(child, mod, buffer, bit_offset);
1499 } else {1533 } else {
...@@ -1516,7 +1550,7 @@ pub const Value = extern union {...@@ -1516,7 +1550,7 @@ pub const Value = extern union {
1516 ) Allocator.Error!Value {1550 ) Allocator.Error!Value {
1517 const target = mod.getTarget();1551 const target = mod.getTarget();
1518 const endian = target.cpu.arch.endian();1552 const endian = target.cpu.arch.endian();
1519 switch (ty.zigTypeTag()) {1553 switch (ty.zigTypeTag(mod)) {
1520 .Void => return Value.void,1554 .Void => return Value.void,
1521 .Bool => {1555 .Bool => {
1522 if (buffer[0] == 0) {1556 if (buffer[0] == 0) {
...@@ -1526,7 +1560,7 @@ pub const Value = extern union {...@@ -1526,7 +1560,7 @@ pub const Value = extern union {
1526 }1560 }
1527 },1561 },
1528 .Int, .Enum => {1562 .Int, .Enum => {
1529 const int_info = ty.intInfo(target);1563 const int_info = ty.intInfo(mod);
1530 const bits = int_info.bits;1564 const bits = int_info.bits;
1531 const byte_count = (bits + 7) / 8;1565 const byte_count = (bits + 7) / 8;
1532 if (bits == 0 or buffer.len == 0) return Value.zero;1566 if (bits == 0 or buffer.len == 0) return Value.zero;
...@@ -1560,7 +1594,7 @@ pub const Value = extern union {...@@ -1560,7 +1594,7 @@ pub const Value = extern union {
1560 },1594 },
1561 .Array => {1595 .Array => {
1562 const elem_ty = ty.childType();1596 const elem_ty = ty.childType();
1563 const elem_size = elem_ty.abiSize(target);1597 const elem_size = elem_ty.abiSize(mod);
1564 const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen()));1598 const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen()));
1565 var offset: usize = 0;1599 var offset: usize = 0;
1566 for (elems) |*elem| {1600 for (elems) |*elem| {
...@@ -1572,7 +1606,7 @@ pub const Value = extern union {...@@ -1572,7 +1606,7 @@ pub const Value = extern union {
1572 .Vector => {1606 .Vector => {
1573 // We use byte_count instead of abi_size here, so that any padding bytes1607 // We use byte_count instead of abi_size here, so that any padding bytes
1574 // follow the data bytes, on both big- and little-endian systems.1608 // 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;
1576 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);1610 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);
1577 },1611 },
1578 .Struct => switch (ty.containerLayout()) {1612 .Struct => switch (ty.containerLayout()) {
...@@ -1581,14 +1615,14 @@ pub const Value = extern union {...@@ -1581,14 +1615,14 @@ pub const Value = extern union {
1581 const fields = ty.structFields().values();1615 const fields = ty.structFields().values();
1582 const field_vals = try arena.alloc(Value, fields.len);1616 const field_vals = try arena.alloc(Value, fields.len);
1583 for (fields, 0..) |field, i| {1617 for (fields, 0..) |field, i| {
1584 const off = @intCast(usize, ty.structFieldOffset(i, target));1618 const off = @intCast(usize, ty.structFieldOffset(i, mod));
1585 const sz = @intCast(usize, ty.structFieldType(i).abiSize(target));1619 const sz = @intCast(usize, ty.structFieldType(i).abiSize(mod));
1586 field_vals[i] = try readFromMemory(field.ty, mod, buffer[off..(off + sz)], arena);1620 field_vals[i] = try readFromMemory(field.ty, mod, buffer[off..(off + sz)], arena);
1587 }1621 }
1588 return Tag.aggregate.create(arena, field_vals);1622 return Tag.aggregate.create(arena, field_vals);
1589 },1623 },
1590 .Packed => {1624 .Packed => {
1591 const byte_count = (@intCast(usize, ty.bitSize(target)) + 7) / 8;1625 const byte_count = (@intCast(usize, ty.bitSize(mod)) + 7) / 8;
1592 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);1626 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);
1593 },1627 },
1594 },1628 },
...@@ -1609,7 +1643,7 @@ pub const Value = extern union {...@@ -1609,7 +1643,7 @@ pub const Value = extern union {
1609 return readFromMemory(Type.usize, mod, buffer, arena);1643 return readFromMemory(Type.usize, mod, buffer, arena);
1610 },1644 },
1611 .Optional => {1645 .Optional => {
1612 assert(ty.isPtrLikeOptional());1646 assert(ty.isPtrLikeOptional(mod));
1613 var buf: Type.Payload.ElemType = undefined;1647 var buf: Type.Payload.ElemType = undefined;
1614 const child = ty.optionalChild(&buf);1648 const child = ty.optionalChild(&buf);
1615 return readFromMemory(child, mod, buffer, arena);1649 return readFromMemory(child, mod, buffer, arena);
...@@ -1631,7 +1665,7 @@ pub const Value = extern union {...@@ -1631,7 +1665,7 @@ pub const Value = extern union {
1631 ) Allocator.Error!Value {1665 ) Allocator.Error!Value {
1632 const target = mod.getTarget();1666 const target = mod.getTarget();
1633 const endian = target.cpu.arch.endian();1667 const endian = target.cpu.arch.endian();
1634 switch (ty.zigTypeTag()) {1668 switch (ty.zigTypeTag(mod)) {
1635 .Void => return Value.void,1669 .Void => return Value.void,
1636 .Bool => {1670 .Bool => {
1637 const byte = switch (endian) {1671 const byte = switch (endian) {
...@@ -1646,8 +1680,8 @@ pub const Value = extern union {...@@ -1646,8 +1680,8 @@ pub const Value = extern union {
1646 },1680 },
1647 .Int, .Enum => {1681 .Int, .Enum => {
1648 if (buffer.len == 0) return Value.zero;1682 if (buffer.len == 0) return Value.zero;
1649 const int_info = ty.intInfo(target);1683 const int_info = ty.intInfo(mod);
1650 const abi_size = @intCast(usize, ty.abiSize(target));1684 const abi_size = @intCast(usize, ty.abiSize(mod));
16511685
1652 const bits = int_info.bits;1686 const bits = int_info.bits;
1653 if (bits == 0) return Value.zero;1687 if (bits == 0) return Value.zero;
...@@ -1677,7 +1711,7 @@ pub const Value = extern union {...@@ -1677,7 +1711,7 @@ pub const Value = extern union {
1677 const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen()));1711 const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen()));
16781712
1679 var bits: u16 = 0;1713 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));
1681 for (elems, 0..) |_, i| {1715 for (elems, 0..) |_, i| {
1682 // On big-endian systems, LLVM reverses the element order of vectors by default1716 // On big-endian systems, LLVM reverses the element order of vectors by default
1683 const tgt_elem_i = if (endian == .Big) elems.len - i - 1 else i;1717 const tgt_elem_i = if (endian == .Big) elems.len - i - 1 else i;
...@@ -1694,7 +1728,7 @@ pub const Value = extern union {...@@ -1694,7 +1728,7 @@ pub const Value = extern union {
1694 const fields = ty.structFields().values();1728 const fields = ty.structFields().values();
1695 const field_vals = try arena.alloc(Value, fields.len);1729 const field_vals = try arena.alloc(Value, fields.len);
1696 for (fields, 0..) |field, i| {1730 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));
1698 field_vals[i] = try readFromPackedMemory(field.ty, mod, buffer, bit_offset + bits, arena);1732 field_vals[i] = try readFromPackedMemory(field.ty, mod, buffer, bit_offset + bits, arena);
1699 bits += field_bits;1733 bits += field_bits;
1700 }1734 }
...@@ -1706,7 +1740,7 @@ pub const Value = extern union {...@@ -1706,7 +1740,7 @@ pub const Value = extern union {
1706 return readFromPackedMemory(Type.usize, mod, buffer, bit_offset, arena);1740 return readFromPackedMemory(Type.usize, mod, buffer, bit_offset, arena);
1707 },1741 },
1708 .Optional => {1742 .Optional => {
1709 assert(ty.isPtrLikeOptional());1743 assert(ty.isPtrLikeOptional(mod));
1710 var buf: Type.Payload.ElemType = undefined;1744 var buf: Type.Payload.ElemType = undefined;
1711 const child = ty.optionalChild(&buf);1745 const child = ty.optionalChild(&buf);
1712 return readFromPackedMemory(child, mod, buffer, bit_offset, arena);1746 return readFromPackedMemory(child, mod, buffer, bit_offset, arena);
...@@ -1764,8 +1798,8 @@ pub const Value = extern union {...@@ -1764,8 +1798,8 @@ pub const Value = extern union {
1764 }1798 }
1765 }1799 }
17661800
1767 pub fn clz(val: Value, ty: Type, target: Target) u64 {1801 pub fn clz(val: Value, ty: Type, mod: *const Module) u64 {
1768 const ty_bits = ty.intInfo(target).bits;1802 const ty_bits = ty.intInfo(mod).bits;
1769 switch (val.tag()) {1803 switch (val.tag()) {
1770 .zero, .bool_false => return ty_bits,1804 .zero, .bool_false => return ty_bits,
1771 .one, .bool_true => return ty_bits - 1,1805 .one, .bool_true => return ty_bits - 1,
...@@ -1792,7 +1826,7 @@ pub const Value = extern union {...@@ -1792,7 +1826,7 @@ pub const Value = extern union {
17921826
1793 .lazy_align, .lazy_size => {1827 .lazy_align, .lazy_size => {
1794 var bigint_buf: BigIntSpace = undefined;1828 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;
1796 return bigint.clz(ty_bits);1830 return bigint.clz(ty_bits);
1797 },1831 },
17981832
...@@ -1800,8 +1834,8 @@ pub const Value = extern union {...@@ -1800,8 +1834,8 @@ pub const Value = extern union {
1800 }1834 }
1801 }1835 }
18021836
1803 pub fn ctz(val: Value, ty: Type, target: Target) u64 {1837 pub fn ctz(val: Value, ty: Type, mod: *const Module) u64 {
1804 const ty_bits = ty.intInfo(target).bits;1838 const ty_bits = ty.intInfo(mod).bits;
1805 switch (val.tag()) {1839 switch (val.tag()) {
1806 .zero, .bool_false => return ty_bits,1840 .zero, .bool_false => return ty_bits,
1807 .one, .bool_true => return 0,1841 .one, .bool_true => return 0,
...@@ -1828,7 +1862,7 @@ pub const Value = extern union {...@@ -1828,7 +1862,7 @@ pub const Value = extern union {
18281862
1829 .lazy_align, .lazy_size => {1863 .lazy_align, .lazy_size => {
1830 var bigint_buf: BigIntSpace = undefined;1864 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;
1832 return bigint.ctz();1866 return bigint.ctz();
1833 },1867 },
18341868
...@@ -1836,7 +1870,7 @@ pub const Value = extern union {...@@ -1836,7 +1870,7 @@ pub const Value = extern union {
1836 }1870 }
1837 }1871 }
18381872
1839 pub fn popCount(val: Value, ty: Type, target: Target) u64 {1873 pub fn popCount(val: Value, ty: Type, mod: *const Module) u64 {
1840 assert(!val.isUndef());1874 assert(!val.isUndef());
1841 switch (val.tag()) {1875 switch (val.tag()) {
1842 .zero, .bool_false => return 0,1876 .zero, .bool_false => return 0,
...@@ -1845,22 +1879,22 @@ pub const Value = extern union {...@@ -1845,22 +1879,22 @@ pub const Value = extern union {
1845 .int_u64 => return @popCount(val.castTag(.int_u64).?.data),1879 .int_u64 => return @popCount(val.castTag(.int_u64).?.data),
18461880
1847 else => {1881 else => {
1848 const info = ty.intInfo(target);1882 const info = ty.intInfo(mod);
18491883
1850 var buffer: Value.BigIntSpace = undefined;1884 var buffer: Value.BigIntSpace = undefined;
1851 const int = val.toBigInt(&buffer, target);1885 const int = val.toBigInt(&buffer, mod);
1852 return @intCast(u64, int.popCount(info.bits));1886 return @intCast(u64, int.popCount(info.bits));
1853 },1887 },
1854 }1888 }
1855 }1889 }
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 {
1858 assert(!val.isUndef());1892 assert(!val.isUndef());
18591893
1860 const info = ty.intInfo(target);1894 const info = ty.intInfo(mod);
18611895
1862 var buffer: Value.BigIntSpace = undefined;1896 var buffer: Value.BigIntSpace = undefined;
1863 const operand_bigint = val.toBigInt(&buffer, target);1897 const operand_bigint = val.toBigInt(&buffer, mod);
18641898
1865 const limbs = try arena.alloc(1899 const limbs = try arena.alloc(
1866 std.math.big.Limb,1900 std.math.big.Limb,
...@@ -1872,16 +1906,16 @@ pub const Value = extern union {...@@ -1872,16 +1906,16 @@ pub const Value = extern union {
1872 return fromBigInt(arena, result_bigint.toConst());1906 return fromBigInt(arena, result_bigint.toConst());
1873 }1907 }
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 {
1876 assert(!val.isUndef());1910 assert(!val.isUndef());
18771911
1878 const info = ty.intInfo(target);1912 const info = ty.intInfo(mod);
18791913
1880 // Bit count must be evenly divisible by 81914 // Bit count must be evenly divisible by 8
1881 assert(info.bits % 8 == 0);1915 assert(info.bits % 8 == 0);
18821916
1883 var buffer: Value.BigIntSpace = undefined;1917 var buffer: Value.BigIntSpace = undefined;
1884 const operand_bigint = val.toBigInt(&buffer, target);1918 const operand_bigint = val.toBigInt(&buffer, mod);
18851919
1886 const limbs = try arena.alloc(1920 const limbs = try arena.alloc(
1887 std.math.big.Limb,1921 std.math.big.Limb,
...@@ -1895,7 +1929,8 @@ pub const Value = extern union {...@@ -1895,7 +1929,8 @@ pub const Value = extern union {
18951929
1896 /// Asserts the value is an integer and not undefined.1930 /// Asserts the value is an integer and not undefined.
1897 /// Returns the number of bits the value requires to represent stored in twos complement form.1931 /// 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();
1899 switch (self.tag()) {1934 switch (self.tag()) {
1900 .zero,1935 .zero,
1901 .bool_false,1936 .bool_false,
...@@ -1926,7 +1961,7 @@ pub const Value = extern union {...@@ -1926,7 +1961,7 @@ pub const Value = extern union {
19261961
1927 else => {1962 else => {
1928 var buffer: BigIntSpace = undefined;1963 var buffer: BigIntSpace = undefined;
1929 return self.toBigInt(&buffer, target).bitCountTwosComp();1964 return self.toBigInt(&buffer, mod).bitCountTwosComp();
1930 },1965 },
1931 }1966 }
1932 }1967 }
...@@ -1962,12 +1997,13 @@ pub const Value = extern union {...@@ -1962,12 +1997,13 @@ pub const Value = extern union {
1962 };1997 };
1963 }1998 }
19641999
1965 pub fn orderAgainstZero(lhs: Value) std.math.Order {2000 pub fn orderAgainstZero(lhs: Value, mod: *const Module) std.math.Order {
1966 return orderAgainstZeroAdvanced(lhs, null) catch unreachable;2001 return orderAgainstZeroAdvanced(lhs, mod, null) catch unreachable;
1967 }2002 }
19682003
1969 pub fn orderAgainstZeroAdvanced(2004 pub fn orderAgainstZeroAdvanced(
1970 lhs: Value,2005 lhs: Value,
2006 mod: *const Module,
1971 opt_sema: ?*Sema,2007 opt_sema: ?*Sema,
1972 ) Module.CompileError!std.math.Order {2008 ) Module.CompileError!std.math.Order {
1973 return switch (lhs.tag()) {2009 return switch (lhs.tag()) {
...@@ -1991,7 +2027,7 @@ pub const Value = extern union {...@@ -1991,7 +2027,7 @@ pub const Value = extern union {
1991 // This is needed to correctly handle hashing the value.2027 // This is needed to correctly handle hashing the value.
1992 // Checks in Sema should prevent direct comparisons from reaching here.2028 // Checks in Sema should prevent direct comparisons from reaching here.
1993 const val = lhs.castTag(.runtime_value).?.data;2029 const val = lhs.castTag(.runtime_value).?.data;
1994 return val.orderAgainstZeroAdvanced(opt_sema);2030 return val.orderAgainstZeroAdvanced(mod, opt_sema);
1995 },2031 },
1996 .int_u64 => std.math.order(lhs.castTag(.int_u64).?.data, 0),2032 .int_u64 => std.math.order(lhs.castTag(.int_u64).?.data, 0),
1997 .int_i64 => std.math.order(lhs.castTag(.int_i64).?.data, 0),2033 .int_i64 => std.math.order(lhs.castTag(.int_i64).?.data, 0),
...@@ -2001,7 +2037,7 @@ pub const Value = extern union {...@@ -2001,7 +2037,7 @@ pub const Value = extern union {
2001 .lazy_align => {2037 .lazy_align => {
2002 const ty = lhs.castTag(.lazy_align).?.data;2038 const ty = lhs.castTag(.lazy_align).?.data;
2003 const strat: Type.AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;2039 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) {
2005 error.NeedLazy => unreachable,2041 error.NeedLazy => unreachable,
2006 else => |e| return e,2042 else => |e| return e,
2007 }) {2043 }) {
...@@ -2013,7 +2049,7 @@ pub const Value = extern union {...@@ -2013,7 +2049,7 @@ pub const Value = extern union {
2013 .lazy_size => {2049 .lazy_size => {
2014 const ty = lhs.castTag(.lazy_size).?.data;2050 const ty = lhs.castTag(.lazy_size).?.data;
2015 const strat: Type.AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;2051 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) {
2017 error.NeedLazy => unreachable,2053 error.NeedLazy => unreachable,
2018 else => |e| return e,2054 else => |e| return e,
2019 }) {2055 }) {
...@@ -2031,7 +2067,7 @@ pub const Value = extern union {...@@ -2031,7 +2067,7 @@ pub const Value = extern union {
20312067
2032 .elem_ptr => {2068 .elem_ptr => {
2033 const elem_ptr = lhs.castTag(.elem_ptr).?.data;2069 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)) {
2035 .lt => unreachable,2071 .lt => unreachable,
2036 .gt => return .gt,2072 .gt => return .gt,
2037 .eq => {2073 .eq => {
...@@ -2049,17 +2085,17 @@ pub const Value = extern union {...@@ -2049,17 +2085,17 @@ pub const Value = extern union {
2049 }2085 }
20502086
2051 /// Asserts the value is comparable.2087 /// Asserts the value is comparable.
2052 pub fn order(lhs: Value, rhs: Value, target: Target) std.math.Order {2088 pub fn order(lhs: Value, rhs: Value, mod: *const Module) std.math.Order {
2053 return orderAdvanced(lhs, rhs, target, null) catch unreachable;2089 return orderAdvanced(lhs, rhs, mod, null) catch unreachable;
2054 }2090 }
20552091
2056 /// Asserts the value is comparable.2092 /// Asserts the value is comparable.
2057 /// If opt_sema is null then this function asserts things are resolved and cannot fail.2093 /// 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 {
2059 const lhs_tag = lhs.tag();2095 const lhs_tag = lhs.tag();
2060 const rhs_tag = rhs.tag();2096 const rhs_tag = rhs.tag();
2061 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(opt_sema);2097 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, opt_sema);
2062 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(opt_sema);2098 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, opt_sema);
2063 switch (lhs_against_zero) {2099 switch (lhs_against_zero) {
2064 .lt => if (rhs_against_zero != .lt) return .lt,2100 .lt => if (rhs_against_zero != .lt) return .lt,
2065 .eq => return rhs_against_zero.invert(),2101 .eq => return rhs_against_zero.invert(),
...@@ -2093,22 +2129,22 @@ pub const Value = extern union {...@@ -2093,22 +2129,22 @@ pub const Value = extern union {
20932129
2094 var lhs_bigint_space: BigIntSpace = undefined;2130 var lhs_bigint_space: BigIntSpace = undefined;
2095 var rhs_bigint_space: BigIntSpace = undefined;2131 var rhs_bigint_space: BigIntSpace = undefined;
2096 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, target, opt_sema);2132 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, mod, opt_sema);
2097 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, target, opt_sema);2133 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, mod, opt_sema);
2098 return lhs_bigint.order(rhs_bigint);2134 return lhs_bigint.order(rhs_bigint);
2099 }2135 }
21002136
2101 /// Asserts the value is comparable. Does not take a type parameter because it supports2137 /// Asserts the value is comparable. Does not take a type parameter because it supports
2102 /// comparisons between heterogeneous types.2138 /// comparisons between heterogeneous types.
2103 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, target: Target) bool {2139 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, mod: *const Module) bool {
2104 return compareHeteroAdvanced(lhs, op, rhs, target, null) catch unreachable;2140 return compareHeteroAdvanced(lhs, op, rhs, mod, null) catch unreachable;
2105 }2141 }
21062142
2107 pub fn compareHeteroAdvanced(2143 pub fn compareHeteroAdvanced(
2108 lhs: Value,2144 lhs: Value,
2109 op: std.math.CompareOperator,2145 op: std.math.CompareOperator,
2110 rhs: Value,2146 rhs: Value,
2111 target: Target,2147 mod: *const Module,
2112 opt_sema: ?*Sema,2148 opt_sema: ?*Sema,
2113 ) !bool {2149 ) !bool {
2114 if (lhs.pointerDecl()) |lhs_decl| {2150 if (lhs.pointerDecl()) |lhs_decl| {
...@@ -2132,20 +2168,20 @@ pub const Value = extern union {...@@ -2132,20 +2168,20 @@ pub const Value = extern union {
2132 else => {},2168 else => {},
2133 }2169 }
2134 }2170 }
2135 return (try orderAdvanced(lhs, rhs, target, opt_sema)).compare(op);2171 return (try orderAdvanced(lhs, rhs, mod, opt_sema)).compare(op);
2136 }2172 }
21372173
2138 /// Asserts the values are comparable. Both operands have type `ty`.2174 /// Asserts the values are comparable. Both operands have type `ty`.
2139 /// For vectors, returns true if comparison is true for ALL elements.2175 /// For vectors, returns true if comparison is true for ALL elements.
2140 pub fn compareAll(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, mod: *Module) bool {2176 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) {
2142 var i: usize = 0;2178 var i: usize = 0;
2143 while (i < ty.vectorLen()) : (i += 1) {2179 while (i < ty.vectorLen()) : (i += 1) {
2144 var lhs_buf: Value.ElemValueBuffer = undefined;2180 var lhs_buf: Value.ElemValueBuffer = undefined;
2145 var rhs_buf: Value.ElemValueBuffer = undefined;2181 var rhs_buf: Value.ElemValueBuffer = undefined;
2146 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);2182 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
2147 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);2183 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)) {
2149 return false;2185 return false;
2150 }2186 }
2151 }2187 }
...@@ -2165,7 +2201,7 @@ pub const Value = extern union {...@@ -2165,7 +2201,7 @@ pub const Value = extern union {
2165 return switch (op) {2201 return switch (op) {
2166 .eq => lhs.eql(rhs, ty, mod),2202 .eq => lhs.eql(rhs, ty, mod),
2167 .neq => !lhs.eql(rhs, ty, mod),2203 .neq => !lhs.eql(rhs, ty, mod),
2168 else => compareHetero(lhs, op, rhs, mod.getTarget()),2204 else => compareHetero(lhs, op, rhs, mod),
2169 };2205 };
2170 }2206 }
21712207
...@@ -2231,7 +2267,7 @@ pub const Value = extern union {...@@ -2231,7 +2267,7 @@ pub const Value = extern union {
2231 .float_128 => if (std.math.isNan(lhs.castTag(.float_128).?.data)) return op == .neq,2267 .float_128 => if (std.math.isNan(lhs.castTag(.float_128).?.data)) return op == .neq,
2232 else => {},2268 else => {},
2233 }2269 }
2234 return (try orderAgainstZeroAdvanced(lhs, opt_sema)).compare(op);2270 return (try orderAgainstZeroAdvanced(lhs, mod, opt_sema)).compare(op);
2235 }2271 }
22362272
2237 pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool {2273 pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool {
...@@ -2346,7 +2382,7 @@ pub const Value = extern union {...@@ -2346,7 +2382,7 @@ pub const Value = extern union {
2346 return true;2382 return true;
2347 }2383 }
23482384
2349 if (ty.zigTypeTag() == .Struct) {2385 if (ty.zigTypeTag(mod) == .Struct) {
2350 const fields = ty.structFields().values();2386 const fields = ty.structFields().values();
2351 assert(fields.len == a_field_vals.len);2387 assert(fields.len == a_field_vals.len);
2352 for (fields, 0..) |field, i| {2388 for (fields, 0..) |field, i| {
...@@ -2406,12 +2442,10 @@ pub const Value = extern union {...@@ -2406,12 +2442,10 @@ pub const Value = extern union {
2406 return false;2442 return false;
2407 }2443 }
24082444
2409 switch (ty.zigTypeTag()) {2445 switch (ty.zigTypeTag(mod)) {
2410 .Type => {2446 .Type => {
2411 var buf_a: ToTypeBuffer = undefined;2447 const a_type = a.toType();
2412 var buf_b: ToTypeBuffer = undefined;2448 const b_type = b.toType();
2413 const a_type = a.toType(&buf_a);
2414 const b_type = b.toType(&buf_b);
2415 return a_type.eql(b_type, mod);2449 return a_type.eql(b_type, mod);
2416 },2450 },
2417 .Enum => {2451 .Enum => {
...@@ -2419,8 +2453,7 @@ pub const Value = extern union {...@@ -2419,8 +2453,7 @@ pub const Value = extern union {
2419 var buf_b: Payload.U64 = undefined;2453 var buf_b: Payload.U64 = undefined;
2420 const a_val = a.enumToInt(ty, &buf_a);2454 const a_val = a.enumToInt(ty, &buf_a);
2421 const b_val = b.enumToInt(ty, &buf_b);2455 const b_val = b.enumToInt(ty, &buf_b);
2422 var buf_ty: Type.Payload.Bits = undefined;2456 const int_ty = ty.intTagType();
2423 const int_ty = ty.intTagType(&buf_ty);
2424 return eqlAdvanced(a_val, int_ty, b_val, int_ty, mod, opt_sema);2457 return eqlAdvanced(a_val, int_ty, b_val, int_ty, mod, opt_sema);
2425 },2458 },
2426 .Array, .Vector => {2459 .Array, .Vector => {
...@@ -2466,11 +2499,11 @@ pub const Value = extern union {...@@ -2466,11 +2499,11 @@ pub const Value = extern union {
2466 // .the_one_possible_value,2499 // .the_one_possible_value,
2467 // .aggregate,2500 // .aggregate,
2468 // Note that we already checked above for matching tags, e.g. both .aggregate.2501 // Note that we already checked above for matching tags, e.g. both .aggregate.
2469 return ty.onePossibleValue() != null;2502 return ty.onePossibleValue(mod) != null;
2470 },2503 },
2471 .Union => {2504 .Union => {
2472 // Here we have to check for value equality, as-if `a` has been coerced to `ty`.2505 // 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) {
2474 return true;2507 return true;
2475 }2508 }
2476 if (a_ty.castTag(.anon_struct)) |payload| {2509 if (a_ty.castTag(.anon_struct)) |payload| {
...@@ -2533,13 +2566,13 @@ pub const Value = extern union {...@@ -2533,13 +2566,13 @@ pub const Value = extern union {
2533 else => {},2566 else => {},
2534 }2567 }
2535 if (a_tag == .null_value or a_tag == .@"error") return false;2568 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);
2537 }2570 }
25382571
2539 /// This function is used by hash maps and so treats floating-point NaNs as equal2572 /// This function is used by hash maps and so treats floating-point NaNs as equal
2540 /// to each other, and not equal to other floating-point values.2573 /// to each other, and not equal to other floating-point values.
2541 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {2574 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);
2543 std.hash.autoHash(hasher, zig_ty_tag);2576 std.hash.autoHash(hasher, zig_ty_tag);
2544 if (val.isUndef()) return;2577 if (val.isUndef()) return;
2545 // The value is runtime-known and shouldn't affect the hash.2578 // The value is runtime-known and shouldn't affect the hash.
...@@ -2555,8 +2588,7 @@ pub const Value = extern union {...@@ -2555,8 +2588,7 @@ pub const Value = extern union {
2555 => {},2588 => {},
25562589
2557 .Type => {2590 .Type => {
2558 var buf: ToTypeBuffer = undefined;2591 return val.toType().hashWithHasher(hasher, mod);
2559 return val.toType(&buf).hashWithHasher(hasher, mod);
2560 },2592 },
2561 .Float => {2593 .Float => {
2562 // For hash/eql purposes, we treat floats as their IEEE integer representation.2594 // For hash/eql purposes, we treat floats as their IEEE integer representation.
...@@ -2588,7 +2620,7 @@ pub const Value = extern union {...@@ -2588,7 +2620,7 @@ pub const Value = extern union {
2588 hash(slice.len, Type.usize, hasher, mod);2620 hash(slice.len, Type.usize, hasher, mod);
2589 },2621 },
25902622
2591 else => return hashPtr(val, hasher, mod.getTarget()),2623 else => return hashPtr(val, hasher, mod),
2592 },2624 },
2593 .Array, .Vector => {2625 .Array, .Vector => {
2594 const len = ty.arrayLen();2626 const len = ty.arrayLen();
...@@ -2648,7 +2680,7 @@ pub const Value = extern union {...@@ -2648,7 +2680,7 @@ pub const Value = extern union {
2648 .Enum => {2680 .Enum => {
2649 var enum_space: Payload.U64 = undefined;2681 var enum_space: Payload.U64 = undefined;
2650 const int_val = val.enumToInt(ty, &enum_space);2682 const int_val = val.enumToInt(ty, &enum_space);
2651 hashInt(int_val, hasher, mod.getTarget());2683 hashInt(int_val, hasher, mod);
2652 },2684 },
2653 .Union => {2685 .Union => {
2654 const union_obj = val.cast(Payload.Union).?.data;2686 const union_obj = val.cast(Payload.Union).?.data;
...@@ -2691,7 +2723,7 @@ pub const Value = extern union {...@@ -2691,7 +2723,7 @@ pub const Value = extern union {
2691 // The value is runtime-known and shouldn't affect the hash.2723 // The value is runtime-known and shouldn't affect the hash.
2692 if (val.tag() == .runtime_value) return;2724 if (val.tag() == .runtime_value) return;
26932725
2694 switch (ty.zigTypeTag()) {2726 switch (ty.zigTypeTag(mod)) {
2695 .Opaque => unreachable, // Cannot hash opaque types2727 .Opaque => unreachable, // Cannot hash opaque types
2696 .Void,2728 .Void,
2697 .NoReturn,2729 .NoReturn,
...@@ -2700,8 +2732,7 @@ pub const Value = extern union {...@@ -2700,8 +2732,7 @@ pub const Value = extern union {
2700 .Struct, // It sure would be nice to do something clever with structs.2732 .Struct, // It sure would be nice to do something clever with structs.
2701 => |zig_type_tag| std.hash.autoHash(hasher, zig_type_tag),2733 => |zig_type_tag| std.hash.autoHash(hasher, zig_type_tag),
2702 .Type => {2734 .Type => {
2703 var buf: ToTypeBuffer = undefined;2735 val.toType().hashWithHasher(hasher, mod);
2704 val.toType(&buf).hashWithHasher(hasher, mod);
2705 },2736 },
2706 .Float, .ComptimeFloat => std.hash.autoHash(hasher, @bitCast(u128, val.toFloat(f128))),2737 .Float, .ComptimeFloat => std.hash.autoHash(hasher, @bitCast(u128, val.toFloat(f128))),
2707 .Bool, .Int, .ComptimeInt, .Pointer, .Fn => switch (val.tag()) {2738 .Bool, .Int, .ComptimeInt, .Pointer, .Fn => switch (val.tag()) {
...@@ -2711,7 +2742,7 @@ pub const Value = extern union {...@@ -2711,7 +2742,7 @@ pub const Value = extern union {
2711 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);2742 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
2712 slice.ptr.hashUncoerced(ptr_ty, hasher, mod);2743 slice.ptr.hashUncoerced(ptr_ty, hasher, mod);
2713 },2744 },
2714 else => val.hashPtr(hasher, mod.getTarget()),2745 else => val.hashPtr(hasher, mod),
2715 },2746 },
2716 .Array, .Vector => {2747 .Array, .Vector => {
2717 const len = ty.arrayLen();2748 const len = ty.arrayLen();
...@@ -2821,16 +2852,16 @@ pub const Value = extern union {...@@ -2821,16 +2852,16 @@ pub const Value = extern union {
2821 };2852 };
2822 }2853 }
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 {
2825 var buffer: BigIntSpace = undefined;2856 var buffer: BigIntSpace = undefined;
2826 const big = int_val.toBigInt(&buffer, target);2857 const big = int_val.toBigInt(&buffer, mod);
2827 std.hash.autoHash(hasher, big.positive);2858 std.hash.autoHash(hasher, big.positive);
2828 for (big.limbs) |limb| {2859 for (big.limbs) |limb| {
2829 std.hash.autoHash(hasher, limb);2860 std.hash.autoHash(hasher, limb);
2830 }2861 }
2831 }2862 }
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 {
2834 switch (ptr_val.tag()) {2865 switch (ptr_val.tag()) {
2835 .decl_ref,2866 .decl_ref,
2836 .decl_ref_mut,2867 .decl_ref_mut,
...@@ -2847,25 +2878,25 @@ pub const Value = extern union {...@@ -2847,25 +2878,25 @@ pub const Value = extern union {
28472878
2848 .elem_ptr => {2879 .elem_ptr => {
2849 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;2880 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);
2851 std.hash.autoHash(hasher, Value.Tag.elem_ptr);2882 std.hash.autoHash(hasher, Value.Tag.elem_ptr);
2852 std.hash.autoHash(hasher, elem_ptr.index);2883 std.hash.autoHash(hasher, elem_ptr.index);
2853 },2884 },
2854 .field_ptr => {2885 .field_ptr => {
2855 const field_ptr = ptr_val.castTag(.field_ptr).?.data;2886 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
2856 std.hash.autoHash(hasher, Value.Tag.field_ptr);2887 std.hash.autoHash(hasher, Value.Tag.field_ptr);
2857 hashPtr(field_ptr.container_ptr, hasher, target);2888 hashPtr(field_ptr.container_ptr, hasher, mod);
2858 std.hash.autoHash(hasher, field_ptr.field_index);2889 std.hash.autoHash(hasher, field_ptr.field_index);
2859 },2890 },
2860 .eu_payload_ptr => {2891 .eu_payload_ptr => {
2861 const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;2892 const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
2862 std.hash.autoHash(hasher, Value.Tag.eu_payload_ptr);2893 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);
2864 },2895 },
2865 .opt_payload_ptr => {2896 .opt_payload_ptr => {
2866 const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;2897 const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
2867 std.hash.autoHash(hasher, Value.Tag.opt_payload_ptr);2898 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);
2869 },2900 },
28702901
2871 .zero,2902 .zero,
...@@ -2880,7 +2911,7 @@ pub const Value = extern union {...@@ -2880,7 +2911,7 @@ pub const Value = extern union {
2880 .the_only_possible_value,2911 .the_only_possible_value,
2881 .lazy_align,2912 .lazy_align,
2882 .lazy_size,2913 .lazy_size,
2883 => return hashInt(ptr_val, hasher, target),2914 => return hashInt(ptr_val, hasher, mod),
28842915
2885 else => unreachable,2916 else => unreachable,
2886 }2917 }
...@@ -2897,11 +2928,11 @@ pub const Value = extern union {...@@ -2897,11 +2928,11 @@ pub const Value = extern union {
28972928
2898 pub fn sliceLen(val: Value, mod: *Module) u64 {2929 pub fn sliceLen(val: Value, mod: *Module) u64 {
2899 return switch (val.tag()) {2930 return switch (val.tag()) {
2900 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(mod.getTarget()),2931 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(mod),
2901 .decl_ref => {2932 .decl_ref => {
2902 const decl_index = val.castTag(.decl_ref).?.data;2933 const decl_index = val.castTag(.decl_ref).?.data;
2903 const decl = mod.declPtr(decl_index);2934 const decl = mod.declPtr(decl_index);
2904 if (decl.ty.zigTypeTag() == .Array) {2935 if (decl.ty.zigTypeTag(mod) == .Array) {
2905 return decl.ty.arrayLen();2936 return decl.ty.arrayLen();
2906 } else {2937 } else {
2907 return 1;2938 return 1;
...@@ -2910,7 +2941,7 @@ pub const Value = extern union {...@@ -2910,7 +2941,7 @@ pub const Value = extern union {
2910 .decl_ref_mut => {2941 .decl_ref_mut => {
2911 const decl_index = val.castTag(.decl_ref_mut).?.data.decl_index;2942 const decl_index = val.castTag(.decl_ref_mut).?.data.decl_index;
2912 const decl = mod.declPtr(decl_index);2943 const decl = mod.declPtr(decl_index);
2913 if (decl.ty.zigTypeTag() == .Array) {2944 if (decl.ty.zigTypeTag(mod) == .Array) {
2914 return decl.ty.arrayLen();2945 return decl.ty.arrayLen();
2915 } else {2946 } else {
2916 return 1;2947 return 1;
...@@ -2918,7 +2949,7 @@ pub const Value = extern union {...@@ -2918,7 +2949,7 @@ pub const Value = extern union {
2918 },2949 },
2919 .comptime_field_ptr => {2950 .comptime_field_ptr => {
2920 const payload = val.castTag(.comptime_field_ptr).?.data;2951 const payload = val.castTag(.comptime_field_ptr).?.data;
2921 if (payload.field_ty.zigTypeTag() == .Array) {2952 if (payload.field_ty.zigTypeTag(mod) == .Array) {
2922 return payload.field_ty.arrayLen();2953 return payload.field_ty.arrayLen();
2923 } else {2954 } else {
2924 return 1;2955 return 1;
...@@ -3003,7 +3034,7 @@ pub const Value = extern union {...@@ -3003,7 +3034,7 @@ pub const Value = extern union {
3003 if (data.container_ptr.pointerDecl()) |decl_index| {3034 if (data.container_ptr.pointerDecl()) |decl_index| {
3004 const container_decl = mod.declPtr(decl_index);3035 const container_decl = mod.declPtr(decl_index);
3005 const field_type = data.container_ty.structFieldType(data.field_index);3036 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);
3007 return field_val.elemValueAdvanced(mod, index, arena, buffer);3038 return field_val.elemValueAdvanced(mod, index, arena, buffer);
3008 } else unreachable;3039 } else unreachable;
3009 },3040 },
...@@ -3032,10 +3063,7 @@ pub const Value = extern union {...@@ -3032,10 +3063,7 @@ pub const Value = extern union {
3032 }3063 }
30333064
3034 /// Returns true if a Value is backed by a variable3065 /// Returns true if a Value is backed by a variable
3035 pub fn isVariable(3066 pub fn isVariable(val: Value, mod: *Module) bool {
3036 val: Value,
3037 mod: *Module,
3038 ) bool {
3039 return switch (val.tag()) {3067 return switch (val.tag()) {
3040 .slice => val.castTag(.slice).?.data.ptr.isVariable(mod),3068 .slice => val.castTag(.slice).?.data.ptr.isVariable(mod),
3041 .comptime_field_ptr => val.castTag(.comptime_field_ptr).?.data.field_val.isVariable(mod),3069 .comptime_field_ptr => val.castTag(.comptime_field_ptr).?.data.field_val.isVariable(mod),
...@@ -3119,7 +3147,7 @@ pub const Value = extern union {...@@ -3119,7 +3147,7 @@ pub const Value = extern union {
3119 };3147 };
3120 }3148 }
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 {
3123 switch (val.tag()) {3151 switch (val.tag()) {
3124 .aggregate => {3152 .aggregate => {
3125 const field_values = val.castTag(.aggregate).?.data;3153 const field_values = val.castTag(.aggregate).?.data;
...@@ -3131,14 +3159,14 @@ pub const Value = extern union {...@@ -3131,14 +3159,14 @@ pub const Value = extern union {
3131 return payload.val;3159 return payload.val;
3132 },3160 },
31333161
3134 .the_only_possible_value => return ty.onePossibleValue().?,3162 .the_only_possible_value => return ty.onePossibleValue(mod).?,
31353163
3136 .empty_struct_value => {3164 .empty_struct_value => {
3137 if (ty.isSimpleTupleOrAnonStruct()) {3165 if (ty.isSimpleTupleOrAnonStruct()) {
3138 const tuple = ty.tupleFields();3166 const tuple = ty.tupleFields();
3139 return tuple.values[index];3167 return tuple.values[index];
3140 }3168 }
3141 if (ty.structFieldValueComptime(index)) |some| {3169 if (ty.structFieldValueComptime(mod, index)) |some| {
3142 return some;3170 return some;
3143 }3171 }
3144 unreachable;3172 unreachable;
...@@ -3165,7 +3193,7 @@ pub const Value = extern union {...@@ -3165,7 +3193,7 @@ pub const Value = extern union {
3165 index: usize,3193 index: usize,
3166 mod: *Module,3194 mod: *Module,
3167 ) Allocator.Error!Value {3195 ) Allocator.Error!Value {
3168 const elem_ty = ty.elemType2();3196 const elem_ty = ty.elemType2(mod);
3169 const ptr_val = switch (val.tag()) {3197 const ptr_val = switch (val.tag()) {
3170 .slice => val.castTag(.slice).?.data.ptr,3198 .slice => val.castTag(.slice).?.data.ptr,
3171 else => val,3199 else => val,
...@@ -3207,7 +3235,7 @@ pub const Value = extern union {...@@ -3207,7 +3235,7 @@ pub const Value = extern union {
3207 switch (self.tag()) {3235 switch (self.tag()) {
3208 .slice => {3236 .slice => {
3209 const payload = self.castTag(.slice).?;3237 const payload = self.castTag(.slice).?;
3210 const len = payload.data.len.toUnsignedInt(mod.getTarget());3238 const len = payload.data.len.toUnsignedInt(mod);
32113239
3212 var elem_value_buf: ElemValueBuffer = undefined;3240 var elem_value_buf: ElemValueBuffer = undefined;
3213 var i: usize = 0;3241 var i: usize = 0;
...@@ -3233,7 +3261,7 @@ pub const Value = extern union {...@@ -3233,7 +3261,7 @@ pub const Value = extern union {
32333261
3234 /// Asserts the value is not undefined and not unreachable.3262 /// Asserts the value is not undefined and not unreachable.
3235 /// Integer value 0 is considered null because of C pointers.3263 /// 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 {
3237 return switch (self.tag()) {3265 return switch (self.tag()) {
3238 .null_value => true,3266 .null_value => true,
3239 .opt_payload => false,3267 .opt_payload => false,
...@@ -3254,7 +3282,7 @@ pub const Value = extern union {...@@ -3254,7 +3282,7 @@ pub const Value = extern union {
3254 .int_i64,3282 .int_i64,
3255 .int_big_positive,3283 .int_big_positive,
3256 .int_big_negative,3284 .int_big_negative,
3257 => self.orderAgainstZero().compare(.eq),3285 => self.orderAgainstZero(mod).compare(.eq),
32583286
3259 .undef => unreachable,3287 .undef => unreachable,
3260 .unreachable_value => unreachable,3288 .unreachable_value => unreachable,
...@@ -3300,8 +3328,8 @@ pub const Value = extern union {...@@ -3300,8 +3328,8 @@ pub const Value = extern union {
3300 }3328 }
33013329
3302 /// Value of the optional, null if optional has no payload.3330 /// Value of the optional, null if optional has no payload.
3303 pub fn optionalValue(val: Value) ?Value {3331 pub fn optionalValue(val: Value, mod: *const Module) ?Value {
3304 if (val.isNull()) return null;3332 if (val.isNull(mod)) return null;
33053333
3306 // Valid for optional representation to be the direct value3334 // Valid for optional representation to be the direct value
3307 // and not use opt_payload.3335 // and not use opt_payload.
...@@ -3333,20 +3361,20 @@ pub const Value = extern union {...@@ -3333,20 +3361,20 @@ pub const Value = extern union {
3333 }3361 }
33343362
3335 pub fn intToFloatAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module, opt_sema: ?*Sema) !Value {3363 pub fn intToFloatAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module, opt_sema: ?*Sema) !Value {
3336 const target = mod.getTarget();3364 if (int_ty.zigTypeTag(mod) == .Vector) {
3337 if (int_ty.zigTypeTag() == .Vector) {
3338 const result_data = try arena.alloc(Value, int_ty.vectorLen());3365 const result_data = try arena.alloc(Value, int_ty.vectorLen());
3339 for (result_data, 0..) |*scalar, i| {3366 for (result_data, 0..) |*scalar, i| {
3340 var buf: Value.ElemValueBuffer = undefined;3367 var buf: Value.ElemValueBuffer = undefined;
3341 const elem_val = val.elemValueBuffer(mod, i, &buf);3368 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);
3343 }3370 }
3344 return Value.Tag.aggregate.create(arena, result_data);3371 return Value.Tag.aggregate.create(arena, result_data);
3345 }3372 }
3346 return intToFloatScalar(val, arena, float_ty, target, opt_sema);3373 return intToFloatScalar(val, arena, float_ty, mod, opt_sema);
3347 }3374 }
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();
3350 switch (val.tag()) {3378 switch (val.tag()) {
3351 .undef, .zero, .one => return val,3379 .undef, .zero, .one => return val,
3352 .the_only_possible_value => return Value.initTag(.zero), // for i0, u03380 .the_only_possible_value => return Value.initTag(.zero), // for i0, u0
...@@ -3369,17 +3397,17 @@ pub const Value = extern union {...@@ -3369,17 +3397,17 @@ pub const Value = extern union {
3369 .lazy_align => {3397 .lazy_align => {
3370 const ty = val.castTag(.lazy_align).?.data;3398 const ty = val.castTag(.lazy_align).?.data;
3371 if (opt_sema) |sema| {3399 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);
3373 } else {3401 } else {
3374 return intToFloatInner(ty.abiAlignment(target), arena, float_ty, target);3402 return intToFloatInner(ty.abiAlignment(mod), arena, float_ty, target);
3375 }3403 }
3376 },3404 },
3377 .lazy_size => {3405 .lazy_size => {
3378 const ty = val.castTag(.lazy_size).?.data;3406 const ty = val.castTag(.lazy_size).?.data;
3379 if (opt_sema) |sema| {3407 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);
3381 } else {3409 } else {
3382 return intToFloatInner(ty.abiSize(target), arena, float_ty, target);3410 return intToFloatInner(ty.abiSize(mod), arena, float_ty, target);
3383 }3411 }
3384 },3412 },
3385 else => unreachable,3413 else => unreachable,
...@@ -3446,19 +3474,18 @@ pub const Value = extern union {...@@ -3446,19 +3474,18 @@ pub const Value = extern union {
3446 arena: Allocator,3474 arena: Allocator,
3447 mod: *Module,3475 mod: *Module,
3448 ) !Value {3476 ) !Value {
3449 const target = mod.getTarget();3477 if (ty.zigTypeTag(mod) == .Vector) {
3450 if (ty.zigTypeTag() == .Vector) {
3451 const result_data = try arena.alloc(Value, ty.vectorLen());3478 const result_data = try arena.alloc(Value, ty.vectorLen());
3452 for (result_data, 0..) |*scalar, i| {3479 for (result_data, 0..) |*scalar, i| {
3453 var lhs_buf: Value.ElemValueBuffer = undefined;3480 var lhs_buf: Value.ElemValueBuffer = undefined;
3454 var rhs_buf: Value.ElemValueBuffer = undefined;3481 var rhs_buf: Value.ElemValueBuffer = undefined;
3455 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3482 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3456 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);3483 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);
3458 }3485 }
3459 return Value.Tag.aggregate.create(arena, result_data);3486 return Value.Tag.aggregate.create(arena, result_data);
3460 }3487 }
3461 return intAddSatScalar(lhs, rhs, ty, arena, target);3488 return intAddSatScalar(lhs, rhs, ty, arena, mod);
3462 }3489 }
34633490
3464 /// Supports integers only; asserts neither operand is undefined.3491 /// Supports integers only; asserts neither operand is undefined.
...@@ -3467,17 +3494,17 @@ pub const Value = extern union {...@@ -3467,17 +3494,17 @@ pub const Value = extern union {
3467 rhs: Value,3494 rhs: Value,
3468 ty: Type,3495 ty: Type,
3469 arena: Allocator,3496 arena: Allocator,
3470 target: Target,3497 mod: *Module,
3471 ) !Value {3498 ) !Value {
3472 assert(!lhs.isUndef());3499 assert(!lhs.isUndef());
3473 assert(!rhs.isUndef());3500 assert(!rhs.isUndef());
34743501
3475 const info = ty.intInfo(target);3502 const info = ty.intInfo(mod);
34763503
3477 var lhs_space: Value.BigIntSpace = undefined;3504 var lhs_space: Value.BigIntSpace = undefined;
3478 var rhs_space: Value.BigIntSpace = undefined;3505 var rhs_space: Value.BigIntSpace = undefined;
3479 const lhs_bigint = lhs.toBigInt(&lhs_space, target);3506 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3480 const rhs_bigint = rhs.toBigInt(&rhs_space, target);3507 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
3481 const limbs = try arena.alloc(3508 const limbs = try arena.alloc(
3482 std.math.big.Limb,3509 std.math.big.Limb,
3483 std.math.big.int.calcTwosCompLimbCount(info.bits),3510 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -3495,19 +3522,18 @@ pub const Value = extern union {...@@ -3495,19 +3522,18 @@ pub const Value = extern union {
3495 arena: Allocator,3522 arena: Allocator,
3496 mod: *Module,3523 mod: *Module,
3497 ) !Value {3524 ) !Value {
3498 const target = mod.getTarget();3525 if (ty.zigTypeTag(mod) == .Vector) {
3499 if (ty.zigTypeTag() == .Vector) {
3500 const result_data = try arena.alloc(Value, ty.vectorLen());3526 const result_data = try arena.alloc(Value, ty.vectorLen());
3501 for (result_data, 0..) |*scalar, i| {3527 for (result_data, 0..) |*scalar, i| {
3502 var lhs_buf: Value.ElemValueBuffer = undefined;3528 var lhs_buf: Value.ElemValueBuffer = undefined;
3503 var rhs_buf: Value.ElemValueBuffer = undefined;3529 var rhs_buf: Value.ElemValueBuffer = undefined;
3504 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3530 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3505 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);3531 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);
3507 }3533 }
3508 return Value.Tag.aggregate.create(arena, result_data);3534 return Value.Tag.aggregate.create(arena, result_data);
3509 }3535 }
3510 return intSubSatScalar(lhs, rhs, ty, arena, target);3536 return intSubSatScalar(lhs, rhs, ty, arena, mod);
3511 }3537 }
35123538
3513 /// Supports integers only; asserts neither operand is undefined.3539 /// Supports integers only; asserts neither operand is undefined.
...@@ -3516,17 +3542,17 @@ pub const Value = extern union {...@@ -3516,17 +3542,17 @@ pub const Value = extern union {
3516 rhs: Value,3542 rhs: Value,
3517 ty: Type,3543 ty: Type,
3518 arena: Allocator,3544 arena: Allocator,
3519 target: Target,3545 mod: *Module,
3520 ) !Value {3546 ) !Value {
3521 assert(!lhs.isUndef());3547 assert(!lhs.isUndef());
3522 assert(!rhs.isUndef());3548 assert(!rhs.isUndef());
35233549
3524 const info = ty.intInfo(target);3550 const info = ty.intInfo(mod);
35253551
3526 var lhs_space: Value.BigIntSpace = undefined;3552 var lhs_space: Value.BigIntSpace = undefined;
3527 var rhs_space: Value.BigIntSpace = undefined;3553 var rhs_space: Value.BigIntSpace = undefined;
3528 const lhs_bigint = lhs.toBigInt(&lhs_space, target);3554 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3529 const rhs_bigint = rhs.toBigInt(&rhs_space, target);3555 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
3530 const limbs = try arena.alloc(3556 const limbs = try arena.alloc(
3531 std.math.big.Limb,3557 std.math.big.Limb,
3532 std.math.big.int.calcTwosCompLimbCount(info.bits),3558 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -3543,8 +3569,7 @@ pub const Value = extern union {...@@ -3543,8 +3569,7 @@ pub const Value = extern union {
3543 arena: Allocator,3569 arena: Allocator,
3544 mod: *Module,3570 mod: *Module,
3545 ) !OverflowArithmeticResult {3571 ) !OverflowArithmeticResult {
3546 const target = mod.getTarget();3572 if (ty.zigTypeTag(mod) == .Vector) {
3547 if (ty.zigTypeTag() == .Vector) {
3548 const overflowed_data = try arena.alloc(Value, ty.vectorLen());3573 const overflowed_data = try arena.alloc(Value, ty.vectorLen());
3549 const result_data = try arena.alloc(Value, ty.vectorLen());3574 const result_data = try arena.alloc(Value, ty.vectorLen());
3550 for (result_data, 0..) |*scalar, i| {3575 for (result_data, 0..) |*scalar, i| {
...@@ -3552,7 +3577,7 @@ pub const Value = extern union {...@@ -3552,7 +3577,7 @@ pub const Value = extern union {
3552 var rhs_buf: Value.ElemValueBuffer = undefined;3577 var rhs_buf: Value.ElemValueBuffer = undefined;
3553 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3578 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3554 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);3579 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);
3556 overflowed_data[i] = of_math_result.overflow_bit;3581 overflowed_data[i] = of_math_result.overflow_bit;
3557 scalar.* = of_math_result.wrapped_result;3582 scalar.* = of_math_result.wrapped_result;
3558 }3583 }
...@@ -3561,7 +3586,7 @@ pub const Value = extern union {...@@ -3561,7 +3586,7 @@ pub const Value = extern union {
3561 .wrapped_result = try Value.Tag.aggregate.create(arena, result_data),3586 .wrapped_result = try Value.Tag.aggregate.create(arena, result_data),
3562 };3587 };
3563 }3588 }
3564 return intMulWithOverflowScalar(lhs, rhs, ty, arena, target);3589 return intMulWithOverflowScalar(lhs, rhs, ty, arena, mod);
3565 }3590 }
35663591
3567 pub fn intMulWithOverflowScalar(3592 pub fn intMulWithOverflowScalar(
...@@ -3569,14 +3594,14 @@ pub const Value = extern union {...@@ -3569,14 +3594,14 @@ pub const Value = extern union {
3569 rhs: Value,3594 rhs: Value,
3570 ty: Type,3595 ty: Type,
3571 arena: Allocator,3596 arena: Allocator,
3572 target: Target,3597 mod: *Module,
3573 ) !OverflowArithmeticResult {3598 ) !OverflowArithmeticResult {
3574 const info = ty.intInfo(target);3599 const info = ty.intInfo(mod);
35753600
3576 var lhs_space: Value.BigIntSpace = undefined;3601 var lhs_space: Value.BigIntSpace = undefined;
3577 var rhs_space: Value.BigIntSpace = undefined;3602 var rhs_space: Value.BigIntSpace = undefined;
3578 const lhs_bigint = lhs.toBigInt(&lhs_space, target);3603 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3579 const rhs_bigint = rhs.toBigInt(&rhs_space, target);3604 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
3580 const limbs = try arena.alloc(3605 const limbs = try arena.alloc(
3581 std.math.big.Limb,3606 std.math.big.Limb,
3582 lhs_bigint.limbs.len + rhs_bigint.limbs.len,3607 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
...@@ -3607,14 +3632,14 @@ pub const Value = extern union {...@@ -3607,14 +3632,14 @@ pub const Value = extern union {
3607 arena: Allocator,3632 arena: Allocator,
3608 mod: *Module,3633 mod: *Module,
3609 ) !Value {3634 ) !Value {
3610 if (ty.zigTypeTag() == .Vector) {3635 if (ty.zigTypeTag(mod) == .Vector) {
3611 const result_data = try arena.alloc(Value, ty.vectorLen());3636 const result_data = try arena.alloc(Value, ty.vectorLen());
3612 for (result_data, 0..) |*scalar, i| {3637 for (result_data, 0..) |*scalar, i| {
3613 var lhs_buf: Value.ElemValueBuffer = undefined;3638 var lhs_buf: Value.ElemValueBuffer = undefined;
3614 var rhs_buf: Value.ElemValueBuffer = undefined;3639 var rhs_buf: Value.ElemValueBuffer = undefined;
3615 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3640 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3616 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);3641 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);
3618 }3643 }
3619 return Value.Tag.aggregate.create(arena, result_data);3644 return Value.Tag.aggregate.create(arena, result_data);
3620 }3645 }
...@@ -3631,7 +3656,7 @@ pub const Value = extern union {...@@ -3631,7 +3656,7 @@ pub const Value = extern union {
3631 ) !Value {3656 ) !Value {
3632 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3657 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
36333658
3634 if (ty.zigTypeTag() == .ComptimeInt) {3659 if (ty.zigTypeTag(mod) == .ComptimeInt) {
3635 return intMul(lhs, rhs, ty, arena, mod);3660 return intMul(lhs, rhs, ty, arena, mod);
3636 }3661 }
36373662
...@@ -3651,19 +3676,18 @@ pub const Value = extern union {...@@ -3651,19 +3676,18 @@ pub const Value = extern union {
3651 arena: Allocator,3676 arena: Allocator,
3652 mod: *Module,3677 mod: *Module,
3653 ) !Value {3678 ) !Value {
3654 const target = mod.getTarget();3679 if (ty.zigTypeTag(mod) == .Vector) {
3655 if (ty.zigTypeTag() == .Vector) {
3656 const result_data = try arena.alloc(Value, ty.vectorLen());3680 const result_data = try arena.alloc(Value, ty.vectorLen());
3657 for (result_data, 0..) |*scalar, i| {3681 for (result_data, 0..) |*scalar, i| {
3658 var lhs_buf: Value.ElemValueBuffer = undefined;3682 var lhs_buf: Value.ElemValueBuffer = undefined;
3659 var rhs_buf: Value.ElemValueBuffer = undefined;3683 var rhs_buf: Value.ElemValueBuffer = undefined;
3660 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3684 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3661 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);3685 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);
3663 }3687 }
3664 return Value.Tag.aggregate.create(arena, result_data);3688 return Value.Tag.aggregate.create(arena, result_data);
3665 }3689 }
3666 return intMulSatScalar(lhs, rhs, ty, arena, target);3690 return intMulSatScalar(lhs, rhs, ty, arena, mod);
3667 }3691 }
36683692
3669 /// Supports (vectors of) integers only; asserts neither operand is undefined.3693 /// Supports (vectors of) integers only; asserts neither operand is undefined.
...@@ -3672,17 +3696,17 @@ pub const Value = extern union {...@@ -3672,17 +3696,17 @@ pub const Value = extern union {
3672 rhs: Value,3696 rhs: Value,
3673 ty: Type,3697 ty: Type,
3674 arena: Allocator,3698 arena: Allocator,
3675 target: Target,3699 mod: *Module,
3676 ) !Value {3700 ) !Value {
3677 assert(!lhs.isUndef());3701 assert(!lhs.isUndef());
3678 assert(!rhs.isUndef());3702 assert(!rhs.isUndef());
36793703
3680 const info = ty.intInfo(target);3704 const info = ty.intInfo(mod);
36813705
3682 var lhs_space: Value.BigIntSpace = undefined;3706 var lhs_space: Value.BigIntSpace = undefined;
3683 var rhs_space: Value.BigIntSpace = undefined;3707 var rhs_space: Value.BigIntSpace = undefined;
3684 const lhs_bigint = lhs.toBigInt(&lhs_space, target);3708 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3685 const rhs_bigint = rhs.toBigInt(&rhs_space, target);3709 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
3686 const limbs = try arena.alloc(3710 const limbs = try arena.alloc(
3687 std.math.big.Limb,3711 std.math.big.Limb,
3688 std.math.max(3712 std.math.max(
...@@ -3702,24 +3726,24 @@ pub const Value = extern union {...@@ -3702,24 +3726,24 @@ pub const Value = extern union {
3702 }3726 }
37033727
3704 /// Supports both floats and ints; handles undefined.3728 /// 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 {
3706 if (lhs.isUndef() or rhs.isUndef()) return undef;3730 if (lhs.isUndef() or rhs.isUndef()) return undef;
3707 if (lhs.isNan()) return rhs;3731 if (lhs.isNan()) return rhs;
3708 if (rhs.isNan()) return lhs;3732 if (rhs.isNan()) return lhs;
37093733
3710 return switch (order(lhs, rhs, target)) {3734 return switch (order(lhs, rhs, mod)) {
3711 .lt => rhs,3735 .lt => rhs,
3712 .gt, .eq => lhs,3736 .gt, .eq => lhs,
3713 };3737 };
3714 }3738 }
37153739
3716 /// Supports both floats and ints; handles undefined.3740 /// 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 {
3718 if (lhs.isUndef() or rhs.isUndef()) return undef;3742 if (lhs.isUndef() or rhs.isUndef()) return undef;
3719 if (lhs.isNan()) return rhs;3743 if (lhs.isNan()) return rhs;
3720 if (rhs.isNan()) return lhs;3744 if (rhs.isNan()) return lhs;
37213745
3722 return switch (order(lhs, rhs, target)) {3746 return switch (order(lhs, rhs, mod)) {
3723 .lt => lhs,3747 .lt => lhs,
3724 .gt, .eq => rhs,3748 .gt, .eq => rhs,
3725 };3749 };
...@@ -3727,24 +3751,23 @@ pub const Value = extern union {...@@ -3727,24 +3751,23 @@ pub const Value = extern union {
37273751
3728 /// operands must be (vectors of) integers; handles undefined scalars.3752 /// operands must be (vectors of) integers; handles undefined scalars.
3729 pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {3753 pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
3730 const target = mod.getTarget();3754 if (ty.zigTypeTag(mod) == .Vector) {
3731 if (ty.zigTypeTag() == .Vector) {
3732 const result_data = try arena.alloc(Value, ty.vectorLen());3755 const result_data = try arena.alloc(Value, ty.vectorLen());
3733 for (result_data, 0..) |*scalar, i| {3756 for (result_data, 0..) |*scalar, i| {
3734 var buf: Value.ElemValueBuffer = undefined;3757 var buf: Value.ElemValueBuffer = undefined;
3735 const elem_val = val.elemValueBuffer(mod, i, &buf);3758 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);
3737 }3760 }
3738 return Value.Tag.aggregate.create(arena, result_data);3761 return Value.Tag.aggregate.create(arena, result_data);
3739 }3762 }
3740 return bitwiseNotScalar(val, ty, arena, target);3763 return bitwiseNotScalar(val, ty, arena, mod);
3741 }3764 }
37423765
3743 /// operands must be integers; handles undefined.3766 /// 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 {
3745 if (val.isUndef()) return Value.initTag(.undef);3768 if (val.isUndef()) return Value.initTag(.undef);
37463769
3747 const info = ty.intInfo(target);3770 const info = ty.intInfo(mod);
37483771
3749 if (info.bits == 0) {3772 if (info.bits == 0) {
3750 return val;3773 return val;
...@@ -3753,7 +3776,7 @@ pub const Value = extern union {...@@ -3753,7 +3776,7 @@ pub const Value = extern union {
3753 // TODO is this a performance issue? maybe we should try the operation without3776 // TODO is this a performance issue? maybe we should try the operation without
3754 // resorting to BigInt first.3777 // resorting to BigInt first.
3755 var val_space: Value.BigIntSpace = undefined;3778 var val_space: Value.BigIntSpace = undefined;
3756 const val_bigint = val.toBigInt(&val_space, target);3779 const val_bigint = val.toBigInt(&val_space, mod);
3757 const limbs = try arena.alloc(3780 const limbs = try arena.alloc(
3758 std.math.big.Limb,3781 std.math.big.Limb,
3759 std.math.big.int.calcTwosCompLimbCount(info.bits),3782 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -3766,31 +3789,30 @@ pub const Value = extern union {...@@ -3766,31 +3789,30 @@ pub const Value = extern union {
37663789
3767 /// operands must be (vectors of) integers; handles undefined scalars.3790 /// operands must be (vectors of) integers; handles undefined scalars.
3768 pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3791 pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3769 const target = mod.getTarget();3792 if (ty.zigTypeTag(mod) == .Vector) {
3770 if (ty.zigTypeTag() == .Vector) {
3771 const result_data = try allocator.alloc(Value, ty.vectorLen());3793 const result_data = try allocator.alloc(Value, ty.vectorLen());
3772 for (result_data, 0..) |*scalar, i| {3794 for (result_data, 0..) |*scalar, i| {
3773 var lhs_buf: Value.ElemValueBuffer = undefined;3795 var lhs_buf: Value.ElemValueBuffer = undefined;
3774 var rhs_buf: Value.ElemValueBuffer = undefined;3796 var rhs_buf: Value.ElemValueBuffer = undefined;
3775 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3797 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3776 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);3798 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);
3778 }3800 }
3779 return Value.Tag.aggregate.create(allocator, result_data);3801 return Value.Tag.aggregate.create(allocator, result_data);
3780 }3802 }
3781 return bitwiseAndScalar(lhs, rhs, allocator, target);3803 return bitwiseAndScalar(lhs, rhs, allocator, mod);
3782 }3804 }
37833805
3784 /// operands must be integers; handles undefined.3806 /// 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 {
3786 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3808 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
37873809
3788 // TODO is this a performance issue? maybe we should try the operation without3810 // TODO is this a performance issue? maybe we should try the operation without
3789 // resorting to BigInt first.3811 // resorting to BigInt first.
3790 var lhs_space: Value.BigIntSpace = undefined;3812 var lhs_space: Value.BigIntSpace = undefined;
3791 var rhs_space: Value.BigIntSpace = undefined;3813 var rhs_space: Value.BigIntSpace = undefined;
3792 const lhs_bigint = lhs.toBigInt(&lhs_space, target);3814 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3793 const rhs_bigint = rhs.toBigInt(&rhs_space, target);3815 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
3794 const limbs = try arena.alloc(3816 const limbs = try arena.alloc(
3795 std.math.big.Limb,3817 std.math.big.Limb,
3796 // + 1 for negatives3818 // + 1 for negatives
...@@ -3803,14 +3825,14 @@ pub const Value = extern union {...@@ -3803,14 +3825,14 @@ pub const Value = extern union {
38033825
3804 /// operands must be (vectors of) integers; handles undefined scalars.3826 /// operands must be (vectors of) integers; handles undefined scalars.
3805 pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {3827 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) {
3807 const result_data = try arena.alloc(Value, ty.vectorLen());3829 const result_data = try arena.alloc(Value, ty.vectorLen());
3808 for (result_data, 0..) |*scalar, i| {3830 for (result_data, 0..) |*scalar, i| {
3809 var lhs_buf: Value.ElemValueBuffer = undefined;3831 var lhs_buf: Value.ElemValueBuffer = undefined;
3810 var rhs_buf: Value.ElemValueBuffer = undefined;3832 var rhs_buf: Value.ElemValueBuffer = undefined;
3811 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3833 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3812 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);3834 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);
3814 }3836 }
3815 return Value.Tag.aggregate.create(arena, result_data);3837 return Value.Tag.aggregate.create(arena, result_data);
3816 }3838 }
...@@ -3823,41 +3845,40 @@ pub const Value = extern union {...@@ -3823,41 +3845,40 @@ pub const Value = extern union {
38233845
3824 const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod);3846 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))
3827 try Value.Tag.int_i64.create(arena, -1)3849 try Value.Tag.int_i64.create(arena, -1)
3828 else3850 else
3829 try ty.maxInt(arena, mod.getTarget());3851 try ty.maxInt(arena, mod);
38303852
3831 return bitwiseXor(anded, all_ones, ty, arena, mod);3853 return bitwiseXor(anded, all_ones, ty, arena, mod);
3832 }3854 }
38333855
3834 /// operands must be (vectors of) integers; handles undefined scalars.3856 /// operands must be (vectors of) integers; handles undefined scalars.
3835 pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3857 pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3836 const target = mod.getTarget();3858 if (ty.zigTypeTag(mod) == .Vector) {
3837 if (ty.zigTypeTag() == .Vector) {
3838 const result_data = try allocator.alloc(Value, ty.vectorLen());3859 const result_data = try allocator.alloc(Value, ty.vectorLen());
3839 for (result_data, 0..) |*scalar, i| {3860 for (result_data, 0..) |*scalar, i| {
3840 var lhs_buf: Value.ElemValueBuffer = undefined;3861 var lhs_buf: Value.ElemValueBuffer = undefined;
3841 var rhs_buf: Value.ElemValueBuffer = undefined;3862 var rhs_buf: Value.ElemValueBuffer = undefined;
3842 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3863 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3843 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);3864 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);
3845 }3866 }
3846 return Value.Tag.aggregate.create(allocator, result_data);3867 return Value.Tag.aggregate.create(allocator, result_data);
3847 }3868 }
3848 return bitwiseOrScalar(lhs, rhs, allocator, target);3869 return bitwiseOrScalar(lhs, rhs, allocator, mod);
3849 }3870 }
38503871
3851 /// operands must be integers; handles undefined.3872 /// 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 {
3853 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3874 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
38543875
3855 // TODO is this a performance issue? maybe we should try the operation without3876 // TODO is this a performance issue? maybe we should try the operation without
3856 // resorting to BigInt first.3877 // resorting to BigInt first.
3857 var lhs_space: Value.BigIntSpace = undefined;3878 var lhs_space: Value.BigIntSpace = undefined;
3858 var rhs_space: Value.BigIntSpace = undefined;3879 var rhs_space: Value.BigIntSpace = undefined;
3859 const lhs_bigint = lhs.toBigInt(&lhs_space, target);3880 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3860 const rhs_bigint = rhs.toBigInt(&rhs_space, target);3881 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
3861 const limbs = try arena.alloc(3882 const limbs = try arena.alloc(
3862 std.math.big.Limb,3883 std.math.big.Limb,
3863 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),3884 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
...@@ -3869,31 +3890,30 @@ pub const Value = extern union {...@@ -3869,31 +3890,30 @@ pub const Value = extern union {
38693890
3870 /// operands must be (vectors of) integers; handles undefined scalars.3891 /// operands must be (vectors of) integers; handles undefined scalars.
3871 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3892 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3872 const target = mod.getTarget();3893 if (ty.zigTypeTag(mod) == .Vector) {
3873 if (ty.zigTypeTag() == .Vector) {
3874 const result_data = try allocator.alloc(Value, ty.vectorLen());3894 const result_data = try allocator.alloc(Value, ty.vectorLen());
3875 for (result_data, 0..) |*scalar, i| {3895 for (result_data, 0..) |*scalar, i| {
3876 var lhs_buf: Value.ElemValueBuffer = undefined;3896 var lhs_buf: Value.ElemValueBuffer = undefined;
3877 var rhs_buf: Value.ElemValueBuffer = undefined;3897 var rhs_buf: Value.ElemValueBuffer = undefined;
3878 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3898 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3879 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);3899 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);
3881 }3901 }
3882 return Value.Tag.aggregate.create(allocator, result_data);3902 return Value.Tag.aggregate.create(allocator, result_data);
3883 }3903 }
3884 return bitwiseXorScalar(lhs, rhs, allocator, target);3904 return bitwiseXorScalar(lhs, rhs, allocator, mod);
3885 }3905 }
38863906
3887 /// operands must be integers; handles undefined.3907 /// 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 {
3889 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3909 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
38903910
3891 // TODO is this a performance issue? maybe we should try the operation without3911 // TODO is this a performance issue? maybe we should try the operation without
3892 // resorting to BigInt first.3912 // resorting to BigInt first.
3893 var lhs_space: Value.BigIntSpace = undefined;3913 var lhs_space: Value.BigIntSpace = undefined;
3894 var rhs_space: Value.BigIntSpace = undefined;3914 var rhs_space: Value.BigIntSpace = undefined;
3895 const lhs_bigint = lhs.toBigInt(&lhs_space, target);3915 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3896 const rhs_bigint = rhs.toBigInt(&rhs_space, target);3916 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
3897 const limbs = try arena.alloc(3917 const limbs = try arena.alloc(
3898 std.math.big.Limb,3918 std.math.big.Limb,
3899 // + 1 for negatives3919 // + 1 for negatives
...@@ -3905,28 +3925,27 @@ pub const Value = extern union {...@@ -3905,28 +3925,27 @@ pub const Value = extern union {
3905 }3925 }
39063926
3907 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3927 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3908 const target = mod.getTarget();3928 if (ty.zigTypeTag(mod) == .Vector) {
3909 if (ty.zigTypeTag() == .Vector) {
3910 const result_data = try allocator.alloc(Value, ty.vectorLen());3929 const result_data = try allocator.alloc(Value, ty.vectorLen());
3911 for (result_data, 0..) |*scalar, i| {3930 for (result_data, 0..) |*scalar, i| {
3912 var lhs_buf: Value.ElemValueBuffer = undefined;3931 var lhs_buf: Value.ElemValueBuffer = undefined;
3913 var rhs_buf: Value.ElemValueBuffer = undefined;3932 var rhs_buf: Value.ElemValueBuffer = undefined;
3914 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3933 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3915 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);3934 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);
3917 }3936 }
3918 return Value.Tag.aggregate.create(allocator, result_data);3937 return Value.Tag.aggregate.create(allocator, result_data);
3919 }3938 }
3920 return intDivScalar(lhs, rhs, allocator, target);3939 return intDivScalar(lhs, rhs, allocator, mod);
3921 }3940 }
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 {
3924 // TODO is this a performance issue? maybe we should try the operation without3943 // TODO is this a performance issue? maybe we should try the operation without
3925 // resorting to BigInt first.3944 // resorting to BigInt first.
3926 var lhs_space: Value.BigIntSpace = undefined;3945 var lhs_space: Value.BigIntSpace = undefined;
3927 var rhs_space: Value.BigIntSpace = undefined;3946 var rhs_space: Value.BigIntSpace = undefined;
3928 const lhs_bigint = lhs.toBigInt(&lhs_space, target);3947 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3929 const rhs_bigint = rhs.toBigInt(&rhs_space, target);3948 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
3930 const limbs_q = try allocator.alloc(3949 const limbs_q = try allocator.alloc(
3931 std.math.big.Limb,3950 std.math.big.Limb,
3932 lhs_bigint.limbs.len,3951 lhs_bigint.limbs.len,
...@@ -3946,28 +3965,27 @@ pub const Value = extern union {...@@ -3946,28 +3965,27 @@ pub const Value = extern union {
3946 }3965 }
39473966
3948 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3967 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3949 const target = mod.getTarget();3968 if (ty.zigTypeTag(mod) == .Vector) {
3950 if (ty.zigTypeTag() == .Vector) {
3951 const result_data = try allocator.alloc(Value, ty.vectorLen());3969 const result_data = try allocator.alloc(Value, ty.vectorLen());
3952 for (result_data, 0..) |*scalar, i| {3970 for (result_data, 0..) |*scalar, i| {
3953 var lhs_buf: Value.ElemValueBuffer = undefined;3971 var lhs_buf: Value.ElemValueBuffer = undefined;
3954 var rhs_buf: Value.ElemValueBuffer = undefined;3972 var rhs_buf: Value.ElemValueBuffer = undefined;
3955 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3973 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3956 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);3974 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);
3958 }3976 }
3959 return Value.Tag.aggregate.create(allocator, result_data);3977 return Value.Tag.aggregate.create(allocator, result_data);
3960 }3978 }
3961 return intDivFloorScalar(lhs, rhs, allocator, target);3979 return intDivFloorScalar(lhs, rhs, allocator, mod);
3962 }3980 }
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 {
3965 // TODO is this a performance issue? maybe we should try the operation without3983 // TODO is this a performance issue? maybe we should try the operation without
3966 // resorting to BigInt first.3984 // resorting to BigInt first.
3967 var lhs_space: Value.BigIntSpace = undefined;3985 var lhs_space: Value.BigIntSpace = undefined;
3968 var rhs_space: Value.BigIntSpace = undefined;3986 var rhs_space: Value.BigIntSpace = undefined;
3969 const lhs_bigint = lhs.toBigInt(&lhs_space, target);3987 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3970 const rhs_bigint = rhs.toBigInt(&rhs_space, target);3988 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
3971 const limbs_q = try allocator.alloc(3989 const limbs_q = try allocator.alloc(
3972 std.math.big.Limb,3990 std.math.big.Limb,
3973 lhs_bigint.limbs.len,3991 lhs_bigint.limbs.len,
...@@ -3987,28 +4005,27 @@ pub const Value = extern union {...@@ -3987,28 +4005,27 @@ pub const Value = extern union {
3987 }4005 }
39884006
3989 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {4007 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3990 const target = mod.getTarget();4008 if (ty.zigTypeTag(mod) == .Vector) {
3991 if (ty.zigTypeTag() == .Vector) {
3992 const result_data = try allocator.alloc(Value, ty.vectorLen());4009 const result_data = try allocator.alloc(Value, ty.vectorLen());
3993 for (result_data, 0..) |*scalar, i| {4010 for (result_data, 0..) |*scalar, i| {
3994 var lhs_buf: Value.ElemValueBuffer = undefined;4011 var lhs_buf: Value.ElemValueBuffer = undefined;
3995 var rhs_buf: Value.ElemValueBuffer = undefined;4012 var rhs_buf: Value.ElemValueBuffer = undefined;
3996 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4013 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3997 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4014 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);
3999 }4016 }
4000 return Value.Tag.aggregate.create(allocator, result_data);4017 return Value.Tag.aggregate.create(allocator, result_data);
4001 }4018 }
4002 return intModScalar(lhs, rhs, allocator, target);4019 return intModScalar(lhs, rhs, allocator, mod);
4003 }4020 }
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 {
4006 // TODO is this a performance issue? maybe we should try the operation without4023 // TODO is this a performance issue? maybe we should try the operation without
4007 // resorting to BigInt first.4024 // resorting to BigInt first.
4008 var lhs_space: Value.BigIntSpace = undefined;4025 var lhs_space: Value.BigIntSpace = undefined;
4009 var rhs_space: Value.BigIntSpace = undefined;4026 var rhs_space: Value.BigIntSpace = undefined;
4010 const lhs_bigint = lhs.toBigInt(&lhs_space, target);4027 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
4011 const rhs_bigint = rhs.toBigInt(&rhs_space, target);4028 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
4012 const limbs_q = try allocator.alloc(4029 const limbs_q = try allocator.alloc(
4013 std.math.big.Limb,4030 std.math.big.Limb,
4014 lhs_bigint.limbs.len,4031 lhs_bigint.limbs.len,
...@@ -4064,14 +4081,14 @@ pub const Value = extern union {...@@ -4064,14 +4081,14 @@ pub const Value = extern union {
40644081
4065 pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4082 pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4066 const target = mod.getTarget();4083 const target = mod.getTarget();
4067 if (float_type.zigTypeTag() == .Vector) {4084 if (float_type.zigTypeTag(mod) == .Vector) {
4068 const result_data = try arena.alloc(Value, float_type.vectorLen());4085 const result_data = try arena.alloc(Value, float_type.vectorLen());
4069 for (result_data, 0..) |*scalar, i| {4086 for (result_data, 0..) |*scalar, i| {
4070 var lhs_buf: Value.ElemValueBuffer = undefined;4087 var lhs_buf: Value.ElemValueBuffer = undefined;
4071 var rhs_buf: Value.ElemValueBuffer = undefined;4088 var rhs_buf: Value.ElemValueBuffer = undefined;
4072 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4089 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4073 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4090 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);
4075 }4092 }
4076 return Value.Tag.aggregate.create(arena, result_data);4093 return Value.Tag.aggregate.create(arena, result_data);
4077 }4094 }
...@@ -4111,14 +4128,14 @@ pub const Value = extern union {...@@ -4111,14 +4128,14 @@ pub const Value = extern union {
41114128
4112 pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4129 pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4113 const target = mod.getTarget();4130 const target = mod.getTarget();
4114 if (float_type.zigTypeTag() == .Vector) {4131 if (float_type.zigTypeTag(mod) == .Vector) {
4115 const result_data = try arena.alloc(Value, float_type.vectorLen());4132 const result_data = try arena.alloc(Value, float_type.vectorLen());
4116 for (result_data, 0..) |*scalar, i| {4133 for (result_data, 0..) |*scalar, i| {
4117 var lhs_buf: Value.ElemValueBuffer = undefined;4134 var lhs_buf: Value.ElemValueBuffer = undefined;
4118 var rhs_buf: Value.ElemValueBuffer = undefined;4135 var rhs_buf: Value.ElemValueBuffer = undefined;
4119 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4136 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4120 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4137 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);
4122 }4139 }
4123 return Value.Tag.aggregate.create(arena, result_data);4140 return Value.Tag.aggregate.create(arena, result_data);
4124 }4141 }
...@@ -4157,28 +4174,27 @@ pub const Value = extern union {...@@ -4157,28 +4174,27 @@ pub const Value = extern union {
4157 }4174 }
41584175
4159 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {4176 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
4160 const target = mod.getTarget();4177 if (ty.zigTypeTag(mod) == .Vector) {
4161 if (ty.zigTypeTag() == .Vector) {
4162 const result_data = try allocator.alloc(Value, ty.vectorLen());4178 const result_data = try allocator.alloc(Value, ty.vectorLen());
4163 for (result_data, 0..) |*scalar, i| {4179 for (result_data, 0..) |*scalar, i| {
4164 var lhs_buf: Value.ElemValueBuffer = undefined;4180 var lhs_buf: Value.ElemValueBuffer = undefined;
4165 var rhs_buf: Value.ElemValueBuffer = undefined;4181 var rhs_buf: Value.ElemValueBuffer = undefined;
4166 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4182 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4167 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4183 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);
4169 }4185 }
4170 return Value.Tag.aggregate.create(allocator, result_data);4186 return Value.Tag.aggregate.create(allocator, result_data);
4171 }4187 }
4172 return intMulScalar(lhs, rhs, allocator, target);4188 return intMulScalar(lhs, rhs, allocator, mod);
4173 }4189 }
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 {
4176 // TODO is this a performance issue? maybe we should try the operation without4192 // TODO is this a performance issue? maybe we should try the operation without
4177 // resorting to BigInt first.4193 // resorting to BigInt first.
4178 var lhs_space: Value.BigIntSpace = undefined;4194 var lhs_space: Value.BigIntSpace = undefined;
4179 var rhs_space: Value.BigIntSpace = undefined;4195 var rhs_space: Value.BigIntSpace = undefined;
4180 const lhs_bigint = lhs.toBigInt(&lhs_space, target);4196 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
4181 const rhs_bigint = rhs.toBigInt(&rhs_space, target);4197 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
4182 const limbs = try allocator.alloc(4198 const limbs = try allocator.alloc(
4183 std.math.big.Limb,4199 std.math.big.Limb,
4184 lhs_bigint.limbs.len + rhs_bigint.limbs.len,4200 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
...@@ -4194,17 +4210,16 @@ pub const Value = extern union {...@@ -4194,17 +4210,16 @@ pub const Value = extern union {
4194 }4210 }
41954211
4196 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, mod: *Module) !Value {4212 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, mod: *Module) !Value {
4197 const target = mod.getTarget();4213 if (ty.zigTypeTag(mod) == .Vector) {
4198 if (ty.zigTypeTag() == .Vector) {
4199 const result_data = try allocator.alloc(Value, ty.vectorLen());4214 const result_data = try allocator.alloc(Value, ty.vectorLen());
4200 for (result_data, 0..) |*scalar, i| {4215 for (result_data, 0..) |*scalar, i| {
4201 var buf: Value.ElemValueBuffer = undefined;4216 var buf: Value.ElemValueBuffer = undefined;
4202 const elem_val = val.elemValueBuffer(mod, i, &buf);4217 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);
4204 }4219 }
4205 return Value.Tag.aggregate.create(allocator, result_data);4220 return Value.Tag.aggregate.create(allocator, result_data);
4206 }4221 }
4207 return intTruncScalar(val, allocator, signedness, bits, target);4222 return intTruncScalar(val, allocator, signedness, bits, mod);
4208 }4223 }
42094224
4210 /// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.4225 /// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.
...@@ -4216,26 +4231,25 @@ pub const Value = extern union {...@@ -4216,26 +4231,25 @@ pub const Value = extern union {
4216 bits: Value,4231 bits: Value,
4217 mod: *Module,4232 mod: *Module,
4218 ) !Value {4233 ) !Value {
4219 const target = mod.getTarget();4234 if (ty.zigTypeTag(mod) == .Vector) {
4220 if (ty.zigTypeTag() == .Vector) {
4221 const result_data = try allocator.alloc(Value, ty.vectorLen());4235 const result_data = try allocator.alloc(Value, ty.vectorLen());
4222 for (result_data, 0..) |*scalar, i| {4236 for (result_data, 0..) |*scalar, i| {
4223 var buf: Value.ElemValueBuffer = undefined;4237 var buf: Value.ElemValueBuffer = undefined;
4224 const elem_val = val.elemValueBuffer(mod, i, &buf);4238 const elem_val = val.elemValueBuffer(mod, i, &buf);
4225 var bits_buf: Value.ElemValueBuffer = undefined;4239 var bits_buf: Value.ElemValueBuffer = undefined;
4226 const bits_elem = bits.elemValueBuffer(mod, i, &bits_buf);4240 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);
4228 }4242 }
4229 return Value.Tag.aggregate.create(allocator, result_data);4243 return Value.Tag.aggregate.create(allocator, result_data);
4230 }4244 }
4231 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt(target)), target);4245 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt(mod)), mod);
4232 }4246 }
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 {
4235 if (bits == 0) return Value.zero;4249 if (bits == 0) return Value.zero;
42364250
4237 var val_space: Value.BigIntSpace = undefined;4251 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
4240 const limbs = try allocator.alloc(4254 const limbs = try allocator.alloc(
4241 std.math.big.Limb,4255 std.math.big.Limb,
...@@ -4248,27 +4262,26 @@ pub const Value = extern union {...@@ -4248,27 +4262,26 @@ pub const Value = extern union {
4248 }4262 }
42494263
4250 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {4264 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
4251 const target = mod.getTarget();4265 if (ty.zigTypeTag(mod) == .Vector) {
4252 if (ty.zigTypeTag() == .Vector) {
4253 const result_data = try allocator.alloc(Value, ty.vectorLen());4266 const result_data = try allocator.alloc(Value, ty.vectorLen());
4254 for (result_data, 0..) |*scalar, i| {4267 for (result_data, 0..) |*scalar, i| {
4255 var lhs_buf: Value.ElemValueBuffer = undefined;4268 var lhs_buf: Value.ElemValueBuffer = undefined;
4256 var rhs_buf: Value.ElemValueBuffer = undefined;4269 var rhs_buf: Value.ElemValueBuffer = undefined;
4257 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4270 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4258 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4271 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);
4260 }4273 }
4261 return Value.Tag.aggregate.create(allocator, result_data);4274 return Value.Tag.aggregate.create(allocator, result_data);
4262 }4275 }
4263 return shlScalar(lhs, rhs, allocator, target);4276 return shlScalar(lhs, rhs, allocator, mod);
4264 }4277 }
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 {
4267 // TODO is this a performance issue? maybe we should try the operation without4280 // TODO is this a performance issue? maybe we should try the operation without
4268 // resorting to BigInt first.4281 // resorting to BigInt first.
4269 var lhs_space: Value.BigIntSpace = undefined;4282 var lhs_space: Value.BigIntSpace = undefined;
4270 const lhs_bigint = lhs.toBigInt(&lhs_space, target);4283 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
4271 const shift = @intCast(usize, rhs.toUnsignedInt(target));4284 const shift = @intCast(usize, rhs.toUnsignedInt(mod));
4272 const limbs = try allocator.alloc(4285 const limbs = try allocator.alloc(
4273 std.math.big.Limb,4286 std.math.big.Limb,
4274 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,4287 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
...@@ -4289,8 +4302,7 @@ pub const Value = extern union {...@@ -4289,8 +4302,7 @@ pub const Value = extern union {
4289 allocator: Allocator,4302 allocator: Allocator,
4290 mod: *Module,4303 mod: *Module,
4291 ) !OverflowArithmeticResult {4304 ) !OverflowArithmeticResult {
4292 const target = mod.getTarget();4305 if (ty.zigTypeTag(mod) == .Vector) {
4293 if (ty.zigTypeTag() == .Vector) {
4294 const overflowed_data = try allocator.alloc(Value, ty.vectorLen());4306 const overflowed_data = try allocator.alloc(Value, ty.vectorLen());
4295 const result_data = try allocator.alloc(Value, ty.vectorLen());4307 const result_data = try allocator.alloc(Value, ty.vectorLen());
4296 for (result_data, 0..) |*scalar, i| {4308 for (result_data, 0..) |*scalar, i| {
...@@ -4298,7 +4310,7 @@ pub const Value = extern union {...@@ -4298,7 +4310,7 @@ pub const Value = extern union {
4298 var rhs_buf: Value.ElemValueBuffer = undefined;4310 var rhs_buf: Value.ElemValueBuffer = undefined;
4299 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4311 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4300 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4312 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);
4302 overflowed_data[i] = of_math_result.overflow_bit;4314 overflowed_data[i] = of_math_result.overflow_bit;
4303 scalar.* = of_math_result.wrapped_result;4315 scalar.* = of_math_result.wrapped_result;
4304 }4316 }
...@@ -4307,7 +4319,7 @@ pub const Value = extern union {...@@ -4307,7 +4319,7 @@ pub const Value = extern union {
4307 .wrapped_result = try Value.Tag.aggregate.create(allocator, result_data),4319 .wrapped_result = try Value.Tag.aggregate.create(allocator, result_data),
4308 };4320 };
4309 }4321 }
4310 return shlWithOverflowScalar(lhs, rhs, ty, allocator, target);4322 return shlWithOverflowScalar(lhs, rhs, ty, allocator, mod);
4311 }4323 }
43124324
4313 pub fn shlWithOverflowScalar(4325 pub fn shlWithOverflowScalar(
...@@ -4315,12 +4327,12 @@ pub const Value = extern union {...@@ -4315,12 +4327,12 @@ pub const Value = extern union {
4315 rhs: Value,4327 rhs: Value,
4316 ty: Type,4328 ty: Type,
4317 allocator: Allocator,4329 allocator: Allocator,
4318 target: Target,4330 mod: *Module,
4319 ) !OverflowArithmeticResult {4331 ) !OverflowArithmeticResult {
4320 const info = ty.intInfo(target);4332 const info = ty.intInfo(mod);
4321 var lhs_space: Value.BigIntSpace = undefined;4333 var lhs_space: Value.BigIntSpace = undefined;
4322 const lhs_bigint = lhs.toBigInt(&lhs_space, target);4334 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
4323 const shift = @intCast(usize, rhs.toUnsignedInt(target));4335 const shift = @intCast(usize, rhs.toUnsignedInt(mod));
4324 const limbs = try allocator.alloc(4336 const limbs = try allocator.alloc(
4325 std.math.big.Limb,4337 std.math.big.Limb,
4326 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,4338 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
...@@ -4348,19 +4360,18 @@ pub const Value = extern union {...@@ -4348,19 +4360,18 @@ pub const Value = extern union {
4348 arena: Allocator,4360 arena: Allocator,
4349 mod: *Module,4361 mod: *Module,
4350 ) !Value {4362 ) !Value {
4351 const target = mod.getTarget();4363 if (ty.zigTypeTag(mod) == .Vector) {
4352 if (ty.zigTypeTag() == .Vector) {
4353 const result_data = try arena.alloc(Value, ty.vectorLen());4364 const result_data = try arena.alloc(Value, ty.vectorLen());
4354 for (result_data, 0..) |*scalar, i| {4365 for (result_data, 0..) |*scalar, i| {
4355 var lhs_buf: Value.ElemValueBuffer = undefined;4366 var lhs_buf: Value.ElemValueBuffer = undefined;
4356 var rhs_buf: Value.ElemValueBuffer = undefined;4367 var rhs_buf: Value.ElemValueBuffer = undefined;
4357 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4368 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4358 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4369 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);
4360 }4371 }
4361 return Value.Tag.aggregate.create(arena, result_data);4372 return Value.Tag.aggregate.create(arena, result_data);
4362 }4373 }
4363 return shlSatScalar(lhs, rhs, ty, arena, target);4374 return shlSatScalar(lhs, rhs, ty, arena, mod);
4364 }4375 }
43654376
4366 pub fn shlSatScalar(4377 pub fn shlSatScalar(
...@@ -4368,15 +4379,15 @@ pub const Value = extern union {...@@ -4368,15 +4379,15 @@ pub const Value = extern union {
4368 rhs: Value,4379 rhs: Value,
4369 ty: Type,4380 ty: Type,
4370 arena: Allocator,4381 arena: Allocator,
4371 target: Target,4382 mod: *Module,
4372 ) !Value {4383 ) !Value {
4373 // TODO is this a performance issue? maybe we should try the operation without4384 // TODO is this a performance issue? maybe we should try the operation without
4374 // resorting to BigInt first.4385 // resorting to BigInt first.
4375 const info = ty.intInfo(target);4386 const info = ty.intInfo(mod);
43764387
4377 var lhs_space: Value.BigIntSpace = undefined;4388 var lhs_space: Value.BigIntSpace = undefined;
4378 const lhs_bigint = lhs.toBigInt(&lhs_space, target);4389 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
4379 const shift = @intCast(usize, rhs.toUnsignedInt(target));4390 const shift = @intCast(usize, rhs.toUnsignedInt(mod));
4380 const limbs = try arena.alloc(4391 const limbs = try arena.alloc(
4381 std.math.big.Limb,4392 std.math.big.Limb,
4382 std.math.big.int.calcTwosCompLimbCount(info.bits) + 1,4393 std.math.big.int.calcTwosCompLimbCount(info.bits) + 1,
...@@ -4397,14 +4408,14 @@ pub const Value = extern union {...@@ -4397,14 +4408,14 @@ pub const Value = extern union {
4397 arena: Allocator,4408 arena: Allocator,
4398 mod: *Module,4409 mod: *Module,
4399 ) !Value {4410 ) !Value {
4400 if (ty.zigTypeTag() == .Vector) {4411 if (ty.zigTypeTag(mod) == .Vector) {
4401 const result_data = try arena.alloc(Value, ty.vectorLen());4412 const result_data = try arena.alloc(Value, ty.vectorLen());
4402 for (result_data, 0..) |*scalar, i| {4413 for (result_data, 0..) |*scalar, i| {
4403 var lhs_buf: Value.ElemValueBuffer = undefined;4414 var lhs_buf: Value.ElemValueBuffer = undefined;
4404 var rhs_buf: Value.ElemValueBuffer = undefined;4415 var rhs_buf: Value.ElemValueBuffer = undefined;
4405 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4416 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4406 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4417 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);
4408 }4419 }
4409 return Value.Tag.aggregate.create(arena, result_data);4420 return Value.Tag.aggregate.create(arena, result_data);
4410 }4421 }
...@@ -4419,33 +4430,32 @@ pub const Value = extern union {...@@ -4419,33 +4430,32 @@ pub const Value = extern union {
4419 mod: *Module,4430 mod: *Module,
4420 ) !Value {4431 ) !Value {
4421 const shifted = try lhs.shl(rhs, ty, arena, mod);4432 const shifted = try lhs.shl(rhs, ty, arena, mod);
4422 const int_info = ty.intInfo(mod.getTarget());4433 const int_info = ty.intInfo(mod);
4423 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, mod);4434 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, mod);
4424 return truncated;4435 return truncated;
4425 }4436 }
44264437
4427 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {4438 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
4428 const target = mod.getTarget();4439 if (ty.zigTypeTag(mod) == .Vector) {
4429 if (ty.zigTypeTag() == .Vector) {
4430 const result_data = try allocator.alloc(Value, ty.vectorLen());4440 const result_data = try allocator.alloc(Value, ty.vectorLen());
4431 for (result_data, 0..) |*scalar, i| {4441 for (result_data, 0..) |*scalar, i| {
4432 var lhs_buf: Value.ElemValueBuffer = undefined;4442 var lhs_buf: Value.ElemValueBuffer = undefined;
4433 var rhs_buf: Value.ElemValueBuffer = undefined;4443 var rhs_buf: Value.ElemValueBuffer = undefined;
4434 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4444 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4435 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4445 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);
4437 }4447 }
4438 return Value.Tag.aggregate.create(allocator, result_data);4448 return Value.Tag.aggregate.create(allocator, result_data);
4439 }4449 }
4440 return shrScalar(lhs, rhs, allocator, target);4450 return shrScalar(lhs, rhs, allocator, mod);
4441 }4451 }
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 {
4444 // TODO is this a performance issue? maybe we should try the operation without4454 // TODO is this a performance issue? maybe we should try the operation without
4445 // resorting to BigInt first.4455 // resorting to BigInt first.
4446 var lhs_space: Value.BigIntSpace = undefined;4456 var lhs_space: Value.BigIntSpace = undefined;
4447 const lhs_bigint = lhs.toBigInt(&lhs_space, target);4457 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
4448 const shift = @intCast(usize, rhs.toUnsignedInt(target));4458 const shift = @intCast(usize, rhs.toUnsignedInt(mod));
44494459
4450 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));4460 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));
4451 if (result_limbs == 0) {4461 if (result_limbs == 0) {
...@@ -4478,12 +4488,12 @@ pub const Value = extern union {...@@ -4478,12 +4488,12 @@ pub const Value = extern union {
4478 mod: *Module,4488 mod: *Module,
4479 ) !Value {4489 ) !Value {
4480 const target = mod.getTarget();4490 const target = mod.getTarget();
4481 if (float_type.zigTypeTag() == .Vector) {4491 if (float_type.zigTypeTag(mod) == .Vector) {
4482 const result_data = try arena.alloc(Value, float_type.vectorLen());4492 const result_data = try arena.alloc(Value, float_type.vectorLen());
4483 for (result_data, 0..) |*scalar, i| {4493 for (result_data, 0..) |*scalar, i| {
4484 var buf: Value.ElemValueBuffer = undefined;4494 var buf: Value.ElemValueBuffer = undefined;
4485 const elem_val = val.elemValueBuffer(mod, i, &buf);4495 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);
4487 }4497 }
4488 return Value.Tag.aggregate.create(arena, result_data);4498 return Value.Tag.aggregate.create(arena, result_data);
4489 }4499 }
...@@ -4514,14 +4524,14 @@ pub const Value = extern union {...@@ -4514,14 +4524,14 @@ pub const Value = extern union {
4514 mod: *Module,4524 mod: *Module,
4515 ) !Value {4525 ) !Value {
4516 const target = mod.getTarget();4526 const target = mod.getTarget();
4517 if (float_type.zigTypeTag() == .Vector) {4527 if (float_type.zigTypeTag(mod) == .Vector) {
4518 const result_data = try arena.alloc(Value, float_type.vectorLen());4528 const result_data = try arena.alloc(Value, float_type.vectorLen());
4519 for (result_data, 0..) |*scalar, i| {4529 for (result_data, 0..) |*scalar, i| {
4520 var lhs_buf: Value.ElemValueBuffer = undefined;4530 var lhs_buf: Value.ElemValueBuffer = undefined;
4521 var rhs_buf: Value.ElemValueBuffer = undefined;4531 var rhs_buf: Value.ElemValueBuffer = undefined;
4522 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4532 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4523 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4533 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);
4525 }4535 }
4526 return Value.Tag.aggregate.create(arena, result_data);4536 return Value.Tag.aggregate.create(arena, result_data);
4527 }4537 }
...@@ -4573,14 +4583,14 @@ pub const Value = extern union {...@@ -4573,14 +4583,14 @@ pub const Value = extern union {
4573 mod: *Module,4583 mod: *Module,
4574 ) !Value {4584 ) !Value {
4575 const target = mod.getTarget();4585 const target = mod.getTarget();
4576 if (float_type.zigTypeTag() == .Vector) {4586 if (float_type.zigTypeTag(mod) == .Vector) {
4577 const result_data = try arena.alloc(Value, float_type.vectorLen());4587 const result_data = try arena.alloc(Value, float_type.vectorLen());
4578 for (result_data, 0..) |*scalar, i| {4588 for (result_data, 0..) |*scalar, i| {
4579 var lhs_buf: Value.ElemValueBuffer = undefined;4589 var lhs_buf: Value.ElemValueBuffer = undefined;
4580 var rhs_buf: Value.ElemValueBuffer = undefined;4590 var rhs_buf: Value.ElemValueBuffer = undefined;
4581 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4591 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4582 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4592 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);
4584 }4594 }
4585 return Value.Tag.aggregate.create(arena, result_data);4595 return Value.Tag.aggregate.create(arena, result_data);
4586 }4596 }
...@@ -4632,14 +4642,14 @@ pub const Value = extern union {...@@ -4632,14 +4642,14 @@ pub const Value = extern union {
4632 mod: *Module,4642 mod: *Module,
4633 ) !Value {4643 ) !Value {
4634 const target = mod.getTarget();4644 const target = mod.getTarget();
4635 if (float_type.zigTypeTag() == .Vector) {4645 if (float_type.zigTypeTag(mod) == .Vector) {
4636 const result_data = try arena.alloc(Value, float_type.vectorLen());4646 const result_data = try arena.alloc(Value, float_type.vectorLen());
4637 for (result_data, 0..) |*scalar, i| {4647 for (result_data, 0..) |*scalar, i| {
4638 var lhs_buf: Value.ElemValueBuffer = undefined;4648 var lhs_buf: Value.ElemValueBuffer = undefined;
4639 var rhs_buf: Value.ElemValueBuffer = undefined;4649 var rhs_buf: Value.ElemValueBuffer = undefined;
4640 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4650 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4641 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4651 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);
4643 }4653 }
4644 return Value.Tag.aggregate.create(arena, result_data);4654 return Value.Tag.aggregate.create(arena, result_data);
4645 }4655 }
...@@ -4691,14 +4701,14 @@ pub const Value = extern union {...@@ -4691,14 +4701,14 @@ pub const Value = extern union {
4691 mod: *Module,4701 mod: *Module,
4692 ) !Value {4702 ) !Value {
4693 const target = mod.getTarget();4703 const target = mod.getTarget();
4694 if (float_type.zigTypeTag() == .Vector) {4704 if (float_type.zigTypeTag(mod) == .Vector) {
4695 const result_data = try arena.alloc(Value, float_type.vectorLen());4705 const result_data = try arena.alloc(Value, float_type.vectorLen());
4696 for (result_data, 0..) |*scalar, i| {4706 for (result_data, 0..) |*scalar, i| {
4697 var lhs_buf: Value.ElemValueBuffer = undefined;4707 var lhs_buf: Value.ElemValueBuffer = undefined;
4698 var rhs_buf: Value.ElemValueBuffer = undefined;4708 var rhs_buf: Value.ElemValueBuffer = undefined;
4699 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4709 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4700 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4710 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);
4702 }4712 }
4703 return Value.Tag.aggregate.create(arena, result_data);4713 return Value.Tag.aggregate.create(arena, result_data);
4704 }4714 }
...@@ -4744,12 +4754,12 @@ pub const Value = extern union {...@@ -4744,12 +4754,12 @@ pub const Value = extern union {
47444754
4745 pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4755 pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4746 const target = mod.getTarget();4756 const target = mod.getTarget();
4747 if (float_type.zigTypeTag() == .Vector) {4757 if (float_type.zigTypeTag(mod) == .Vector) {
4748 const result_data = try arena.alloc(Value, float_type.vectorLen());4758 const result_data = try arena.alloc(Value, float_type.vectorLen());
4749 for (result_data, 0..) |*scalar, i| {4759 for (result_data, 0..) |*scalar, i| {
4750 var buf: Value.ElemValueBuffer = undefined;4760 var buf: Value.ElemValueBuffer = undefined;
4751 const elem_val = val.elemValueBuffer(mod, i, &buf);4761 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);
4753 }4763 }
4754 return Value.Tag.aggregate.create(arena, result_data);4764 return Value.Tag.aggregate.create(arena, result_data);
4755 }4765 }
...@@ -4784,12 +4794,12 @@ pub const Value = extern union {...@@ -4784,12 +4794,12 @@ pub const Value = extern union {
47844794
4785 pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4795 pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4786 const target = mod.getTarget();4796 const target = mod.getTarget();
4787 if (float_type.zigTypeTag() == .Vector) {4797 if (float_type.zigTypeTag(mod) == .Vector) {
4788 const result_data = try arena.alloc(Value, float_type.vectorLen());4798 const result_data = try arena.alloc(Value, float_type.vectorLen());
4789 for (result_data, 0..) |*scalar, i| {4799 for (result_data, 0..) |*scalar, i| {
4790 var buf: Value.ElemValueBuffer = undefined;4800 var buf: Value.ElemValueBuffer = undefined;
4791 const elem_val = val.elemValueBuffer(mod, i, &buf);4801 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);
4793 }4803 }
4794 return Value.Tag.aggregate.create(arena, result_data);4804 return Value.Tag.aggregate.create(arena, result_data);
4795 }4805 }
...@@ -4824,12 +4834,12 @@ pub const Value = extern union {...@@ -4824,12 +4834,12 @@ pub const Value = extern union {
48244834
4825 pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4835 pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4826 const target = mod.getTarget();4836 const target = mod.getTarget();
4827 if (float_type.zigTypeTag() == .Vector) {4837 if (float_type.zigTypeTag(mod) == .Vector) {
4828 const result_data = try arena.alloc(Value, float_type.vectorLen());4838 const result_data = try arena.alloc(Value, float_type.vectorLen());
4829 for (result_data, 0..) |*scalar, i| {4839 for (result_data, 0..) |*scalar, i| {
4830 var buf: Value.ElemValueBuffer = undefined;4840 var buf: Value.ElemValueBuffer = undefined;
4831 const elem_val = val.elemValueBuffer(mod, i, &buf);4841 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);
4833 }4843 }
4834 return Value.Tag.aggregate.create(arena, result_data);4844 return Value.Tag.aggregate.create(arena, result_data);
4835 }4845 }
...@@ -4864,12 +4874,12 @@ pub const Value = extern union {...@@ -4864,12 +4874,12 @@ pub const Value = extern union {
48644874
4865 pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4875 pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4866 const target = mod.getTarget();4876 const target = mod.getTarget();
4867 if (float_type.zigTypeTag() == .Vector) {4877 if (float_type.zigTypeTag(mod) == .Vector) {
4868 const result_data = try arena.alloc(Value, float_type.vectorLen());4878 const result_data = try arena.alloc(Value, float_type.vectorLen());
4869 for (result_data, 0..) |*scalar, i| {4879 for (result_data, 0..) |*scalar, i| {
4870 var buf: Value.ElemValueBuffer = undefined;4880 var buf: Value.ElemValueBuffer = undefined;
4871 const elem_val = val.elemValueBuffer(mod, i, &buf);4881 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);
4873 }4883 }
4874 return Value.Tag.aggregate.create(arena, result_data);4884 return Value.Tag.aggregate.create(arena, result_data);
4875 }4885 }
...@@ -4904,12 +4914,12 @@ pub const Value = extern union {...@@ -4904,12 +4914,12 @@ pub const Value = extern union {
49044914
4905 pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4915 pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4906 const target = mod.getTarget();4916 const target = mod.getTarget();
4907 if (float_type.zigTypeTag() == .Vector) {4917 if (float_type.zigTypeTag(mod) == .Vector) {
4908 const result_data = try arena.alloc(Value, float_type.vectorLen());4918 const result_data = try arena.alloc(Value, float_type.vectorLen());
4909 for (result_data, 0..) |*scalar, i| {4919 for (result_data, 0..) |*scalar, i| {
4910 var buf: Value.ElemValueBuffer = undefined;4920 var buf: Value.ElemValueBuffer = undefined;
4911 const elem_val = val.elemValueBuffer(mod, i, &buf);4921 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);
4913 }4923 }
4914 return Value.Tag.aggregate.create(arena, result_data);4924 return Value.Tag.aggregate.create(arena, result_data);
4915 }4925 }
...@@ -4944,12 +4954,12 @@ pub const Value = extern union {...@@ -4944,12 +4954,12 @@ pub const Value = extern union {
49444954
4945 pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4955 pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4946 const target = mod.getTarget();4956 const target = mod.getTarget();
4947 if (float_type.zigTypeTag() == .Vector) {4957 if (float_type.zigTypeTag(mod) == .Vector) {
4948 const result_data = try arena.alloc(Value, float_type.vectorLen());4958 const result_data = try arena.alloc(Value, float_type.vectorLen());
4949 for (result_data, 0..) |*scalar, i| {4959 for (result_data, 0..) |*scalar, i| {
4950 var buf: Value.ElemValueBuffer = undefined;4960 var buf: Value.ElemValueBuffer = undefined;
4951 const elem_val = val.elemValueBuffer(mod, i, &buf);4961 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);
4953 }4963 }
4954 return Value.Tag.aggregate.create(arena, result_data);4964 return Value.Tag.aggregate.create(arena, result_data);
4955 }4965 }
...@@ -4984,12 +4994,12 @@ pub const Value = extern union {...@@ -4984,12 +4994,12 @@ pub const Value = extern union {
49844994
4985 pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4995 pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4986 const target = mod.getTarget();4996 const target = mod.getTarget();
4987 if (float_type.zigTypeTag() == .Vector) {4997 if (float_type.zigTypeTag(mod) == .Vector) {
4988 const result_data = try arena.alloc(Value, float_type.vectorLen());4998 const result_data = try arena.alloc(Value, float_type.vectorLen());
4989 for (result_data, 0..) |*scalar, i| {4999 for (result_data, 0..) |*scalar, i| {
4990 var buf: Value.ElemValueBuffer = undefined;5000 var buf: Value.ElemValueBuffer = undefined;
4991 const elem_val = val.elemValueBuffer(mod, i, &buf);5001 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);
4993 }5003 }
4994 return Value.Tag.aggregate.create(arena, result_data);5004 return Value.Tag.aggregate.create(arena, result_data);
4995 }5005 }
...@@ -5024,12 +5034,12 @@ pub const Value = extern union {...@@ -5024,12 +5034,12 @@ pub const Value = extern union {
50245034
5025 pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {5035 pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
5026 const target = mod.getTarget();5036 const target = mod.getTarget();
5027 if (float_type.zigTypeTag() == .Vector) {5037 if (float_type.zigTypeTag(mod) == .Vector) {
5028 const result_data = try arena.alloc(Value, float_type.vectorLen());5038 const result_data = try arena.alloc(Value, float_type.vectorLen());
5029 for (result_data, 0..) |*scalar, i| {5039 for (result_data, 0..) |*scalar, i| {
5030 var buf: Value.ElemValueBuffer = undefined;5040 var buf: Value.ElemValueBuffer = undefined;
5031 const elem_val = val.elemValueBuffer(mod, i, &buf);5041 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);
5033 }5043 }
5034 return Value.Tag.aggregate.create(arena, result_data);5044 return Value.Tag.aggregate.create(arena, result_data);
5035 }5045 }
...@@ -5064,12 +5074,12 @@ pub const Value = extern union {...@@ -5064,12 +5074,12 @@ pub const Value = extern union {
50645074
5065 pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {5075 pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
5066 const target = mod.getTarget();5076 const target = mod.getTarget();
5067 if (float_type.zigTypeTag() == .Vector) {5077 if (float_type.zigTypeTag(mod) == .Vector) {
5068 const result_data = try arena.alloc(Value, float_type.vectorLen());5078 const result_data = try arena.alloc(Value, float_type.vectorLen());
5069 for (result_data, 0..) |*scalar, i| {5079 for (result_data, 0..) |*scalar, i| {
5070 var buf: Value.ElemValueBuffer = undefined;5080 var buf: Value.ElemValueBuffer = undefined;
5071 const elem_val = val.elemValueBuffer(mod, i, &buf);5081 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);
5073 }5083 }
5074 return Value.Tag.aggregate.create(arena, result_data);5084 return Value.Tag.aggregate.create(arena, result_data);
5075 }5085 }
...@@ -5104,12 +5114,12 @@ pub const Value = extern union {...@@ -5104,12 +5114,12 @@ pub const Value = extern union {
51045114
5105 pub fn fabs(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {5115 pub fn fabs(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
5106 const target = mod.getTarget();5116 const target = mod.getTarget();
5107 if (float_type.zigTypeTag() == .Vector) {5117 if (float_type.zigTypeTag(mod) == .Vector) {
5108 const result_data = try arena.alloc(Value, float_type.vectorLen());5118 const result_data = try arena.alloc(Value, float_type.vectorLen());
5109 for (result_data, 0..) |*scalar, i| {5119 for (result_data, 0..) |*scalar, i| {
5110 var buf: Value.ElemValueBuffer = undefined;5120 var buf: Value.ElemValueBuffer = undefined;
5111 const elem_val = val.elemValueBuffer(mod, i, &buf);5121 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);
5113 }5123 }
5114 return Value.Tag.aggregate.create(arena, result_data);5124 return Value.Tag.aggregate.create(arena, result_data);
5115 }5125 }
...@@ -5144,12 +5154,12 @@ pub const Value = extern union {...@@ -5144,12 +5154,12 @@ pub const Value = extern union {
51445154
5145 pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {5155 pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
5146 const target = mod.getTarget();5156 const target = mod.getTarget();
5147 if (float_type.zigTypeTag() == .Vector) {5157 if (float_type.zigTypeTag(mod) == .Vector) {
5148 const result_data = try arena.alloc(Value, float_type.vectorLen());5158 const result_data = try arena.alloc(Value, float_type.vectorLen());
5149 for (result_data, 0..) |*scalar, i| {5159 for (result_data, 0..) |*scalar, i| {
5150 var buf: Value.ElemValueBuffer = undefined;5160 var buf: Value.ElemValueBuffer = undefined;
5151 const elem_val = val.elemValueBuffer(mod, i, &buf);5161 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);
5153 }5163 }
5154 return Value.Tag.aggregate.create(arena, result_data);5164 return Value.Tag.aggregate.create(arena, result_data);
5155 }5165 }
...@@ -5184,12 +5194,12 @@ pub const Value = extern union {...@@ -5184,12 +5194,12 @@ pub const Value = extern union {
51845194
5185 pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {5195 pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
5186 const target = mod.getTarget();5196 const target = mod.getTarget();
5187 if (float_type.zigTypeTag() == .Vector) {5197 if (float_type.zigTypeTag(mod) == .Vector) {
5188 const result_data = try arena.alloc(Value, float_type.vectorLen());5198 const result_data = try arena.alloc(Value, float_type.vectorLen());
5189 for (result_data, 0..) |*scalar, i| {5199 for (result_data, 0..) |*scalar, i| {
5190 var buf: Value.ElemValueBuffer = undefined;5200 var buf: Value.ElemValueBuffer = undefined;
5191 const elem_val = val.elemValueBuffer(mod, i, &buf);5201 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);
5193 }5203 }
5194 return Value.Tag.aggregate.create(arena, result_data);5204 return Value.Tag.aggregate.create(arena, result_data);
5195 }5205 }
...@@ -5224,12 +5234,12 @@ pub const Value = extern union {...@@ -5224,12 +5234,12 @@ pub const Value = extern union {
52245234
5225 pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {5235 pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
5226 const target = mod.getTarget();5236 const target = mod.getTarget();
5227 if (float_type.zigTypeTag() == .Vector) {5237 if (float_type.zigTypeTag(mod) == .Vector) {
5228 const result_data = try arena.alloc(Value, float_type.vectorLen());5238 const result_data = try arena.alloc(Value, float_type.vectorLen());
5229 for (result_data, 0..) |*scalar, i| {5239 for (result_data, 0..) |*scalar, i| {
5230 var buf: Value.ElemValueBuffer = undefined;5240 var buf: Value.ElemValueBuffer = undefined;
5231 const elem_val = val.elemValueBuffer(mod, i, &buf);5241 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);
5233 }5243 }
5234 return Value.Tag.aggregate.create(arena, result_data);5244 return Value.Tag.aggregate.create(arena, result_data);
5235 }5245 }
...@@ -5264,12 +5274,12 @@ pub const Value = extern union {...@@ -5264,12 +5274,12 @@ pub const Value = extern union {
52645274
5265 pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {5275 pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
5266 const target = mod.getTarget();5276 const target = mod.getTarget();
5267 if (float_type.zigTypeTag() == .Vector) {5277 if (float_type.zigTypeTag(mod) == .Vector) {
5268 const result_data = try arena.alloc(Value, float_type.vectorLen());5278 const result_data = try arena.alloc(Value, float_type.vectorLen());
5269 for (result_data, 0..) |*scalar, i| {5279 for (result_data, 0..) |*scalar, i| {
5270 var buf: Value.ElemValueBuffer = undefined;5280 var buf: Value.ElemValueBuffer = undefined;
5271 const elem_val = val.elemValueBuffer(mod, i, &buf);5281 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);
5273 }5283 }
5274 return Value.Tag.aggregate.create(arena, result_data);5284 return Value.Tag.aggregate.create(arena, result_data);
5275 }5285 }
...@@ -5311,7 +5321,7 @@ pub const Value = extern union {...@@ -5311,7 +5321,7 @@ pub const Value = extern union {
5311 mod: *Module,5321 mod: *Module,
5312 ) !Value {5322 ) !Value {
5313 const target = mod.getTarget();5323 const target = mod.getTarget();
5314 if (float_type.zigTypeTag() == .Vector) {5324 if (float_type.zigTypeTag(mod) == .Vector) {
5315 const result_data = try arena.alloc(Value, float_type.vectorLen());5325 const result_data = try arena.alloc(Value, float_type.vectorLen());
5316 for (result_data, 0..) |*scalar, i| {5326 for (result_data, 0..) |*scalar, i| {
5317 var mulend1_buf: Value.ElemValueBuffer = undefined;5327 var mulend1_buf: Value.ElemValueBuffer = undefined;
...@@ -5321,7 +5331,7 @@ pub const Value = extern union {...@@ -5321,7 +5331,7 @@ pub const Value = extern union {
5321 var addend_buf: Value.ElemValueBuffer = undefined;5331 var addend_buf: Value.ElemValueBuffer = undefined;
5322 const addend_elem = addend.elemValueBuffer(mod, i, &addend_buf);5332 const addend_elem = addend.elemValueBuffer(mod, i, &addend_buf);
5323 scalar.* = try mulAddScalar(5333 scalar.* = try mulAddScalar(
5324 float_type.scalarType(),5334 float_type.scalarType(mod),
5325 mulend1_elem,5335 mulend1_elem,
5326 mulend2_elem,5336 mulend2_elem,
5327 addend_elem,5337 addend_elem,
...@@ -5380,8 +5390,7 @@ pub const Value = extern union {...@@ -5380,8 +5390,7 @@ pub const Value = extern union {
5380 /// If the value is represented in-memory as a series of bytes that all5390 /// If the value is represented in-memory as a series of bytes that all
5381 /// have the same value, return that byte value, otherwise null.5391 /// have the same value, return that byte value, otherwise null.
5382 pub fn hasRepeatedByteRepr(val: Value, ty: Type, mod: *Module, value_buffer: *Payload.U64) !?Value {5392 pub fn hasRepeatedByteRepr(val: Value, ty: Type, mod: *Module, value_buffer: *Payload.U64) !?Value {
5383 const target = mod.getTarget();5393 const abi_size = std.math.cast(usize, ty.abiSize(mod)) orelse return null;
5384 const abi_size = std.math.cast(usize, ty.abiSize(target)) orelse return null;
5385 assert(abi_size >= 1);5394 assert(abi_size >= 1);
5386 const byte_buffer = try mod.gpa.alloc(u8, abi_size);5395 const byte_buffer = try mod.gpa.alloc(u8, abi_size);
5387 defer mod.gpa.free(byte_buffer);5396 defer mod.gpa.free(byte_buffer);
...@@ -5549,16 +5558,6 @@ pub const Value = extern union {...@@ -5549,16 +5558,6 @@ pub const Value = extern union {
5549 data: Type,5558 data: Type,
5550 };5559 };
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
5562 pub const Float_16 = struct {5561 pub const Float_16 = struct {
5563 pub const base_tag = Tag.float_16;5562 pub const base_tag = Tag.float_16;
55645563
...@@ -5659,7 +5658,10 @@ pub const Value = extern union {...@@ -5659,7 +5658,10 @@ pub const Value = extern union {
56595658
5660 pub const zero = initTag(.zero);5659 pub const zero = initTag(.zero);
5661 pub const one = initTag(.one);5660 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 };
5663 pub const undef = initTag(.undef);5665 pub const undef = initTag(.undef);
5664 pub const @"void" = initTag(.void_value);5666 pub const @"void" = initTag(.void_value);
5665 pub const @"null" = initTag(.null_value);5667 pub const @"null" = initTag(.null_value);