aarch64: implement some safety checks

Closes #24553
This commit is contained in:
Jacob Young 2025-07-26 03:09:55 -04:00
parent 1274254c48
commit 69abc945e4
124 changed files with 1078 additions and 365 deletions

View File

@ -1816,10 +1816,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
if (options.skip_linker_dependencies) break :s .none;
const want = options.want_compiler_rt orelse is_exe_or_dyn_lib;
if (!want) break :s .none;
if (have_zcu) {
if (have_zcu and target_util.canBuildLibCompilerRt(target, use_llvm, build_options.have_llvm and use_llvm)) {
if (output_mode == .Obj) break :s .zcu;
if (target.ofmt == .coff and target_util.zigBackend(target, use_llvm) == .stage2_x86_64)
break :s if (is_exe_or_dyn_lib) .dyn_lib else .zcu;
if (switch (target_util.zigBackend(target, use_llvm)) {
else => false,
.stage2_aarch64, .stage2_x86_64 => target.ofmt == .coff,
}) break :s if (is_exe_or_dyn_lib) .dyn_lib else .zcu;
}
if (is_exe_or_dyn_lib) break :s .lib;
break :s .obj;
@ -1854,7 +1856,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
const want_ubsan_rt = options.want_ubsan_rt orelse (can_build_ubsan_rt and any_sanitize_c == .full and is_exe_or_dyn_lib);
if (!want_ubsan_rt) break :s .none;
if (options.skip_linker_dependencies) break :s .none;
if (have_zcu) break :s .zcu;
if (have_zcu and target_util.canBuildLibUbsanRt(target, use_llvm, build_options.have_llvm and use_llvm)) break :s .zcu;
if (is_exe_or_dyn_lib) break :s .lib;
break :s .obj;
};

View File

@ -168141,7 +168141,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
.unused,
.unused,
},
.dst_temps = .{ .{ .cc = .b }, .unused },
.dst_temps = .{ .{ .cc = .be }, .unused },
.clobbers = .{ .eflags = true },
.each = .{ .once = &.{
.{ ._, ._, .lea, .tmp1p, .lea(.tmp0), ._, ._ },
@ -168165,7 +168165,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
.unused,
.unused,
},
.dst_temps = .{ .{ .cc = .b }, .unused },
.dst_temps = .{ .{ .cc = .be }, .unused },
.clobbers = .{ .eflags = true },
.each = .{ .once = &.{
.{ ._, ._, .lea, .tmp1p, .lea(.tmp0), ._, ._ },
@ -168189,7 +168189,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
.unused,
.unused,
},
.dst_temps = .{ .{ .cc = .b }, .unused },
.dst_temps = .{ .{ .cc = .be }, .unused },
.clobbers = .{ .eflags = true },
.each = .{ .once = &.{
.{ ._, ._, .lea, .tmp1p, .lea(.tmp0), ._, ._ },

View File

@ -168,11 +168,12 @@ pub fn emitMir(emit: *Emit) Error!void {
else if (emit.bin_file.cast(.macho)) |macho_file|
macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|
return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
else if (emit.bin_file.cast(.coff)) |coff_file| sym_index: {
const atom = coff_file.getOrCreateAtomForLazySymbol(emit.pt, lazy_sym) catch |err|
return emit.fail("{s} creating lazy symbol", .{@errorName(err)});
break :sym_index coff_file.getAtom(atom).getSymbolIndex().?;
} else if (emit.bin_file.cast(.plan9)) |p9_file|
else if (emit.bin_file.cast(.coff)) |coff_file|
if (coff_file.getOrCreateAtomForLazySymbol(emit.pt, lazy_sym)) |atom|
coff_file.getAtom(atom).getSymbolIndex().?
else |err|
return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
else if (emit.bin_file.cast(.plan9)) |p9_file|
p9_file.getOrCreateAtomForLazySymbol(emit.pt, lazy_sym) catch |err|
return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
else

View File

@ -47,6 +47,7 @@ pub fn generate(
.literals = .empty,
.nav_relocs = .empty,
.uav_relocs = .empty,
.lazy_relocs = .empty,
.global_relocs = .empty,
.literal_relocs = .empty,
@ -101,8 +102,8 @@ pub fn generate(
};
switch (passed_vi.parent(&isel)) {
.unallocated => if (!mod.strip) {
var part_it = arg_vi.parts(&isel);
const first_passed_part_vi = part_it.next() orelse passed_vi;
var part_it = passed_vi.parts(&isel);
const first_passed_part_vi = part_it.next().?;
const hint_ra = first_passed_part_vi.hint(&isel).?;
passed_vi.setParent(&isel, .{ .stack_slot = if (hint_ra.isVector())
isel.va_list.__vr_top.withOffset(@as(i8, -16) *
@ -167,6 +168,7 @@ pub fn generate(
.literals = &.{},
.nav_relocs = &.{},
.uav_relocs = &.{},
.lazy_relocs = &.{},
.global_relocs = &.{},
.literal_relocs = &.{},
};
@ -174,6 +176,7 @@ pub fn generate(
mir.literals = try isel.literals.toOwnedSlice(gpa);
mir.nav_relocs = try isel.nav_relocs.toOwnedSlice(gpa);
mir.uav_relocs = try isel.uav_relocs.toOwnedSlice(gpa);
mir.lazy_relocs = try isel.lazy_relocs.toOwnedSlice(gpa);
mir.global_relocs = try isel.global_relocs.toOwnedSlice(gpa);
mir.literal_relocs = try isel.literal_relocs.toOwnedSlice(gpa);
return mir;

View File

@ -6,14 +6,19 @@ pub const Operand = union(enum) {
};
pub fn nextInstruction(as: *Assemble) !?Instruction {
@setEvalBranchQuota(37_000);
@setEvalBranchQuota(42_000);
comptime var ct_token_buf: [token_buf_len]u8 = undefined;
var token_buf: [token_buf_len]u8 = undefined;
const original_source = while (true) {
const original_source = as.source;
const source_token = try as.nextToken(&token_buf, .{});
if (source_token.len == 0) return null;
if (source_token[0] != '\n') break original_source;
switch (source_token.len) {
0 => return null,
else => switch (source_token[0]) {
else => break original_source,
'\n', ';' => {},
},
}
};
log.debug(
\\.
@ -52,7 +57,13 @@ pub fn nextInstruction(as: *Assemble) !?Instruction {
std.zig.fmtString(source_token),
});
if (pattern_token.len == 0) {
if (source_token.len > 0 and source_token[0] != '\n') break :next_pattern;
switch (source_token.len) {
0 => {},
else => switch (source_token[0]) {
else => break :next_pattern,
'\n', ';' => {},
},
}
const encode = @field(Instruction, @tagName(instruction.encode[0]));
const Encode = @TypeOf(encode);
var args: std.meta.ArgsTuple(Encode) = undefined;
@ -65,7 +76,7 @@ pub fn nextInstruction(as: *Assemble) !?Instruction {
const symbol = &@field(symbols, symbol_name);
symbol.* = zonCast(SymbolSpec, @field(instruction.symbols, symbol_name), .{}).parse(source_token) orelse break :next_pattern;
log.debug("{s} = {any}", .{ symbol_name, symbol.* });
} else if (!std.ascii.eqlIgnoreCase(pattern_token, source_token)) break :next_pattern;
} else if (!toUpperEqlAssertUpper(source_token, pattern_token)) break :next_pattern;
}
}
log.debug("'{s}' not matched...", .{instruction.pattern});
@ -125,6 +136,15 @@ fn zonCast(comptime Result: type, zon_value: anytype, symbols: anytype) Result {
}
}
fn toUpperEqlAssertUpper(lhs: []const u8, rhs: []const u8) bool {
if (lhs.len != rhs.len) return false;
for (lhs, rhs) |l, r| {
assert(!std.ascii.isLower(r));
if (std.ascii.toUpper(l) != r) return false;
}
return true;
}
const token_buf_len = "v31.b[15]".len;
fn nextToken(as: *Assemble, buf: *[token_buf_len]u8, comptime opts: struct {
operands: bool = false,
@ -134,7 +154,7 @@ fn nextToken(as: *Assemble, buf: *[token_buf_len]u8, comptime opts: struct {
while (true) c: switch (as.source[0]) {
0 => return as.source[0..0],
'\t', '\n' + 1...'\r', ' ' => as.source = as.source[1..],
'\n', '!', '#', ',', '[', ']' => {
'\n', '!', '#', ',', ';', '[', ']' => {
defer as.source = as.source[1..];
return as.source[0..1];
},

View File

@ -4,6 +4,7 @@ epilogue: []const Instruction,
literals: []const u32,
nav_relocs: []const Reloc.Nav,
uav_relocs: []const Reloc.Uav,
lazy_relocs: []const Reloc.Lazy,
global_relocs: []const Reloc.Global,
literal_relocs: []const Reloc.Literal,
@ -21,8 +22,13 @@ pub const Reloc = struct {
reloc: Reloc,
};
pub const Lazy = struct {
symbol: link.File.LazySymbol,
reloc: Reloc,
};
pub const Global = struct {
global: [*:0]const u8,
name: [*:0]const u8,
reloc: Reloc,
};
@ -38,6 +44,7 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
gpa.free(mir.literals);
gpa.free(mir.nav_relocs);
gpa.free(mir.uav_relocs);
gpa.free(mir.lazy_relocs);
gpa.free(mir.global_relocs);
gpa.free(mir.literal_relocs);
mir.* = undefined;
@ -119,16 +126,37 @@ pub fn emit(
body_end - Instruction.size * (1 + uav_reloc.reloc.label),
uav_reloc.reloc.addend,
);
for (mir.lazy_relocs) |lazy_reloc| try emitReloc(
lf,
zcu,
func.owner_nav,
if (lf.cast(.elf)) |ef|
ef.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(ef, pt, lazy_reloc.symbol) catch |err|
return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
else if (lf.cast(.macho)) |mf|
mf.getZigObject().?.getOrCreateMetadataForLazySymbol(mf, pt, lazy_reloc.symbol) catch |err|
return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
else if (lf.cast(.coff)) |cf|
if (cf.getOrCreateAtomForLazySymbol(pt, lazy_reloc.symbol)) |atom|
cf.getAtom(atom).getSymbolIndex().?
else |err|
return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
else
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
mir.body[lazy_reloc.reloc.label],
body_end - Instruction.size * (1 + lazy_reloc.reloc.label),
lazy_reloc.reloc.addend,
);
for (mir.global_relocs) |global_reloc| try emitReloc(
lf,
zcu,
func.owner_nav,
if (lf.cast(.elf)) |ef|
try ef.getGlobalSymbol(std.mem.span(global_reloc.global), null)
try ef.getGlobalSymbol(std.mem.span(global_reloc.name), null)
else if (lf.cast(.macho)) |mf|
try mf.getGlobalSymbol(std.mem.span(global_reloc.global), null)
try mf.getGlobalSymbol(std.mem.span(global_reloc.name), null)
else if (lf.cast(.coff)) |cf|
try cf.getGlobalSymbol(std.mem.span(global_reloc.global), "compiler_rt")
try cf.getGlobalSymbol(std.mem.span(global_reloc.name), "compiler_rt")
else
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
mir.body[global_reloc.reloc.label],
@ -172,35 +200,6 @@ fn emitReloc(
const gpa = zcu.gpa;
switch (instruction.decode()) {
else => unreachable,
.branch_exception_generating_system => |decoded| if (lf.cast(.elf)) |ef| {
const zo = ef.zigObjectPtr().?;
const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
const r_type: std.elf.R_AARCH64 = switch (decoded.decode().unconditional_branch_immediate.group.op) {
.b => .JUMP26,
.bl => .CALL26,
};
try atom.addReloc(gpa, .{
.r_offset = offset,
.r_info = @as(u64, sym_index) << 32 | @intFromEnum(r_type),
.r_addend = @bitCast(addend),
}, zo);
} else if (lf.cast(.macho)) |mf| {
const zo = mf.getZigObject().?;
const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?;
try atom.addReloc(mf, .{
.tag = .@"extern",
.offset = offset,
.target = sym_index,
.addend = @bitCast(addend),
.type = .branch,
.meta = .{
.pcrel = true,
.has_subtractor = false,
.length = 2,
.symbolnum = @intCast(sym_index),
},
});
},
.data_processing_immediate => |decoded| if (lf.cast(.elf)) |ef| {
const zo = ef.zigObjectPtr().?;
const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
@ -259,6 +258,80 @@ fn emitReloc(
},
}
},
.branch_exception_generating_system => |decoded| if (lf.cast(.elf)) |ef| {
const zo = ef.zigObjectPtr().?;
const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
const r_type: std.elf.R_AARCH64 = switch (decoded.decode().unconditional_branch_immediate.group.op) {
.b => .JUMP26,
.bl => .CALL26,
};
try atom.addReloc(gpa, .{
.r_offset = offset,
.r_info = @as(u64, sym_index) << 32 | @intFromEnum(r_type),
.r_addend = @bitCast(addend),
}, zo);
} else if (lf.cast(.macho)) |mf| {
const zo = mf.getZigObject().?;
const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?;
try atom.addReloc(mf, .{
.tag = .@"extern",
.offset = offset,
.target = sym_index,
.addend = @bitCast(addend),
.type = .branch,
.meta = .{
.pcrel = true,
.has_subtractor = false,
.length = 2,
.symbolnum = @intCast(sym_index),
},
});
},
.load_store => |decoded| if (lf.cast(.elf)) |ef| {
const zo = ef.zigObjectPtr().?;
const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {
.integer => |integer| switch (integer.decode()) {
.unallocated, .prfm => unreachable,
.strb, .ldrb, .ldrsb => .LDST8_ABS_LO12_NC,
.strh, .ldrh, .ldrsh => .LDST16_ABS_LO12_NC,
.ldrsw => .LDST32_ABS_LO12_NC,
inline .str, .ldr => |encoded| switch (encoded.sf) {
.word => .LDST32_ABS_LO12_NC,
.doubleword => .LDST64_ABS_LO12_NC,
},
},
.vector => |vector| switch (vector.group.opc1.decode(vector.group.size)) {
.byte => .LDST8_ABS_LO12_NC,
.half => .LDST16_ABS_LO12_NC,
.single => .LDST32_ABS_LO12_NC,
.double => .LDST64_ABS_LO12_NC,
.quad => .LDST128_ABS_LO12_NC,
.scalable, .predicate => unreachable,
},
};
try atom.addReloc(gpa, .{
.r_offset = offset,
.r_info = @as(u64, sym_index) << 32 | @intFromEnum(r_type),
.r_addend = @bitCast(addend),
}, zo);
} else if (lf.cast(.macho)) |mf| {
const zo = mf.getZigObject().?;
const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?;
try atom.addReloc(mf, .{
.tag = .@"extern",
.offset = offset,
.target = sym_index,
.addend = @bitCast(addend),
.type = .pageoff,
.meta = .{
.pcrel = false,
.has_subtractor = false,
.length = 2,
.symbolnum = @intCast(sym_index),
},
});
},
}
}

File diff suppressed because it is too large Load Diff

View File

@ -213,6 +213,63 @@
},
.encode = .{ .ands, .Xd, .Xn, .{ .shifted_register_explicit = .{ .register = .Xm, .shift = .shift, .amount = .amount } } },
},
// C6.2.16 ASR (register)
.{
.pattern = "ASR <Wd>, <Wn>, <Wm>",
.symbols = .{
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
},
.encode = .{ .asrv, .Wd, .Wn, .Wm },
},
.{
.pattern = "ASR <Xd>, <Xn>, <Xm>",
.symbols = .{
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
},
.encode = .{ .asrv, .Xd, .Xn, .Xm },
},
// C6.2.17 ASR (immediate)
.{
.pattern = "ASR <Wd>, <Wn>, #<shift>",
.symbols = .{
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
.shift = .{ .imm = .{ .type = .{ .signedness = .unsigned, .bits = 5 } } },
},
.encode = .{ .sbfm, .Wd, .Wn, .{ .N = .word, .immr = .shift, .imms = 31 } },
},
.{
.pattern = "ASR <Xd>, <Xn>, #<shift>",
.symbols = .{
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.shift = .{ .imm = .{ .type = .{ .signedness = .unsigned, .bits = 6 } } },
},
.encode = .{ .sbfm, .Xd, .Xn, .{ .N = .doubleword, .immr = .shift, .imms = 63 } },
},
// C6.2.18 ASRV
.{
.pattern = "ASRV <Wd>, <Wn>, <Wm>",
.symbols = .{
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
},
.encode = .{ .asrv, .Wd, .Wn, .Wm },
},
.{
.pattern = "ASRV <Xd>, <Xn>, <Xm>",
.symbols = .{
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
},
.encode = .{ .asrv, .Xd, .Xn, .Xm },
},
// C6.2.35 BLR
.{
.pattern = "BLR <Xn>",
@ -681,6 +738,82 @@
},
.encode = .{ .ldr, .Xt, .{ .unsigned_offset = .{ .base = .Xn, .offset = .pimm } } },
},
// C6.2.212 LSL (register)
.{
.pattern = "LSL <Wd>, <Wn>, <Wm>",
.symbols = .{
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
},
.encode = .{ .lslv, .Wd, .Wn, .Wm },
},
.{
.pattern = "LSL <Xd>, <Xn>, <Xm>",
.symbols = .{
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
},
.encode = .{ .lslv, .Xd, .Xn, .Xm },
},
// C6.2.214 LSLV
.{
.pattern = "LSLV <Wd>, <Wn>, <Wm>",
.symbols = .{
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
},
.encode = .{ .lslv, .Wd, .Wn, .Wm },
},
.{
.pattern = "LSLV <Xd>, <Xn>, <Xm>",
.symbols = .{
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
},
.encode = .{ .lslv, .Xd, .Xn, .Xm },
},
// C6.2.215 LSR (register)
.{
.pattern = "LSR <Wd>, <Wn>, <Wm>",
.symbols = .{
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
},
.encode = .{ .lsrv, .Wd, .Wn, .Wm },
},
.{
.pattern = "LSR <Xd>, <Xn>, <Xm>",
.symbols = .{
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
},
.encode = .{ .lsrv, .Xd, .Xn, .Xm },
},
// C6.2.217 LSRV
.{
.pattern = "LSRV <Wd>, <Wn>, <Wm>",
.symbols = .{
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
},
.encode = .{ .lsrv, .Wd, .Wn, .Wm },
},
.{
.pattern = "LSRV <Xd>, <Xn>, <Xm>",
.symbols = .{
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
},
.encode = .{ .lsrv, .Xd, .Xn, .Xm },
},
// C6.2.220 MOV (to/from SP)
.{
.pattern = "MOV WSP, <Wn|WSP>",
@ -964,6 +1097,63 @@
},
.encode = .{ .ret, .Xn },
},
// C6.2.261 ROR (immediate)
.{
.pattern = "ROR <Wd>, <Ws>, #<shift>",
.symbols = .{
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
.Ws = .{ .reg = .{ .format = .{ .integer = .word } } },
.shift = .{ .imm = .{ .type = .{ .signedness = .unsigned, .bits = 5 } } },
},
.encode = .{ .extr, .Wd, .Ws, .Ws, .shift },
},
.{
.pattern = "ROR <Xd>, <Xs>, #<shift>",
.symbols = .{
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xs = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.shift = .{ .imm = .{ .type = .{ .signedness = .unsigned, .bits = 6 } } },
},
.encode = .{ .extr, .Xd, .Xs, .Xs, .shift },
},
// C6.2.262 ROR (register)
.{
.pattern = "ROR <Wd>, <Wn>, <Wm>",
.symbols = .{
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
},
.encode = .{ .rorv, .Wd, .Wn, .Wm },
},
.{
.pattern = "ROR <Xd>, <Xn>, <Xm>",
.symbols = .{
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
},
.encode = .{ .rorv, .Xd, .Xn, .Xm },
},
// C6.2.263 RORV
.{
.pattern = "RORV <Wd>, <Wn>, <Wm>",
.symbols = .{
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
},
.encode = .{ .rorv, .Wd, .Wn, .Wm },
},
.{
.pattern = "RORV <Xd>, <Xn>, <Xm>",
.symbols = .{
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
},
.encode = .{ .rorv, .Xd, .Xn, .Xm },
},
// C6.2.268 SBFM
.{
.pattern = "SBFM <Wd>, <Wn>, #<immr>, #<imms>",

View File

@ -351,7 +351,7 @@ pub fn defaultCompilerRtOptimizeMode(target: *const std.Target) std.builtin.Opti
}
}
pub fn canBuildLibCompilerRt(target: *const std.Target, use_llvm: bool, comptime have_llvm: bool) bool {
pub fn canBuildLibCompilerRt(target: *const std.Target, use_llvm: bool, have_llvm: bool) bool {
switch (target.os.tag) {
.plan9 => return false,
else => {},
@ -373,7 +373,7 @@ pub fn canBuildLibCompilerRt(target: *const std.Target, use_llvm: bool, comptime
};
}
pub fn canBuildLibUbsanRt(target: *const std.Target, use_llvm: bool, comptime have_llvm: bool) bool {
pub fn canBuildLibUbsanRt(target: *const std.Target, use_llvm: bool, have_llvm: bool) bool {
switch (target.cpu.arch) {
.spirv32, .spirv64 => return false,
// 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
}
return switch (zigBackend(target, use_llvm)) {
.stage2_llvm => true,
.stage2_wasm => false,
.stage2_x86_64 => switch (target.ofmt) {
.elf, .macho => true,
else => have_llvm,
@ -860,6 +861,7 @@ pub fn zigBackend(target: *const std.Target, use_llvm: bool) std.builtin.Compile
pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, comptime feature: Feature) bool {
return switch (feature) {
.panic_fn => switch (backend) {
.stage2_aarch64,
.stage2_c,
.stage2_llvm,
.stage2_x86_64,

View File

@ -590,7 +590,6 @@ test "error union comptime caching" {
}
test "@errorName" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
@ -605,7 +604,6 @@ fn gimmeItBroke() anyerror {
}
test "@errorName sentinel length matches slice length" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
@ -883,7 +881,6 @@ test "catch within a function that calls no errorable functions" {
}
test "error from comptime string" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;

View File

@ -6,7 +6,6 @@ fn retAddr() usize {
}
test "return address" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;

View File

@ -19,4 +19,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -7,5 +7,5 @@ export fn entry3() callconv(.avr_interrupt) void {}
// target=aarch64-linux-none
//
// :1:30: error: calling convention 'x86_64_interrupt' only available on architectures 'x86_64'
// :1:30: error: calling convention 'x86_interrupt' only available on architectures 'x86'
// :1:30: error: calling convention 'avr_interrupt' only available on architectures 'avr'
// :2:30: error: calling convention 'x86_interrupt' only available on architectures 'x86'
// :3:30: error: calling convention 'avr_interrupt' only available on architectures 'avr'

View File

@ -25,7 +25,7 @@ pub fn main() Error!void {
// error
// backend=stage2
// target=native
// target=x86_64-linux
//
// :23:29: error: expected type 'error{InvalidCharacter}', found '@typeInfo(@typeInfo(@TypeOf(tmp.fooey)).@"fn".return_type.?).error_union.error_set'
// :23:29: note: 'error.InvalidDirection' not a member of destination error set

View File

@ -10,7 +10,7 @@ comptime {
// error
// backend=stage2
// target=native
// target=x86_64-linux
//
// :8:41: error: expected type '*align(2) const fn () void', found '*const fn () void'
// :8:41: note: pointer alignment '1' cannot cast into pointer alignment '2'

View File

@ -15,6 +15,6 @@ pub fn main() void {
// error
// backend=stage2
// target=native
// target=x86_64-linux
//
// :9:28: error: incompatible types: 'builtin.Type.EnumField' and 'void'

View File

@ -6,6 +6,6 @@ pub fn main() void {
// error
// backend=stage2
// target=native
// target=x86_64-linux
//
// :2:23: error: expected error union type, found 'bool'

View File

@ -1,7 +1,7 @@
const builtin = @import("builtin");
const std = @import("std");
fn _start() callconv(.naked) void {}
pub fn _start() callconv(.naked) void {}
comptime {
@export(&_start, .{ .name = if (builtin.cpu.arch.isMIPS()) "__start" else "_start" });

View File

@ -22,4 +22,4 @@ fn foo(bytes: []u8) u32 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -23,4 +23,4 @@ fn baz(_: Foo) void {}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -20,4 +20,4 @@ pub fn main() u8 {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -20,4 +20,4 @@ pub fn main() u8 {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -18,4 +18,4 @@ fn foo(set1: Set1) Set2 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -17,4 +17,4 @@ fn foo() anyerror!i32 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -19,4 +19,4 @@ fn bar(one: u1, not_zero: i32) void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -13,4 +13,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -13,4 +13,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -13,4 +13,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -13,4 +13,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -13,4 +13,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -13,4 +13,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -13,4 +13,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -13,4 +13,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -13,4 +13,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -13,4 +13,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -17,4 +17,4 @@ fn bar(a: f32) i8 {
fn baz(_: i8) void {}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -17,4 +17,4 @@ fn bar(a: f32) u8 {
fn baz(_: u8) void {}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -17,4 +17,4 @@ fn bar(a: f32) u8 {
fn baz(_: u8) void {}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -16,4 +16,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -16,4 +16,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -16,4 +16,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -23,4 +23,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -24,4 +24,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -16,4 +16,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -16,4 +16,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -24,4 +24,4 @@ fn bar(f: *Foo) void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -13,4 +13,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -18,4 +18,4 @@ fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -16,4 +16,4 @@ fn bar(x: u16) anyerror {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -18,4 +18,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -20,4 +20,4 @@ fn divExact(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -18,4 +18,4 @@ fn divExact(a: i32, b: i32) i32 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -22,4 +22,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -21,4 +21,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -18,4 +18,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -20,4 +20,4 @@ fn add(a: u16, b: u16) u16 {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -19,4 +19,4 @@ fn div0(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -17,4 +17,4 @@ fn div0(a: i32, b: i32) i32 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -18,4 +18,4 @@ fn mul(a: u16, b: u16) u16 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -18,4 +18,4 @@ fn neg(a: i16) i16 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -18,4 +18,4 @@ fn sub(a: u16, b: u16) u16 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -16,4 +16,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -16,4 +16,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -16,4 +16,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -15,4 +15,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -15,4 +15,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -17,4 +17,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -17,4 +17,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -17,4 +17,4 @@ fn div0(a: u32, b: u32) u32 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -17,4 +17,4 @@ fn mod0(a: i32, b: i32) i32 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -20,4 +20,4 @@ pub fn main() void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -16,4 +16,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -16,4 +16,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -19,4 +19,4 @@ fn foo() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -17,4 +17,4 @@ fn foo(a: u32) u32 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -18,4 +18,4 @@ fn bar(a: []const i32) i32 {
fn baz(_: i32) void {}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -18,4 +18,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -20,4 +20,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -18,4 +18,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -17,4 +17,4 @@ fn rem0(a: i32, b: i32) i32 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -19,4 +19,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -19,4 +19,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -20,4 +20,4 @@ fn div(a: @Vector(4, i16), b: @Vector(4, i16)) @Vector(4, i16) {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -18,4 +18,4 @@ fn div(a: i16, b: i16) i16 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -16,4 +16,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -17,4 +17,4 @@ fn unsigned_cast(x: i32) u32 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -18,4 +18,4 @@ fn shl(a: i16, b: u4) i16 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -18,4 +18,4 @@ fn shr(a: i16, b: u4) i16 {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -18,4 +18,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -15,4 +15,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -15,4 +15,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -17,4 +17,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux

View File

@ -17,4 +17,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -16,4 +16,4 @@ pub fn main() !void {
}
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -21,4 +21,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -20,4 +20,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -18,4 +18,4 @@ pub fn main() !void {
// run
// backend=stage2,llvm
// target=native
// target=x86_64-linux,aarch64-linux

View File

@ -24,4 +24,4 @@ const std = @import("std");
// run
// backend=stage2,llvm
// target=x86_64-linux
// target=x86_64-linux,aarch64-linux

View File

@ -24,4 +24,4 @@ const std = @import("std");
// run
// backend=stage2,llvm
// target=x86_64-linux
// target=x86_64-linux,aarch64-linux

View File

@ -24,4 +24,4 @@ const std = @import("std");
// run
// backend=stage2,llvm
// target=x86_64-linux
// target=x86_64-linux,aarch64-linux

Some files were not shown because too many files have changed in this diff Show More