authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-30 14:34:53-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-08-30 14:34:53-07:00
loga4cc43c42b5e139276190dc426aa5ecb3564c52d
treed66ab8eb0531c2a69d7be15aec1e50879be1cc23
parent5723fcaac1b473acee2fb3f5ea5486527eac5359
parent832f74876e557f25e7d4b202b40d24976a6e20a1
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21174 from alexrp/win-arm

Change `arm-windows-gnu` to `thumb-windows-gnu`, plus some initial port work

9 files changed, 148 insertions(+), 44 deletions(-)

lib/compiler_rt/arm.zig+5-4
......@@ -2,6 +2,7 @@
22//! This file includes all ARM-only functions.
33const std = @import("std");
44const builtin = @import("builtin");
5const target = builtin.target;
56const arch = builtin.cpu.arch;
67const common = @import("common.zig");
78
......@@ -14,11 +15,11 @@ comptime {
1415 @export(&__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = common.linkage, .visibility = common.visibility });
1516 @export(&__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = common.linkage, .visibility = common.visibility });
1617
17 @export(&__aeabi_ldivmod, .{ .name = "__aeabi_ldivmod", .linkage = common.linkage, .visibility = common.visibility });
18 @export(&__aeabi_uldivmod, .{ .name = "__aeabi_uldivmod", .linkage = common.linkage, .visibility = common.visibility });
18 @export(&__aeabi_ldivmod, .{ .name = if (target.isMinGW()) "__rt_sdiv64" else "__aeabi_ldivmod", .linkage = common.linkage, .visibility = common.visibility });
19 @export(&__aeabi_uldivmod, .{ .name = if (target.isMinGW()) "__rt_udiv64" else "__aeabi_uldivmod", .linkage = common.linkage, .visibility = common.visibility });
1920
20 @export(&__aeabi_idivmod, .{ .name = "__aeabi_idivmod", .linkage = common.linkage, .visibility = common.visibility });
21 @export(&__aeabi_uidivmod, .{ .name = "__aeabi_uidivmod", .linkage = common.linkage, .visibility = common.visibility });
21 @export(&__aeabi_idivmod, .{ .name = if (target.isMinGW()) "__rt_sdiv" else "__aeabi_idivmod", .linkage = common.linkage, .visibility = common.visibility });
22 @export(&__aeabi_uidivmod, .{ .name = if (target.isMinGW()) "__rt_udiv" else "__aeabi_uidivmod", .linkage = common.linkage, .visibility = common.visibility });
2223
2324 @export(&__aeabi_memcpy, .{ .name = "__aeabi_memcpy", .linkage = common.linkage, .visibility = common.visibility });
2425 @export(&__aeabi_memcpy4, .{ .name = "__aeabi_memcpy4", .linkage = common.linkage, .visibility = common.visibility });
lib/compiler_rt/stack_probe.zig+32-21
......@@ -5,9 +5,6 @@ const arch = builtin.cpu.arch;
55const abi = builtin.abi;
66const is_test = builtin.is_test;
77
8const is_gnu = abi.isGnu();
9const is_mingw = os_tag == .windows and is_gnu;
10
118const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .internal else .weak;
129const strong_linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .internal else .strong;
1310pub const panic = @import("common.zig").panic;
......@@ -15,11 +12,11 @@ pub const panic = @import("common.zig").panic;
1512comptime {
1613 if (builtin.os.tag == .windows) {
1714 // Default stack-probe functions emitted by LLVM
18 if (is_mingw) {
15 if (builtin.target.isMinGW()) {
1916 @export(&_chkstk, .{ .name = "_alloca", .linkage = linkage });
2017 @export(&___chkstk_ms, .{ .name = "___chkstk_ms", .linkage = linkage });
2118
22 if (arch.isAARCH64()) {
19 if (arch == .thumb or arch == .aarch64) {
2320 @export(&__chkstk, .{ .name = "__chkstk", .linkage = linkage });
2421 }
2522 } else if (!builtin.link_libc) {
......@@ -100,6 +97,35 @@ fn win_probe_stack_only() void {
10097 @setRuntimeSafety(false);
10198
10299 switch (arch) {
100 .thumb => {
101 asm volatile (
102 \\ lsl r4, r4, #2
103 \\ mov r12, sp
104 \\ push {r5, r6}
105 \\ mov r5, r4
106 \\1:
107 \\ sub r12, r12, #4096
108 \\ subs r5, r5, #4096
109 \\ ldr r6, [r12]
110 \\ bgt 1b
111 \\ pop {r5, r6}
112 \\ bx lr
113 );
114 },
115 .aarch64 => {
116 asm volatile (
117 \\ lsl x16, x15, #4
118 \\ mov x17, sp
119 \\1:
120 \\
121 \\ sub x17, x17, 4096
122 \\ subs x16, x16, 4096
123 \\ ldr xzr, [x17]
124 \\ b.gt 1b
125 \\
126 \\ ret
127 );
128 },
103129 .x86_64 => {
104130 asm volatile (
105131 \\ push %%rcx
......@@ -144,21 +170,6 @@ fn win_probe_stack_only() void {
144170 },
145171 else => {},
146172 }
147 if (comptime arch.isAARCH64()) {
148 // NOTE: page size hardcoded to 4096 for now
149 asm volatile (
150 \\ lsl x16, x15, #4
151 \\ mov x17, sp
152 \\1:
153 \\
154 \\ sub x17, x17, 4096
155 \\ subs x16, x16, 4096
156 \\ ldr xzr, [x17]
157 \\ b.gt 1b
158 \\
159 \\ ret
160 );
161 }
162173
163174 unreachable;
164175}
......@@ -240,7 +251,7 @@ pub fn _chkstk() callconv(.Naked) void {
240251}
241252pub fn __chkstk() callconv(.Naked) void {
242253 @setRuntimeSafety(false);
243 if (comptime arch.isAARCH64()) {
254 if (arch == .thumb or arch == .aarch64) {
244255 @call(.always_inline, win_probe_stack_only, .{});
245256 } else switch (arch) {
246257 .x86 => @call(.always_inline, win_probe_stack_adjust_sp, .{}),
lib/std/builtin.zig+1-1
......@@ -603,7 +603,7 @@ pub const VaList = switch (builtin.cpu.arch) {
603603 .ios, .macos, .tvos, .watchos, .visionos => *u8,
604604 else => @compileError("disabled due to miscompilations"), // VaListAarch64,
605605 },
606 .arm => switch (builtin.os.tag) {
606 .arm, .armeb, .thumb, .thumbeb => switch (builtin.os.tag) {
607607 .ios, .macos, .tvos, .watchos, .visionos => *u8,
608608 else => *anyopaque,
609609 },
lib/std/debug.zig+2-2
......@@ -789,7 +789,7 @@ pub noinline fn walkStackWindows(addresses: []usize, existing_context: ?*const w
789789 }
790790
791791 var i: usize = 0;
792 var image_base: usize = undefined;
792 var image_base: windows.DWORD64 = undefined;
793793 var history_table: windows.UNWIND_HISTORY_TABLE = std.mem.zeroes(windows.UNWIND_HISTORY_TABLE);
794794
795795 while (i < addresses.len) : (i += 1) {
......@@ -809,7 +809,7 @@ pub noinline fn walkStackWindows(addresses: []usize, existing_context: ?*const w
809809 );
810810 } else {
811811 // leaf function
812 context.setIp(@as(*u64, @ptrFromInt(current_regs.sp)).*);
812 context.setIp(@as(*usize, @ptrFromInt(current_regs.sp)).*);
813813 context.setSp(current_regs.sp + @sizeOf(usize));
814814 }
815815
lib/std/os/windows.zig+92
......@@ -2123,6 +2123,10 @@ pub fn teb() *TEB {
21232123 );
21242124 }
21252125 },
2126 .thumb => asm (
2127 \\ mrc p15, 0, %[ptr], c13, c0, 2
2128 : [ptr] "=r" (-> *TEB),
2129 ),
21262130 .aarch64 => asm (
21272131 \\ mov %[ptr], x18
21282132 : [ptr] "=r" (-> *TEB),
......@@ -4120,6 +4124,10 @@ pub const XMM_SAVE_AREA32 = switch (native_arch) {
41204124};
41214125
41224126pub const NEON128 = switch (native_arch) {
4127 .thumb => extern struct {
4128 Low: ULONGLONG,
4129 High: LONGLONG,
4130 },
41234131 .aarch64 => extern union {
41244132 DUMMYSTRUCTNAME: extern struct {
41254133 Low: ULONGLONG,
......@@ -4248,6 +4256,54 @@ pub const CONTEXT = switch (native_arch) {
42484256 ctx.Rsp = sp;
42494257 }
42504258 },
4259 .thumb => extern struct {
4260 ContextFlags: ULONG,
4261 R0: ULONG,
4262 R1: ULONG,
4263 R2: ULONG,
4264 R3: ULONG,
4265 R4: ULONG,
4266 R5: ULONG,
4267 R6: ULONG,
4268 R7: ULONG,
4269 R8: ULONG,
4270 R9: ULONG,
4271 R10: ULONG,
4272 R11: ULONG,
4273 R12: ULONG,
4274 Sp: ULONG,
4275 Lr: ULONG,
4276 Pc: ULONG,
4277 Cpsr: ULONG,
4278 Fpcsr: ULONG,
4279 Padding: ULONG,
4280 DUMMYUNIONNAME: extern union {
4281 Q: [16]NEON128,
4282 D: [32]ULONGLONG,
4283 S: [32]ULONG,
4284 },
4285 Bvr: [8]ULONG,
4286 Bcr: [8]ULONG,
4287 Wvr: [1]ULONG,
4288 Wcr: [1]ULONG,
4289 Padding2: [2]ULONG,
4290
4291 pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize, sp: usize } {
4292 return .{
4293 .bp = ctx.DUMMYUNIONNAME.S[11],
4294 .ip = ctx.Pc,
4295 .sp = ctx.Sp,
4296 };
4297 }
4298
4299 pub fn setIp(ctx: *CONTEXT, ip: usize) void {
4300 ctx.Pc = ip;
4301 }
4302
4303 pub fn setSp(ctx: *CONTEXT, sp: usize) void {
4304 ctx.Sp = sp;
4305 }
4306 },
42514307 .aarch64 => extern struct {
42524308 ContextFlags: ULONG align(16),
42534309 Cpsr: ULONG,
......@@ -4322,6 +4378,23 @@ pub const RUNTIME_FUNCTION = switch (native_arch) {
43224378 EndAddress: DWORD,
43234379 UnwindData: DWORD,
43244380 },
4381 .thumb => extern struct {
4382 BeginAddress: DWORD,
4383 DUMMYUNIONNAME: extern union {
4384 UnwindData: DWORD,
4385 DUMMYSTRUCTNAME: packed struct {
4386 Flag: u2,
4387 FunctionLength: u11,
4388 Ret: u2,
4389 H: u1,
4390 Reg: u3,
4391 R: u1,
4392 L: u1,
4393 C: u1,
4394 StackAdjust: u10,
4395 },
4396 },
4397 },
43254398 .aarch64 => extern struct {
43264399 BeginAddress: DWORD,
43274400 DUMMYUNIONNAME: extern union {
......@@ -4345,6 +4418,25 @@ pub const KNONVOLATILE_CONTEXT_POINTERS = switch (native_arch) {
43454418 FloatingContext: [16]?*M128A,
43464419 IntegerContext: [16]?*ULONG64,
43474420 },
4421 .thumb => extern struct {
4422 R4: ?*DWORD,
4423 R5: ?*DWORD,
4424 R6: ?*DWORD,
4425 R7: ?*DWORD,
4426 R8: ?*DWORD,
4427 R9: ?*DWORD,
4428 R10: ?*DWORD,
4429 R11: ?*DWORD,
4430 Lr: ?*DWORD,
4431 D8: ?*ULONGLONG,
4432 D9: ?*ULONGLONG,
4433 D10: ?*ULONGLONG,
4434 D11: ?*ULONGLONG,
4435 D12: ?*ULONGLONG,
4436 D13: ?*ULONGLONG,
4437 D14: ?*ULONGLONG,
4438 D15: ?*ULONGLONG,
4439 },
43484440 .aarch64 => extern struct {
43494441 X19: ?*DWORD64,
43504442 X20: ?*DWORD64,
lib/std/zig/WindowsSdk.zig+8-8
......@@ -580,10 +580,10 @@ pub const Installation = struct {
580580 defer options_key.closeKey();
581581
582582 const option_name = comptime switch (builtin.target.cpu.arch) {
583 .arm, .armeb => "OptionId.DesktopCPParm",
583 .thumb => "OptionId.DesktopCPParm",
584584 .aarch64 => "OptionId.DesktopCPParm64",
585 .x86_64 => "OptionId.DesktopCPPx64",
586585 .x86 => "OptionId.DesktopCPPx86",
586 .x86_64 => "OptionId.DesktopCPPx64",
587587 else => |tag| @compileError("Windows SDK cannot be detected on architecture " ++ tag),
588588 };
589589
......@@ -824,10 +824,10 @@ const MsvcLibDir = struct {
824824 try lib_dir_buf.appendSlice("VC\\Tools\\MSVC\\");
825825 try lib_dir_buf.appendSlice(default_tools_version);
826826 const folder_with_arch = "\\Lib\\" ++ comptime switch (builtin.target.cpu.arch) {
827 .thumb => "arm",
828 .aarch64 => "arm64",
827829 .x86 => "x86",
828830 .x86_64 => "x64",
829 .arm, .armeb => "arm",
830 .aarch64 => "arm64",
831831 else => |tag| @compileError("MSVC lib dir cannot be detected on architecture " ++ tag),
832832 };
833833 try lib_dir_buf.appendSlice(folder_with_arch);
......@@ -909,10 +909,10 @@ const MsvcLibDir = struct {
909909 }
910910
911911 const folder_with_arch = "\\Lib\\" ++ comptime switch (builtin.target.cpu.arch) {
912 .thumb => "arm",
913 .aarch64 => "arm64",
912914 .x86 => "x86",
913915 .x86_64 => "x64",
914 .arm, .armeb => "arm",
915 .aarch64 => "arm64",
916916 else => |tag| @compileError("MSVC lib dir cannot be detected on architecture " ++ tag),
917917 };
918918
......@@ -977,10 +977,10 @@ const MsvcLibDir = struct {
977977 errdefer base_path.deinit();
978978
979979 const folder_with_arch = "\\VC\\lib\\" ++ comptime switch (builtin.target.cpu.arch) {
980 .thumb => "arm",
981 .aarch64 => "arm64",
980982 .x86 => "", //x86 is in the root of the Lib folder
981983 .x86_64 => "amd64",
982 .arm, .armeb => "arm",
983 .aarch64 => "arm64",
984984 else => |tag| @compileError("MSVC lib dir cannot be detected on architecture " ++ tag),
985985 };
986986 try base_path.appendSlice(folder_with_arch);
lib/std/zig/target.zig+1-1
......@@ -32,7 +32,7 @@ pub const available_libcs = [_]ArchOsAbi{
3232 .{ .arch = .thumbeb, .os = .linux, .abi = .gnueabihf },
3333 .{ .arch = .thumbeb, .os = .linux, .abi = .musleabi },
3434 .{ .arch = .thumbeb, .os = .linux, .abi = .musleabihf },
35 .{ .arch = .arm, .os = .windows, .abi = .gnu },
35 .{ .arch = .thumb, .os = .windows, .abi = .gnu },
3636 .{ .arch = .csky, .os = .linux, .abi = .gnueabi, .glibc_min = .{ .major = 2, .minor = 29, .patch = 0 } },
3737 .{ .arch = .csky, .os = .linux, .abi = .gnueabihf, .glibc_min = .{ .major = 2, .minor = 29, .patch = 0 } },
3838 .{ .arch = .x86, .os = .linux, .abi = .gnu },
src/link/Coff.zig+1-1
......@@ -276,7 +276,7 @@ pub fn createEmpty(
276276 .image_base = options.image_base orelse switch (output_mode) {
277277 .Exe => switch (target.cpu.arch) {
278278 .aarch64 => 0x140000000,
279 .x86_64, .x86 => 0x400000,
279 .thumb, .x86_64, .x86 => 0x400000,
280280 else => unreachable,
281281 },
282282 .Lib => 0x10000000,
src/mingw.zig+6-6
......@@ -95,7 +95,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: std.Progre
9595 });
9696 }
9797 }
98 } else if (target.cpu.arch.isARM()) {
98 } else if (target.cpu.arch.isThumb()) {
9999 for (mingw32_arm32_src) |dep| {
100100 try c_source_files.append(.{
101101 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
......@@ -139,7 +139,7 @@ fn add_cc_args(
139139 });
140140
141141 const target = comp.getTarget();
142 if (target.cpu.arch.isARM() and target.ptrBitWidth() == 32) {
142 if (target.cpu.arch.isThumb()) {
143143 try args.append("-mfpu=vfp");
144144 }
145145
......@@ -222,10 +222,10 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
222222 });
223223
224224 const target_defines = switch (target.cpu.arch) {
225 .thumb => "#define DEF_ARM32\n",
226 .aarch64 => "#define DEF_ARM64\n",
225227 .x86 => "#define DEF_I386\n",
226228 .x86_64 => "#define DEF_X64\n",
227 .arm, .armeb, .thumb, .thumbeb => "#define DEF_ARM32\n",
228 .aarch64, .aarch64_be => "#define DEF_ARM64\n",
229229 else => unreachable,
230230 };
231231
......@@ -321,10 +321,10 @@ fn findDef(
321321 lib_name: []const u8,
322322) ![]u8 {
323323 const lib_path = switch (target.cpu.arch) {
324 .thumb => "libarm32",
325 .aarch64 => "libarm64",
324326 .x86 => "lib32",
325327 .x86_64 => "lib64",
326 .arm, .armeb, .thumb, .thumbeb => "libarm32",
327 .aarch64, .aarch64_be => "libarm64",
328328 else => unreachable,
329329 };
330330