authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-07-26 03:09:55-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-07-26 17:31:04-04:00
log69abc945e45af3f447f9ee07d426d1ec40cf3f15
tree457a9ee76f91135cf7a71192a09c317a63c05961
parent1274254c48ee105623c513dfc01451fee2912c5b

aarch64: implement some safety checks

Closes #24553

124 files changed, 1078 insertions(+), 365 deletions(-)

src/Compilation.zig+6-4
......@@ -1816,10 +1816,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
18161816 if (options.skip_linker_dependencies) break :s .none;
18171817 const want = options.want_compiler_rt orelse is_exe_or_dyn_lib;
18181818 if (!want) break :s .none;
1819 if (have_zcu) {
1819 if (have_zcu and target_util.canBuildLibCompilerRt(target, use_llvm, build_options.have_llvm and use_llvm)) {
18201820 if (output_mode == .Obj) break :s .zcu;
1821 if (target.ofmt == .coff and target_util.zigBackend(target, use_llvm) == .stage2_x86_64)
1822 break :s if (is_exe_or_dyn_lib) .dyn_lib else .zcu;
1821 if (switch (target_util.zigBackend(target, use_llvm)) {
1822 else => false,
1823 .stage2_aarch64, .stage2_x86_64 => target.ofmt == .coff,
1824 }) break :s if (is_exe_or_dyn_lib) .dyn_lib else .zcu;
18231825 }
18241826 if (is_exe_or_dyn_lib) break :s .lib;
18251827 break :s .obj;
......@@ -1854,7 +1856,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
18541856 const want_ubsan_rt = options.want_ubsan_rt orelse (can_build_ubsan_rt and any_sanitize_c == .full and is_exe_or_dyn_lib);
18551857 if (!want_ubsan_rt) break :s .none;
18561858 if (options.skip_linker_dependencies) break :s .none;
1857 if (have_zcu) break :s .zcu;
1859 if (have_zcu and target_util.canBuildLibUbsanRt(target, use_llvm, build_options.have_llvm and use_llvm)) break :s .zcu;
18581860 if (is_exe_or_dyn_lib) break :s .lib;
18591861 break :s .obj;
18601862 };
src/arch/x86_64/CodeGen.zig+3-3
......@@ -168141,7 +168141,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
168141168141 .unused,
168142168142 .unused,
168143168143 },
168144 .dst_temps = .{ .{ .cc = .b }, .unused },
168144 .dst_temps = .{ .{ .cc = .be }, .unused },
168145168145 .clobbers = .{ .eflags = true },
168146168146 .each = .{ .once = &.{
168147168147 .{ ._, ._, .lea, .tmp1p, .lea(.tmp0), ._, ._ },
......@@ -168165,7 +168165,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
168165168165 .unused,
168166168166 .unused,
168167168167 },
168168 .dst_temps = .{ .{ .cc = .b }, .unused },
168168 .dst_temps = .{ .{ .cc = .be }, .unused },
168169168169 .clobbers = .{ .eflags = true },
168170168170 .each = .{ .once = &.{
168171168171 .{ ._, ._, .lea, .tmp1p, .lea(.tmp0), ._, ._ },
......@@ -168189,7 +168189,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
168189168189 .unused,
168190168190 .unused,
168191168191 },
168192 .dst_temps = .{ .{ .cc = .b }, .unused },
168192 .dst_temps = .{ .{ .cc = .be }, .unused },
168193168193 .clobbers = .{ .eflags = true },
168194168194 .each = .{ .once = &.{
168195168195 .{ ._, ._, .lea, .tmp1p, .lea(.tmp0), ._, ._ },
src/arch/x86_64/Emit.zig+6-5
......@@ -168,11 +168,12 @@ pub fn emitMir(emit: *Emit) Error!void {
168168 else if (emit.bin_file.cast(.macho)) |macho_file|
169169 macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|
170170 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
171 else if (emit.bin_file.cast(.coff)) |coff_file| sym_index: {
172 const atom = coff_file.getOrCreateAtomForLazySymbol(emit.pt, lazy_sym) catch |err|
173 return emit.fail("{s} creating lazy symbol", .{@errorName(err)});
174 break :sym_index coff_file.getAtom(atom).getSymbolIndex().?;
175 } else if (emit.bin_file.cast(.plan9)) |p9_file|
171 else if (emit.bin_file.cast(.coff)) |coff_file|
172 if (coff_file.getOrCreateAtomForLazySymbol(emit.pt, lazy_sym)) |atom|
173 coff_file.getAtom(atom).getSymbolIndex().?
174 else |err|
175 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
176 else if (emit.bin_file.cast(.plan9)) |p9_file|
176177 p9_file.getOrCreateAtomForLazySymbol(emit.pt, lazy_sym) catch |err|
177178 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
178179 else
src/codegen/aarch64.zig+5-2
......@@ -47,6 +47,7 @@ pub fn generate(
4747 .literals = .empty,
4848 .nav_relocs = .empty,
4949 .uav_relocs = .empty,
50 .lazy_relocs = .empty,
5051 .global_relocs = .empty,
5152 .literal_relocs = .empty,
5253
......@@ -101,8 +102,8 @@ pub fn generate(
101102 };
102103 switch (passed_vi.parent(&isel)) {
103104 .unallocated => if (!mod.strip) {
104 var part_it = arg_vi.parts(&isel);
105 const first_passed_part_vi = part_it.next() orelse passed_vi;
105 var part_it = passed_vi.parts(&isel);
106 const first_passed_part_vi = part_it.next().?;
106107 const hint_ra = first_passed_part_vi.hint(&isel).?;
107108 passed_vi.setParent(&isel, .{ .stack_slot = if (hint_ra.isVector())
108109 isel.va_list.__vr_top.withOffset(@as(i8, -16) *
......@@ -167,6 +168,7 @@ pub fn generate(
167168 .literals = &.{},
168169 .nav_relocs = &.{},
169170 .uav_relocs = &.{},
171 .lazy_relocs = &.{},
170172 .global_relocs = &.{},
171173 .literal_relocs = &.{},
172174 };
......@@ -174,6 +176,7 @@ pub fn generate(
174176 mir.literals = try isel.literals.toOwnedSlice(gpa);
175177 mir.nav_relocs = try isel.nav_relocs.toOwnedSlice(gpa);
176178 mir.uav_relocs = try isel.uav_relocs.toOwnedSlice(gpa);
179 mir.lazy_relocs = try isel.lazy_relocs.toOwnedSlice(gpa);
177180 mir.global_relocs = try isel.global_relocs.toOwnedSlice(gpa);
178181 mir.literal_relocs = try isel.literal_relocs.toOwnedSlice(gpa);
179182 return mir;
src/codegen/aarch64/Assemble.zig+26-6
......@@ -6,14 +6,19 @@ pub const Operand = union(enum) {
66};
77
88pub fn nextInstruction(as: *Assemble) !?Instruction {
9 @setEvalBranchQuota(37_000);
9 @setEvalBranchQuota(42_000);
1010 comptime var ct_token_buf: [token_buf_len]u8 = undefined;
1111 var token_buf: [token_buf_len]u8 = undefined;
1212 const original_source = while (true) {
1313 const original_source = as.source;
1414 const source_token = try as.nextToken(&token_buf, .{});
15 if (source_token.len == 0) return null;
16 if (source_token[0] != '\n') break original_source;
15 switch (source_token.len) {
16 0 => return null,
17 else => switch (source_token[0]) {
18 else => break original_source,
19 '\n', ';' => {},
20 },
21 }
1722 };
1823 log.debug(
1924 \\.
......@@ -52,7 +57,13 @@ pub fn nextInstruction(as: *Assemble) !?Instruction {
5257 std.zig.fmtString(source_token),
5358 });
5459 if (pattern_token.len == 0) {
55 if (source_token.len > 0 and source_token[0] != '\n') break :next_pattern;
60 switch (source_token.len) {
61 0 => {},
62 else => switch (source_token[0]) {
63 else => break :next_pattern,
64 '\n', ';' => {},
65 },
66 }
5667 const encode = @field(Instruction, @tagName(instruction.encode[0]));
5768 const Encode = @TypeOf(encode);
5869 var args: std.meta.ArgsTuple(Encode) = undefined;
......@@ -65,7 +76,7 @@ pub fn nextInstruction(as: *Assemble) !?Instruction {
6576 const symbol = &@field(symbols, symbol_name);
6677 symbol.* = zonCast(SymbolSpec, @field(instruction.symbols, symbol_name), .{}).parse(source_token) orelse break :next_pattern;
6778 log.debug("{s} = {any}", .{ symbol_name, symbol.* });
68 } else if (!std.ascii.eqlIgnoreCase(pattern_token, source_token)) break :next_pattern;
79 } else if (!toUpperEqlAssertUpper(source_token, pattern_token)) break :next_pattern;
6980 }
7081 }
7182 log.debug("'{s}' not matched...", .{instruction.pattern});
......@@ -125,6 +136,15 @@ fn zonCast(comptime Result: type, zon_value: anytype, symbols: anytype) Result {
125136 }
126137}
127138
139fn toUpperEqlAssertUpper(lhs: []const u8, rhs: []const u8) bool {
140 if (lhs.len != rhs.len) return false;
141 for (lhs, rhs) |l, r| {
142 assert(!std.ascii.isLower(r));
143 if (std.ascii.toUpper(l) != r) return false;
144 }
145 return true;
146}
147
128148const token_buf_len = "v31.b[15]".len;
129149fn nextToken(as: *Assemble, buf: *[token_buf_len]u8, comptime opts: struct {
130150 operands: bool = false,
......@@ -134,7 +154,7 @@ fn nextToken(as: *Assemble, buf: *[token_buf_len]u8, comptime opts: struct {
134154 while (true) c: switch (as.source[0]) {
135155 0 => return as.source[0..0],
136156 '\t', '\n' + 1...'\r', ' ' => as.source = as.source[1..],
137 '\n', '!', '#', ',', '[', ']' => {
157 '\n', '!', '#', ',', ';', '[', ']' => {
138158 defer as.source = as.source[1..];
139159 return as.source[0..1];
140160 },
src/codegen/aarch64/Mir.zig+106-33
......@@ -4,6 +4,7 @@ epilogue: []const Instruction,
44literals: []const u32,
55nav_relocs: []const Reloc.Nav,
66uav_relocs: []const Reloc.Uav,
7lazy_relocs: []const Reloc.Lazy,
78global_relocs: []const Reloc.Global,
89literal_relocs: []const Reloc.Literal,
910
......@@ -21,8 +22,13 @@ pub const Reloc = struct {
2122 reloc: Reloc,
2223 };
2324
25 pub const Lazy = struct {
26 symbol: link.File.LazySymbol,
27 reloc: Reloc,
28 };
29
2430 pub const Global = struct {
25 global: [*:0]const u8,
31 name: [*:0]const u8,
2632 reloc: Reloc,
2733 };
2834
......@@ -38,6 +44,7 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
3844 gpa.free(mir.literals);
3945 gpa.free(mir.nav_relocs);
4046 gpa.free(mir.uav_relocs);
47 gpa.free(mir.lazy_relocs);
4148 gpa.free(mir.global_relocs);
4249 gpa.free(mir.literal_relocs);
4350 mir.* = undefined;
......@@ -119,16 +126,37 @@ pub fn emit(
119126 body_end - Instruction.size * (1 + uav_reloc.reloc.label),
120127 uav_reloc.reloc.addend,
121128 );
129 for (mir.lazy_relocs) |lazy_reloc| try emitReloc(
130 lf,
131 zcu,
132 func.owner_nav,
133 if (lf.cast(.elf)) |ef|
134 ef.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(ef, pt, lazy_reloc.symbol) catch |err|
135 return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
136 else if (lf.cast(.macho)) |mf|
137 mf.getZigObject().?.getOrCreateMetadataForLazySymbol(mf, pt, lazy_reloc.symbol) catch |err|
138 return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
139 else if (lf.cast(.coff)) |cf|
140 if (cf.getOrCreateAtomForLazySymbol(pt, lazy_reloc.symbol)) |atom|
141 cf.getAtom(atom).getSymbolIndex().?
142 else |err|
143 return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
144 else
145 return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
146 mir.body[lazy_reloc.reloc.label],
147 body_end - Instruction.size * (1 + lazy_reloc.reloc.label),
148 lazy_reloc.reloc.addend,
149 );
122150 for (mir.global_relocs) |global_reloc| try emitReloc(
123151 lf,
124152 zcu,
125153 func.owner_nav,
126154 if (lf.cast(.elf)) |ef|
127 try ef.getGlobalSymbol(std.mem.span(global_reloc.global), null)
155 try ef.getGlobalSymbol(std.mem.span(global_reloc.name), null)
128156 else if (lf.cast(.macho)) |mf|
129 try mf.getGlobalSymbol(std.mem.span(global_reloc.global), null)
157 try mf.getGlobalSymbol(std.mem.span(global_reloc.name), null)
130158 else if (lf.cast(.coff)) |cf|
131 try cf.getGlobalSymbol(std.mem.span(global_reloc.global), "compiler_rt")
159 try cf.getGlobalSymbol(std.mem.span(global_reloc.name), "compiler_rt")
132160 else
133161 return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
134162 mir.body[global_reloc.reloc.label],
......@@ -172,35 +200,6 @@ fn emitReloc(
172200 const gpa = zcu.gpa;
173201 switch (instruction.decode()) {
174202 else => unreachable,
175 .branch_exception_generating_system => |decoded| if (lf.cast(.elf)) |ef| {
176 const zo = ef.zigObjectPtr().?;
177 const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
178 const r_type: std.elf.R_AARCH64 = switch (decoded.decode().unconditional_branch_immediate.group.op) {
179 .b => .JUMP26,
180 .bl => .CALL26,
181 };
182 try atom.addReloc(gpa, .{
183 .r_offset = offset,
184 .r_info = @as(u64, sym_index) << 32 | @intFromEnum(r_type),
185 .r_addend = @bitCast(addend),
186 }, zo);
187 } else if (lf.cast(.macho)) |mf| {
188 const zo = mf.getZigObject().?;
189 const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?;
190 try atom.addReloc(mf, .{
191 .tag = .@"extern",
192 .offset = offset,
193 .target = sym_index,
194 .addend = @bitCast(addend),
195 .type = .branch,
196 .meta = .{
197 .pcrel = true,
198 .has_subtractor = false,
199 .length = 2,
200 .symbolnum = @intCast(sym_index),
201 },
202 });
203 },
204203 .data_processing_immediate => |decoded| if (lf.cast(.elf)) |ef| {
205204 const zo = ef.zigObjectPtr().?;
206205 const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
......@@ -259,6 +258,80 @@ fn emitReloc(
259258 },
260259 }
261260 },
261 .branch_exception_generating_system => |decoded| if (lf.cast(.elf)) |ef| {
262 const zo = ef.zigObjectPtr().?;
263 const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
264 const r_type: std.elf.R_AARCH64 = switch (decoded.decode().unconditional_branch_immediate.group.op) {
265 .b => .JUMP26,
266 .bl => .CALL26,
267 };
268 try atom.addReloc(gpa, .{
269 .r_offset = offset,
270 .r_info = @as(u64, sym_index) << 32 | @intFromEnum(r_type),
271 .r_addend = @bitCast(addend),
272 }, zo);
273 } else if (lf.cast(.macho)) |mf| {
274 const zo = mf.getZigObject().?;
275 const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?;
276 try atom.addReloc(mf, .{
277 .tag = .@"extern",
278 .offset = offset,
279 .target = sym_index,
280 .addend = @bitCast(addend),
281 .type = .branch,
282 .meta = .{
283 .pcrel = true,
284 .has_subtractor = false,
285 .length = 2,
286 .symbolnum = @intCast(sym_index),
287 },
288 });
289 },
290 .load_store => |decoded| if (lf.cast(.elf)) |ef| {
291 const zo = ef.zigObjectPtr().?;
292 const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
293 const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {
294 .integer => |integer| switch (integer.decode()) {
295 .unallocated, .prfm => unreachable,
296 .strb, .ldrb, .ldrsb => .LDST8_ABS_LO12_NC,
297 .strh, .ldrh, .ldrsh => .LDST16_ABS_LO12_NC,
298 .ldrsw => .LDST32_ABS_LO12_NC,
299 inline .str, .ldr => |encoded| switch (encoded.sf) {
300 .word => .LDST32_ABS_LO12_NC,
301 .doubleword => .LDST64_ABS_LO12_NC,
302 },
303 },
304 .vector => |vector| switch (vector.group.opc1.decode(vector.group.size)) {
305 .byte => .LDST8_ABS_LO12_NC,
306 .half => .LDST16_ABS_LO12_NC,
307 .single => .LDST32_ABS_LO12_NC,
308 .double => .LDST64_ABS_LO12_NC,
309 .quad => .LDST128_ABS_LO12_NC,
310 .scalable, .predicate => unreachable,
311 },
312 };
313 try atom.addReloc(gpa, .{
314 .r_offset = offset,
315 .r_info = @as(u64, sym_index) << 32 | @intFromEnum(r_type),
316 .r_addend = @bitCast(addend),
317 }, zo);
318 } else if (lf.cast(.macho)) |mf| {
319 const zo = mf.getZigObject().?;
320 const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?;
321 try atom.addReloc(mf, .{
322 .tag = .@"extern",
323 .offset = offset,
324 .target = sym_index,
325 .addend = @bitCast(addend),
326 .type = .pageoff,
327 .meta = .{
328 .pcrel = false,
329 .has_subtractor = false,
330 .length = 2,
331 .symbolnum = @intCast(sym_index),
332 },
333 });
334 },
262335 }
263336}
264337
src/codegen/aarch64/Select.zig+618-188
......@@ -22,6 +22,7 @@ instructions: std.ArrayListUnmanaged(codegen.aarch64.encoding.Instruction),
2222literals: std.ArrayListUnmanaged(u32),
2323nav_relocs: std.ArrayListUnmanaged(codegen.aarch64.Mir.Reloc.Nav),
2424uav_relocs: std.ArrayListUnmanaged(codegen.aarch64.Mir.Reloc.Uav),
25lazy_relocs: std.ArrayListUnmanaged(codegen.aarch64.Mir.Reloc.Lazy),
2526global_relocs: std.ArrayListUnmanaged(codegen.aarch64.Mir.Reloc.Global),
2627literal_relocs: std.ArrayListUnmanaged(codegen.aarch64.Mir.Reloc.Literal),
2728
......@@ -50,11 +51,11 @@ pub const Block = struct {
5051 std.math.maxInt(@typeInfo(Air.Inst.Index).@"enum".tag_type),
5152 );
5253
53 fn branch(block: *const Block, isel: *Select) !void {
54 if (isel.instructions.items.len > block.target_label) {
55 try isel.emit(.b(@intCast((isel.instructions.items.len + 1 - block.target_label) << 2)));
54 fn branch(target_block: *const Block, isel: *Select) !void {
55 if (isel.instructions.items.len > target_block.target_label) {
56 try isel.emit(.b(@intCast((isel.instructions.items.len + 1 - target_block.target_label) << 2)));
5657 }
57 try isel.merge(&block.live_registers, .{});
58 try isel.merge(&target_block.live_registers, .{});
5859 }
5960};
6061
......@@ -84,12 +85,12 @@ pub const Loop = struct {
8485
8586 pub const empty_list: u32 = std.math.maxInt(u32);
8687
87 fn branch(loop: *Loop, isel: *Select) !void {
88 fn branch(target_loop: *Loop, isel: *Select) !void {
8889 try isel.instructions.ensureUnusedCapacity(isel.pt.zcu.gpa, 1);
89 const repeat_list_tail = loop.repeat_list;
90 loop.repeat_list = @intCast(isel.instructions.items.len);
90 const repeat_list_tail = target_loop.repeat_list;
91 target_loop.repeat_list = @intCast(isel.instructions.items.len);
9192 isel.instructions.appendAssumeCapacity(@bitCast(repeat_list_tail));
92 try isel.merge(&loop.live_registers, .{});
93 try isel.merge(&target_loop.live_registers, .{});
9394 }
9495};
9596
......@@ -108,6 +109,7 @@ pub fn deinit(isel: *Select) void {
108109 isel.literals.deinit(gpa);
109110 isel.nav_relocs.deinit(gpa);
110111 isel.uav_relocs.deinit(gpa);
112 isel.lazy_relocs.deinit(gpa);
111113 isel.global_relocs.deinit(gpa);
112114 isel.literal_relocs.deinit(gpa);
113115
......@@ -864,7 +866,7 @@ pub fn finishAnalysis(isel: *Select) !void {
864866 }
865867}
866868
867pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
869pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, CodegenFail }!void {
868870 const zcu = isel.pt.zcu;
869871 const ip = &zcu.intern_pool;
870872 const gpa = zcu.gpa;
......@@ -946,7 +948,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
946948 }
947949 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
948950 },
949 .add, .add_optimized, .add_wrap, .sub, .sub_optimized, .sub_wrap => |air_tag| {
951 .add, .add_safe, .add_optimized, .add_wrap, .sub, .sub_safe, .sub_optimized, .sub_wrap => |air_tag| {
950952 if (isel.live_values.fetchRemove(air.inst_index)) |res_vi| unused: {
951953 defer res_vi.value.deref(isel);
952954
......@@ -954,13 +956,16 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
954956 const ty = isel.air.typeOf(bin_op.lhs, ip);
955957 if (!ty.isRuntimeFloat()) try res_vi.value.addOrSubtract(isel, ty, try isel.use(bin_op.lhs), switch (air_tag) {
956958 else => unreachable,
957 .add, .add_wrap => .add,
958 .sub, .sub_wrap => .sub,
959 }, try isel.use(bin_op.rhs), .{ .wrap = switch (air_tag) {
960 else => unreachable,
961 .add, .sub => false,
962 .add_wrap, .sub_wrap => true,
963 } }) else switch (ty.floatBits(isel.target)) {
959 .add, .add_safe, .add_wrap => .add,
960 .sub, .sub_safe, .sub_wrap => .sub,
961 }, try isel.use(bin_op.rhs), .{
962 .overflow = switch (air_tag) {
963 else => unreachable,
964 .add, .sub => .@"unreachable",
965 .add_safe, .sub_safe => .{ .panic = .integer_overflow },
966 .add_wrap, .sub_wrap => .wrap,
967 },
968 }) else switch (ty.floatBits(isel.target)) {
964969 else => unreachable,
965970 16, 32, 64 => |bits| {
966971 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
......@@ -1021,7 +1026,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
10211026
10221027 try call.prepareCallee(isel);
10231028 try isel.global_relocs.append(gpa, .{
1024 .global = switch (air_tag) {
1029 .name = switch (air_tag) {
10251030 else => unreachable,
10261031 .add, .add_optimized => switch (bits) {
10271032 else => unreachable,
......@@ -1336,7 +1341,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
13361341
13371342 try call.prepareCallee(isel);
13381343 try isel.global_relocs.append(gpa, .{
1339 .global = switch (bits) {
1344 .name = switch (bits) {
13401345 else => unreachable,
13411346 16 => "__mulhf3",
13421347 32 => "__mulsf3",
......@@ -1379,6 +1384,143 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
13791384 }
13801385 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
13811386 },
1387 .mul_safe => |air_tag| {
1388 if (isel.live_values.fetchRemove(air.inst_index)) |res_vi| unused: {
1389 defer res_vi.value.deref(isel);
1390
1391 const bin_op = air.data(air.inst_index).bin_op;
1392 const ty = isel.air.typeOf(bin_op.lhs, ip);
1393 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
1394 const int_info = ty.intInfo(zcu);
1395 switch (int_info.signedness) {
1396 .signed => switch (int_info.bits) {
1397 0 => unreachable,
1398 1 => {
1399 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
1400 const lhs_vi = try isel.use(bin_op.lhs);
1401 const rhs_vi = try isel.use(bin_op.rhs);
1402 const lhs_mat = try lhs_vi.matReg(isel);
1403 const rhs_mat = try rhs_vi.matReg(isel);
1404 try isel.emit(.orr(res_ra.w(), lhs_mat.ra.w(), .{ .register = rhs_mat.ra.w() }));
1405 const skip_label = isel.instructions.items.len;
1406 try isel.emitPanic(.integer_overflow);
1407 try isel.emit(.@"b."(
1408 .invert(.ne),
1409 @intCast((isel.instructions.items.len + 1 - skip_label) << 2),
1410 ));
1411 try isel.emit(.ands(.wzr, lhs_mat.ra.w(), .{ .register = rhs_mat.ra.w() }));
1412 try rhs_mat.finish(isel);
1413 try lhs_mat.finish(isel);
1414 },
1415 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
1416 },
1417 .unsigned => switch (int_info.bits) {
1418 0 => unreachable,
1419 1 => {
1420 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
1421 const lhs_vi = try isel.use(bin_op.lhs);
1422 const rhs_vi = try isel.use(bin_op.rhs);
1423 const lhs_mat = try lhs_vi.matReg(isel);
1424 const rhs_mat = try rhs_vi.matReg(isel);
1425 try isel.emit(.@"and"(res_ra.w(), lhs_mat.ra.w(), .{ .register = rhs_mat.ra.w() }));
1426 try rhs_mat.finish(isel);
1427 try lhs_mat.finish(isel);
1428 },
1429 2...16 => |bits| {
1430 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
1431 const lhs_vi = try isel.use(bin_op.lhs);
1432 const rhs_vi = try isel.use(bin_op.rhs);
1433 const lhs_mat = try lhs_vi.matReg(isel);
1434 const rhs_mat = try rhs_vi.matReg(isel);
1435 const skip_label = isel.instructions.items.len;
1436 try isel.emitPanic(.integer_overflow);
1437 try isel.emit(.@"b."(
1438 .eq,
1439 @intCast((isel.instructions.items.len + 1 - skip_label) << 2),
1440 ));
1441 try isel.emit(.ands(.wzr, res_ra.w(), .{ .immediate = .{
1442 .N = .word,
1443 .immr = @intCast(32 - bits),
1444 .imms = @intCast(32 - bits - 1),
1445 } }));
1446 try isel.emit(.madd(res_ra.w(), lhs_mat.ra.w(), rhs_mat.ra.w(), .wzr));
1447 try rhs_mat.finish(isel);
1448 try lhs_mat.finish(isel);
1449 },
1450 17...32 => |bits| {
1451 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
1452 const lhs_vi = try isel.use(bin_op.lhs);
1453 const rhs_vi = try isel.use(bin_op.rhs);
1454 const lhs_mat = try lhs_vi.matReg(isel);
1455 const rhs_mat = try rhs_vi.matReg(isel);
1456 const skip_label = isel.instructions.items.len;
1457 try isel.emitPanic(.integer_overflow);
1458 try isel.emit(.@"b."(
1459 .eq,
1460 @intCast((isel.instructions.items.len + 1 - skip_label) << 2),
1461 ));
1462 try isel.emit(.ands(.xzr, res_ra.x(), .{ .immediate = .{
1463 .N = .doubleword,
1464 .immr = @intCast(64 - bits),
1465 .imms = @intCast(64 - bits - 1),
1466 } }));
1467 try isel.emit(.umaddl(res_ra.x(), lhs_mat.ra.w(), rhs_mat.ra.w(), .xzr));
1468 try rhs_mat.finish(isel);
1469 try lhs_mat.finish(isel);
1470 },
1471 33...63 => |bits| {
1472 const lo64_ra = try res_vi.value.defReg(isel) orelse break :unused;
1473 const lhs_vi = try isel.use(bin_op.lhs);
1474 const rhs_vi = try isel.use(bin_op.rhs);
1475 const lhs_mat = try lhs_vi.matReg(isel);
1476 const rhs_mat = try rhs_vi.matReg(isel);
1477 const hi64_ra = hi64_ra: {
1478 const lo64_lock = isel.tryLockReg(lo64_ra);
1479 defer lo64_lock.unlock(isel);
1480 break :hi64_ra try isel.allocIntReg();
1481 };
1482 defer isel.freeReg(hi64_ra);
1483 const skip_label = isel.instructions.items.len;
1484 try isel.emitPanic(.integer_overflow);
1485 try isel.emit(.cbz(
1486 hi64_ra.x(),
1487 @intCast((isel.instructions.items.len + 1 - skip_label) << 2),
1488 ));
1489 try isel.emit(.orr(hi64_ra.x(), hi64_ra.x(), .{ .shifted_register = .{
1490 .register = lo64_ra.x(),
1491 .shift = .{ .lsr = @intCast(bits) },
1492 } }));
1493 try isel.emit(.madd(lo64_ra.x(), lhs_mat.ra.x(), rhs_mat.ra.x(), .xzr));
1494 try isel.emit(.umulh(hi64_ra.x(), lhs_mat.ra.x(), rhs_mat.ra.x()));
1495 try rhs_mat.finish(isel);
1496 try lhs_mat.finish(isel);
1497 },
1498 64 => {
1499 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
1500 const lhs_vi = try isel.use(bin_op.lhs);
1501 const rhs_vi = try isel.use(bin_op.rhs);
1502 const lhs_mat = try lhs_vi.matReg(isel);
1503 const rhs_mat = try rhs_vi.matReg(isel);
1504 try isel.emit(.madd(res_ra.x(), lhs_mat.ra.x(), rhs_mat.ra.x(), .xzr));
1505 const hi64_ra = try isel.allocIntReg();
1506 defer isel.freeReg(hi64_ra);
1507 const skip_label = isel.instructions.items.len;
1508 try isel.emitPanic(.integer_overflow);
1509 try isel.emit(.cbz(
1510 hi64_ra.x(),
1511 @intCast((isel.instructions.items.len + 1 - skip_label) << 2),
1512 ));
1513 try isel.emit(.umulh(hi64_ra.x(), lhs_mat.ra.x(), rhs_mat.ra.x()));
1514 try rhs_mat.finish(isel);
1515 try lhs_mat.finish(isel);
1516 },
1517 65...128 => return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
1518 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
1519 },
1520 }
1521 }
1522 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
1523 },
13821524 .mul_sat => |air_tag| {
13831525 if (isel.live_values.fetchRemove(air.inst_index)) |res_vi| unused: {
13841526 defer res_vi.value.deref(isel);
......@@ -1674,7 +1816,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
16741816
16751817 try call.prepareCallee(isel);
16761818 try isel.global_relocs.append(gpa, .{
1677 .global = switch (bits) {
1819 .name = switch (bits) {
16781820 else => unreachable,
16791821 16 => "__divhf3",
16801822 32 => "__divsf3",
......@@ -1813,7 +1955,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
18131955
18141956 try call.prepareCallee(isel);
18151957 try isel.global_relocs.append(gpa, .{
1816 .global = switch (int_info.signedness) {
1958 .name = switch (int_info.signedness) {
18171959 .signed => "__divti3",
18181960 .unsigned => "__udivti3",
18191961 },
......@@ -1917,7 +2059,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
19172059 else => unreachable,
19182060 .div_trunc, .div_trunc_optimized => {
19192061 try isel.global_relocs.append(gpa, .{
1920 .global = switch (bits) {
2062 .name = switch (bits) {
19212063 else => unreachable,
19222064 16 => "__trunch",
19232065 32 => "truncf",
......@@ -1931,7 +2073,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
19312073 },
19322074 .div_floor, .div_floor_optimized => {
19332075 try isel.global_relocs.append(gpa, .{
1934 .global = switch (bits) {
2076 .name = switch (bits) {
19352077 else => unreachable,
19362078 16 => "__floorh",
19372079 32 => "floorf",
......@@ -1946,7 +2088,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
19462088 .div_exact, .div_exact_optimized => {},
19472089 }
19482090 try isel.global_relocs.append(gpa, .{
1949 .global = switch (bits) {
2091 .name = switch (bits) {
19502092 else => unreachable,
19512093 16 => "__divhf3",
19522094 32 => "__divsf3",
......@@ -2046,7 +2188,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
20462188
20472189 try call.prepareCallee(isel);
20482190 try isel.global_relocs.append(gpa, .{
2049 .global = switch (bits) {
2191 .name = switch (bits) {
20502192 else => unreachable,
20512193 16 => "__fmodh",
20522194 32 => "fmodf",
......@@ -2212,7 +2354,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
22122354
22132355 try call.prepareCallee(isel);
22142356 try isel.global_relocs.append(gpa, .{
2215 .global = switch (air_tag) {
2357 .name = switch (air_tag) {
22162358 else => unreachable,
22172359 .max => switch (bits) {
22182360 else => unreachable,
......@@ -2284,7 +2426,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
22842426 else => unreachable,
22852427 .add_with_overflow => .add,
22862428 .sub_with_overflow => .sub,
2287 }, rhs_vi, .{ .wrap = true, .overflow_ra = try overflow_vi.?.defReg(isel) orelse .zr });
2429 }, rhs_vi, .{
2430 .overflow = if (try overflow_vi.?.defReg(isel)) |overflow_ra| .{ .ra = overflow_ra } else .wrap,
2431 });
22882432 }
22892433 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
22902434 },
......@@ -3092,7 +3236,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
30923236
30933237 try call.prepareCallee(isel);
30943238 try isel.global_relocs.append(gpa, .{
3095 .global = "memcpy",
3239 .name = "memcpy",
30963240 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
30973241 });
30983242 try isel.emit(.bl(0));
......@@ -3119,7 +3263,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
31193263
31203264 try call.prepareCallee(isel);
31213265 try isel.global_relocs.append(gpa, .{
3122 .global = "memcpy",
3266 .name = "memcpy",
31233267 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
31243268 });
31253269 try isel.emit(.bl(0));
......@@ -3139,19 +3283,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
31393283 .block => {
31403284 const ty_pl = air.data(air.inst_index).ty_pl;
31413285 const extra = isel.air.extraData(Air.Block, ty_pl.payload);
3142
3143 if (ty_pl.ty != .noreturn_type) {
3144 isel.blocks.putAssumeCapacityNoClobber(air.inst_index, .{
3145 .live_registers = isel.live_registers,
3146 .target_label = @intCast(isel.instructions.items.len),
3147 });
3148 }
3149 try isel.body(@ptrCast(isel.air.extra.items[extra.end..][0..extra.data.body_len]));
3150 if (ty_pl.ty != .noreturn_type) {
3151 const block_entry = isel.blocks.pop().?;
3152 assert(block_entry.key == air.inst_index);
3153 if (isel.live_values.fetchRemove(air.inst_index)) |result_vi| result_vi.value.deref(isel);
3154 }
3286 try isel.block(air.inst_index, ty_pl.ty.toType(), @ptrCast(
3287 isel.air.extra.items[extra.end..][0..extra.data.body_len],
3288 ));
31553289 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
31563290 },
31573291 .loop => {
......@@ -3175,11 +3309,11 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
31753309 }
31763310
31773311 // IT'S DOM TIME!!!
3178 for (isel.blocks.values(), 0..) |*block, dom_index| {
3312 for (isel.blocks.values(), 0..) |*dom_block, dom_index| {
31793313 if (@as(u1, @truncate(isel.dom.items[
31803314 loop.dom + dom_index / @bitSizeOf(DomInt)
31813315 ] >> @truncate(dom_index))) == 0) continue;
3182 var live_reg_it = block.live_registers.iterator();
3316 var live_reg_it = dom_block.live_registers.iterator();
31833317 while (live_reg_it.next()) |live_reg_entry| switch (live_reg_entry.value.*) {
31843318 _ => |live_vi| try live_vi.mat(isel),
31853319 .allocating => unreachable,
......@@ -3211,8 +3345,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
32113345 },
32123346 .br => {
32133347 const br = air.data(air.inst_index).br;
3214 const block = isel.blocks.getPtr(br.block_inst).?;
3215 try block.branch(isel);
3348 try isel.blocks.getPtr(br.block_inst).?.branch(isel);
32163349 if (isel.live_values.get(br.block_inst)) |dst_vi| try dst_vi.move(isel, br.operand);
32173350 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
32183351 },
......@@ -3224,6 +3357,22 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
32243357 try isel.emit(.brk(0xf000));
32253358 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
32263359 },
3360 .ret_addr => {
3361 if (isel.live_values.fetchRemove(air.inst_index)) |addr_vi| unused: {
3362 defer addr_vi.value.deref(isel);
3363 const addr_ra = try addr_vi.value.defReg(isel) orelse break :unused;
3364 try isel.emit(.ldr(addr_ra.x(), .{ .unsigned_offset = .{ .base = .fp, .offset = 8 } }));
3365 }
3366 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
3367 },
3368 .frame_addr => {
3369 if (isel.live_values.fetchRemove(air.inst_index)) |addr_vi| unused: {
3370 defer addr_vi.value.deref(isel);
3371 const addr_ra = try addr_vi.value.defReg(isel) orelse break :unused;
3372 try isel.emit(.orr(addr_ra.x(), .xzr, .{ .register = .fp }));
3373 }
3374 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
3375 },
32273376 .call => {
32283377 const pl_op = air.data(air.inst_index).pl_op;
32293378 const extra = isel.air.extraData(Air.Call, pl_op.payload);
......@@ -3312,7 +3461,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
33123461 var param_part_it = passed_vi.parts(isel);
33133462 var arg_part_it = arg_vi.parts(isel);
33143463 if (arg_part_it.only()) |_| {
3315 try isel.values.ensureUnusedCapacity(isel.pt.zcu.gpa, param_part_it.remaining);
3464 try isel.values.ensureUnusedCapacity(gpa, param_part_it.remaining);
33163465 arg_vi.setParts(isel, param_part_it.remaining);
33173466 while (param_part_it.next()) |param_part_vi| _ = arg_vi.addPart(
33183467 isel,
......@@ -3659,7 +3808,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
36593808
36603809 try call.prepareCallee(isel);
36613810 try isel.global_relocs.append(gpa, .{
3662 .global = switch (air_tag) {
3811 .name = switch (air_tag) {
36633812 else => unreachable,
36643813 .sqrt => switch (bits) {
36653814 else => unreachable,
......@@ -3751,7 +3900,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
37513900
37523901 try call.prepareCallee(isel);
37533902 try isel.global_relocs.append(gpa, .{
3754 .global = switch (air_tag) {
3903 .name = switch (air_tag) {
37553904 else => unreachable,
37563905 .sin => switch (bits) {
37573906 else => unreachable,
......@@ -4239,7 +4388,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
42394388
42404389 try call.prepareCallee(isel);
42414390 try isel.global_relocs.append(gpa, .{
4242 .global = switch (bits) {
4391 .name = switch (bits) {
42434392 else => unreachable,
42444393 16 => "__cmphf2",
42454394 32 => "__cmpsf2",
......@@ -4629,6 +4778,14 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
46294778 try isel.emit(.nop());
46304779 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
46314780 },
4781 .dbg_inline_block => {
4782 const ty_pl = air.data(air.inst_index).ty_pl;
4783 const extra = isel.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
4784 try isel.block(air.inst_index, ty_pl.ty.toType(), @ptrCast(
4785 isel.air.extra.items[extra.end..][0..extra.data.body_len],
4786 ));
4787 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
4788 },
46324789 .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => {
46334790 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
46344791 },
......@@ -4724,7 +4881,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
47244881
47254882 try call.prepareCallee(isel);
47264883 try isel.global_relocs.append(gpa, .{
4727 .global = "memcpy",
4884 .name = "memcpy",
47284885 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
47294886 });
47304887 try isel.emit(.bl(0));
......@@ -4816,10 +4973,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
48164973 const ptr_ty = isel.air.typeOf(bin_op.lhs, ip);
48174974 const ptr_info = ptr_ty.ptrInfo(zcu);
48184975 if (ptr_info.packed_offset.host_size > 0) return isel.fail("packed store", .{});
4819 if (bin_op.rhs.toInterned()) |rhs_val| if (ip.isUndef(rhs_val)) {
4820 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
4821 break :air_tag;
4822 };
4976 if (bin_op.rhs.toInterned()) |rhs_val| if (ip.isUndef(rhs_val))
4977 break :air_tag if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
48234978
48244979 const src_vi = try isel.use(bin_op.rhs);
48254980 const size = src_vi.size(isel);
......@@ -4833,8 +4988,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
48334988 });
48344989 try ptr_mat.finish(isel);
48354990
4836 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
4837 break :air_tag;
4991 break :air_tag if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
48384992 },
48394993 else => {},
48404994 };
......@@ -4843,7 +4997,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
48434997
48444998 try call.prepareCallee(isel);
48454999 try isel.global_relocs.append(gpa, .{
4846 .global = "memcpy",
5000 .name = "memcpy",
48475001 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
48485002 });
48495003 try isel.emit(.bl(0));
......@@ -4906,7 +5060,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
49065060
49075061 try call.prepareCallee(isel);
49085062 try isel.global_relocs.append(gpa, .{
4909 .global = switch (dst_bits) {
5063 .name = switch (dst_bits) {
49105064 else => unreachable,
49115065 16 => switch (src_bits) {
49125066 else => unreachable,
......@@ -5060,6 +5214,108 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
50605214 }
50615215 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
50625216 },
5217 .intcast_safe => |air_tag| {
5218 if (isel.live_values.fetchRemove(air.inst_index)) |dst_vi| unused: {
5219 defer dst_vi.value.deref(isel);
5220
5221 const ty_op = air.data(air.inst_index).ty_op;
5222 const dst_ty = ty_op.ty.toType();
5223 const dst_int_info = dst_ty.intInfo(zcu);
5224 const src_ty = isel.air.typeOf(ty_op.operand, ip);
5225 const src_int_info = src_ty.intInfo(zcu);
5226 const can_be_negative = dst_int_info.signedness == .signed and
5227 src_int_info.signedness == .signed;
5228 const panic_id: Zcu.SimplePanicId = panic_id: switch (dst_ty.zigTypeTag(zcu)) {
5229 else => unreachable,
5230 .int => .integer_out_of_bounds,
5231 .@"enum" => {
5232 if (!dst_ty.isNonexhaustiveEnum(zcu)) {
5233 return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });
5234 }
5235 break :panic_id .invalid_enum_value;
5236 },
5237 };
5238 if (dst_ty.toIntern() == src_ty.toIntern()) {
5239 try dst_vi.value.move(isel, ty_op.operand);
5240 } else if (dst_int_info.bits <= 64 and src_int_info.bits <= 64) {
5241 const dst_ra = try dst_vi.value.defReg(isel) orelse break :unused;
5242 const src_vi = try isel.use(ty_op.operand);
5243 const dst_active_bits = dst_int_info.bits - @intFromBool(dst_int_info.signedness == .signed);
5244 const src_active_bits = src_int_info.bits - @intFromBool(src_int_info.signedness == .signed);
5245 if ((dst_int_info.signedness != .unsigned or src_int_info.signedness != .signed) and dst_active_bits >= src_active_bits) {
5246 const src_mat = try src_vi.matReg(isel);
5247 try isel.emit(if (can_be_negative and dst_active_bits > 32 and src_active_bits <= 32)
5248 .sbfm(dst_ra.x(), src_mat.ra.x(), .{
5249 .N = .doubleword,
5250 .immr = 0,
5251 .imms = @intCast(src_int_info.bits - 1),
5252 })
5253 else switch (src_int_info.bits) {
5254 else => unreachable,
5255 1...32 => .orr(dst_ra.w(), .wzr, .{ .register = src_mat.ra.w() }),
5256 33...64 => .orr(dst_ra.x(), .xzr, .{ .register = src_mat.ra.x() }),
5257 });
5258 try src_mat.finish(isel);
5259 } else {
5260 const skip_label = isel.instructions.items.len;
5261 try isel.emitPanic(panic_id);
5262 try isel.emit(.@"b."(
5263 .eq,
5264 @intCast((isel.instructions.items.len + 1 - skip_label) << 2),
5265 ));
5266 if (can_be_negative) {
5267 const src_mat = src_mat: {
5268 const dst_lock = isel.lockReg(dst_ra);
5269 defer dst_lock.unlock(isel);
5270 break :src_mat try src_vi.matReg(isel);
5271 };
5272 try isel.emit(switch (src_int_info.bits) {
5273 else => unreachable,
5274 1...32 => .subs(.wzr, dst_ra.w(), .{ .register = src_mat.ra.w() }),
5275 33...64 => .subs(.xzr, dst_ra.x(), .{ .register = src_mat.ra.x() }),
5276 });
5277 try isel.emit(switch (@max(dst_int_info.bits, src_int_info.bits)) {
5278 else => unreachable,
5279 1...32 => .sbfm(dst_ra.w(), src_mat.ra.w(), .{
5280 .N = .word,
5281 .immr = 0,
5282 .imms = @intCast(dst_int_info.bits - 1),
5283 }),
5284 33...64 => .sbfm(dst_ra.x(), src_mat.ra.x(), .{
5285 .N = .doubleword,
5286 .immr = 0,
5287 .imms = @intCast(dst_int_info.bits - 1),
5288 }),
5289 });
5290 try src_mat.finish(isel);
5291 } else {
5292 const src_mat = try src_vi.matReg(isel);
5293 try isel.emit(switch (@min(dst_int_info.bits, src_int_info.bits)) {
5294 else => unreachable,
5295 1...32 => .orr(dst_ra.w(), .wzr, .{ .register = src_mat.ra.w() }),
5296 33...64 => .orr(dst_ra.x(), .xzr, .{ .register = src_mat.ra.x() }),
5297 });
5298 const active_bits = @min(dst_active_bits, src_active_bits);
5299 try isel.emit(switch (src_int_info.bits) {
5300 else => unreachable,
5301 1...32 => .ands(.wzr, src_mat.ra.w(), .{ .immediate = .{
5302 .N = .word,
5303 .immr = @intCast(32 - active_bits),
5304 .imms = @intCast(32 - active_bits - 1),
5305 } }),
5306 33...64 => .ands(.xzr, src_mat.ra.x(), .{ .immediate = .{
5307 .N = .doubleword,
5308 .immr = @intCast(64 - active_bits),
5309 .imms = @intCast(64 - active_bits - 1),
5310 } }),
5311 });
5312 try src_mat.finish(isel);
5313 }
5314 }
5315 } else return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });
5316 }
5317 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
5318 },
50635319 .trunc => |air_tag| {
50645320 if (isel.live_values.fetchRemove(air.inst_index)) |dst_vi| unused: {
50655321 defer dst_vi.value.deref(isel);
......@@ -5832,7 +6088,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
58326088
58336089 try call.prepareCallee(isel);
58346090 try isel.global_relocs.append(gpa, .{
5835 .global = switch (dst_int_info.bits) {
6091 .name = switch (dst_int_info.bits) {
58366092 else => unreachable,
58376093 1...32 => switch (dst_int_info.signedness) {
58386094 .signed => switch (src_bits) {
......@@ -5972,7 +6228,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
59726228
59736229 try call.prepareCallee(isel);
59746230 try isel.global_relocs.append(gpa, .{
5975 .global = switch (src_int_info.bits) {
6231 .name = switch (src_int_info.bits) {
59766232 else => unreachable,
59776233 1...32 => switch (src_int_info.signedness) {
59786234 .signed => switch (dst_bits) {
......@@ -6055,14 +6311,20 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
60556311 }
60566312 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
60576313 },
6058 .memset => |air_tag| {
6314 .memset, .memset_safe => |air_tag| {
60596315 const bin_op = air.data(air.inst_index).bin_op;
60606316 const dst_ty = isel.air.typeOf(bin_op.lhs, ip);
60616317 const dst_info = dst_ty.ptrInfo(zcu);
60626318 const fill_byte: union(enum) { constant: u8, value: Air.Inst.Ref } = fill_byte: {
6063 if (bin_op.rhs.toInterned()) |fill_val|
6319 if (bin_op.rhs.toInterned()) |fill_val| {
6320 if (ip.isUndef(fill_val)) switch (air_tag) {
6321 else => unreachable,
6322 .memset => break :air_tag if (air.next()) |next_air_tag| continue :air_tag next_air_tag,
6323 .memset_safe => break :fill_byte .{ .constant = 0xaa },
6324 };
60646325 if (try isel.hasRepeatedByteRepr(.fromInterned(fill_val))) |fill_byte|
60656326 break :fill_byte .{ .constant = fill_byte };
6327 }
60666328 switch (dst_ty.elemType2(zcu).abiSize(zcu)) {
60676329 0 => unreachable,
60686330 1 => break :fill_byte .{ .value = bin_op.rhs },
......@@ -6121,8 +6383,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
61216383 .c => unreachable,
61226384 }
61236385
6124 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
6125 break :air_tag;
6386 break :air_tag if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
61266387 },
61276388 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty) }),
61286389 }
......@@ -6133,7 +6394,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
61336394
61346395 try call.prepareCallee(isel);
61356396 try isel.global_relocs.append(gpa, .{
6136 .global = "memset",
6397 .name = "memset",
61376398 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
61386399 });
61396400 try isel.emit(.bl(0));
......@@ -6179,7 +6440,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
61796440
61806441 try call.prepareCallee(isel);
61816442 try isel.global_relocs.append(gpa, .{
6182 .global = @tagName(air_tag),
6443 .name = @tagName(air_tag),
61836444 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
61846445 });
61856446 try isel.emit(.bl(0));
......@@ -6268,6 +6529,72 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
62686529
62696530 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
62706531 },
6532 .error_name => {
6533 if (isel.live_values.fetchRemove(air.inst_index)) |name_vi| unused: {
6534 defer name_vi.value.deref(isel);
6535 var ptr_part_it = name_vi.value.field(.slice_const_u8_sentinel_0, 0, 8);
6536 const ptr_part_vi = try ptr_part_it.only(isel);
6537 const ptr_part_ra = try ptr_part_vi.?.defReg(isel);
6538 var len_part_it = name_vi.value.field(.slice_const_u8_sentinel_0, 8, 8);
6539 const len_part_vi = try len_part_it.only(isel);
6540 const len_part_ra = try len_part_vi.?.defReg(isel);
6541 if (ptr_part_ra == null and len_part_ra == null) break :unused;
6542
6543 const un_op = air.data(air.inst_index).un_op;
6544 const err_vi = try isel.use(un_op);
6545 const err_mat = try err_vi.matReg(isel);
6546 const ptr_ra = try isel.allocIntReg();
6547 defer isel.freeReg(ptr_ra);
6548 const start_ra, const end_ra = range_ras: {
6549 const name_lock: RegLock = if (len_part_ra != null) if (ptr_part_ra) |name_ptr_ra|
6550 isel.tryLockReg(name_ptr_ra)
6551 else
6552 .empty else .empty;
6553 defer name_lock.unlock(isel);
6554 break :range_ras .{ try isel.allocIntReg(), try isel.allocIntReg() };
6555 };
6556 defer {
6557 isel.freeReg(start_ra);
6558 isel.freeReg(end_ra);
6559 }
6560 if (len_part_ra) |name_len_ra| try isel.emit(.sub(
6561 name_len_ra.w(),
6562 end_ra.w(),
6563 .{ .register = start_ra.w() },
6564 ));
6565 if (ptr_part_ra) |name_ptr_ra| try isel.emit(.add(
6566 name_ptr_ra.x(),
6567 ptr_ra.x(),
6568 .{ .extended_register = .{
6569 .register = start_ra.w(),
6570 .extend = .{ .uxtw = 0 },
6571 } },
6572 ));
6573 if (len_part_ra) |_| try isel.emit(.sub(end_ra.w(), end_ra.w(), .{ .immediate = 1 }));
6574 try isel.emit(.ldp(start_ra.w(), end_ra.w(), .{ .base = start_ra.x() }));
6575 try isel.emit(.add(start_ra.x(), ptr_ra.x(), .{ .extended_register = .{
6576 .register = err_mat.ra.w(),
6577 .extend = switch (zcu.errorSetBits()) {
6578 else => unreachable,
6579 1...8 => .{ .uxtb = 2 },
6580 9...16 => .{ .uxth = 2 },
6581 17...32 => .{ .uxtw = 2 },
6582 },
6583 } }));
6584 try isel.lazy_relocs.append(gpa, .{
6585 .symbol = .{ .kind = .const_data, .ty = .anyerror_type },
6586 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
6587 });
6588 try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));
6589 try isel.lazy_relocs.append(gpa, .{
6590 .symbol = .{ .kind = .const_data, .ty = .anyerror_type },
6591 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
6592 });
6593 try isel.emit(.adrp(ptr_ra.x(), 0));
6594 try err_mat.finish(isel);
6595 }
6596 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
6597 },
62716598 .aggregate_init => {
62726599 if (isel.live_values.fetchRemove(air.inst_index)) |agg_vi| {
62736600 defer agg_vi.value.deref(isel);
......@@ -6362,7 +6689,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
63626689
63636690 try call.prepareCallee(isel);
63646691 try isel.global_relocs.append(gpa, .{
6365 .global = "memcpy",
6692 .name = "memcpy",
63666693 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
63676694 });
63686695 try isel.emit(.bl(0));
......@@ -6478,7 +6805,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
64786805
64796806 try call.prepareCallee(isel);
64806807 try isel.global_relocs.append(gpa, .{
6481 .global = switch (bits) {
6808 .name = switch (bits) {
64826809 else => unreachable,
64836810 16 => "__fmah",
64846811 32 => "fmaf",
......@@ -6559,6 +6886,32 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
65596886 }
65606887 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
65616888 },
6889 .cmp_lt_errors_len => {
6890 if (isel.live_values.fetchRemove(air.inst_index)) |is_vi| unused: {
6891 defer is_vi.value.deref(isel);
6892 const is_ra = try is_vi.value.defReg(isel) orelse break :unused;
6893 try isel.emit(.csinc(is_ra.w(), .wzr, .wzr, .invert(.ls)));
6894
6895 const un_op = air.data(air.inst_index).un_op;
6896 const err_vi = try isel.use(un_op);
6897 const err_mat = try err_vi.matReg(isel);
6898 const ptr_ra = try isel.allocIntReg();
6899 defer isel.freeReg(ptr_ra);
6900 try isel.emit(.subs(.wzr, err_mat.ra.w(), .{ .register = ptr_ra.w() }));
6901 try isel.lazy_relocs.append(gpa, .{
6902 .symbol = .{ .kind = .const_data, .ty = .anyerror_type },
6903 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
6904 });
6905 try isel.emit(.ldr(ptr_ra.w(), .{ .base = ptr_ra.x() }));
6906 try isel.lazy_relocs.append(gpa, .{
6907 .symbol = .{ .kind = .const_data, .ty = .anyerror_type },
6908 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
6909 });
6910 try isel.emit(.adrp(ptr_ra.x(), 0));
6911 try err_mat.finish(isel);
6912 }
6913 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
6914 },
65626915 .runtime_nav_ptr => {
65636916 if (isel.live_values.fetchRemove(air.inst_index)) |ptr_vi| unused: {
65646917 defer ptr_vi.value.deref(isel);
......@@ -6567,19 +6920,19 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
65676920 const ty_nav = air.data(air.inst_index).ty_nav;
65686921 if (ZigType.fromInterned(ip.getNav(ty_nav.nav).typeOf(ip)).isFnOrHasRuntimeBits(zcu)) switch (true) {
65696922 false => {
6570 try isel.nav_relocs.append(zcu.gpa, .{
6923 try isel.nav_relocs.append(gpa, .{
65716924 .nav = ty_nav.nav,
65726925 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
65736926 });
65746927 try isel.emit(.adr(ptr_ra.x(), 0));
65756928 },
65766929 true => {
6577 try isel.nav_relocs.append(zcu.gpa, .{
6930 try isel.nav_relocs.append(gpa, .{
65786931 .nav = ty_nav.nav,
65796932 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
65806933 });
65816934 try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));
6582 try isel.nav_relocs.append(zcu.gpa, .{
6935 try isel.nav_relocs.append(gpa, .{
65836936 .nav = ty_nav.nav,
65846937 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
65856938 });
......@@ -6589,9 +6942,6 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
65896942 }
65906943 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
65916944 },
6592 .add_safe,
6593 .sub_safe,
6594 .mul_safe,
65956945 .inferred_alloc,
65966946 .inferred_alloc_comptime,
65976947 .int_from_float_safe,
......@@ -6822,6 +7172,9 @@ pub fn layout(
68227172 saves_len += 1;
68237173 saves_size += 8;
68247174 deferred_gr = null;
7175 } else switch (@as(u1, @truncate(saved_gra_len))) {
7176 0 => {},
7177 1 => saves_size += 8,
68257178 }
68267179 save_ra = if (mod.strip) incoming.ngrn else CallAbiIterator.ngrn_start;
68277180 while (save_ra != if (have_va) CallAbiIterator.ngrn_end else incoming.ngrn) : (save_ra = @enumFromInt(@intFromEnum(save_ra) + 1)) {
......@@ -6844,42 +7197,42 @@ pub fn layout(
68447197 {
68457198 wip_mir_log.debug("{f}<prologue>:", .{nav.fqn.fmt(ip)});
68467199 var save_index: usize = 0;
6847 while (save_index < saves.len) {
6848 if (save_index + 2 <= saves.len and saves[save_index + 0].class == saves[save_index + 1].class and
6849 saves[save_index + 0].offset + saves[save_index + 0].size == saves[save_index + 1].offset)
6850 {
6851 try isel.emit(.stp(
6852 saves[save_index + 0].register,
6853 saves[save_index + 1].register,
6854 switch (saves[save_index + 0].offset) {
6855 0 => .{ .pre_index = .{
6856 .base = .sp,
6857 .index = @intCast(-@as(i11, saves_size)),
6858 } },
6859 else => |offset| .{ .signed_offset = .{
6860 .base = .sp,
6861 .offset = @intCast(offset),
6862 } },
6863 },
6864 ));
6865 save_index += 2;
6866 } else {
6867 try isel.emit(.str(
6868 saves[save_index].register,
6869 switch (saves[save_index].offset) {
6870 0 => .{ .pre_index = .{
6871 .base = .sp,
6872 .index = @intCast(-@as(i11, saves_size)),
6873 } },
6874 else => |offset| .{ .unsigned_offset = .{
6875 .base = .sp,
6876 .offset = @intCast(offset),
6877 } },
6878 },
6879 ));
6880 save_index += 1;
6881 }
6882 }
7200 while (save_index < saves.len) if (save_index + 2 <= saves.len and
7201 saves[save_index + 0].class == saves[save_index + 1].class and
7202 saves[save_index + 0].size == saves[save_index + 1].size and
7203 saves[save_index + 0].offset + saves[save_index + 0].size == saves[save_index + 1].offset)
7204 {
7205 try isel.emit(.stp(
7206 saves[save_index + 0].register,
7207 saves[save_index + 1].register,
7208 switch (saves[save_index + 0].offset) {
7209 0 => .{ .pre_index = .{
7210 .base = .sp,
7211 .index = @intCast(-@as(i11, saves_size)),
7212 } },
7213 else => |offset| .{ .signed_offset = .{
7214 .base = .sp,
7215 .offset = @intCast(offset),
7216 } },
7217 },
7218 ));
7219 save_index += 2;
7220 } else {
7221 try isel.emit(.str(
7222 saves[save_index].register,
7223 switch (saves[save_index].offset) {
7224 0 => .{ .pre_index = .{
7225 .base = .sp,
7226 .index = @intCast(-@as(i11, saves_size)),
7227 } },
7228 else => |offset| .{ .unsigned_offset = .{
7229 .base = .sp,
7230 .offset = @intCast(offset),
7231 } },
7232 },
7233 ));
7234 save_index += 1;
7235 };
68837236
68847237 try isel.emit(.add(.fp, .sp, .{ .immediate = frame_record_offset }));
68857238 const scratch_reg: Register = if (isel.stack_align == .@"16")
......@@ -7053,11 +7406,43 @@ fn fmtConstant(isel: *Select, constant: Constant) @typeInfo(@TypeOf(Constant.fmt
70537406 return constant.fmtValue(isel.pt);
70547407}
70557408
7409fn block(
7410 isel: *Select,
7411 air_inst_index: Air.Inst.Index,
7412 res_ty: ZigType,
7413 air_body: []const Air.Inst.Index,
7414) !void {
7415 if (res_ty.toIntern() != .noreturn_type) {
7416 isel.blocks.putAssumeCapacityNoClobber(air_inst_index, .{
7417 .live_registers = isel.live_registers,
7418 .target_label = @intCast(isel.instructions.items.len),
7419 });
7420 }
7421 try isel.body(air_body);
7422 if (res_ty.toIntern() != .noreturn_type) {
7423 const block_entry = isel.blocks.pop().?;
7424 assert(block_entry.key == air_inst_index);
7425 if (isel.live_values.fetchRemove(air_inst_index)) |result_vi| result_vi.value.deref(isel);
7426 }
7427}
7428
70567429fn emit(isel: *Select, instruction: codegen.aarch64.encoding.Instruction) !void {
70577430 wip_mir_log.debug(" | {f}", .{instruction});
70587431 try isel.instructions.append(isel.pt.zcu.gpa, instruction);
70597432}
70607433
7434fn emitPanic(isel: *Select, panic_id: Zcu.SimplePanicId) !void {
7435 const zcu = isel.pt.zcu;
7436 try isel.nav_relocs.append(zcu.gpa, .{
7437 .nav = switch (zcu.intern_pool.indexToKey(zcu.builtin_decl_values.get(panic_id.toBuiltin()))) {
7438 else => unreachable,
7439 inline .@"extern", .func => |func| func.owner_nav,
7440 },
7441 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
7442 });
7443 try isel.emit(.bl(0));
7444}
7445
70617446fn emitLiteral(isel: *Select, bytes: []const u8) !void {
70627447 const words: []align(1) const u32 = @ptrCast(bytes);
70637448 const literals = try isel.literals.addManyAsSlice(isel.pt.zcu.gpa, words.len);
......@@ -8104,6 +8489,32 @@ pub const Value = struct {
81048489 }
81058490 }
81068491
8492 const AddOrSubtractOptions = struct {
8493 overflow: Overflow,
8494
8495 const Overflow = union(enum) {
8496 @"unreachable",
8497 panic: Zcu.SimplePanicId,
8498 wrap,
8499 ra: Register.Alias,
8500
8501 fn defCond(overflow: Overflow, isel: *Select, cond: codegen.aarch64.encoding.ConditionCode) !void {
8502 switch (overflow) {
8503 .@"unreachable" => unreachable,
8504 .panic => |panic_id| {
8505 const skip_label = isel.instructions.items.len;
8506 try isel.emitPanic(panic_id);
8507 try isel.emit(.@"b."(
8508 cond.invert(),
8509 @intCast((isel.instructions.items.len + 1 - skip_label) << 2),
8510 ));
8511 },
8512 .wrap => {},
8513 .ra => |overflow_ra| try isel.emit(.csinc(overflow_ra.w(), .wzr, .wzr, cond.invert())),
8514 }
8515 }
8516 };
8517 };
81078518 fn addOrSubtract(
81088519 res_vi: Value.Index,
81098520 isel: *Select,
......@@ -8111,19 +8522,21 @@ pub const Value = struct {
81118522 lhs_vi: Value.Index,
81128523 op: codegen.aarch64.encoding.Instruction.AddSubtractOp,
81138524 rhs_vi: Value.Index,
8114 opts: struct {
8115 wrap: bool,
8116 overflow_ra: Register.Alias = .zr,
8117 },
8525 opts: AddOrSubtractOptions,
81188526 ) !void {
8119 assert(opts.wrap or opts.overflow_ra == .zr);
81208527 const zcu = isel.pt.zcu;
81218528 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(op), isel.fmtType(ty) });
81228529 const int_info = ty.intInfo(zcu);
81238530 if (int_info.bits > 128) return isel.fail("too big {s} {f}", .{ @tagName(op), isel.fmtType(ty) });
81248531 var part_offset = res_vi.size(isel);
8125 var need_wrap = opts.wrap;
8126 var need_carry = opts.overflow_ra != .zr;
8532 var need_wrap = switch (opts.overflow) {
8533 .@"unreachable" => false,
8534 .panic, .wrap, .ra => true,
8535 };
8536 var need_carry = switch (opts.overflow) {
8537 .@"unreachable", .wrap => false,
8538 .panic, .ra => true,
8539 };
81278540 while (part_offset > 0) : (need_wrap = false) {
81288541 const part_size = @min(part_offset, 8);
81298542 part_offset -= part_size;
......@@ -8133,48 +8546,87 @@ pub const Value = struct {
81338546 const unwrapped_res_part_ra = unwrapped_res_part_ra: {
81348547 if (!need_wrap) break :unwrapped_res_part_ra wrapped_res_part_ra;
81358548 if (int_info.bits % 32 == 0) {
8136 if (opts.overflow_ra != .zr) try isel.emit(.csinc(opts.overflow_ra.w(), .wzr, .wzr, .invert(switch (int_info.signedness) {
8549 try opts.overflow.defCond(isel, switch (int_info.signedness) {
81378550 .signed => .vs,
81388551 .unsigned => switch (op) {
81398552 .add => .cs,
81408553 .sub => .cc,
81418554 },
8142 })));
8555 });
81438556 break :unwrapped_res_part_ra wrapped_res_part_ra;
81448557 }
8145 const wrapped_part_ra, const unwrapped_part_ra = if (opts.overflow_ra != .zr) part_ra: {
8146 switch (op) {
8147 .add => {},
8148 .sub => switch (int_info.signedness) {
8149 .signed => {},
8150 .unsigned => {
8151 try isel.emit(.csinc(opts.overflow_ra.w(), .wzr, .wzr, .invert(.cc)));
8152 break :part_ra .{ wrapped_res_part_ra, wrapped_res_part_ra };
8153 },
8558 need_carry = false;
8559 const wrapped_part_ra, const unwrapped_part_ra = part_ra: switch (opts.overflow) {
8560 .@"unreachable" => unreachable,
8561 .panic, .ra => switch (int_info.signedness) {
8562 .signed => {
8563 try opts.overflow.defCond(isel, .ne);
8564 const wrapped_part_ra = switch (wrapped_res_part_ra) {
8565 else => |res_part_ra| res_part_ra,
8566 .zr => try isel.allocIntReg(),
8567 };
8568 errdefer if (wrapped_part_ra != wrapped_res_part_ra) isel.freeReg(wrapped_part_ra);
8569 const unwrapped_part_ra = unwrapped_part_ra: {
8570 const wrapped_res_part_lock: RegLock = switch (wrapped_res_part_ra) {
8571 else => |res_part_ra| isel.lockReg(res_part_ra),
8572 .zr => .empty,
8573 };
8574 defer wrapped_res_part_lock.unlock(isel);
8575 break :unwrapped_part_ra try isel.allocIntReg();
8576 };
8577 errdefer isel.freeReg(unwrapped_part_ra);
8578 switch (part_size) {
8579 else => unreachable,
8580 1...4 => try isel.emit(.subs(.wzr, wrapped_part_ra.w(), .{ .register = unwrapped_part_ra.w() })),
8581 5...8 => try isel.emit(.subs(.xzr, wrapped_part_ra.x(), .{ .register = unwrapped_part_ra.x() })),
8582 }
8583 break :part_ra .{ wrapped_part_ra, unwrapped_part_ra };
81548584 },
8155 }
8156 try isel.emit(.csinc(opts.overflow_ra.w(), .wzr, .wzr, .invert(.ne)));
8157 const wrapped_part_ra = switch (wrapped_res_part_ra) {
8158 else => |res_part_ra| res_part_ra,
8159 .zr => try isel.allocIntReg(),
8160 };
8161 errdefer if (wrapped_part_ra != wrapped_res_part_ra) isel.freeReg(wrapped_part_ra);
8162 const unwrapped_part_ra = unwrapped_part_ra: {
8163 const wrapped_res_part_lock: RegLock = switch (wrapped_res_part_ra) {
8164 else => |res_part_ra| isel.lockReg(res_part_ra),
8165 .zr => .empty,
8166 };
8167 defer wrapped_res_part_lock.unlock(isel);
8168 break :unwrapped_part_ra try isel.allocIntReg();
8169 };
8170 errdefer isel.freeReg(unwrapped_part_ra);
8171 switch (part_size) {
8172 else => unreachable,
8173 1...4 => try isel.emit(.subs(.wzr, wrapped_part_ra.w(), .{ .register = unwrapped_part_ra.w() })),
8174 5...8 => try isel.emit(.subs(.xzr, wrapped_part_ra.x(), .{ .register = unwrapped_part_ra.x() })),
8175 }
8176 break :part_ra .{ wrapped_part_ra, unwrapped_part_ra };
8177 } else .{ wrapped_res_part_ra, wrapped_res_part_ra };
8585 .unsigned => {
8586 const unwrapped_part_ra = unwrapped_part_ra: {
8587 const wrapped_res_part_lock: RegLock = switch (wrapped_res_part_ra) {
8588 else => |res_part_ra| isel.lockReg(res_part_ra),
8589 .zr => .empty,
8590 };
8591 defer wrapped_res_part_lock.unlock(isel);
8592 break :unwrapped_part_ra try isel.allocIntReg();
8593 };
8594 errdefer isel.freeReg(unwrapped_part_ra);
8595 const bit: u6 = @truncate(int_info.bits);
8596 switch (opts.overflow) {
8597 .@"unreachable", .wrap => unreachable,
8598 .panic => |panic_id| {
8599 const skip_label = isel.instructions.items.len;
8600 try isel.emitPanic(panic_id);
8601 try isel.emit(.tbz(
8602 switch (bit) {
8603 0, 32 => unreachable,
8604 1...31 => unwrapped_part_ra.w(),
8605 33...63 => unwrapped_part_ra.x(),
8606 },
8607 bit,
8608 @intCast((isel.instructions.items.len + 1 - skip_label) << 2),
8609 ));
8610 },
8611 .ra => |overflow_ra| try isel.emit(switch (bit) {
8612 0, 32 => unreachable,
8613 1...31 => .ubfm(overflow_ra.w(), unwrapped_part_ra.w(), .{
8614 .N = .word,
8615 .immr = bit,
8616 .imms = bit,
8617 }),
8618 33...63 => .ubfm(overflow_ra.x(), unwrapped_part_ra.x(), .{
8619 .N = .doubleword,
8620 .immr = bit,
8621 .imms = bit,
8622 }),
8623 }),
8624 }
8625 break :part_ra .{ wrapped_res_part_ra, unwrapped_part_ra };
8626 },
8627 },
8628 .wrap => .{ wrapped_res_part_ra, wrapped_res_part_ra },
8629 };
81788630 defer if (wrapped_part_ra != wrapped_res_part_ra) isel.freeReg(wrapped_part_ra);
81798631 errdefer if (unwrapped_part_ra != wrapped_res_part_ra) isel.freeReg(unwrapped_part_ra);
81808632 if (wrapped_part_ra != .zr) try isel.emit(switch (part_size) {
......@@ -8650,41 +9102,15 @@ pub const Value = struct {
86509102 expected_live_registers: *const LiveRegisters,
86519103 ) !void {
86529104 try vi.liveIn(isel, src_ra, expected_live_registers);
8653 const offset_from_parent: i65, const parent_vi = vi.valueParent(isel);
9105 const offset_from_parent, const parent_vi = vi.valueParent(isel);
86549106 switch (parent_vi.parent(isel)) {
86559107 .unallocated => {},
8656 .stack_slot => |stack_slot| {
8657 const offset = stack_slot.offset + offset_from_parent;
8658 try isel.emit(switch (vi.size(isel)) {
8659 else => unreachable,
8660 1 => if (src_ra.isVector()) .str(src_ra.b(), .{ .unsigned_offset = .{
8661 .base = stack_slot.base.x(),
8662 .offset = @intCast(offset),
8663 } }) else .strb(src_ra.w(), .{ .unsigned_offset = .{
8664 .base = stack_slot.base.x(),
8665 .offset = @intCast(offset),
8666 } }),
8667 2 => if (src_ra.isVector()) .str(src_ra.h(), .{ .unsigned_offset = .{
8668 .base = stack_slot.base.x(),
8669 .offset = @intCast(offset),
8670 } }) else .strh(src_ra.w(), .{ .unsigned_offset = .{
8671 .base = stack_slot.base.x(),
8672 .offset = @intCast(offset),
8673 } }),
8674 4 => .str(if (src_ra.isVector()) src_ra.s() else src_ra.w(), .{ .unsigned_offset = .{
8675 .base = stack_slot.base.x(),
8676 .offset = @intCast(offset),
8677 } }),
8678 8 => .str(if (src_ra.isVector()) src_ra.d() else src_ra.x(), .{ .unsigned_offset = .{
8679 .base = stack_slot.base.x(),
8680 .offset = @intCast(offset),
8681 } }),
8682 16 => .str(src_ra.q(), .{ .unsigned_offset = .{
8683 .base = stack_slot.base.x(),
8684 .offset = @intCast(offset),
8685 } }),
8686 });
8687 },
9108 .stack_slot => |stack_slot| if (stack_slot.base != Register.Alias.fp) try isel.storeReg(
9109 src_ra,
9110 vi.size(isel),
9111 stack_slot.base,
9112 @as(i65, stack_slot.offset) + offset_from_parent,
9113 ),
86889114 else => unreachable,
86899115 }
86909116 try vi.spillReg(isel, src_ra, 0, expected_live_registers);
......@@ -9631,14 +10057,18 @@ pub const Value = struct {
963110057 var base_ptr = ip.indexToKey(base).ptr;
963210058 const eu_ty = ip.indexToKey(base_ptr.ty).ptr_type.child;
963310059 const payload_ty = ip.indexToKey(eu_ty).error_union_type.payload_type;
9634 base_ptr.byte_offset += codegen.errUnionPayloadOffset(.fromInterned(payload_ty), zcu);
10060 base_ptr.byte_offset += codegen.errUnionPayloadOffset(.fromInterned(payload_ty), zcu) + ptr.byte_offset;
10061 continue :constant_key .{ .ptr = base_ptr };
10062 },
10063 .opt_payload => |base| {
10064 var base_ptr = ip.indexToKey(base).ptr;
10065 base_ptr.byte_offset += ptr.byte_offset;
963510066 continue :constant_key .{ .ptr = base_ptr };
963610067 },
9637 .opt_payload => |base| continue :constant_key .{ .ptr = ip.indexToKey(base).ptr },
963810068 .field => |field| {
963910069 var base_ptr = ip.indexToKey(field.base).ptr;
964010070 const agg_ty: ZigType = .fromInterned(ip.indexToKey(base_ptr.ty).ptr_type.child);
9641 base_ptr.byte_offset += agg_ty.structFieldOffset(@intCast(field.index), zcu);
10071 base_ptr.byte_offset += agg_ty.structFieldOffset(@intCast(field.index), zcu) + ptr.byte_offset;
964210072 continue :constant_key .{ .ptr = base_ptr };
964310073 },
964410074 .comptime_alloc, .comptime_field, .arr_elem => unreachable,
src/codegen/aarch64/instructions.zon+190
......@@ -213,6 +213,63 @@
213213 },
214214 .encode = .{ .ands, .Xd, .Xn, .{ .shifted_register_explicit = .{ .register = .Xm, .shift = .shift, .amount = .amount } } },
215215 },
216 // C6.2.16 ASR (register)
217 .{
218 .pattern = "ASR <Wd>, <Wn>, <Wm>",
219 .symbols = .{
220 .Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
221 .Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
222 .Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
223 },
224 .encode = .{ .asrv, .Wd, .Wn, .Wm },
225 },
226 .{
227 .pattern = "ASR <Xd>, <Xn>, <Xm>",
228 .symbols = .{
229 .Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
230 .Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
231 .Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
232 },
233 .encode = .{ .asrv, .Xd, .Xn, .Xm },
234 },
235 // C6.2.17 ASR (immediate)
236 .{
237 .pattern = "ASR <Wd>, <Wn>, #<shift>",
238 .symbols = .{
239 .Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
240 .Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
241 .shift = .{ .imm = .{ .type = .{ .signedness = .unsigned, .bits = 5 } } },
242 },
243 .encode = .{ .sbfm, .Wd, .Wn, .{ .N = .word, .immr = .shift, .imms = 31 } },
244 },
245 .{
246 .pattern = "ASR <Xd>, <Xn>, #<shift>",
247 .symbols = .{
248 .Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
249 .Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
250 .shift = .{ .imm = .{ .type = .{ .signedness = .unsigned, .bits = 6 } } },
251 },
252 .encode = .{ .sbfm, .Xd, .Xn, .{ .N = .doubleword, .immr = .shift, .imms = 63 } },
253 },
254 // C6.2.18 ASRV
255 .{
256 .pattern = "ASRV <Wd>, <Wn>, <Wm>",
257 .symbols = .{
258 .Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
259 .Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
260 .Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
261 },
262 .encode = .{ .asrv, .Wd, .Wn, .Wm },
263 },
264 .{
265 .pattern = "ASRV <Xd>, <Xn>, <Xm>",
266 .symbols = .{
267 .Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
268 .Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
269 .Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
270 },
271 .encode = .{ .asrv, .Xd, .Xn, .Xm },
272 },
216273 // C6.2.35 BLR
217274 .{
218275 .pattern = "BLR <Xn>",
......@@ -681,6 +738,82 @@
681738 },
682739 .encode = .{ .ldr, .Xt, .{ .unsigned_offset = .{ .base = .Xn, .offset = .pimm } } },
683740 },
741 // C6.2.212 LSL (register)
742 .{
743 .pattern = "LSL <Wd>, <Wn>, <Wm>",
744 .symbols = .{
745 .Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
746 .Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
747 .Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
748 },
749 .encode = .{ .lslv, .Wd, .Wn, .Wm },
750 },
751 .{
752 .pattern = "LSL <Xd>, <Xn>, <Xm>",
753 .symbols = .{
754 .Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
755 .Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
756 .Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
757 },
758 .encode = .{ .lslv, .Xd, .Xn, .Xm },
759 },
760 // C6.2.214 LSLV
761 .{
762 .pattern = "LSLV <Wd>, <Wn>, <Wm>",
763 .symbols = .{
764 .Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
765 .Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
766 .Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
767 },
768 .encode = .{ .lslv, .Wd, .Wn, .Wm },
769 },
770 .{
771 .pattern = "LSLV <Xd>, <Xn>, <Xm>",
772 .symbols = .{
773 .Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
774 .Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
775 .Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
776 },
777 .encode = .{ .lslv, .Xd, .Xn, .Xm },
778 },
779 // C6.2.215 LSR (register)
780 .{
781 .pattern = "LSR <Wd>, <Wn>, <Wm>",
782 .symbols = .{
783 .Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
784 .Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
785 .Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
786 },
787 .encode = .{ .lsrv, .Wd, .Wn, .Wm },
788 },
789 .{
790 .pattern = "LSR <Xd>, <Xn>, <Xm>",
791 .symbols = .{
792 .Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
793 .Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
794 .Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
795 },
796 .encode = .{ .lsrv, .Xd, .Xn, .Xm },
797 },
798 // C6.2.217 LSRV
799 .{
800 .pattern = "LSRV <Wd>, <Wn>, <Wm>",
801 .symbols = .{
802 .Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
803 .Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
804 .Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
805 },
806 .encode = .{ .lsrv, .Wd, .Wn, .Wm },
807 },
808 .{
809 .pattern = "LSRV <Xd>, <Xn>, <Xm>",
810 .symbols = .{
811 .Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
812 .Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
813 .Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
814 },
815 .encode = .{ .lsrv, .Xd, .Xn, .Xm },
816 },
684817 // C6.2.220 MOV (to/from SP)
685818 .{
686819 .pattern = "MOV WSP, <Wn|WSP>",
......@@ -964,6 +1097,63 @@
9641097 },
9651098 .encode = .{ .ret, .Xn },
9661099 },
1100 // C6.2.261 ROR (immediate)
1101 .{
1102 .pattern = "ROR <Wd>, <Ws>, #<shift>",
1103 .symbols = .{
1104 .Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
1105 .Ws = .{ .reg = .{ .format = .{ .integer = .word } } },
1106 .shift = .{ .imm = .{ .type = .{ .signedness = .unsigned, .bits = 5 } } },
1107 },
1108 .encode = .{ .extr, .Wd, .Ws, .Ws, .shift },
1109 },
1110 .{
1111 .pattern = "ROR <Xd>, <Xs>, #<shift>",
1112 .symbols = .{
1113 .Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
1114 .Xs = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
1115 .shift = .{ .imm = .{ .type = .{ .signedness = .unsigned, .bits = 6 } } },
1116 },
1117 .encode = .{ .extr, .Xd, .Xs, .Xs, .shift },
1118 },
1119 // C6.2.262 ROR (register)
1120 .{
1121 .pattern = "ROR <Wd>, <Wn>, <Wm>",
1122 .symbols = .{
1123 .Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
1124 .Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
1125 .Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
1126 },
1127 .encode = .{ .rorv, .Wd, .Wn, .Wm },
1128 },
1129 .{
1130 .pattern = "ROR <Xd>, <Xn>, <Xm>",
1131 .symbols = .{
1132 .Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
1133 .Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
1134 .Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
1135 },
1136 .encode = .{ .rorv, .Xd, .Xn, .Xm },
1137 },
1138 // C6.2.263 RORV
1139 .{
1140 .pattern = "RORV <Wd>, <Wn>, <Wm>",
1141 .symbols = .{
1142 .Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
1143 .Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
1144 .Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
1145 },
1146 .encode = .{ .rorv, .Wd, .Wn, .Wm },
1147 },
1148 .{
1149 .pattern = "RORV <Xd>, <Xn>, <Xm>",
1150 .symbols = .{
1151 .Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
1152 .Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
1153 .Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
1154 },
1155 .encode = .{ .rorv, .Xd, .Xn, .Xm },
1156 },
9671157 // C6.2.268 SBFM
9681158 .{
9691159 .pattern = "SBFM <Wd>, <Wn>, #<immr>, #<imms>",
src/target.zig+4-2
......@@ -351,7 +351,7 @@ pub fn defaultCompilerRtOptimizeMode(target: *const std.Target) std.builtin.Opti
351351 }
352352}
353353
354pub fn canBuildLibCompilerRt(target: *const std.Target, use_llvm: bool, comptime have_llvm: bool) bool {
354pub fn canBuildLibCompilerRt(target: *const std.Target, use_llvm: bool, have_llvm: bool) bool {
355355 switch (target.os.tag) {
356356 .plan9 => return false,
357357 else => {},
......@@ -373,7 +373,7 @@ pub fn canBuildLibCompilerRt(target: *const std.Target, use_llvm: bool, comptime
373373 };
374374}
375375
376pub fn canBuildLibUbsanRt(target: *const std.Target, use_llvm: bool, comptime have_llvm: bool) bool {
376pub fn canBuildLibUbsanRt(target: *const std.Target, use_llvm: bool, have_llvm: bool) bool {
377377 switch (target.cpu.arch) {
378378 .spirv32, .spirv64 => return false,
379379 // Remove this once https://github.com/ziglang/zig/issues/23715 is fixed
......@@ -382,6 +382,7 @@ pub fn canBuildLibUbsanRt(target: *const std.Target, use_llvm: bool, comptime ha
382382 }
383383 return switch (zigBackend(target, use_llvm)) {
384384 .stage2_llvm => true,
385 .stage2_wasm => false,
385386 .stage2_x86_64 => switch (target.ofmt) {
386387 .elf, .macho => true,
387388 else => have_llvm,
......@@ -860,6 +861,7 @@ pub fn zigBackend(target: *const std.Target, use_llvm: bool) std.builtin.Compile
860861pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, comptime feature: Feature) bool {
861862 return switch (feature) {
862863 .panic_fn => switch (backend) {
864 .stage2_aarch64,
863865 .stage2_c,
864866 .stage2_llvm,
865867 .stage2_x86_64,
test/behavior/error.zig-3
......@@ -590,7 +590,6 @@ test "error union comptime caching" {
590590}
591591
592592test "@errorName" {
593 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
594593 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
595594 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
596595 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
......@@ -605,7 +604,6 @@ fn gimmeItBroke() anyerror {
605604}
606605
607606test "@errorName sentinel length matches slice length" {
608 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
609607 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
610608 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
611609 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
......@@ -883,7 +881,6 @@ test "catch within a function that calls no errorable functions" {
883881}
884882
885883test "error from comptime string" {
886 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
887884 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
888885 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
889886 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
test/behavior/return_address.zig-1
......@@ -6,7 +6,6 @@ fn retAddr() usize {
66}
77
88test "return address" {
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
109 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1110 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1211 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
test/cases/array_in_anon_struct.zig+1-1
......@@ -19,4 +19,4 @@ pub fn main() !void {
1919
2020// run
2121// backend=stage2,llvm
22// target=native
22// target=x86_64-linux,aarch64-linux
test/cases/compile_errors/callconv_interrupt_on_unsupported_platform.zig+2-2
......@@ -7,5 +7,5 @@ export fn entry3() callconv(.avr_interrupt) void {}
77// target=aarch64-linux-none
88//
99// :1:30: error: calling convention 'x86_64_interrupt' only available on architectures 'x86_64'
10// :1:30: error: calling convention 'x86_interrupt' only available on architectures 'x86'
11// :1:30: error: calling convention 'avr_interrupt' only available on architectures 'avr'
10// :2:30: error: calling convention 'x86_interrupt' only available on architectures 'x86'
11// :3:30: error: calling convention 'avr_interrupt' only available on architectures 'avr'
test/cases/compile_errors/error_set_membership.zig+1-1
......@@ -25,7 +25,7 @@ pub fn main() Error!void {
2525
2626// error
2727// backend=stage2
28// target=native
28// target=x86_64-linux
2929//
3030// :23:29: error: expected type 'error{InvalidCharacter}', found '@typeInfo(@typeInfo(@TypeOf(tmp.fooey)).@"fn".return_type.?).error_union.error_set'
3131// :23:29: note: 'error.InvalidDirection' not a member of destination error set
test/cases/compile_errors/function_ptr_alignment.zig+1-1
......@@ -10,7 +10,7 @@ comptime {
1010
1111// error
1212// backend=stage2
13// target=native
13// target=x86_64-linux
1414//
1515// :8:41: error: expected type '*align(2) const fn () void', found '*const fn () void'
1616// :8:41: note: pointer alignment '1' cannot cast into pointer alignment '2'
test/cases/compile_errors/issue_15572_break_on_inline_while.zig+1-1
......@@ -15,6 +15,6 @@ pub fn main() void {
1515
1616// error
1717// backend=stage2
18// target=native
18// target=x86_64-linux
1919//
2020// :9:28: error: incompatible types: 'builtin.Type.EnumField' and 'void'
test/cases/compile_errors/switch_on_non_err_union.zig+1-1
......@@ -6,6 +6,6 @@ pub fn main() void {
66
77// error
88// backend=stage2
9// target=native
9// target=x86_64-linux
1010//
1111// :2:23: error: expected error union type, found 'bool'
test/cases/pic_freestanding.zig+1-1
......@@ -1,7 +1,7 @@
11const builtin = @import("builtin");
22const std = @import("std");
33
4fn _start() callconv(.naked) void {}
4pub fn _start() callconv(.naked) void {}
55
66comptime {
77 @export(&_start, .{ .name = if (builtin.cpu.arch.isMIPS()) "__start" else "_start" });
test/cases/safety/@alignCast misaligned.zig +1-1
......@@ -22,4 +22,4 @@ fn foo(bytes: []u8) u32 {
2222}
2323// run
2424// backend=stage2,llvm
25// target=native
25// target=x86_64-linux,aarch64-linux
test/cases/safety/@enumFromInt - no matching tag value.zig +1-1
......@@ -23,4 +23,4 @@ fn baz(_: Foo) void {}
2323
2424// run
2525// backend=stage2,llvm
26// target=native
26// target=x86_64-linux
test/cases/safety/@enumFromInt truncated bits - exhaustive.zig +1-1
......@@ -20,4 +20,4 @@ pub fn main() u8 {
2020
2121// run
2222// backend=stage2,llvm
23// target=native
23// target=x86_64-linux
test/cases/safety/@enumFromInt truncated bits - nonexhaustive.zig +1-1
......@@ -20,4 +20,4 @@ pub fn main() u8 {
2020
2121// run
2222// backend=stage2,llvm
23// target=native
23// target=x86_64-linux
test/cases/safety/@errorCast error not present in destination.zig +1-1
......@@ -18,4 +18,4 @@ fn foo(set1: Set1) Set2 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux
test/cases/safety/@errorCast error union casted to disjoint set.zig +1-1
......@@ -17,4 +17,4 @@ fn foo() anyerror!i32 {
1717}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux
test/cases/safety/@intCast to u0.zig +1-1
......@@ -19,4 +19,4 @@ fn bar(one: u1, not_zero: i32) void {
1919}
2020// run
2121// backend=stage2,llvm
22// target=native
22// target=x86_64-linux,aarch64-linux
test/cases/safety/@intFromFloat cannot fit - boundary case - i0 max.zig +1-1
......@@ -13,4 +13,4 @@ pub fn main() !void {
1313}
1414// run
1515// backend=stage2,llvm
16// target=native
16// target=x86_64-linux,aarch64-linux
test/cases/safety/@intFromFloat cannot fit - boundary case - i0 min.zig +1-1
......@@ -13,4 +13,4 @@ pub fn main() !void {
1313}
1414// run
1515// backend=stage2,llvm
16// target=native
16// target=x86_64-linux,aarch64-linux
test/cases/safety/@intFromFloat cannot fit - boundary case - signed max.zig +1-1
......@@ -13,4 +13,4 @@ pub fn main() !void {
1313}
1414// run
1515// backend=stage2,llvm
16// target=native
16// target=x86_64-linux
test/cases/safety/@intFromFloat cannot fit - boundary case - signed min.zig +1-1
......@@ -13,4 +13,4 @@ pub fn main() !void {
1313}
1414// run
1515// backend=stage2,llvm
16// target=native
16// target=x86_64-linux
test/cases/safety/@intFromFloat cannot fit - boundary case - u0 max.zig +1-1
......@@ -13,4 +13,4 @@ pub fn main() !void {
1313}
1414// run
1515// backend=stage2,llvm
16// target=native
16// target=x86_64-linux,aarch64-linux
test/cases/safety/@intFromFloat cannot fit - boundary case - u0 min.zig +1-1
......@@ -13,4 +13,4 @@ pub fn main() !void {
1313}
1414// run
1515// backend=stage2,llvm
16// target=native
16// target=x86_64-linux,aarch64-linux
test/cases/safety/@intFromFloat cannot fit - boundary case - unsigned max.zig +1-1
......@@ -13,4 +13,4 @@ pub fn main() !void {
1313}
1414// run
1515// backend=stage2,llvm
16// target=native
16// target=x86_64-linux
test/cases/safety/@intFromFloat cannot fit - boundary case - unsigned min.zig +1-1
......@@ -13,4 +13,4 @@ pub fn main() !void {
1313}
1414// run
1515// backend=stage2,llvm
16// target=native
16// target=x86_64-linux
test/cases/safety/@intFromFloat cannot fit - boundary case - vector max.zig +1-1
......@@ -13,4 +13,4 @@ pub fn main() !void {
1313}
1414// run
1515// backend=stage2,llvm
16// target=native
16// target=x86_64-linux
test/cases/safety/@intFromFloat cannot fit - boundary case - vector min.zig +1-1
......@@ -13,4 +13,4 @@ pub fn main() !void {
1313}
1414// run
1515// backend=stage2,llvm
16// target=native
16// target=x86_64-linux
test/cases/safety/@intFromFloat cannot fit - negative out of range.zig +1-1
......@@ -17,4 +17,4 @@ fn bar(a: f32) i8 {
1717fn baz(_: i8) void {}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux
test/cases/safety/@intFromFloat cannot fit - negative to unsigned.zig +1-1
......@@ -17,4 +17,4 @@ fn bar(a: f32) u8 {
1717fn baz(_: u8) void {}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux
test/cases/safety/@intFromFloat cannot fit - positive out of range.zig +1-1
......@@ -17,4 +17,4 @@ fn bar(a: f32) u8 {
1717fn baz(_: u8) void {}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux
test/cases/safety/@ptrFromInt address zero to non-optional byte-aligned pointer.zig +1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/safety/@ptrFromInt address zero to non-optional pointer.zig +1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/safety/@ptrFromInt with misaligned address.zig +1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/safety/@tagName on corrupted enum value.zig +1-1
......@@ -23,4 +23,4 @@ pub fn main() !void {
2323
2424// run
2525// backend=stage2,llvm
26// target=native
26// target=x86_64-linux
test/cases/safety/@tagName on corrupted union value.zig +1-1
......@@ -24,4 +24,4 @@ pub fn main() !void {
2424
2525// run
2626// backend=stage2,llvm
27// target=native
27// target=x86_64-linux
test/cases/safety/array slice sentinel mismatch vector.zig +1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux
test/cases/safety/array slice sentinel mismatch.zig +1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/safety/bad union field access.zig +1-1
......@@ -24,4 +24,4 @@ fn bar(f: *Foo) void {
2424}
2525// run
2626// backend=stage2,llvm
27// target=native
27// target=x86_64-linux
test/cases/safety/calling panic.zig +1-1
......@@ -13,4 +13,4 @@ pub fn main() !void {
1313}
1414// run
1515// backend=stage2,llvm
16// target=native
16// target=x86_64-linux,aarch64-linux
test/cases/safety/cast []u8 to bigger slice of wrong size.zig +1-1
......@@ -18,4 +18,4 @@ fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/cast integer to global error and no code matches.zig +1-1
......@@ -16,4 +16,4 @@ fn bar(x: u16) anyerror {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/safety/empty slice with sentinel out of bounds.zig +1-1
......@@ -18,4 +18,4 @@ pub fn main() !void {
1818
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/exact division failure - vectors.zig +1-1
......@@ -20,4 +20,4 @@ fn divExact(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) {
2020}
2121// run
2222// backend=stage2,llvm
23// target=native
23// target=x86_64-linux
test/cases/safety/exact division failure.zig +1-1
......@@ -18,4 +18,4 @@ fn divExact(a: i32, b: i32) i32 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/for_len_mismatch.zig+1-1
......@@ -22,4 +22,4 @@ pub fn main() !void {
2222}
2323// run
2424// backend=stage2,llvm
25// target=native
25// target=x86_64-linux,aarch64-linux
test/cases/safety/for_len_mismatch_three.zig+1-1
......@@ -21,4 +21,4 @@ pub fn main() !void {
2121}
2222// run
2323// backend=stage2,llvm
24// target=native
24// target=x86_64-linux,aarch64-linux
test/cases/safety/ignored expression integer overflow.zig +1-1
......@@ -18,4 +18,4 @@ pub fn main() !void {
1818
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux
test/cases/safety/integer addition overflow.zig +1-1
......@@ -20,4 +20,4 @@ fn add(a: u16, b: u16) u16 {
2020
2121// run
2222// backend=stage2,llvm
23// target=native
23// target=x86_64-linux,aarch64-linux
test/cases/safety/integer division by zero - vectors.zig +1-1
......@@ -19,4 +19,4 @@ fn div0(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) {
1919}
2020// run
2121// backend=stage2,llvm
22// target=native
22// target=x86_64-linux
test/cases/safety/integer division by zero.zig +1-1
......@@ -17,4 +17,4 @@ fn div0(a: i32, b: i32) i32 {
1717}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux,aarch64-linux
test/cases/safety/integer multiplication overflow.zig +1-1
......@@ -18,4 +18,4 @@ fn mul(a: u16, b: u16) u16 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/integer negation overflow.zig +1-1
......@@ -18,4 +18,4 @@ fn neg(a: i16) i16 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/integer subtraction overflow.zig +1-1
......@@ -18,4 +18,4 @@ fn sub(a: u16, b: u16) u16 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/memcpy_alias.zig+1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/safety/memcpy_len_mismatch.zig+1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/safety/memmove_len_mismatch.zig+1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/safety/memset_array_undefined_bytes.zig+1-1
......@@ -15,4 +15,4 @@ pub fn main() !void {
1515}
1616// run
1717// backend=stage2,llvm
18// target=native
18// target=x86_64-linux,aarch64-linux
test/cases/safety/memset_array_undefined_large.zig+1-1
......@@ -15,4 +15,4 @@ pub fn main() !void {
1515}
1616// run
1717// backend=stage2,llvm
18// target=native
18// target=x86_64-linux,aarch64-linux
test/cases/safety/memset_slice_undefined_bytes.zig+1-1
......@@ -17,4 +17,4 @@ pub fn main() !void {
1717}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux,aarch64-linux
test/cases/safety/memset_slice_undefined_large.zig+1-1
......@@ -17,4 +17,4 @@ pub fn main() !void {
1717}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux,aarch64-linux
test/cases/safety/modrem by zero.zig +1-1
......@@ -17,4 +17,4 @@ fn div0(a: u32, b: u32) u32 {
1717}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux,aarch64-linux
test/cases/safety/modulus by zero.zig +1-1
......@@ -17,4 +17,4 @@ fn mod0(a: i32, b: i32) i32 {
1717}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux
test/cases/safety/noreturn returned.zig +1-1
......@@ -20,4 +20,4 @@ pub fn main() void {
2020}
2121// run
2222// backend=stage2,llvm
23// target=native
23// target=x86_64-linux,aarch64-linux
test/cases/safety/optional unwrap operator on C pointer.zig +1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/safety/optional unwrap operator on null pointer.zig +1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/safety/optional_empty_error_set.zig+1-1
......@@ -19,4 +19,4 @@ fn foo() !void {
1919}
2020// run
2121// backend=stage2,llvm
22// target=native
22// target=x86_64-linux,aarch64-linux
test/cases/safety/out of bounds array slice by length.zig +1-1
......@@ -17,4 +17,4 @@ fn foo(a: u32) u32 {
1717}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux,aarch64-linux
test/cases/safety/out of bounds slice access.zig +1-1
......@@ -18,4 +18,4 @@ fn bar(a: []const i32) i32 {
1818fn baz(_: i32) void {}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/pointer casting null to non-optional pointer.zig +1-1
......@@ -18,4 +18,4 @@ pub fn main() !void {
1818
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/pointer casting to null function pointer.zig +1-1
......@@ -20,4 +20,4 @@ pub fn main() !void {
2020
2121// run
2222// backend=stage2,llvm
23// target=native
23// target=x86_64-linux,aarch64-linux
test/cases/safety/pointer slice sentinel mismatch.zig +1-1
......@@ -18,4 +18,4 @@ pub fn main() !void {
1818
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/remainder division by zero.zig +1-1
......@@ -17,4 +17,4 @@ fn rem0(a: i32, b: i32) i32 {
1717}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux,aarch64-linux
test/cases/safety/shift left by huge amount.zig +1-1
......@@ -19,4 +19,4 @@ pub fn main() !void {
1919
2020// run
2121// backend=stage2,llvm
22// target=native
22// target=x86_64-linux,aarch64-linux
test/cases/safety/shift right by huge amount.zig +1-1
......@@ -19,4 +19,4 @@ pub fn main() !void {
1919
2020// run
2121// backend=stage2,llvm
22// target=native
22// target=x86_64-linux,aarch64-linux
test/cases/safety/signed integer division overflow - vectors.zig +1-1
......@@ -20,4 +20,4 @@ fn div(a: @Vector(4, i16), b: @Vector(4, i16)) @Vector(4, i16) {
2020}
2121// run
2222// backend=stage2,llvm
23// target=native
23// target=x86_64-linux
test/cases/safety/signed integer division overflow.zig +1-1
......@@ -18,4 +18,4 @@ fn div(a: i16, b: i16) i16 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/signed integer not fitting in cast to unsigned integer - widening.zig +1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux
test/cases/safety/signed integer not fitting in cast to unsigned integer.zig +1-1
......@@ -17,4 +17,4 @@ fn unsigned_cast(x: i32) u32 {
1717}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux,aarch64-linux
test/cases/safety/signed shift left overflow.zig +1-1
......@@ -18,4 +18,4 @@ fn shl(a: i16, b: u4) i16 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux
test/cases/safety/signed shift right overflow.zig +1-1
......@@ -18,4 +18,4 @@ fn shr(a: i16, b: u4) i16 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/signed-unsigned vector cast.zig +1-1
......@@ -18,4 +18,4 @@ pub fn main() !void {
1818
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux
test/cases/safety/slice by length sentinel mismatch on lhs.zig +1-1
......@@ -15,4 +15,4 @@ pub fn main() !void {
1515}
1616// run
1717// backend=stage2,llvm
18// target=native
18// target=x86_64-linux,aarch64-linux
test/cases/safety/slice by length sentinel mismatch on rhs.zig +1-1
......@@ -15,4 +15,4 @@ pub fn main() !void {
1515}
1616// run
1717// backend=stage2,llvm
18// target=native
18// target=x86_64-linux,aarch64-linux
test/cases/safety/slice sentinel mismatch - floats.zig +1-1
......@@ -17,4 +17,4 @@ pub fn main() !void {
1717
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux
test/cases/safety/slice sentinel mismatch - optional pointers.zig +1-1
......@@ -17,4 +17,4 @@ pub fn main() !void {
1717
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux,aarch64-linux
test/cases/safety/slice slice sentinel mismatch.zig +1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/safety/slice start index greater than end index.zig +1-1
......@@ -21,4 +21,4 @@ pub fn main() !void {
2121
2222// run
2323// backend=stage2,llvm
24// target=native
24// target=x86_64-linux,aarch64-linux
test/cases/safety/slice with sentinel out of bounds - runtime len.zig +1-1
......@@ -20,4 +20,4 @@ pub fn main() !void {
2020
2121// run
2222// backend=stage2,llvm
23// target=native
23// target=x86_64-linux,aarch64-linux
test/cases/safety/slice with sentinel out of bounds.zig +1-1
......@@ -18,4 +18,4 @@ pub fn main() !void {
1818
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/slice_cast_change_len_0.zig+1-1
......@@ -24,4 +24,4 @@ const std = @import("std");
2424
2525// run
2626// backend=stage2,llvm
27// target=x86_64-linux
27// target=x86_64-linux,aarch64-linux
test/cases/safety/slice_cast_change_len_1.zig+1-1
......@@ -24,4 +24,4 @@ const std = @import("std");
2424
2525// run
2626// backend=stage2,llvm
27// target=x86_64-linux
27// target=x86_64-linux,aarch64-linux
test/cases/safety/slice_cast_change_len_2.zig+1-1
......@@ -24,4 +24,4 @@ const std = @import("std");
2424
2525// run
2626// backend=stage2,llvm
27// target=x86_64-linux
27// target=x86_64-linux,aarch64-linux
test/cases/safety/slicing null C pointer - runtime len.zig +1-1
......@@ -18,4 +18,4 @@ pub fn main() !void {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/slicing null C pointer.zig +1-1
......@@ -17,4 +17,4 @@ pub fn main() !void {
1717}
1818// run
1919// backend=stage2,llvm
20// target=native
20// target=x86_64-linux,aarch64-linux
test/cases/safety/switch else on corrupt enum value - one prong.zig +1-1
......@@ -21,4 +21,4 @@ pub fn main() !void {
2121}
2222// run
2323// backend=stage2,llvm
24// target=native
24// target=x86_64-linux
test/cases/safety/switch else on corrupt enum value - union.zig +1-1
......@@ -26,4 +26,4 @@ pub fn main() !void {
2626}
2727// run
2828// backend=stage2,llvm
29// target=native
29// target=x86_64-linux
test/cases/safety/switch else on corrupt enum value.zig +1-1
......@@ -20,4 +20,4 @@ pub fn main() !void {
2020}
2121// run
2222// backend=stage2,llvm
23// target=native
23// target=x86_64-linux
test/cases/safety/switch on corrupted enum value.zig +1-1
......@@ -24,4 +24,4 @@ pub fn main() !void {
2424
2525// run
2626// backend=stage2,llvm
27// target=native
27// target=x86_64-linux,aarch64-linux
test/cases/safety/switch on corrupted union value.zig +1-1
......@@ -24,4 +24,4 @@ pub fn main() !void {
2424
2525// run
2626// backend=stage2,llvm
27// target=native
27// target=x86_64-linux
test/cases/safety/truncating vector cast.zig +1-1
......@@ -18,4 +18,4 @@ pub fn main() !void {
1818
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux
test/cases/safety/unreachable.zig+1-1
......@@ -12,4 +12,4 @@ pub fn main() !void {
1212}
1313// run
1414// backend=stage2,llvm
15// target=native
15// target=x86_64-linux,aarch64-linux
test/cases/safety/unsigned integer not fitting in cast to signed integer - same bit count.zig +1-1
......@@ -16,4 +16,4 @@ pub fn main() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux
test/cases/safety/unsigned shift left overflow.zig +1-1
......@@ -18,4 +18,4 @@ fn shl(a: u16, b: u4) u16 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux
test/cases/safety/unsigned shift right overflow.zig +1-1
......@@ -18,4 +18,4 @@ fn shr(a: u16, b: u4) u16 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/unsigned-signed vector cast.zig +1-1
......@@ -18,4 +18,4 @@ pub fn main() !void {
1818
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux
test/cases/safety/unwrap error switch.zig +1-1
......@@ -18,4 +18,4 @@ fn bar() !void {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/unwrap error.zig +1-1
......@@ -16,4 +16,4 @@ fn bar() !void {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/safety/value does not fit in shortening cast - u0.zig +1-1
......@@ -18,4 +18,4 @@ fn shorten_cast(x: u8) u0 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/value does not fit in shortening cast.zig +1-1
......@@ -18,4 +18,4 @@ fn shorten_cast(x: i32) i8 {
1818}
1919// run
2020// backend=stage2,llvm
21// target=native
21// target=x86_64-linux,aarch64-linux
test/cases/safety/vector integer addition overflow.zig +1-1
......@@ -19,4 +19,4 @@ fn add(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) {
1919}
2020// run
2121// backend=stage2,llvm
22// target=native
22// target=x86_64-linux
test/cases/safety/vector integer multiplication overflow.zig +1-1
......@@ -19,4 +19,4 @@ fn mul(a: @Vector(4, u8), b: @Vector(4, u8)) @Vector(4, u8) {
1919}
2020// run
2121// backend=stage2,llvm
22// target=native
22// target=x86_64-linux
test/cases/safety/vector integer negation overflow.zig +1-1
......@@ -19,4 +19,4 @@ fn neg(a: @Vector(4, i16)) @Vector(4, i16) {
1919}
2020// run
2121// backend=stage2,llvm
22// target=native
22// target=x86_64-linux
test/cases/safety/vector integer subtraction overflow.zig +1-1
......@@ -19,4 +19,4 @@ fn sub(a: @Vector(4, u32), b: @Vector(4, u32)) @Vector(4, u32) {
1919}
2020// run
2121// backend=stage2,llvm
22// target=native
22// target=x86_64-linux
test/cases/safety/zero casted to error.zig +1-1
......@@ -16,4 +16,4 @@ fn bar(x: u16) anyerror {
1616}
1717// run
1818// backend=stage2,llvm
19// target=native
19// target=x86_64-linux,aarch64-linux
test/cases/taking_pointer_of_global_tagged_union.zig+1-1
......@@ -23,4 +23,4 @@ pub fn main() !void {
2323
2424// run
2525// backend=stage2,llvm
26// target=native
26// target=x86_64-linux
test/src/Cases.zig+1-5
......@@ -436,7 +436,7 @@ fn addFromDirInner(
436436 const target = &resolved_target.result;
437437 for (backends) |backend| {
438438 if (backend == .stage2 and
439 target.cpu.arch != .wasm32 and target.cpu.arch != .x86_64 and target.cpu.arch != .spirv64)
439 target.cpu.arch != .aarch64 and target.cpu.arch != .wasm32 and target.cpu.arch != .x86_64 and target.cpu.arch != .spirv64)
440440 {
441441 // Other backends don't support new liveness format
442442 continue;
......@@ -447,10 +447,6 @@ fn addFromDirInner(
447447 // Rosetta has issues with ZLD
448448 continue;
449449 }
450 if (backend == .stage2 and target.ofmt == .coff) {
451 // COFF linker has bitrotted
452 continue;
453 }
454450
455451 const next = ctx.cases.items.len;
456452 try ctx.cases.append(.{