mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Merge pull request #21174 from alexrp/win-arm
Change `arm-windows-gnu` to `thumb-windows-gnu`, plus some initial port work
This commit is contained in:
commit
a4cc43c42b
@ -2,6 +2,7 @@
|
||||
//! This file includes all ARM-only functions.
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const target = builtin.target;
|
||||
const arch = builtin.cpu.arch;
|
||||
const common = @import("common.zig");
|
||||
|
||||
@ -14,11 +15,11 @@ comptime {
|
||||
@export(&__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = common.linkage, .visibility = common.visibility });
|
||||
|
||||
@export(&__aeabi_ldivmod, .{ .name = "__aeabi_ldivmod", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&__aeabi_uldivmod, .{ .name = "__aeabi_uldivmod", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&__aeabi_ldivmod, .{ .name = if (target.isMinGW()) "__rt_sdiv64" else "__aeabi_ldivmod", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&__aeabi_uldivmod, .{ .name = if (target.isMinGW()) "__rt_udiv64" else "__aeabi_uldivmod", .linkage = common.linkage, .visibility = common.visibility });
|
||||
|
||||
@export(&__aeabi_idivmod, .{ .name = "__aeabi_idivmod", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&__aeabi_uidivmod, .{ .name = "__aeabi_uidivmod", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&__aeabi_idivmod, .{ .name = if (target.isMinGW()) "__rt_sdiv" else "__aeabi_idivmod", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&__aeabi_uidivmod, .{ .name = if (target.isMinGW()) "__rt_udiv" else "__aeabi_uidivmod", .linkage = common.linkage, .visibility = common.visibility });
|
||||
|
||||
@export(&__aeabi_memcpy, .{ .name = "__aeabi_memcpy", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&__aeabi_memcpy4, .{ .name = "__aeabi_memcpy4", .linkage = common.linkage, .visibility = common.visibility });
|
||||
|
||||
@ -5,9 +5,6 @@ const arch = builtin.cpu.arch;
|
||||
const abi = builtin.abi;
|
||||
const is_test = builtin.is_test;
|
||||
|
||||
const is_gnu = abi.isGnu();
|
||||
const is_mingw = os_tag == .windows and is_gnu;
|
||||
|
||||
const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .internal else .weak;
|
||||
const strong_linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .internal else .strong;
|
||||
pub const panic = @import("common.zig").panic;
|
||||
@ -15,11 +12,11 @@ pub const panic = @import("common.zig").panic;
|
||||
comptime {
|
||||
if (builtin.os.tag == .windows) {
|
||||
// Default stack-probe functions emitted by LLVM
|
||||
if (is_mingw) {
|
||||
if (builtin.target.isMinGW()) {
|
||||
@export(&_chkstk, .{ .name = "_alloca", .linkage = linkage });
|
||||
@export(&___chkstk_ms, .{ .name = "___chkstk_ms", .linkage = linkage });
|
||||
|
||||
if (arch.isAARCH64()) {
|
||||
if (arch == .thumb or arch == .aarch64) {
|
||||
@export(&__chkstk, .{ .name = "__chkstk", .linkage = linkage });
|
||||
}
|
||||
} else if (!builtin.link_libc) {
|
||||
@ -100,6 +97,35 @@ fn win_probe_stack_only() void {
|
||||
@setRuntimeSafety(false);
|
||||
|
||||
switch (arch) {
|
||||
.thumb => {
|
||||
asm volatile (
|
||||
\\ lsl r4, r4, #2
|
||||
\\ mov r12, sp
|
||||
\\ push {r5, r6}
|
||||
\\ mov r5, r4
|
||||
\\1:
|
||||
\\ sub r12, r12, #4096
|
||||
\\ subs r5, r5, #4096
|
||||
\\ ldr r6, [r12]
|
||||
\\ bgt 1b
|
||||
\\ pop {r5, r6}
|
||||
\\ bx lr
|
||||
);
|
||||
},
|
||||
.aarch64 => {
|
||||
asm volatile (
|
||||
\\ lsl x16, x15, #4
|
||||
\\ mov x17, sp
|
||||
\\1:
|
||||
\\
|
||||
\\ sub x17, x17, 4096
|
||||
\\ subs x16, x16, 4096
|
||||
\\ ldr xzr, [x17]
|
||||
\\ b.gt 1b
|
||||
\\
|
||||
\\ ret
|
||||
);
|
||||
},
|
||||
.x86_64 => {
|
||||
asm volatile (
|
||||
\\ push %%rcx
|
||||
@ -144,21 +170,6 @@ fn win_probe_stack_only() void {
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
if (comptime arch.isAARCH64()) {
|
||||
// NOTE: page size hardcoded to 4096 for now
|
||||
asm volatile (
|
||||
\\ lsl x16, x15, #4
|
||||
\\ mov x17, sp
|
||||
\\1:
|
||||
\\
|
||||
\\ sub x17, x17, 4096
|
||||
\\ subs x16, x16, 4096
|
||||
\\ ldr xzr, [x17]
|
||||
\\ b.gt 1b
|
||||
\\
|
||||
\\ ret
|
||||
);
|
||||
}
|
||||
|
||||
unreachable;
|
||||
}
|
||||
@ -240,7 +251,7 @@ pub fn _chkstk() callconv(.Naked) void {
|
||||
}
|
||||
pub fn __chkstk() callconv(.Naked) void {
|
||||
@setRuntimeSafety(false);
|
||||
if (comptime arch.isAARCH64()) {
|
||||
if (arch == .thumb or arch == .aarch64) {
|
||||
@call(.always_inline, win_probe_stack_only, .{});
|
||||
} else switch (arch) {
|
||||
.x86 => @call(.always_inline, win_probe_stack_adjust_sp, .{}),
|
||||
|
||||
@ -603,7 +603,7 @@ pub const VaList = switch (builtin.cpu.arch) {
|
||||
.ios, .macos, .tvos, .watchos, .visionos => *u8,
|
||||
else => @compileError("disabled due to miscompilations"), // VaListAarch64,
|
||||
},
|
||||
.arm => switch (builtin.os.tag) {
|
||||
.arm, .armeb, .thumb, .thumbeb => switch (builtin.os.tag) {
|
||||
.ios, .macos, .tvos, .watchos, .visionos => *u8,
|
||||
else => *anyopaque,
|
||||
},
|
||||
|
||||
@ -789,7 +789,7 @@ pub noinline fn walkStackWindows(addresses: []usize, existing_context: ?*const w
|
||||
}
|
||||
|
||||
var i: usize = 0;
|
||||
var image_base: usize = undefined;
|
||||
var image_base: windows.DWORD64 = undefined;
|
||||
var history_table: windows.UNWIND_HISTORY_TABLE = std.mem.zeroes(windows.UNWIND_HISTORY_TABLE);
|
||||
|
||||
while (i < addresses.len) : (i += 1) {
|
||||
@ -809,7 +809,7 @@ pub noinline fn walkStackWindows(addresses: []usize, existing_context: ?*const w
|
||||
);
|
||||
} else {
|
||||
// leaf function
|
||||
context.setIp(@as(*u64, @ptrFromInt(current_regs.sp)).*);
|
||||
context.setIp(@as(*usize, @ptrFromInt(current_regs.sp)).*);
|
||||
context.setSp(current_regs.sp + @sizeOf(usize));
|
||||
}
|
||||
|
||||
|
||||
@ -2123,6 +2123,10 @@ pub fn teb() *TEB {
|
||||
);
|
||||
}
|
||||
},
|
||||
.thumb => asm (
|
||||
\\ mrc p15, 0, %[ptr], c13, c0, 2
|
||||
: [ptr] "=r" (-> *TEB),
|
||||
),
|
||||
.aarch64 => asm (
|
||||
\\ mov %[ptr], x18
|
||||
: [ptr] "=r" (-> *TEB),
|
||||
@ -4120,6 +4124,10 @@ pub const XMM_SAVE_AREA32 = switch (native_arch) {
|
||||
};
|
||||
|
||||
pub const NEON128 = switch (native_arch) {
|
||||
.thumb => extern struct {
|
||||
Low: ULONGLONG,
|
||||
High: LONGLONG,
|
||||
},
|
||||
.aarch64 => extern union {
|
||||
DUMMYSTRUCTNAME: extern struct {
|
||||
Low: ULONGLONG,
|
||||
@ -4248,6 +4256,54 @@ pub const CONTEXT = switch (native_arch) {
|
||||
ctx.Rsp = sp;
|
||||
}
|
||||
},
|
||||
.thumb => extern struct {
|
||||
ContextFlags: ULONG,
|
||||
R0: ULONG,
|
||||
R1: ULONG,
|
||||
R2: ULONG,
|
||||
R3: ULONG,
|
||||
R4: ULONG,
|
||||
R5: ULONG,
|
||||
R6: ULONG,
|
||||
R7: ULONG,
|
||||
R8: ULONG,
|
||||
R9: ULONG,
|
||||
R10: ULONG,
|
||||
R11: ULONG,
|
||||
R12: ULONG,
|
||||
Sp: ULONG,
|
||||
Lr: ULONG,
|
||||
Pc: ULONG,
|
||||
Cpsr: ULONG,
|
||||
Fpcsr: ULONG,
|
||||
Padding: ULONG,
|
||||
DUMMYUNIONNAME: extern union {
|
||||
Q: [16]NEON128,
|
||||
D: [32]ULONGLONG,
|
||||
S: [32]ULONG,
|
||||
},
|
||||
Bvr: [8]ULONG,
|
||||
Bcr: [8]ULONG,
|
||||
Wvr: [1]ULONG,
|
||||
Wcr: [1]ULONG,
|
||||
Padding2: [2]ULONG,
|
||||
|
||||
pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize, sp: usize } {
|
||||
return .{
|
||||
.bp = ctx.DUMMYUNIONNAME.S[11],
|
||||
.ip = ctx.Pc,
|
||||
.sp = ctx.Sp,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn setIp(ctx: *CONTEXT, ip: usize) void {
|
||||
ctx.Pc = ip;
|
||||
}
|
||||
|
||||
pub fn setSp(ctx: *CONTEXT, sp: usize) void {
|
||||
ctx.Sp = sp;
|
||||
}
|
||||
},
|
||||
.aarch64 => extern struct {
|
||||
ContextFlags: ULONG align(16),
|
||||
Cpsr: ULONG,
|
||||
@ -4322,6 +4378,23 @@ pub const RUNTIME_FUNCTION = switch (native_arch) {
|
||||
EndAddress: DWORD,
|
||||
UnwindData: DWORD,
|
||||
},
|
||||
.thumb => extern struct {
|
||||
BeginAddress: DWORD,
|
||||
DUMMYUNIONNAME: extern union {
|
||||
UnwindData: DWORD,
|
||||
DUMMYSTRUCTNAME: packed struct {
|
||||
Flag: u2,
|
||||
FunctionLength: u11,
|
||||
Ret: u2,
|
||||
H: u1,
|
||||
Reg: u3,
|
||||
R: u1,
|
||||
L: u1,
|
||||
C: u1,
|
||||
StackAdjust: u10,
|
||||
},
|
||||
},
|
||||
},
|
||||
.aarch64 => extern struct {
|
||||
BeginAddress: DWORD,
|
||||
DUMMYUNIONNAME: extern union {
|
||||
@ -4345,6 +4418,25 @@ pub const KNONVOLATILE_CONTEXT_POINTERS = switch (native_arch) {
|
||||
FloatingContext: [16]?*M128A,
|
||||
IntegerContext: [16]?*ULONG64,
|
||||
},
|
||||
.thumb => extern struct {
|
||||
R4: ?*DWORD,
|
||||
R5: ?*DWORD,
|
||||
R6: ?*DWORD,
|
||||
R7: ?*DWORD,
|
||||
R8: ?*DWORD,
|
||||
R9: ?*DWORD,
|
||||
R10: ?*DWORD,
|
||||
R11: ?*DWORD,
|
||||
Lr: ?*DWORD,
|
||||
D8: ?*ULONGLONG,
|
||||
D9: ?*ULONGLONG,
|
||||
D10: ?*ULONGLONG,
|
||||
D11: ?*ULONGLONG,
|
||||
D12: ?*ULONGLONG,
|
||||
D13: ?*ULONGLONG,
|
||||
D14: ?*ULONGLONG,
|
||||
D15: ?*ULONGLONG,
|
||||
},
|
||||
.aarch64 => extern struct {
|
||||
X19: ?*DWORD64,
|
||||
X20: ?*DWORD64,
|
||||
|
||||
@ -580,10 +580,10 @@ pub const Installation = struct {
|
||||
defer options_key.closeKey();
|
||||
|
||||
const option_name = comptime switch (builtin.target.cpu.arch) {
|
||||
.arm, .armeb => "OptionId.DesktopCPParm",
|
||||
.thumb => "OptionId.DesktopCPParm",
|
||||
.aarch64 => "OptionId.DesktopCPParm64",
|
||||
.x86_64 => "OptionId.DesktopCPPx64",
|
||||
.x86 => "OptionId.DesktopCPPx86",
|
||||
.x86_64 => "OptionId.DesktopCPPx64",
|
||||
else => |tag| @compileError("Windows SDK cannot be detected on architecture " ++ tag),
|
||||
};
|
||||
|
||||
@ -824,10 +824,10 @@ const MsvcLibDir = struct {
|
||||
try lib_dir_buf.appendSlice("VC\\Tools\\MSVC\\");
|
||||
try lib_dir_buf.appendSlice(default_tools_version);
|
||||
const folder_with_arch = "\\Lib\\" ++ comptime switch (builtin.target.cpu.arch) {
|
||||
.thumb => "arm",
|
||||
.aarch64 => "arm64",
|
||||
.x86 => "x86",
|
||||
.x86_64 => "x64",
|
||||
.arm, .armeb => "arm",
|
||||
.aarch64 => "arm64",
|
||||
else => |tag| @compileError("MSVC lib dir cannot be detected on architecture " ++ tag),
|
||||
};
|
||||
try lib_dir_buf.appendSlice(folder_with_arch);
|
||||
@ -909,10 +909,10 @@ const MsvcLibDir = struct {
|
||||
}
|
||||
|
||||
const folder_with_arch = "\\Lib\\" ++ comptime switch (builtin.target.cpu.arch) {
|
||||
.thumb => "arm",
|
||||
.aarch64 => "arm64",
|
||||
.x86 => "x86",
|
||||
.x86_64 => "x64",
|
||||
.arm, .armeb => "arm",
|
||||
.aarch64 => "arm64",
|
||||
else => |tag| @compileError("MSVC lib dir cannot be detected on architecture " ++ tag),
|
||||
};
|
||||
|
||||
@ -977,10 +977,10 @@ const MsvcLibDir = struct {
|
||||
errdefer base_path.deinit();
|
||||
|
||||
const folder_with_arch = "\\VC\\lib\\" ++ comptime switch (builtin.target.cpu.arch) {
|
||||
.thumb => "arm",
|
||||
.aarch64 => "arm64",
|
||||
.x86 => "", //x86 is in the root of the Lib folder
|
||||
.x86_64 => "amd64",
|
||||
.arm, .armeb => "arm",
|
||||
.aarch64 => "arm64",
|
||||
else => |tag| @compileError("MSVC lib dir cannot be detected on architecture " ++ tag),
|
||||
};
|
||||
try base_path.appendSlice(folder_with_arch);
|
||||
|
||||
@ -32,7 +32,7 @@ pub const available_libcs = [_]ArchOsAbi{
|
||||
.{ .arch = .thumbeb, .os = .linux, .abi = .gnueabihf },
|
||||
.{ .arch = .thumbeb, .os = .linux, .abi = .musleabi },
|
||||
.{ .arch = .thumbeb, .os = .linux, .abi = .musleabihf },
|
||||
.{ .arch = .arm, .os = .windows, .abi = .gnu },
|
||||
.{ .arch = .thumb, .os = .windows, .abi = .gnu },
|
||||
.{ .arch = .csky, .os = .linux, .abi = .gnueabi, .glibc_min = .{ .major = 2, .minor = 29, .patch = 0 } },
|
||||
.{ .arch = .csky, .os = .linux, .abi = .gnueabihf, .glibc_min = .{ .major = 2, .minor = 29, .patch = 0 } },
|
||||
.{ .arch = .x86, .os = .linux, .abi = .gnu },
|
||||
|
||||
@ -276,7 +276,7 @@ pub fn createEmpty(
|
||||
.image_base = options.image_base orelse switch (output_mode) {
|
||||
.Exe => switch (target.cpu.arch) {
|
||||
.aarch64 => 0x140000000,
|
||||
.x86_64, .x86 => 0x400000,
|
||||
.thumb, .x86_64, .x86 => 0x400000,
|
||||
else => unreachable,
|
||||
},
|
||||
.Lib => 0x10000000,
|
||||
|
||||
@ -95,7 +95,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: std.Progre
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (target.cpu.arch.isARM()) {
|
||||
} else if (target.cpu.arch.isThumb()) {
|
||||
for (mingw32_arm32_src) |dep| {
|
||||
try c_source_files.append(.{
|
||||
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
|
||||
@ -139,7 +139,7 @@ fn add_cc_args(
|
||||
});
|
||||
|
||||
const target = comp.getTarget();
|
||||
if (target.cpu.arch.isARM() and target.ptrBitWidth() == 32) {
|
||||
if (target.cpu.arch.isThumb()) {
|
||||
try args.append("-mfpu=vfp");
|
||||
}
|
||||
|
||||
@ -222,10 +222,10 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
|
||||
});
|
||||
|
||||
const target_defines = switch (target.cpu.arch) {
|
||||
.thumb => "#define DEF_ARM32\n",
|
||||
.aarch64 => "#define DEF_ARM64\n",
|
||||
.x86 => "#define DEF_I386\n",
|
||||
.x86_64 => "#define DEF_X64\n",
|
||||
.arm, .armeb, .thumb, .thumbeb => "#define DEF_ARM32\n",
|
||||
.aarch64, .aarch64_be => "#define DEF_ARM64\n",
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
@ -321,10 +321,10 @@ fn findDef(
|
||||
lib_name: []const u8,
|
||||
) ![]u8 {
|
||||
const lib_path = switch (target.cpu.arch) {
|
||||
.thumb => "libarm32",
|
||||
.aarch64 => "libarm64",
|
||||
.x86 => "lib32",
|
||||
.x86_64 => "lib64",
|
||||
.arm, .armeb, .thumb, .thumbeb => "libarm32",
|
||||
.aarch64, .aarch64_be => "libarm64",
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user