Skip to content

Commit da408bd

Browse files
authored
Merge pull request #24585 from jacobly0/aarch64
aarch64: more progress
2 parents e12dc49 + 7894703 commit da408bd

File tree

137 files changed

+1590
-523
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

137 files changed

+1590
-523
lines changed

lib/compiler_rt.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ comptime {
240240
_ = @import("compiler_rt/udivmodti4.zig");
241241

242242
// extra
243-
if (builtin.zig_backend != .stage2_aarch64) _ = @import("compiler_rt/os_version_check.zig");
243+
_ = @import("compiler_rt/os_version_check.zig");
244244
_ = @import("compiler_rt/emutls.zig");
245245
_ = @import("compiler_rt/arm.zig");
246246
_ = @import("compiler_rt/aulldiv.zig");

src/Compilation.zig

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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/Package/Module.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
250250
};
251251

252252
const stack_check = b: {
253-
if (!target_util.supportsStackProbing(target)) {
253+
if (!target_util.supportsStackProbing(target, zig_backend)) {
254254
if (options.inherited.stack_check == true)
255255
return error.StackCheckUnsupportedByTarget;
256256
break :b false;

src/arch/x86_64/CodeGen.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168137,7 +168137,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
168137168137
.unused,
168138168138
.unused,
168139168139
},
168140-
.dst_temps = .{ .{ .cc = .b }, .unused },
168140+
.dst_temps = .{ .{ .cc = .be }, .unused },
168141168141
.clobbers = .{ .eflags = true },
168142168142
.each = .{ .once = &.{
168143168143
.{ ._, ._, .lea, .tmp1p, .lea(.tmp0), ._, ._ },
@@ -168161,7 +168161,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
168161168161
.unused,
168162168162
.unused,
168163168163
},
168164-
.dst_temps = .{ .{ .cc = .b }, .unused },
168164+
.dst_temps = .{ .{ .cc = .be }, .unused },
168165168165
.clobbers = .{ .eflags = true },
168166168166
.each = .{ .once = &.{
168167168167
.{ ._, ._, .lea, .tmp1p, .lea(.tmp0), ._, ._ },
@@ -168185,7 +168185,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
168185168185
.unused,
168186168186
.unused,
168187168187
},
168188-
.dst_temps = .{ .{ .cc = .b }, .unused },
168188+
.dst_temps = .{ .{ .cc = .be }, .unused },
168189168189
.clobbers = .{ .eflags = true },
168190168190
.each = .{ .once = &.{
168191168191
.{ ._, ._, .lea, .tmp1p, .lea(.tmp0), ._, ._ },

src/arch/x86_64/Emit.zig

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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,13 +168,15 @@ pub fn generate(
167168
.literals = &.{},
168169
.nav_relocs = &.{},
169170
.uav_relocs = &.{},
171+
.lazy_relocs = &.{},
170172
.global_relocs = &.{},
171173
.literal_relocs = &.{},
172174
};
173175
errdefer mir.deinit(gpa);
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

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@ pub const Operand = union(enum) {
66
};
77

88
pub 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

139+
fn 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+
128148
const token_buf_len = "v31.b[15]".len;
129149
fn 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

Lines changed: 106 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ epilogue: []const Instruction,
44
literals: []const u32,
55
nav_relocs: []const Reloc.Nav,
66
uav_relocs: []const Reloc.Uav,
7+
lazy_relocs: []const Reloc.Lazy,
78
global_relocs: []const Reloc.Global,
89
literal_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

0 commit comments

Comments
 (0)