Merge branch 'master' into zon/serializer-unicode-escaping

This commit is contained in:
Nurul Huda (Apon) 2025-10-24 22:09:56 +06:00 committed by GitHub
commit a57a46d86f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 1349 additions and 309 deletions

File diff suppressed because it is too large Load diff

View file

@ -1235,6 +1235,18 @@ const LinuxThreadImpl = struct {
: [ptr] "r" (@intFromPtr(self.mapped.ptr)), : [ptr] "r" (@intFromPtr(self.mapped.ptr)),
[len] "r" (self.mapped.len), [len] "r" (self.mapped.len),
: .{ .memory = true }), : .{ .memory = true }),
.alpha => asm volatile (
\\ ldi $0, 73 # SYS_munmap
\\ mov %[ptr], $16
\\ mov %[len], $17
\\ callsys
\\ ldi $0, 1 # SYS_exit
\\ ldi $16, 0
\\ callsys
:
: [ptr] "r" (@intFromPtr(self.mapped.ptr)),
[len] "r" (self.mapped.len),
: .{ .memory = true }),
.hexagon => asm volatile ( .hexagon => asm volatile (
\\ r6 = #215 // SYS_munmap \\ r6 = #215 // SYS_munmap
\\ r0 = %[ptr] \\ r0 = %[ptr]
@ -1247,6 +1259,42 @@ const LinuxThreadImpl = struct {
: [ptr] "r" (@intFromPtr(self.mapped.ptr)), : [ptr] "r" (@intFromPtr(self.mapped.ptr)),
[len] "r" (self.mapped.len), [len] "r" (self.mapped.len),
: .{ .memory = true }), : .{ .memory = true }),
.hppa => asm volatile (
\\ ldi 91, %%r20 /* SYS_munmap */
\\ copy %[ptr], %%r26
\\ copy %[len], %%r25
\\ ble 0x100(%%sr2, %%r0)
\\ ldi 1, %%r20 /* SYS_exit */
\\ ldi 0, %%r26
\\ ble 0x100(%%sr2, %%r0)
:
: [ptr] "r" (@intFromPtr(self.mapped.ptr)),
[len] "r" (self.mapped.len),
: .{ .memory = true }),
.m68k => asm volatile (
\\ move.l #91, %%d0 // SYS_munmap
\\ move.l %[ptr], %%d1
\\ move.l %[len], %%d2
\\ trap #0
\\ move.l #1, %%d0 // SYS_exit
\\ move.l #0, %%d1
\\ trap #0
:
: [ptr] "r" (@intFromPtr(self.mapped.ptr)),
[len] "r" (self.mapped.len),
: .{ .memory = true }),
.microblaze, .microblazeel => asm volatile (
\\ ori r12, r0, 91 # SYS_munmap
\\ ori r5, %[ptr], 0
\\ ori r6, %[len], 0
\\ brki r14, 0x8
\\ ori r12, r0, 1 # SYS_exit
\\ or r5, r0, r0
\\ brki r14, 0x8
:
: [ptr] "r" (@intFromPtr(self.mapped.ptr)),
[len] "r" (self.mapped.len),
: .{ .memory = true }),
// We set `sp` to the address of the current function as a workaround for a Linux // We set `sp` to the address of the current function as a workaround for a Linux
// kernel bug that caused syscalls to return EFAULT if the stack pointer is invalid. // kernel bug that caused syscalls to return EFAULT if the stack pointer is invalid.
// The bug was introduced in 46e12c07b3b9603c60fc1d421ff18618241cb081 and fixed in // The bug was introduced in 46e12c07b3b9603c60fc1d421ff18618241cb081 and fixed in
@ -1335,6 +1383,28 @@ const LinuxThreadImpl = struct {
: [ptr] "r" (@intFromPtr(self.mapped.ptr)), : [ptr] "r" (@intFromPtr(self.mapped.ptr)),
[len] "r" (self.mapped.len), [len] "r" (self.mapped.len),
: .{ .memory = true }), : .{ .memory = true }),
.sh, .sheb => asm volatile (
\\ mov #91, r3 ! SYS_munmap
\\ mov %[ptr], r4
\\ mov %[len], r5
\\ trapa #31
\\ or r0, r0
\\ or r0, r0
\\ or r0, r0
\\ or r0, r0
\\ or r0, r0
\\ mov #1, r3 ! SYS_exit
\\ mov #0, r4
\\ trapa #31
\\ or r0, r0
\\ or r0, r0
\\ or r0, r0
\\ or r0, r0
\\ or r0, r0
:
: [ptr] "r" (@intFromPtr(self.mapped.ptr)),
[len] "r" (self.mapped.len),
: .{ .memory = true }),
.sparc => asm volatile ( .sparc => asm volatile (
\\ # See sparc64 comments below. \\ # See sparc64 comments below.
\\ 1: \\ 1:

View file

@ -419,6 +419,7 @@ pub fn cacheLineForCpu(cpu: std.Target.Cpu) u16 {
.aarch64, .aarch64,
.aarch64_be, .aarch64_be,
.arc, .arc,
.arceb,
.powerpc64, .powerpc64,
.powerpc64le, .powerpc64le,
=> 128, => 128,
@ -432,20 +433,29 @@ pub fn cacheLineForCpu(cpu: std.Target.Cpu) u16 {
// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mipsle.go#L7 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mipsle.go#L7
// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips64x.go#L9 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips64x.go#L9
// - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/sparc/include/asm/cache.h#L14 // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/sparc/include/asm/cache.h#L14
// - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/microblaze/include/asm/cache.h#L15
// - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/sh/include/cpu-sh4/cpu/cache.h#L10
.arm, .arm,
.armeb, .armeb,
.thumb, .thumb,
.thumbeb, .thumbeb,
.microblaze,
.microblazeel,
.mips, .mips,
.mipsel, .mipsel,
.mips64, .mips64,
.mips64el, .mips64el,
.sh,
.sheb,
.sparc, .sparc,
.sparc64, .sparc64,
=> 32, => 32,
// - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/m68k/include/asm/cache.h#L10 // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/m68k/include/asm/cache.h#L10
// - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/openrisc/include/asm/cache.h#L24 // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/openrisc/include/asm/cache.h#L24
// - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/parisc/include/asm/cache.h#L16
.hppa,
.hppa64,
.m68k, .m68k,
.or1k, .or1k,
=> 16, => 16,
@ -468,6 +478,7 @@ pub fn cacheLineForCpu(cpu: std.Target.Cpu) u16 {
// - https://github.com/golang/go/blob/19e923182e590ae6568c2c714f20f32512aeb3e3/src/internal/cpu/cpu_riscv64.go#L7 // - https://github.com/golang/go/blob/19e923182e590ae6568c2c714f20f32512aeb3e3/src/internal/cpu/cpu_riscv64.go#L7
// - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/xtensa/variants/csp/include/variant/core.h#L209 // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/xtensa/variants/csp/include/variant/core.h#L209
// - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/csky/Kconfig#L183 // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/csky/Kconfig#L183
// - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/alpha/include/asm/cache.h#L11
// - https://www.xmos.com/download/The-XMOS-XS3-Architecture.pdf // - https://www.xmos.com/download/The-XMOS-XS3-Architecture.pdf
else => 64, else => 64,
}; };

View file

@ -204,6 +204,7 @@ pub const CallingConvention = union(enum(u8)) {
// Calling conventions for the `x86_64` architecture. // Calling conventions for the `x86_64` architecture.
x86_64_sysv: CommonOptions, x86_64_sysv: CommonOptions,
x86_64_x32: CommonOptions,
x86_64_win: CommonOptions, x86_64_win: CommonOptions,
x86_64_regcall_v3_sysv: CommonOptions, x86_64_regcall_v3_sysv: CommonOptions,
x86_64_regcall_v4_win: CommonOptions, x86_64_regcall_v4_win: CommonOptions,
@ -229,6 +230,9 @@ pub const CallingConvention = union(enum(u8)) {
aarch64_vfabi: CommonOptions, aarch64_vfabi: CommonOptions,
aarch64_vfabi_sve: CommonOptions, aarch64_vfabi_sve: CommonOptions,
/// The standard `alpha` calling convention.
alpha_osf: CommonOptions,
// Calling convetions for the `arm`, `armeb`, `thumb`, and `thumbeb` architectures. // Calling convetions for the `arm`, `armeb`, `thumb`, and `thumbeb` architectures.
/// ARM Architecture Procedure Call Standard /// ARM Architecture Procedure Call Standard
arm_aapcs: CommonOptions, arm_aapcs: CommonOptions,
@ -275,7 +279,7 @@ pub const CallingConvention = union(enum(u8)) {
/// The standard `wasm32` and `wasm64` calling convention, as specified in the WebAssembly Tool Conventions. /// The standard `wasm32` and `wasm64` calling convention, as specified in the WebAssembly Tool Conventions.
wasm_mvp: CommonOptions, wasm_mvp: CommonOptions,
/// The standard `arc` calling convention. /// The standard `arc`/`arceb` calling convention.
arc_sysv: CommonOptions, arc_sysv: CommonOptions,
arc_interrupt: ArcInterruptOptions, arc_interrupt: ArcInterruptOptions,
@ -296,6 +300,12 @@ pub const CallingConvention = union(enum(u8)) {
hexagon_sysv: CommonOptions, hexagon_sysv: CommonOptions,
hexagon_sysv_hvx: CommonOptions, hexagon_sysv_hvx: CommonOptions,
/// The standard `hppa` calling convention.
hppa_elf: CommonOptions,
/// The standard `hppa64` calling convention.
hppa64_elf: CommonOptions,
/// The standard `lanai` calling convention. /// The standard `lanai` calling convention.
lanai_sysv: CommonOptions, lanai_sysv: CommonOptions,
@ -311,8 +321,13 @@ pub const CallingConvention = union(enum(u8)) {
m68k_rtd: CommonOptions, m68k_rtd: CommonOptions,
m68k_interrupt: CommonOptions, m68k_interrupt: CommonOptions,
/// The standard `microblaze`/`microblazeel` calling convention.
microblaze_std: CommonOptions,
microblaze_interrupt: MicroblazeInterruptOptions,
/// The standard `msp430` calling convention. /// The standard `msp430` calling convention.
msp430_eabi: CommonOptions, msp430_eabi: CommonOptions,
msp430_interrupt: CommonOptions,
/// The standard `or1k` calling convention. /// The standard `or1k` calling convention.
or1k_sysv: CommonOptions, or1k_sysv: CommonOptions,
@ -324,6 +339,11 @@ pub const CallingConvention = union(enum(u8)) {
s390x_sysv: CommonOptions, s390x_sysv: CommonOptions,
s390x_sysv_vx: CommonOptions, s390x_sysv_vx: CommonOptions,
// Calling conventions for the `sh`/`sheb` architecture.
sh_gnu: CommonOptions,
sh_renesas: CommonOptions,
sh_interrupt: ShInterruptOptions,
/// The standard `ve` calling convention. /// The standard `ve` calling convention.
ve_sysv: CommonOptions, ve_sysv: CommonOptions,
@ -331,7 +351,7 @@ pub const CallingConvention = union(enum(u8)) {
xcore_xs1: CommonOptions, xcore_xs1: CommonOptions,
xcore_xs2: CommonOptions, xcore_xs2: CommonOptions,
// Calling conventions for the `xtensa` architecture. // Calling conventions for the `xtensa`/`xtensaeb` architecture.
xtensa_call0: CommonOptions, xtensa_call0: CommonOptions,
xtensa_windowed: CommonOptions, xtensa_windowed: CommonOptions,
@ -403,6 +423,25 @@ pub const CallingConvention = union(enum(u8)) {
}; };
}; };
/// Options for the `microblaze_interrupt` calling convention.
pub const MicroblazeInterruptOptions = struct {
/// The boundary the stack is aligned to when the function is called.
/// `null` means the default for this calling convention.
incoming_stack_alignment: ?u64 = null,
type: InterruptType = .regular,
pub const InterruptType = enum(u2) {
/// User exception; return with `rtsd`.
user,
/// Regular interrupt; return with `rtid`.
regular,
/// Fast interrupt; return with `rtid`.
fast,
/// Software breakpoint; return with `rtbd`.
breakpoint,
};
};
/// Options for the `mips_interrupt` and `mips64_interrupt` calling conventions. /// Options for the `mips_interrupt` and `mips64_interrupt` calling conventions.
pub const MipsInterruptOptions = struct { pub const MipsInterruptOptions = struct {
/// The boundary the stack is aligned to when the function is called. /// The boundary the stack is aligned to when the function is called.
@ -438,6 +477,25 @@ pub const CallingConvention = union(enum(u8)) {
}; };
}; };
/// Options for the `sh_interrupt` calling convention.
pub const ShInterruptOptions = struct {
/// The boundary the stack is aligned to when the function is called.
/// `null` means the default for this calling convention.
incoming_stack_alignment: ?u64 = null,
save: SaveBehavior = .full,
pub const SaveBehavior = enum(u3) {
/// Save only fpscr (if applicable).
fpscr,
/// Save only high-numbered registers, i.e. r0 through r7 are *not* saved.
high,
/// Save all registers normally.
full,
/// Save all registers using the CPU's fast register bank.
bank,
};
};
/// Returns the array of `std.Target.Cpu.Arch` to which this `CallingConvention` applies. /// Returns the array of `std.Target.Cpu.Arch` to which this `CallingConvention` applies.
/// Asserts that `cc` is not `.auto`, `.@"async"`, `.naked`, or `.@"inline"`. /// Asserts that `cc` is not `.auto`, `.@"async"`, `.naked`, or `.@"inline"`.
pub fn archs(cc: CallingConvention) []const std.Target.Cpu.Arch { pub fn archs(cc: CallingConvention) []const std.Target.Cpu.Arch {
@ -459,21 +517,6 @@ pub const CallingConvention = union(enum(u8)) {
/// This data structure is used by the Zig language code generation and /// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation. /// therefore must be kept in sync with the compiler implementation.
pub const AddressSpace = enum(u5) { pub const AddressSpace = enum(u5) {
/// The places where a user can specify an address space attribute
pub const Context = enum {
/// A function is specified to be placed in a certain address space.
function,
/// A (global) variable is specified to be placed in a certain address space.
/// In contrast to .constant, these values (and thus the address space they will be
/// placed in) are required to be mutable.
variable,
/// A (global) constant value is specified to be placed in a certain address space.
/// In contrast to .variable, values placed in this address space are not required to be mutable.
constant,
/// A pointer is ascripted to point into a certain address space.
pointer,
};
// CPU address spaces. // CPU address spaces.
generic, generic,
gs, gs,
@ -858,6 +901,13 @@ pub const VaListAarch64 = extern struct {
__vr_offs: c_int, __vr_offs: c_int,
}; };
/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const VaListAlpha = extern struct {
__base: *anyopaque,
__offset: c_int,
};
/// This data structure is used by the Zig language code generation and /// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation. /// therefore must be kept in sync with the compiler implementation.
pub const VaListArm = extern struct { pub const VaListArm = extern struct {
@ -891,6 +941,16 @@ pub const VaListS390x = extern struct {
__overflow_area_pointer: *anyopaque, __overflow_area_pointer: *anyopaque,
}; };
/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const VaListSh = extern struct {
__va_next_o: *anyopaque,
__va_next_o_limit: *anyopaque,
__va_next_fp: *anyopaque,
__va_next_fp_limit: *anyopaque,
__va_next_stack: *anyopaque,
};
/// This data structure is used by the Zig language code generation and /// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation. /// therefore must be kept in sync with the compiler implementation.
pub const VaListX86_64 = extern struct { pub const VaListX86_64 = extern struct {
@ -920,14 +980,19 @@ pub const VaList = switch (builtin.cpu.arch) {
.x86, .x86,
=> *u8, => *u8,
.arc, .arc,
.arceb,
.avr, .avr,
.bpfel, .bpfel,
.bpfeb, .bpfeb,
.csky, .csky,
.hppa,
.hppa64,
.lanai, .lanai,
.loongarch32, .loongarch32,
.loongarch64, .loongarch64,
.m68k, .m68k,
.microblaze,
.microblazeel,
.mips, .mips,
.mipsel, .mipsel,
.mips64, .mips64,
@ -952,6 +1017,7 @@ pub const VaList = switch (builtin.cpu.arch) {
.stage2_llvm => @compileError("disabled due to miscompilations"), .stage2_llvm => @compileError("disabled due to miscompilations"),
}, },
}, },
.alpha => VaListAlpha,
.arm, .armeb, .thumb, .thumbeb => VaListArm, .arm, .armeb, .thumb, .thumbeb => VaListArm,
.hexagon => if (builtin.target.abi.isMusl()) VaListHexagon else *u8, .hexagon => if (builtin.target.abi.isMusl()) VaListHexagon else *u8,
.powerpc, .powerpcle => switch (builtin.os.tag) { .powerpc, .powerpcle => switch (builtin.os.tag) {
@ -959,6 +1025,7 @@ pub const VaList = switch (builtin.cpu.arch) {
else => VaListPowerPc, else => VaListPowerPc,
}, },
.s390x => VaListS390x, .s390x => VaListS390x,
.sh, .sheb => VaListSh, // This is wrong for `sh_renesas`: https://github.com/ziglang/zig/issues/24692#issuecomment-3150779829
.x86_64 => switch (builtin.os.tag) { .x86_64 => switch (builtin.os.tag) {
.uefi, .windows => switch (builtin.zig_backend) { .uefi, .windows => switch (builtin.zig_backend) {
else => *u8, else => *u8,
@ -966,7 +1033,7 @@ pub const VaList = switch (builtin.cpu.arch) {
}, },
else => VaListX86_64, else => VaListX86_64,
}, },
.xtensa => VaListXtensa, .xtensa, .xtensaeb => VaListXtensa,
else => @compileError("VaList not supported for this target yet"), else => @compileError("VaList not supported for this target yet"),
}; };

View file

@ -779,7 +779,7 @@ pub const Clobbers = switch (@import("builtin").cpu.arch) {
lr: bool = false, lr: bool = false,
sr: bool = false, sr: bool = false,
}, },
.xtensa => packed struct { .xtensa, .xtensaeb => packed struct {
/// Whether the inline assembly code may perform stores to memory /// Whether the inline assembly code may perform stores to memory
/// addresses other than those derived from input pointer provenance. /// addresses other than those derived from input pointer provenance.
memory: bool = false, memory: bool = false,
@ -1591,7 +1591,7 @@ pub const Clobbers = switch (@import("builtin").cpu.arch) {
vr30: bool = false, vr30: bool = false,
vr31: bool = false, vr31: bool = false,
}, },
.arc => packed struct { .arc, .arceb => packed struct {
/// Whether the inline assembly code may perform stores to memory /// Whether the inline assembly code may perform stores to memory
/// addresses other than those derived from input pointer provenance. /// addresses other than those derived from input pointer provenance.
memory: bool = false, memory: bool = false,
@ -2197,6 +2197,321 @@ pub const Clobbers = switch (@import("builtin").cpu.arch) {
msa_map: bool = false, msa_map: bool = false,
msa_unmap: bool = false, msa_unmap: bool = false,
}, },
.alpha => packed struct {
/// Whether the inline assembly code may perform stores to memory
/// addresses other than those derived from input pointer provenance.
memory: bool = false,
r0: bool = false,
r1: bool = false,
r2: bool = false,
r3: bool = false,
r4: bool = false,
r5: bool = false,
r6: bool = false,
r7: bool = false,
r8: bool = false,
r9: bool = false,
r10: bool = false,
r11: bool = false,
r12: bool = false,
r13: bool = false,
r14: bool = false,
r15: bool = false,
r16: bool = false,
r17: bool = false,
r18: bool = false,
r19: bool = false,
r20: bool = false,
r21: bool = false,
r22: bool = false,
r23: bool = false,
r24: bool = false,
r25: bool = false,
r26: bool = false,
r27: bool = false,
r28: bool = false,
r29: bool = false,
r30: bool = false,
f0: bool = false,
f1: bool = false,
f2: bool = false,
f3: bool = false,
f4: bool = false,
f5: bool = false,
f6: bool = false,
f7: bool = false,
f8: bool = false,
f9: bool = false,
f10: bool = false,
f11: bool = false,
f12: bool = false,
f13: bool = false,
f14: bool = false,
f15: bool = false,
f16: bool = false,
f17: bool = false,
f18: bool = false,
f19: bool = false,
f20: bool = false,
f21: bool = false,
f22: bool = false,
f23: bool = false,
f24: bool = false,
f25: bool = false,
f26: bool = false,
f27: bool = false,
f28: bool = false,
f29: bool = false,
f30: bool = false,
},
.hppa, .hppa64 => packed struct {
/// Whether the inline assembly code may perform stores to memory
/// addresses other than those derived from input pointer provenance.
memory: bool = false,
sar: bool = false,
r1: bool = false,
r2: bool = false,
r3: bool = false,
r4: bool = false,
r5: bool = false,
r6: bool = false,
r7: bool = false,
r8: bool = false,
r9: bool = false,
r10: bool = false,
r11: bool = false,
r12: bool = false,
r13: bool = false,
r14: bool = false,
r15: bool = false,
r16: bool = false,
r17: bool = false,
r18: bool = false,
r19: bool = false,
r20: bool = false,
r21: bool = false,
r22: bool = false,
r23: bool = false,
r24: bool = false,
r25: bool = false,
r26: bool = false,
r27: bool = false,
r28: bool = false,
r29: bool = false,
r30: bool = false,
r31: bool = false,
fr4: bool = false,
fr5: bool = false,
fr6: bool = false,
fr7: bool = false,
fr8: bool = false,
fr9: bool = false,
fr10: bool = false,
fr11: bool = false,
fr12: bool = false,
fr13: bool = false,
fr14: bool = false,
fr15: bool = false,
fr16: bool = false,
fr17: bool = false,
fr18: bool = false,
fr19: bool = false,
fr20: bool = false,
fr21: bool = false,
fr22: bool = false,
fr23: bool = false,
fr24: bool = false,
fr25: bool = false,
fr26: bool = false,
fr27: bool = false,
fr28: bool = false,
fr29: bool = false,
fr30: bool = false,
fr31: bool = false,
fr4r: bool = false,
fr5r: bool = false,
fr6r: bool = false,
fr7r: bool = false,
fr8r: bool = false,
fr9r: bool = false,
fr10r: bool = false,
fr11r: bool = false,
fr12r: bool = false,
fr13r: bool = false,
fr14r: bool = false,
fr15r: bool = false,
fr16r: bool = false,
fr17r: bool = false,
fr18r: bool = false,
fr19r: bool = false,
fr20r: bool = false,
fr21r: bool = false,
fr22r: bool = false,
fr23r: bool = false,
fr24r: bool = false,
fr25r: bool = false,
fr26r: bool = false,
fr27r: bool = false,
fr28r: bool = false,
fr29r: bool = false,
fr30r: bool = false,
fr31r: bool = false,
},
.microblaze, .microblazeel => packed struct {
/// Whether the inline assembly code may perform stores to memory
/// addresses other than those derived from input pointer provenance.
memory: bool = false,
rmsr: bool = false,
r1: bool = false,
r2: bool = false,
r3: bool = false,
r4: bool = false,
r5: bool = false,
r6: bool = false,
r7: bool = false,
r8: bool = false,
r9: bool = false,
r10: bool = false,
r11: bool = false,
r12: bool = false,
r13: bool = false,
r14: bool = false,
r15: bool = false,
r16: bool = false,
r17: bool = false,
r18: bool = false,
r19: bool = false,
r20: bool = false,
r21: bool = false,
r22: bool = false,
r23: bool = false,
r24: bool = false,
r25: bool = false,
r26: bool = false,
r27: bool = false,
r28: bool = false,
r29: bool = false,
r30: bool = false,
r31: bool = false,
},
.sh, .sheb => packed struct {
/// Whether the inline assembly code may perform stores to memory
/// addresses other than those derived from input pointer provenance.
memory: bool = false,
sr: bool = false,
gbr: bool = false,
pr: bool = false,
r0: bool = false,
r1: bool = false,
r2: bool = false,
r3: bool = false,
r4: bool = false,
r5: bool = false,
r6: bool = false,
r7: bool = false,
r8: bool = false,
r9: bool = false,
r10: bool = false,
r11: bool = false,
r12: bool = false,
r13: bool = false,
r14: bool = false,
r15: bool = false,
mach: bool = false,
macl: bool = false,
fr0: bool = false,
fr1: bool = false,
fr2: bool = false,
fr3: bool = false,
fr4: bool = false,
fr5: bool = false,
fr6: bool = false,
fr7: bool = false,
fr8: bool = false,
fr9: bool = false,
fr10: bool = false,
fr11: bool = false,
fr12: bool = false,
fr13: bool = false,
fr14: bool = false,
fr15: bool = false,
dr0: bool = false,
dr2: bool = false,
dr4: bool = false,
dr6: bool = false,
dr8: bool = false,
dr10: bool = false,
dr12: bool = false,
dr14: bool = false,
fv0: bool = false,
fv4: bool = false,
fv8: bool = false,
fv12: bool = false,
xf0: bool = false,
xf1: bool = false,
xf2: bool = false,
xf3: bool = false,
xf4: bool = false,
xf5: bool = false,
xf6: bool = false,
xf7: bool = false,
xf8: bool = false,
xf9: bool = false,
xf10: bool = false,
xf11: bool = false,
xf12: bool = false,
xf13: bool = false,
xf14: bool = false,
xf15: bool = false,
xd0: bool = false,
xd2: bool = false,
xd4: bool = false,
xd6: bool = false,
xd8: bool = false,
xd10: bool = false,
xd12: bool = false,
xd14: bool = false,
xmtrx: bool = false,
fpul: bool = false,
fpscr: bool = false,
ms: bool = false,
me: bool = false,
rs: bool = false,
re: bool = false,
a0: bool = false,
a0g: bool = false,
a1: bool = false,
a1g: bool = false,
m0: bool = false,
m1: bool = false,
x0: bool = false,
x1: bool = false,
y0: bool = false,
y1: bool = false,
dsr: bool = false,
},
else => packed struct { else => packed struct {
/// Whether the inline assembly code may perform stores to memory /// Whether the inline assembly code may perform stores to memory
/// addresses other than those derived from input pointer provenance. /// addresses other than those derived from input pointer provenance.

View file

@ -872,13 +872,18 @@ const StackIterator = union(enum) {
}; };
const fp_usability: FpUsability = switch (builtin.target.cpu.arch) { const fp_usability: FpUsability = switch (builtin.target.cpu.arch) {
.alpha,
.avr, .avr,
.csky, .csky,
.microblaze,
.microblazeel,
.mips, .mips,
.mipsel, .mipsel,
.mips64, .mips64,
.mips64el, .mips64el,
.msp430, .msp430,
.sh,
.sheb,
.xcore, .xcore,
=> .useless, => .useless,
.hexagon, .hexagon,
@ -969,11 +974,15 @@ const StackIterator = union(enum) {
const ra_ptr: *const usize = @ptrFromInt(ra_addr); const ra_ptr: *const usize = @ptrFromInt(ra_addr);
const bp = applyOffset(bp_ptr.*, stack_bias) orelse return .end; const bp = applyOffset(bp_ptr.*, stack_bias) orelse return .end;
// The stack grows downards, so `bp > fp` should always hold. If it doesn't, this // If the stack grows downwards, `bp > fp` should always hold; conversely, if it
// frame is invalid, so we'll treat it as though it we reached end of stack. The // grows upwards, `bp < fp` should always hold. If that is not the case, this
// frame is invalid, so we'll treat it as though we reached end of stack. The
// exception is address 0, which is a graceful end-of-stack signal, in which case // exception is address 0, which is a graceful end-of-stack signal, in which case
// *this* return address is valid and the *next* iteration will be the last. // *this* return address is valid and the *next* iteration will be the last.
if (bp != 0 and bp <= fp) return .end; if (bp != 0 and switch (comptime builtin.target.stackGrowth()) {
.down => bp <= fp,
.up => bp >= fp,
}) return .end;
it.fp = bp; it.fp = bp;
const ra = stripInstructionPtrAuthCode(ra_ptr.*); const ra = stripInstructionPtrAuthCode(ra_ptr.*);
@ -985,6 +994,11 @@ const StackIterator = union(enum) {
/// Offset of the saved base pointer (previous frame pointer) wrt the frame pointer. /// Offset of the saved base pointer (previous frame pointer) wrt the frame pointer.
const fp_to_bp_offset = off: { const fp_to_bp_offset = off: {
// On 32-bit PA-RISC, the base pointer is the final word of the frame marker.
if (native_arch == .hppa) break :off -1 * @sizeOf(usize);
// On 64-bit PA-RISC, the frame marker was shrunk significantly; now there's just the return
// address followed by the base pointer.
if (native_arch == .hppa64) break :off -1 * @sizeOf(usize);
// On LoongArch and RISC-V, the frame pointer points to the top of the saved register area, // On LoongArch and RISC-V, the frame pointer points to the top of the saved register area,
// in which the base pointer is the first word. // in which the base pointer is the first word.
if (native_arch.isLoongArch() or native_arch.isRISCV()) break :off -2 * @sizeOf(usize); if (native_arch.isLoongArch() or native_arch.isRISCV()) break :off -2 * @sizeOf(usize);
@ -999,6 +1013,11 @@ const StackIterator = union(enum) {
/// Offset of the saved return address wrt the frame pointer. /// Offset of the saved return address wrt the frame pointer.
const fp_to_ra_offset = off: { const fp_to_ra_offset = off: {
// On 32-bit PA-RISC, the return address sits in the middle-ish of the frame marker.
if (native_arch == .hppa) break :off -5 * @sizeOf(usize);
// On 64-bit PA-RISC, the frame marker was shrunk significantly; now there's just the return
// address followed by the base pointer.
if (native_arch == .hppa64) break :off -2 * @sizeOf(usize);
// On LoongArch and RISC-V, the frame pointer points to the top of the saved register area, // On LoongArch and RISC-V, the frame pointer points to the top of the saved register area,
// in which the return address is the second word. // in which the return address is the second word.
if (native_arch.isLoongArch() or native_arch.isRISCV()) break :off -1 * @sizeOf(usize); if (native_arch.isLoongArch() or native_arch.isRISCV()) break :off -1 * @sizeOf(usize);

View file

@ -1430,7 +1430,7 @@ pub fn compactUnwindToDwarfRegNumber(unwind_reg_number: u3) !u16 {
pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 { pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
return switch (arch) { return switch (arch) {
.aarch64, .aarch64_be => 32, .aarch64, .aarch64_be => 32,
.arc => 160, .arc, .arceb => 160,
.arm, .armeb, .thumb, .thumbeb => 15, .arm, .armeb, .thumb, .thumbeb => 15,
.csky => 64, .csky => 64,
.hexagon => 76, .hexagon => 76,
@ -1453,7 +1453,7 @@ pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 { pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
return switch (arch) { return switch (arch) {
.aarch64, .aarch64_be => 29, .aarch64, .aarch64_be => 29,
.arc => 27, .arc, .arceb => 27,
.arm, .armeb, .thumb, .thumbeb => 11, .arm, .armeb, .thumb, .thumbeb => 11,
.csky => 14, .csky => 14,
.hexagon => 30, .hexagon => 30,
@ -1476,7 +1476,7 @@ pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 { pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {
return switch (arch) { return switch (arch) {
.aarch64, .aarch64_be => 31, .aarch64, .aarch64_be => 31,
.arc => 28, .arc, .arceb => 28,
.arm, .armeb, .thumb, .thumbeb => 13, .arm, .armeb, .thumb, .thumbeb => 13,
.csky => 14, .csky => 14,
.hexagon => 29, .hexagon => 29,

View file

@ -102,7 +102,7 @@ pub const can_unwind: bool = s: {
.x86, .x86,
.x86_64, .x86_64,
}, },
// Not supported yet: arm/armeb/thumb/thumbeb, xtensa // Not supported yet: arm/armeb/thumb/thumbeb, xtensa/xtensaeb
.linux => &.{ .linux => &.{
.aarch64, .aarch64,
.aarch64_be, .aarch64_be,

View file

@ -5,7 +5,7 @@ pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuCont
root.debug.CpuContext root.debug.CpuContext
else switch (native_arch) { else switch (native_arch) {
.aarch64, .aarch64_be => Aarch64, .aarch64, .aarch64_be => Aarch64,
.arc => Arc, .arc, .arceb => Arc,
.arm, .armeb, .thumb, .thumbeb => Arm, .arm, .armeb, .thumb, .thumbeb => Arm,
.csky => Csky, .csky => Csky,
.hexagon => Hexagon, .hexagon => Hexagon,
@ -36,7 +36,7 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
const uc: *const signal_ucontext_t = @ptrCast(@alignCast(ctx_ptr)); const uc: *const signal_ucontext_t = @ptrCast(@alignCast(ctx_ptr));
// Deal with some special cases first. // Deal with some special cases first.
if (native_arch == .arc and native_os == .linux) { if (native_arch.isArc() and native_os == .linux) {
var native: Native = .{ var native: Native = .{
.r = [_]u32{ uc.mcontext.r31, uc.mcontext.r30, 0, uc.mcontext.r28 } ++ .r = [_]u32{ uc.mcontext.r31, uc.mcontext.r30, 0, uc.mcontext.r28 } ++
uc.mcontext.r27_26 ++ uc.mcontext.r27_26 ++
@ -1492,6 +1492,21 @@ const X86_64 = struct {
/// as unsigned everywhere even if that's not how they're declared in the C headers. /// as unsigned everywhere even if that's not how they're declared in the C headers.
const signal_ucontext_t = switch (native_os) { const signal_ucontext_t = switch (native_os) {
.linux => switch (native_arch) { .linux => switch (native_arch) {
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/alpha/include/asm/ucontext.h
.alpha => extern struct {
_flags: u64,
_link: ?*signal_ucontext_t,
_osf_sigmask: u64,
_stack: std.os.linux.stack_t,
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/alpha/include/uapi/asm/sigcontext.h
mcontext: extern struct {
_onstack: i64,
_mask: i64,
pc: u64,
_ps: i64,
r: [32]u64,
},
},
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/arm64/include/uapi/asm/ucontext.h // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/arm64/include/uapi/asm/ucontext.h
.aarch64, .aarch64,
.aarch64_be, .aarch64_be,
@ -1553,6 +1568,7 @@ const signal_ucontext_t = switch (native_os) {
}, },
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/include/uapi/asm-generic/ucontext.h // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/include/uapi/asm-generic/ucontext.h
.arc, .arc,
.arceb,
.csky, .csky,
.hexagon, .hexagon,
.m68k, .m68k,
@ -1565,13 +1581,14 @@ const signal_ucontext_t = switch (native_os) {
.x86, .x86,
.x86_64, .x86_64,
.xtensa, .xtensa,
.xtensaeb,
=> extern struct { => extern struct {
_flags: usize, _flags: usize,
_link: ?*signal_ucontext_t, _link: ?*signal_ucontext_t,
_stack: std.os.linux.stack_t, _stack: std.os.linux.stack_t,
mcontext: switch (native_arch) { mcontext: switch (native_arch) {
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/arc/include/uapi/asm/sigcontext.h // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/arc/include/uapi/asm/sigcontext.h
.arc => extern struct { .arc, .arceb => extern struct {
_pad1: u32, _pad1: u32,
_bta: u32, _bta: u32,
_lp: extern struct { _lp: extern struct {
@ -1616,6 +1633,21 @@ const signal_ucontext_t = switch (native_os) {
_ugp: u32, _ugp: u32,
pc: u32, pc: u32,
}, },
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/parisc/include/uapi/asm/sigcontext.h
.hppa => extern struct {
_flags: u32,
_psw: u32,
r1_19: [19]u32,
r20: u32,
r21: u32,
r22: u32,
r23_29: [7]u32,
r30: u32,
r31: u32,
_fr: [32]f64,
_iasq: [2]u32,
iaoq: [2]u32,
},
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/m68k/include/asm/ucontext.h // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/m68k/include/asm/ucontext.h
.m68k => extern struct { .m68k => extern struct {
_version: i32, _version: i32,
@ -1623,6 +1655,11 @@ const signal_ucontext_t = switch (native_os) {
a: [8]u32, a: [8]u32,
pc: u32, pc: u32,
}, },
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/microblaze/include/uapi/asm/sigcontext.h
.microblaze, .microblazeel => extern struct {
r: [32]u32,
pc: u32,
},
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/mips/include/uapi/asm/sigcontext.h // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/mips/include/uapi/asm/sigcontext.h
.mips, .mipsel => extern struct { .mips, .mipsel => extern struct {
_regmask: u32, _regmask: u32,
@ -1652,6 +1689,13 @@ const signal_ucontext_t = switch (native_os) {
}, },
r: [16]u64, r: [16]u64,
}, },
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/sh/include/uapi/asm/sigcontext.h
.sh, .sheb => extern struct {
_oldmask: u32,
r: [16]u32,
pc: u32,
pr: u32,
},
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/x86/include/uapi/asm/sigcontext.h // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/x86/include/uapi/asm/sigcontext.h
.x86 => extern struct { .x86 => extern struct {
_gs: u32, _gs: u32,
@ -1691,7 +1735,7 @@ const signal_ucontext_t = switch (native_os) {
rip: u64, rip: u64,
}, },
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/xtensa/include/uapi/asm/sigcontext.h // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/xtensa/include/uapi/asm/sigcontext.h
.xtensa => extern struct { .xtensa, .xtensaeb => extern struct {
pc: u32, pc: u32,
_ps: u32, _ps: u32,
_l: extern struct { _l: extern struct {
@ -1948,6 +1992,7 @@ const signal_ucontext_t = switch (native_os) {
_err: i32, _err: i32,
eip: u32, eip: u32,
}, },
// https://github.com/illumos/illumos-gate/blob/d4ce137bba3bd16823db6374d9e9a643264ce245/usr/src/uts/intel/sys/mcontext.h
.x86_64 => extern struct { .x86_64 => extern struct {
r15: u64, r15: u64,
r14: u64, r14: u64,
@ -1984,6 +2029,14 @@ const signal_ucontext_t = switch (native_os) {
x: [30]u64, x: [30]u64,
}, },
}, },
// https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/alpha/include/signal.h
.alpha => extern struct {
_cookie: i64,
_mask: i64,
pc: u64,
_ps: i64,
r: [32]u64,
},
// https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/arm/include/signal.h // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/arm/include/signal.h
.arm => extern struct { .arm => extern struct {
_cookie: i32, _cookie: i32,
@ -1995,6 +2048,22 @@ const signal_ucontext_t = switch (native_os) {
pc: u32, pc: u32,
}, },
}, },
// https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/hppa/include/signal.h
.hppa => extern struct {
_unused: u32,
_mask: i32,
_fp: u32,
iaoq: [2]u32,
_resv: [2]u32,
r22: u32,
r21: u32,
r30: u32,
r20: u32,
_sar: u32,
r1_19: [19]u32,
r23_29: [7]u32,
r31: u32,
},
// https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/mips64/include/signal.h // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/mips64/include/signal.h
.mips64, .mips64el => extern struct { .mips64, .mips64el => extern struct {
_cookie: i64, _cookie: i64,
@ -2034,6 +2103,18 @@ const signal_ucontext_t = switch (native_os) {
}, },
// https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/sparc64/include/signal.h // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/sparc64/include/signal.h
.sparc64 => @compileError("sparc64-openbsd ucontext_t missing"), .sparc64 => @compileError("sparc64-openbsd ucontext_t missing"),
// https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/sh/include/signal.h
.sh, .sheb => extern struct {
pc: u32,
_sr: i32,
_gbr: i32,
_macl: i32,
_mach: i32,
pr: u32,
r13_0: [14]u32,
r15: u32,
r14: u32,
},
// https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/i386/include/signal.h // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/i386/include/signal.h
.x86 => extern struct { .x86 => extern struct {
mcontext: extern struct { mcontext: extern struct {
@ -2100,6 +2181,12 @@ const signal_ucontext_t = switch (native_os) {
sp: u64, sp: u64,
pc: u64, pc: u64,
}, },
// https://github.com/NetBSD/src/blob/861008c62187bf7bc0aac4d81e52ed6eee4d0c74/sys/arch/alpha/include/mcontext.h
.alpha => extern struct {
r: [32]u64,
pc: u64,
},
// https://github.com/NetBSD/src/blob/861008c62187bf7bc0aac4d81e52ed6eee4d0c74/sys/arch/arm/include/mcontext.h
.arm, .armeb => extern struct { .arm, .armeb => extern struct {
r: [15]u32 align(8), r: [15]u32 align(8),
pc: u32, pc: u32,
@ -2118,6 +2205,7 @@ const signal_ucontext_t = switch (native_os) {
_cause: i32, _cause: i32,
pc: u32, pc: u32,
}, },
// https://github.com/NetBSD/src/blob/861008c62187bf7bc0aac4d81e52ed6eee4d0c74/sys/arch/mips/include/mcontext.h
.mips64, .mips64el => @compileError("https://github.com/ziglang/zig/issues/23765#issuecomment-2880386178"), .mips64, .mips64el => @compileError("https://github.com/ziglang/zig/issues/23765#issuecomment-2880386178"),
// https://github.com/NetBSD/src/blob/861008c62187bf7bc0aac4d81e52ed6eee4d0c74/sys/arch/powerpc/include/mcontext.h // https://github.com/NetBSD/src/blob/861008c62187bf7bc0aac4d81e52ed6eee4d0c74/sys/arch/powerpc/include/mcontext.h
.powerpc => extern struct { .powerpc => extern struct {
@ -2129,6 +2217,18 @@ const signal_ucontext_t = switch (native_os) {
// https://github.com/NetBSD/src/blob/861008c62187bf7bc0aac4d81e52ed6eee4d0c74/sys/arch/sparc/include/mcontext.h // https://github.com/NetBSD/src/blob/861008c62187bf7bc0aac4d81e52ed6eee4d0c74/sys/arch/sparc/include/mcontext.h
.sparc => @compileError("sparc-netbsd mcontext_t missing"), .sparc => @compileError("sparc-netbsd mcontext_t missing"),
.sparc64 => @compileError("sparc64-netbsd mcontext_t missing"), .sparc64 => @compileError("sparc64-netbsd mcontext_t missing"),
// https://github.com/NetBSD/src/blob/861008c62187bf7bc0aac4d81e52ed6eee4d0c74/sys/arch/sh3/include/mcontext.h
.sh, .sheb => extern struct {
_gbr: i32,
pc: u32,
_sr: i32,
_macl: i32,
_mach: i32,
pr: u32,
r14: u32,
r13_0: [14]u32,
r15: u32,
},
// https://github.com/NetBSD/src/blob/861008c62187bf7bc0aac4d81e52ed6eee4d0c74/sys/arch/i386/include/mcontext.h // https://github.com/NetBSD/src/blob/861008c62187bf7bc0aac4d81e52ed6eee4d0c74/sys/arch/i386/include/mcontext.h
.x86 => extern struct { .x86 => extern struct {
_gs: i32, _gs: i32,

View file

@ -736,11 +736,14 @@ const page_size_min_default: ?usize = switch (builtin.os.tag) {
}, },
.netbsd => switch (builtin.cpu.arch) { .netbsd => switch (builtin.cpu.arch) {
// NetBSD/sys/arch/* // NetBSD/sys/arch/*
.alpha => 8 << 10,
.x86, .x86_64 => 4 << 10, .x86, .x86_64 => 4 << 10,
.thumb, .thumbeb, .arm, .armeb => 4 << 10, .thumb, .thumbeb, .arm, .armeb => 4 << 10,
.aarch64, .aarch64_be => 4 << 10, .aarch64, .aarch64_be => 4 << 10,
.hppa => 4 << 10,
.mips, .mipsel, .mips64, .mips64el => 4 << 10, .mips, .mipsel, .mips64, .mips64el => 4 << 10,
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10, .powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10,
.sh, .sheb => 4 << 10,
.sparc => 4 << 10, .sparc => 4 << 10,
.sparc64 => 8 << 10, .sparc64 => 8 << 10,
.riscv32, .riscv64 => 4 << 10, .riscv32, .riscv64 => 4 << 10,
@ -754,11 +757,14 @@ const page_size_min_default: ?usize = switch (builtin.os.tag) {
}, },
.openbsd => switch (builtin.cpu.arch) { .openbsd => switch (builtin.cpu.arch) {
// OpenBSD/sys/arch/* // OpenBSD/sys/arch/*
.alpha => 8 << 10,
.hppa => 4 << 10,
.x86, .x86_64 => 4 << 10, .x86, .x86_64 => 4 << 10,
.thumb, .thumbeb, .arm, .armeb, .aarch64, .aarch64_be => 4 << 10, .thumb, .thumbeb, .arm, .armeb, .aarch64, .aarch64_be => 4 << 10,
.mips64, .mips64el => 4 << 10, .mips64, .mips64el => 4 << 10,
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10, .powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10,
.riscv64 => 4 << 10, .riscv64 => 4 << 10,
.sh, .sheb => 4 << 10,
.sparc64 => 8 << 10, .sparc64 => 8 << 10,
else => null, else => null,
}, },
@ -824,22 +830,26 @@ const page_size_min_default: ?usize = switch (builtin.os.tag) {
.emscripten => 64 << 10, .emscripten => 64 << 10,
.linux => switch (builtin.cpu.arch) { .linux => switch (builtin.cpu.arch) {
// Linux/arch/*/Kconfig // Linux/arch/*/Kconfig
.arc => 4 << 10, .alpha => 8 << 10,
.arc, .arceb => 4 << 10,
.thumb, .thumbeb, .arm, .armeb => 4 << 10, .thumb, .thumbeb, .arm, .armeb => 4 << 10,
.aarch64, .aarch64_be => 4 << 10, .aarch64, .aarch64_be => 4 << 10,
.csky => 4 << 10, .csky => 4 << 10,
.hexagon => 4 << 10, .hexagon => 4 << 10,
.hppa => 4 << 10,
.loongarch32, .loongarch64 => 4 << 10, .loongarch32, .loongarch64 => 4 << 10,
.m68k => 4 << 10, .m68k => 4 << 10,
.microblaze, .microblazeel => 4 << 10,
.mips, .mipsel, .mips64, .mips64el => 4 << 10, .mips, .mipsel, .mips64, .mips64el => 4 << 10,
.or1k => 8 << 10, .or1k => 8 << 10,
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10, .powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10,
.riscv32, .riscv64 => 4 << 10, .riscv32, .riscv64 => 4 << 10,
.s390x => 4 << 10, .s390x => 4 << 10,
.sh, .sheb => 4 << 10,
.sparc => 4 << 10, .sparc => 4 << 10,
.sparc64 => 8 << 10, .sparc64 => 8 << 10,
.x86, .x86_64 => 4 << 10, .x86, .x86_64 => 4 << 10,
.xtensa => 4 << 10, .xtensa, .xtensaeb => 4 << 10,
else => null, else => null,
}, },
.freestanding, .other => switch (builtin.cpu.arch) { .freestanding, .other => switch (builtin.cpu.arch) {
@ -885,11 +895,14 @@ const page_size_max_default: ?usize = switch (builtin.os.tag) {
}, },
.netbsd => switch (builtin.cpu.arch) { .netbsd => switch (builtin.cpu.arch) {
// NetBSD/sys/arch/* // NetBSD/sys/arch/*
.alpha => 8 << 10,
.x86, .x86_64 => 4 << 10, .x86, .x86_64 => 4 << 10,
.thumb, .thumbeb, .arm, .armeb => 4 << 10, .thumb, .thumbeb, .arm, .armeb => 4 << 10,
.aarch64, .aarch64_be => 64 << 10, .aarch64, .aarch64_be => 64 << 10,
.hppa => 4 << 10,
.mips, .mipsel, .mips64, .mips64el => 16 << 10, .mips, .mipsel, .mips64, .mips64el => 16 << 10,
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 16 << 10, .powerpc, .powerpc64, .powerpc64le, .powerpcle => 16 << 10,
.sh, .sheb => 4 << 10,
.sparc => 8 << 10, .sparc => 8 << 10,
.sparc64 => 8 << 10, .sparc64 => 8 << 10,
.riscv32, .riscv64 => 4 << 10, .riscv32, .riscv64 => 4 << 10,
@ -902,11 +915,14 @@ const page_size_max_default: ?usize = switch (builtin.os.tag) {
}, },
.openbsd => switch (builtin.cpu.arch) { .openbsd => switch (builtin.cpu.arch) {
// OpenBSD/sys/arch/* // OpenBSD/sys/arch/*
.alpha => 8 << 10,
.hppa => 4 << 10,
.x86, .x86_64 => 4 << 10, .x86, .x86_64 => 4 << 10,
.thumb, .thumbeb, .arm, .armeb, .aarch64, .aarch64_be => 4 << 10, .thumb, .thumbeb, .arm, .armeb, .aarch64, .aarch64_be => 4 << 10,
.mips64, .mips64el => 16 << 10, .mips64, .mips64el => 16 << 10,
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10, .powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10,
.riscv64 => 4 << 10, .riscv64 => 4 << 10,
.sh, .sheb => 4 << 10,
.sparc64 => 8 << 10, .sparc64 => 8 << 10,
else => null, else => null,
}, },
@ -972,22 +988,26 @@ const page_size_max_default: ?usize = switch (builtin.os.tag) {
.emscripten => 64 << 10, .emscripten => 64 << 10,
.linux => switch (builtin.cpu.arch) { .linux => switch (builtin.cpu.arch) {
// Linux/arch/*/Kconfig // Linux/arch/*/Kconfig
.arc => 16 << 10, .alpha => 8 << 10,
.arc, .arceb => 16 << 10,
.thumb, .thumbeb, .arm, .armeb => 4 << 10, .thumb, .thumbeb, .arm, .armeb => 4 << 10,
.aarch64, .aarch64_be => 64 << 10, .aarch64, .aarch64_be => 64 << 10,
.csky => 4 << 10, .csky => 4 << 10,
.hexagon => 256 << 10, .hexagon => 256 << 10,
.hppa => 64 << 10,
.loongarch32, .loongarch64 => 64 << 10, .loongarch32, .loongarch64 => 64 << 10,
.m68k => 8 << 10, .m68k => 8 << 10,
.microblaze, .microblazeel => 4 << 10,
.mips, .mipsel, .mips64, .mips64el => 64 << 10, .mips, .mipsel, .mips64, .mips64el => 64 << 10,
.or1k => 8 << 10, .or1k => 8 << 10,
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 256 << 10, .powerpc, .powerpc64, .powerpc64le, .powerpcle => 256 << 10,
.riscv32, .riscv64 => 4 << 10, .riscv32, .riscv64 => 4 << 10,
.s390x => 4 << 10, .s390x => 4 << 10,
.sh, .sheb => 64 << 10,
.sparc => 4 << 10, .sparc => 4 << 10,
.sparc64 => 8 << 10, .sparc64 => 8 << 10,
.x86, .x86_64 => 4 << 10, .x86, .x86_64 => 4 << 10,
.xtensa => 4 << 10, .xtensa, .xtensaeb => 4 << 10,
else => null, else => null,
}, },
.freestanding => switch (builtin.cpu.arch) { .freestanding => switch (builtin.cpu.arch) {

View file

@ -116,7 +116,7 @@ pub const SECCOMP = @import("linux/seccomp.zig");
pub const syscalls = @import("linux/syscalls.zig"); pub const syscalls = @import("linux/syscalls.zig");
pub const SYS = switch (native_arch) { pub const SYS = switch (native_arch) {
.arc => syscalls.Arc, .arc, .arceb => syscalls.Arc,
.aarch64, .aarch64_be => syscalls.Arm64, .aarch64, .aarch64_be => syscalls.Arm64,
.arm, .armeb, .thumb, .thumbeb => syscalls.Arm, .arm, .armeb, .thumb, .thumbeb => syscalls.Arm,
.csky => syscalls.CSky, .csky => syscalls.CSky,
@ -141,7 +141,7 @@ pub const SYS = switch (native_arch) {
.gnux32, .muslx32 => syscalls.X32, .gnux32, .muslx32 => syscalls.X32,
else => syscalls.X64, else => syscalls.X64,
}, },
.xtensa => syscalls.Xtensa, .xtensa, .xtensaeb => syscalls.Xtensa,
else => @compileError("The Zig Standard Library is missing syscall definitions for the target CPU architecture"), else => @compileError("The Zig Standard Library is missing syscall definitions for the target CPU architecture"),
}; };
@ -3686,7 +3686,7 @@ pub const PROT = struct {
pub const EXEC = 0x4; pub const EXEC = 0x4;
/// page may be used for atomic ops /// page may be used for atomic ops
pub const SEM = switch (native_arch) { pub const SEM = switch (native_arch) {
.mips, .mipsel, .mips64, .mips64el, .xtensa => 0x10, .mips, .mipsel, .mips64, .mips64el, .xtensa, .xtensaeb => 0x10,
else => 0x8, else => 0x8,
}; };
/// mprotect flag: extend change to start of growsdown vma /// mprotect flag: extend change to start of growsdown vma
@ -6161,6 +6161,7 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
pub const MINSIGSTKSZ = switch (native_arch) { pub const MINSIGSTKSZ = switch (native_arch) {
.arc, .arc,
.arceb,
.arm, .arm,
.armeb, .armeb,
.csky, .csky,
@ -6181,6 +6182,7 @@ pub const MINSIGSTKSZ = switch (native_arch) {
.x86, .x86,
.x86_64, .x86_64,
.xtensa, .xtensa,
.xtensaeb,
=> 2048, => 2048,
.loongarch64, .loongarch64,
.sparc, .sparc,
@ -6196,6 +6198,7 @@ pub const MINSIGSTKSZ = switch (native_arch) {
}; };
pub const SIGSTKSZ = switch (native_arch) { pub const SIGSTKSZ = switch (native_arch) {
.arc, .arc,
.arceb,
.arm, .arm,
.armeb, .armeb,
.csky, .csky,
@ -6216,6 +6219,7 @@ pub const SIGSTKSZ = switch (native_arch) {
.x86, .x86,
.x86_64, .x86_64,
.xtensa, .xtensa,
.xtensaeb,
=> 8192, => 8192,
.aarch64, .aarch64,
.aarch64_be, .aarch64_be,
@ -9740,6 +9744,7 @@ pub const AUDIT = struct {
.armeb, .thumbeb => .ARMEB, .armeb, .thumbeb => .ARMEB,
.aarch64 => .AARCH64, .aarch64 => .AARCH64,
.arc => .ARCV2, .arc => .ARCV2,
.arceb => .ARCV2BE,
.csky => .CSKY, .csky => .CSKY,
.hexagon => .HEXAGON, .hexagon => .HEXAGON,
.loongarch32 => .LOONGARCH32, .loongarch32 => .LOONGARCH32,

View file

@ -46,7 +46,7 @@ const Variant = enum {
/// -------------------------------------^------------- /// -------------------------------------^-------------
/// `-- The TP register points here. /// `-- The TP register points here.
/// ///
/// The offset (which can be zero) is applied to the TP only; there is never physical gap /// The offset (which can be zero) is applied to the TP only; there is never a physical gap
/// between the ABI TCB and the TLS blocks. This implies that we only need to align the TP. /// between the ABI TCB and the TLS blocks. This implies that we only need to align the TP.
/// ///
/// The first (and only) word in the ABI TCB points to the DTV. /// The first (and only) word in the ABI TCB points to the DTV.
@ -63,12 +63,19 @@ const Variant = enum {
}; };
const current_variant: Variant = switch (native_arch) { const current_variant: Variant = switch (native_arch) {
.arc,
.arm,
.armeb,
.aarch64, .aarch64,
.aarch64_be, .aarch64_be,
.alpha,
.arc,
.arceb,
.arm,
.armeb,
.csky, .csky,
.hppa,
.microblaze,
.microblazeel,
.sh,
.sheb,
.thumb, .thumb,
.thumbeb, .thumbeb,
=> .I_original, => .I_original,
@ -133,18 +140,22 @@ const current_dtv_offset = switch (native_arch) {
/// Per-thread storage for the ELF TLS ABI. /// Per-thread storage for the ELF TLS ABI.
const AbiTcb = switch (current_variant) { const AbiTcb = switch (current_variant) {
.I_original, .I_modified => switch (native_arch) { .I_original, .I_modified => switch (native_arch) {
// ARM EABI mandates enough space for two pointers: the first one points to the DTV as
// usual, while the second one is unspecified.
.aarch64, .aarch64,
.aarch64_be, .aarch64_be,
.alpha,
.arm, .arm,
.armeb, .armeb,
.hppa,
.microblaze,
.microblazeel,
.sh,
.sheb,
.thumb, .thumb,
.thumbeb, .thumbeb,
=> extern struct { => extern struct {
/// This is offset by `current_dtv_offset`. /// This is offset by `current_dtv_offset`.
dtv: usize, dtv: usize,
reserved: ?*anyopaque, _reserved: ?*anyopaque,
}, },
else => extern struct { else => extern struct {
/// This is offset by `current_dtv_offset`. /// This is offset by `current_dtv_offset`.
@ -243,7 +254,15 @@ pub fn setThreadPointer(addr: usize) void {
: [addr] "r" (addr), : [addr] "r" (addr),
); );
}, },
.arc => { .alpha => {
asm volatile (
\\ lda a0, %[addr]
\\ wruniq
:
: [addr] "r" (addr),
);
},
.arc, .arceb => {
// We apparently need to both set r25 (TP) *and* inform the kernel... // We apparently need to both set r25 (TP) *and* inform the kernel...
asm volatile ( asm volatile (
\\ mov r25, %[addr] \\ mov r25, %[addr]
@ -268,6 +287,13 @@ pub fn setThreadPointer(addr: usize) void {
: [addr] "r" (addr), : [addr] "r" (addr),
); );
}, },
.hppa => {
asm volatile (
\\ ble 0xe0(%%sr2, %%r0)
:
: [addr] "={r26}" (addr),
: .{ .r29 = true });
},
.loongarch32, .loongarch64 => { .loongarch32, .loongarch64 => {
asm volatile ( asm volatile (
\\ move $tp, %[addr] \\ move $tp, %[addr]
@ -286,6 +312,13 @@ pub fn setThreadPointer(addr: usize) void {
const rc = @call(.always_inline, linux.syscall1, .{ .set_thread_area, addr }); const rc = @call(.always_inline, linux.syscall1, .{ .set_thread_area, addr });
assert(rc == 0); assert(rc == 0);
}, },
.microblaze, .microblazeel => {
asm volatile (
\\ ori r21, %[addr], 0
:
: [addr] "r" (addr),
);
},
.or1k => { .or1k => {
asm volatile ( asm volatile (
\\ l.ori r10, %[addr], 0 \\ l.ori r10, %[addr], 0
@ -317,6 +350,13 @@ pub fn setThreadPointer(addr: usize) void {
: [addr] "r" (addr), : [addr] "r" (addr),
: .{ .r0 = true }); : .{ .r0 = true });
}, },
.sh, .sheb => {
asm volatile (
\\ ldc gbr, %[addr]
:
: [addr] "r" (addr),
);
},
.sparc, .sparc64 => { .sparc, .sparc64 => {
asm volatile ( asm volatile (
\\ mov %[addr], %%g7 \\ mov %[addr], %%g7

View file

@ -3,6 +3,7 @@ const builtin = @import("builtin");
const elf = std.elf; const elf = std.elf;
const assert = std.debug.assert; const assert = std.debug.assert;
const R_ALPHA_RELATIVE = 27;
const R_AMD64_RELATIVE = 8; const R_AMD64_RELATIVE = 8;
const R_386_RELATIVE = 8; const R_386_RELATIVE = 8;
const R_ARC_RELATIVE = 56; const R_ARC_RELATIVE = 56;
@ -12,28 +13,33 @@ const R_CSKY_RELATIVE = 9;
const R_HEXAGON_RELATIVE = 35; const R_HEXAGON_RELATIVE = 35;
const R_LARCH_RELATIVE = 3; const R_LARCH_RELATIVE = 3;
const R_68K_RELATIVE = 22; const R_68K_RELATIVE = 22;
const R_MICROBLAZE_REL = 16;
const R_MIPS_RELATIVE = 128; const R_MIPS_RELATIVE = 128;
const R_OR1K_RELATIVE = 21; const R_OR1K_RELATIVE = 21;
const R_PPC_RELATIVE = 22; const R_PPC_RELATIVE = 22;
const R_RISCV_RELATIVE = 3; const R_RISCV_RELATIVE = 3;
const R_390_RELATIVE = 12; const R_390_RELATIVE = 12;
const R_SH_RELATIVE = 165;
const R_SPARC_RELATIVE = 22; const R_SPARC_RELATIVE = 22;
const R_RELATIVE = switch (builtin.cpu.arch) { const R_RELATIVE = switch (builtin.cpu.arch) {
.x86 => R_386_RELATIVE, .x86 => R_386_RELATIVE,
.x86_64 => R_AMD64_RELATIVE, .x86_64 => R_AMD64_RELATIVE,
.arc => R_ARC_RELATIVE, .arc, .arceb => R_ARC_RELATIVE,
.arm, .armeb, .thumb, .thumbeb => R_ARM_RELATIVE, .arm, .armeb, .thumb, .thumbeb => R_ARM_RELATIVE,
.aarch64, .aarch64_be => R_AARCH64_RELATIVE, .aarch64, .aarch64_be => R_AARCH64_RELATIVE,
.alpha => R_ALPHA_RELATIVE,
.csky => R_CSKY_RELATIVE, .csky => R_CSKY_RELATIVE,
.hexagon => R_HEXAGON_RELATIVE, .hexagon => R_HEXAGON_RELATIVE,
.loongarch32, .loongarch64 => R_LARCH_RELATIVE, .loongarch32, .loongarch64 => R_LARCH_RELATIVE,
.m68k => R_68K_RELATIVE, .m68k => R_68K_RELATIVE,
.microblaze, .microblazeel => R_MICROBLAZE_REL,
.mips, .mipsel, .mips64, .mips64el => R_MIPS_RELATIVE, .mips, .mipsel, .mips64, .mips64el => R_MIPS_RELATIVE,
.or1k => R_OR1K_RELATIVE, .or1k => R_OR1K_RELATIVE,
.powerpc, .powerpcle, .powerpc64, .powerpc64le => R_PPC_RELATIVE, .powerpc, .powerpcle, .powerpc64, .powerpc64le => R_PPC_RELATIVE,
.riscv32, .riscv32be, .riscv64, .riscv64be => R_RISCV_RELATIVE, .riscv32, .riscv32be, .riscv64, .riscv64be => R_RISCV_RELATIVE,
.s390x => R_390_RELATIVE, .s390x => R_390_RELATIVE,
.sh, .sheb => R_SH_RELATIVE,
.sparc, .sparc64 => R_SPARC_RELATIVE, .sparc, .sparc64 => R_SPARC_RELATIVE,
else => @compileError("Missing R_RELATIVE definition for this target"), else => @compileError("Missing R_RELATIVE definition for this target"),
}; };
@ -58,7 +64,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
\\ lea _DYNAMIC(%%rip), %[ret] \\ lea _DYNAMIC(%%rip), %[ret]
: [ret] "=r" (-> [*]const elf.Dyn), : [ret] "=r" (-> [*]const elf.Dyn),
), ),
.arc => asm volatile ( .arc, .arceb => asm volatile (
\\ .weak _DYNAMIC \\ .weak _DYNAMIC
\\ .hidden _DYNAMIC \\ .hidden _DYNAMIC
\\ add %[ret], pcl, _DYNAMIC@pcl \\ add %[ret], pcl, _DYNAMIC@pcl
@ -83,6 +89,15 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
\\ add %[ret], %[ret], #:lo12:_DYNAMIC \\ add %[ret], %[ret], #:lo12:_DYNAMIC
: [ret] "=r" (-> [*]const elf.Dyn), : [ret] "=r" (-> [*]const elf.Dyn),
), ),
// The compiler is not required to load the GP register, so do it ourselves.
.alpha => asm volatile (
\\ br $29, 1f
\\1:
\\ ldgp $29, 0($29)
\\ ldq %[ret], -0x8000($29)
: [ret] "=r" (-> [*]const elf.Dyn),
:
: .{ .r26 = true }),
// The CSKY ABI requires the gb register to point to the GOT. Additionally, the first // The CSKY ABI requires the gb register to point to the GOT. Additionally, the first
// entry in the GOT is defined to hold the address of _DYNAMIC. // entry in the GOT is defined to hold the address of _DYNAMIC.
.csky => asm volatile ( .csky => asm volatile (
@ -118,6 +133,10 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
\\ lea (%[ret], %%pc), %[ret] \\ lea (%[ret], %%pc), %[ret]
: [ret] "=r" (-> [*]const elf.Dyn), : [ret] "=r" (-> [*]const elf.Dyn),
), ),
.microblaze, .microblazeel => asm volatile (
\\ lwi %[ret], r20, 0
: [ret] "=r" (-> [*]const elf.Dyn),
),
.mips, .mipsel => asm volatile ( .mips, .mipsel => asm volatile (
\\ .weak _DYNAMIC \\ .weak _DYNAMIC
\\ .hidden _DYNAMIC \\ .hidden _DYNAMIC
@ -206,6 +225,20 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
\\ 2: \\ 2:
: [ret] "=a" (-> [*]const elf.Dyn), : [ret] "=a" (-> [*]const elf.Dyn),
), ),
.sh, .sheb => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ mova 1f, r0
\\ mov.l 1f, %[ret]
\\ add r0, %[ret]
\\ bra 2f
\\1:
\\ .balign 4
\\ .long DYNAMIC - .
\\2:
: [ret] "=r" (-> [*]const elf.Dyn),
:
: .{ .r0 = true }),
// The compiler does not necessarily have any obligation to load the `l7` register (pointing // The compiler does not necessarily have any obligation to load the `l7` register (pointing
// to the GOT), so do it ourselves just in case. // to the GOT), so do it ourselves just in case.
.sparc, .sparc64 => asm volatile ( .sparc, .sparc64 => asm volatile (

View file

@ -195,13 +195,15 @@ fn _start() callconv(.naked) noreturn {
// This is the first userspace frame. Prevent DWARF-based unwinders from unwinding further. We // This is the first userspace frame. Prevent DWARF-based unwinders from unwinding further. We
// prevent FP-based unwinders from unwinding further by zeroing the register below. // prevent FP-based unwinders from unwinding further by zeroing the register below.
if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (switch (native_arch) { if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (switch (native_arch) {
.arc => ".cfi_undefined blink",
.arm, .armeb, .thumb, .thumbeb => "", // https://github.com/llvm/llvm-project/issues/115891
.aarch64, .aarch64_be => ".cfi_undefined lr", .aarch64, .aarch64_be => ".cfi_undefined lr",
.alpha => ".cfi_undefined $26",
.arc, .arceb => ".cfi_undefined blink",
.arm, .armeb, .thumb, .thumbeb => "", // https://github.com/llvm/llvm-project/issues/115891
.csky => ".cfi_undefined lr", .csky => ".cfi_undefined lr",
.hexagon => ".cfi_undefined r31", .hexagon => ".cfi_undefined r31",
.loongarch32, .loongarch64 => ".cfi_undefined 1", .loongarch32, .loongarch64 => ".cfi_undefined 1",
.m68k => ".cfi_undefined %%pc", .m68k => ".cfi_undefined %%pc",
.microblaze, .microblazeel => ".cfi_undefined r15",
.mips, .mipsel, .mips64, .mips64el => ".cfi_undefined $ra", .mips, .mipsel, .mips64, .mips64el => ".cfi_undefined $ra",
.or1k => ".cfi_undefined r9", .or1k => ".cfi_undefined r9",
.powerpc, .powerpcle, .powerpc64, .powerpc64le => ".cfi_undefined lr", .powerpc, .powerpcle, .powerpc64, .powerpc64le => ".cfi_undefined lr",
@ -210,6 +212,7 @@ fn _start() callconv(.naked) noreturn {
else else
".cfi_undefined ra", ".cfi_undefined ra",
.s390x => ".cfi_undefined %%r14", .s390x => ".cfi_undefined %%r14",
.sh, .sheb => ".cfi_undefined pr",
.sparc, .sparc64 => ".cfi_undefined %%i7", .sparc, .sparc64 => ".cfi_undefined %%i7",
.x86 => ".cfi_undefined %%eip", .x86 => ".cfi_undefined %%eip",
.x86_64 => ".cfi_undefined %%rip", .x86_64 => ".cfi_undefined %%rip",
@ -253,7 +256,19 @@ fn _start() callconv(.naked) noreturn {
\\ and sp, x0, #-16 \\ and sp, x0, #-16
\\ b %[posixCallMainAndExit] \\ b %[posixCallMainAndExit]
, ,
.arc => .alpha =>
// $15 = FP, $26 = LR, $29 = GP, $30 = SP
\\ br $29, 1f
\\1:
\\ ldgp $29, 0($29)
\\ mov 0, $15
\\ mov 0, $26
\\ mov $30, $16
\\ ldi $1, -16
\\ and $30, $30, $1
\\ jsr $26, %[posixCallMainAndExit]
,
.arc, .arceb =>
// ARC v1 and v2 had a very low stack alignment requirement of 4; v3 increased it to 16. // ARC v1 and v2 had a very low stack alignment requirement of 4; v3 increased it to 16.
\\ mov fp, 0 \\ mov fp, 0
\\ mov blink, 0 \\ mov blink, 0
@ -333,6 +348,16 @@ fn _start() callconv(.naked) noreturn {
\\ lea %[posixCallMainAndExit] - . - 8, %%a0 \\ lea %[posixCallMainAndExit] - . - 8, %%a0
\\ jsr (%%pc, %%a0) \\ jsr (%%pc, %%a0)
, ,
.microblaze, .microblazeel =>
// r1 = SP, r15 = LR, r19 = FP, r20 = GP
\\ ori r15, r0, r0
\\ ori r19, r0, r0
\\ mfs r20, rpc
\\ addik r20, r20, _GLOBAL_OFFSET_TABLE_ + 8
\\ ori r5, r1, r0
\\ andi r1, r1, -4
\\ brlid r15, %[posixCallMainAndExit]
,
.mips, .mipsel => .mips, .mipsel =>
\\ move $fp, $zero \\ move $fp, $zero
\\ bal 1f \\ bal 1f
@ -431,6 +456,21 @@ fn _start() callconv(.naked) noreturn {
\\ stg %%r0, 0(%%r15) \\ stg %%r0, 0(%%r15)
\\ jg %[posixCallMainAndExit] \\ jg %[posixCallMainAndExit]
, ,
.sh, .sheb =>
// r14 = FP, r15 = SP, pr = LR
\\ mov #0, r0
\\ lds r0, pr
\\ mov r0, r14
\\ mov r15, r4
\\ mov #-4, r0
\\ and r0, r15
\\ mov.l 2f, r1
\\1:
\\ bsrf r1
\\2:
\\ .balign 4
\\ .long %[posixCallMainAndExit]@PCREL - (1b + 4 - .)
,
.sparc => .sparc =>
// argc is stored after a register window (16 registers * 4 bytes). // argc is stored after a register window (16 registers * 4 bytes).
// i7 = LR // i7 = LR

View file

@ -100,10 +100,14 @@ pub fn getExternalExecutor(
else => bad_result, else => bad_result,
}, },
inline .aarch64_be, inline .aarch64_be,
.alpha,
.armeb, .armeb,
.hexagon, .hexagon,
.hppa,
.loongarch64, .loongarch64,
.m68k, .m68k,
.microblaze,
.microblazeel,
.mips, .mips,
.mipsel, .mipsel,
.mips64, .mips64,
@ -114,26 +118,34 @@ pub fn getExternalExecutor(
.powerpc64le, .powerpc64le,
.riscv32, .riscv32,
.s390x, .s390x,
.sh,
.sheb,
.sparc, .sparc,
.sparc64, .sparc64,
.thumb, .thumb,
.thumbeb, .thumbeb,
.xtensa, .xtensa,
.xtensaeb,
=> |t| switch (candidate.os.tag) { => |t| switch (candidate.os.tag) {
.linux, .linux,
=> .{ .qemu = switch (t) { => .{
.powerpc => "qemu-ppc", .qemu = switch (t) {
.powerpc64 => "qemu-ppc64", .powerpc => "qemu-ppc",
.powerpc64le => "qemu-ppc64le", .powerpc64 => "qemu-ppc64",
.mips64, .mips64el => switch (candidate.abi) { .powerpc64le => "qemu-ppc64le",
.gnuabin32, .muslabin32 => if (t == .mips64el) "qemu-mipsn32el" else "qemu-mipsn32", .mips64, .mips64el => switch (candidate.abi) {
.gnuabin32, .muslabin32 => if (t == .mips64el) "qemu-mipsn32el" else "qemu-mipsn32",
else => "qemu-" ++ @tagName(t),
},
// TODO: Actually check the SuperH version.
.sh => "qemu-sh4",
.sheb => "qemu-sh4eb",
.sparc => if (candidate.cpu.has(.sparc, .v8plus)) "qemu-sparc32plus" else "qemu-sparc",
.thumb => "qemu-arm",
.thumbeb => "qemu-armeb",
else => "qemu-" ++ @tagName(t), else => "qemu-" ++ @tagName(t),
}, },
.sparc => if (candidate.cpu.has(.sparc, .v8plus)) "qemu-sparc32plus" else "qemu-sparc", },
.thumb => "qemu-arm",
.thumbeb => "qemu-armeb",
else => "qemu-" ++ @tagName(t),
} },
else => bad_result, else => bad_result,
}, },
else => bad_result, else => bad_result,

View file

@ -12960,6 +12960,11 @@ const PackedCallingConvention = packed struct(u18) {
.incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0), .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
.extra = @intFromEnum(pl.type), .extra = @intFromEnum(pl.type),
}, },
std.builtin.CallingConvention.MicroblazeInterruptOptions => .{
.tag = tag,
.incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
.extra = @intFromEnum(pl.type),
},
std.builtin.CallingConvention.MipsInterruptOptions => .{ std.builtin.CallingConvention.MipsInterruptOptions => .{
.tag = tag, .tag = tag,
.incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0), .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
@ -12970,6 +12975,11 @@ const PackedCallingConvention = packed struct(u18) {
.incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0), .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
.extra = @intFromEnum(pl.mode), .extra = @intFromEnum(pl.mode),
}, },
std.builtin.CallingConvention.ShInterruptOptions => .{
.tag = tag,
.incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
.extra = @intFromEnum(pl.save),
},
else => comptime unreachable, else => comptime unreachable,
}, },
}; };
@ -12997,6 +13007,10 @@ const PackedCallingConvention = packed struct(u18) {
.incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(), .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
.type = @enumFromInt(cc.extra), .type = @enumFromInt(cc.extra),
}, },
std.builtin.CallingConvention.MicroblazeInterruptOptions => .{
.incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
.type = @enumFromInt(cc.extra),
},
std.builtin.CallingConvention.MipsInterruptOptions => .{ std.builtin.CallingConvention.MipsInterruptOptions => .{
.incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(), .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
.mode = @enumFromInt(cc.extra), .mode = @enumFromInt(cc.extra),
@ -13005,6 +13019,10 @@ const PackedCallingConvention = packed struct(u18) {
.incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(), .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
.mode = @enumFromInt(cc.extra), .mode = @enumFromInt(cc.extra),
}, },
std.builtin.CallingConvention.ShInterruptOptions => .{
.incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
.save = @enumFromInt(cc.extra),
},
else => comptime unreachable, else => comptime unreachable,
}, },
), ),

View file

@ -9035,6 +9035,7 @@ pub fn handleExternLibName(
/// functions or there are no more other calling conventions that support variadic functions. /// functions or there are no more other calling conventions that support variadic functions.
const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention.Tag{ const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention.Tag{
.x86_64_sysv, .x86_64_sysv,
.x86_64_x32,
.x86_64_win, .x86_64_win,
.x86_sysv, .x86_sysv,
.x86_win, .x86_win,
@ -9043,8 +9044,10 @@ const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention
.aarch64_aapcs_win, .aarch64_aapcs_win,
.aarch64_vfabi, .aarch64_vfabi,
.aarch64_vfabi_sve, .aarch64_vfabi_sve,
.alpha_osf,
.arm_aapcs, .arm_aapcs,
.arm_aapcs_vfp, .arm_aapcs_vfp,
.microblaze_std,
.mips64_n64, .mips64_n64,
.mips64_n32, .mips64_n32,
.mips_o32, .mips_o32,
@ -9068,6 +9071,8 @@ const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention
.csky_sysv, .csky_sysv,
.hexagon_sysv, .hexagon_sysv,
.hexagon_sysv_hvx, .hexagon_sysv_hvx,
.hppa_elf,
.hppa64_elf,
.lanai_sysv, .lanai_sysv,
.loongarch64_lp64, .loongarch64_lp64,
.loongarch32_ilp32, .loongarch32_ilp32,
@ -9078,6 +9083,8 @@ const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention
.or1k_sysv, .or1k_sysv,
.s390x_sysv, .s390x_sysv,
.s390x_sysv_vx, .s390x_sysv_vx,
.sh_gnu,
.sh_renesas,
.ve_sysv, .ve_sysv,
.xcore_xs1, .xcore_xs1,
.xcore_xs2, .xcore_xs2,
@ -9128,10 +9135,13 @@ fn callConvIsCallable(cc: std.builtin.CallingConvention.Tag) bool {
.avr_signal, .avr_signal,
.csky_interrupt, .csky_interrupt,
.m68k_interrupt, .m68k_interrupt,
.microblaze_interrupt,
.mips_interrupt, .mips_interrupt,
.mips64_interrupt, .mips64_interrupt,
.msp430_interrupt,
.riscv32_interrupt, .riscv32_interrupt,
.riscv64_interrupt, .riscv64_interrupt,
.sh_interrupt,
.x86_interrupt, .x86_interrupt,
.x86_64_interrupt, .x86_64_interrupt,
@ -9156,7 +9166,7 @@ fn checkMergeAllowed(sema: *Sema, block: *Block, src: LazySrcLoc, peer_ty: Type)
} }
const as = peer_ty.ptrAddressSpace(zcu); const as = peer_ty.ptrAddressSpace(zcu);
if (!target_util.arePointersLogical(target, as)) { if (!target_util.shouldBlockPointerOps(target, as)) {
return; return;
} }
@ -9287,13 +9297,16 @@ fn funcCommon(
}, },
.arc_interrupt, .arc_interrupt,
.arm_interrupt, .arm_interrupt,
.microblaze_interrupt,
.mips64_interrupt, .mips64_interrupt,
.mips_interrupt, .mips_interrupt,
.riscv64_interrupt, .riscv64_interrupt,
.riscv32_interrupt, .riscv32_interrupt,
.sh_interrupt,
.avr_interrupt, .avr_interrupt,
.csky_interrupt, .csky_interrupt,
.m68k_interrupt, .m68k_interrupt,
.msp430_interrupt,
.avr_signal, .avr_signal,
=> return sema.fail(block, param_src, "parameters are not allowed with '{s}' calling convention", .{@tagName(cc)}), => return sema.fail(block, param_src, "parameters are not allowed with '{s}' calling convention", .{@tagName(cc)}),
else => {}, else => {},
@ -9517,10 +9530,13 @@ fn finishFunc(
.mips_interrupt, .mips_interrupt,
.riscv64_interrupt, .riscv64_interrupt,
.riscv32_interrupt, .riscv32_interrupt,
.sh_interrupt,
.arc_interrupt, .arc_interrupt,
.avr_interrupt, .avr_interrupt,
.csky_interrupt, .csky_interrupt,
.m68k_interrupt, .m68k_interrupt,
.microblaze_interrupt,
.msp430_interrupt,
.avr_signal, .avr_signal,
=> if (return_type.zigTypeTag(zcu) != .void and return_type.zigTypeTag(zcu) != .noreturn) { => if (return_type.zigTypeTag(zcu) != .void and return_type.zigTypeTag(zcu) != .noreturn) {
return sema.fail(block, ret_ty_src, "function with calling convention '{s}' must return 'void' or 'noreturn'", .{@tagName(cc_resolved)}); return sema.fail(block, ret_ty_src, "function with calling convention '{s}' must return 'void' or 'noreturn'", .{@tagName(cc_resolved)});
@ -22669,7 +22685,7 @@ fn ptrCastFull(
try sema.validateRuntimeValue(block, operand_src, operand); try sema.validateRuntimeValue(block, operand_src, operand);
const can_cast_to_int = !target_util.arePointersLogical(zcu.getTarget(), operand_ty.ptrAddressSpace(zcu)); const can_cast_to_int = !target_util.shouldBlockPointerOps(zcu.getTarget(), operand_ty.ptrAddressSpace(zcu));
const need_null_check = can_cast_to_int and block.wantSafety() and operand_ty.ptrAllowsZero(zcu) and !dest_ty.ptrAllowsZero(zcu); const need_null_check = can_cast_to_int and block.wantSafety() and operand_ty.ptrAllowsZero(zcu) and !dest_ty.ptrAllowsZero(zcu);
const need_align_check = can_cast_to_int and block.wantSafety() and dest_align.compare(.gt, src_align); const need_align_check = can_cast_to_int and block.wantSafety() and dest_align.compare(.gt, src_align);
@ -23247,7 +23263,7 @@ fn checkLogicalPtrOperation(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ
if (zcu.intern_pool.indexToKey(ty.toIntern()) == .ptr_type) { if (zcu.intern_pool.indexToKey(ty.toIntern()) == .ptr_type) {
const target = zcu.getTarget(); const target = zcu.getTarget();
const as = ty.ptrAddressSpace(zcu); const as = ty.ptrAddressSpace(zcu);
if (target_util.arePointersLogical(target, as)) { if (target_util.shouldBlockPointerOps(target, as)) {
return sema.failWithOwnedErrorMsg(block, msg: { return sema.failWithOwnedErrorMsg(block, msg: {
const msg = try sema.errMsg(src, "illegal operation on logical pointer of type '{f}'", .{ty.fmt(pt)}); const msg = try sema.errMsg(src, "illegal operation on logical pointer of type '{f}'", .{ty.fmt(pt)});
errdefer msg.destroy(sema.gpa); errdefer msg.destroy(sema.gpa);
@ -28100,7 +28116,7 @@ fn validateRuntimeElemAccess(
if (zcu.intern_pool.indexToKey(parent_ty.toIntern()) == .ptr_type) { if (zcu.intern_pool.indexToKey(parent_ty.toIntern()) == .ptr_type) {
const target = zcu.getTarget(); const target = zcu.getTarget();
const as = parent_ty.ptrAddressSpace(zcu); const as = parent_ty.ptrAddressSpace(zcu);
if (target_util.arePointersLogical(target, as)) { if (target_util.shouldBlockPointerOps(target, as)) {
return sema.fail(block, elem_index_src, "cannot access element of logical pointer '{f}'", .{parent_ty.fmt(pt)}); return sema.fail(block, elem_index_src, "cannot access element of logical pointer '{f}'", .{parent_ty.fmt(pt)});
} }
} }
@ -30047,12 +30063,18 @@ fn callconvCoerceAllowed(
std.builtin.CallingConvention.ArmInterruptOptions => { std.builtin.CallingConvention.ArmInterruptOptions => {
if (src_data.type != dest_data.type) return false; if (src_data.type != dest_data.type) return false;
}, },
std.builtin.CallingConvention.MicroblazeInterruptOptions => {
if (src_data.type != dest_data.type) return false;
},
std.builtin.CallingConvention.MipsInterruptOptions => { std.builtin.CallingConvention.MipsInterruptOptions => {
if (src_data.mode != dest_data.mode) return false; if (src_data.mode != dest_data.mode) return false;
}, },
std.builtin.CallingConvention.RiscvInterruptOptions => { std.builtin.CallingConvention.RiscvInterruptOptions => {
if (src_data.mode != dest_data.mode) return false; if (src_data.mode != dest_data.mode) return false;
}, },
std.builtin.CallingConvention.ShInterruptOptions => {
if (src_data.save != dest_data.save) return false;
},
else => comptime unreachable, else => comptime unreachable,
} }
}, },
@ -36495,7 +36517,7 @@ fn resolveAddressSpace(
block: *Block, block: *Block,
src: LazySrcLoc, src: LazySrcLoc,
zir_ref: Zir.Inst.Ref, zir_ref: Zir.Inst.Ref,
ctx: std.builtin.AddressSpace.Context, ctx: std.Target.AddressSpaceContext,
) !std.builtin.AddressSpace { ) !std.builtin.AddressSpace {
const air_ref = try sema.resolveInst(zir_ref); const air_ref = try sema.resolveInst(zir_ref);
return sema.analyzeAsAddressSpace(block, src, air_ref, ctx); return sema.analyzeAsAddressSpace(block, src, air_ref, ctx);
@ -36506,7 +36528,7 @@ pub fn analyzeAsAddressSpace(
block: *Block, block: *Block,
src: LazySrcLoc, src: LazySrcLoc,
air_ref: Air.Inst.Ref, air_ref: Air.Inst.Ref,
ctx: std.builtin.AddressSpace.Context, ctx: std.Target.AddressSpaceContext,
) !std.builtin.AddressSpace { ) !std.builtin.AddressSpace {
const pt = sema.pt; const pt = sema.pt;
const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace); const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
@ -37631,7 +37653,7 @@ pub fn resolveNavPtrModifiers(
}; };
const @"addrspace": std.builtin.AddressSpace = as: { const @"addrspace": std.builtin.AddressSpace = as: {
const addrspace_ctx: std.builtin.AddressSpace.Context = switch (zir_decl.kind) { const addrspace_ctx: std.Target.AddressSpaceContext = switch (zir_decl.kind) {
.@"var" => .variable, .@"var" => .variable,
else => switch (nav_ty.zigTypeTag(zcu)) { else => switch (nav_ty.zigTypeTag(zcu)) {
.@"fn" => .function, .@"fn" => .function,

View file

@ -3836,61 +3836,17 @@ pub fn atomicPtrAlignment(
) AtomicPtrAlignmentError!Alignment { ) AtomicPtrAlignmentError!Alignment {
const target = zcu.getTarget(); const target = zcu.getTarget();
const max_atomic_bits: u16 = switch (target.cpu.arch) { const max_atomic_bits: u16 = switch (target.cpu.arch) {
.avr,
.msp430,
=> 16,
.arc,
.arm,
.armeb,
.hexagon,
.m68k,
.mips,
.mipsel,
.nvptx,
.or1k,
.powerpc,
.powerpcle,
.riscv32,
.riscv32be,
.sparc,
.thumb,
.thumbeb,
.x86,
.xcore,
.kalimba,
.lanai,
.wasm32,
.csky,
.spirv32,
.loongarch32,
.xtensa,
.propeller,
=> 32,
.amdgcn,
.bpfel,
.bpfeb,
.mips64,
.mips64el,
.nvptx64,
.powerpc64,
.powerpc64le,
.riscv64,
.riscv64be,
.sparc64,
.s390x,
.wasm64,
.ve,
.spirv64,
.loongarch64,
=> 64,
.aarch64, .aarch64,
.aarch64_be, .aarch64_be,
=> 128, => 128,
.x86_64 => if (target.cpu.has(.x86, .cx16)) 128 else 64, .mips64,
.mips64el,
=> 64, // N32 should be 64, not 32.
.x86_64 => if (target.cpu.has(.x86, .cx16)) 128 else 64, // x32 should be 64 or 128, not 32.
else => target.ptrBitWidth(),
}; };
if (ty.toIntern() == .bool_type) return .none; if (ty.toIntern() == .bool_type) return .none;
@ -4470,6 +4426,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
.riscv32_ilp32_v, .riscv32_ilp32_v,
.m68k_rtd, .m68k_rtd,
.m68k_interrupt, .m68k_interrupt,
.msp430_interrupt,
=> |opts| opts.incoming_stack_alignment == null, => |opts| opts.incoming_stack_alignment == null,
.arm_aapcs_vfp, .arm_aapcs_vfp,
@ -4481,6 +4438,9 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
.arm_interrupt, .arm_interrupt,
=> |opts| opts.incoming_stack_alignment == null, => |opts| opts.incoming_stack_alignment == null,
.microblaze_interrupt,
=> |opts| opts.incoming_stack_alignment == null,
.mips_interrupt, .mips_interrupt,
.mips64_interrupt, .mips64_interrupt,
=> |opts| opts.incoming_stack_alignment == null, => |opts| opts.incoming_stack_alignment == null,
@ -4489,6 +4449,9 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
.riscv64_interrupt, .riscv64_interrupt,
=> |opts| opts.incoming_stack_alignment == null, => |opts| opts.incoming_stack_alignment == null,
.sh_interrupt,
=> |opts| opts.incoming_stack_alignment == null,
.x86_sysv, .x86_sysv,
.x86_win, .x86_win,
.x86_stdcall, .x86_stdcall,

View file

@ -8092,6 +8092,13 @@ fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8
.avr_signal => "signal", .avr_signal => "signal",
.microblaze_interrupt => |opts| switch (opts.type) {
.user => "save_volatiles",
.regular => "interrupt_handler",
.fast => "fast_interrupt",
.breakpoint => "break_handler",
},
.mips_interrupt, .mips_interrupt,
.mips64_interrupt, .mips64_interrupt,
=> |opts| switch (opts.mode) { => |opts| switch (opts.mode) {
@ -8106,11 +8113,20 @@ fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8
inline else => |m| "interrupt(\"" ++ @tagName(m) ++ "\")", inline else => |m| "interrupt(\"" ++ @tagName(m) ++ "\")",
}, },
.sh_renesas => "renesas",
.sh_interrupt => |opts| switch (opts.save) {
.fpscr => "trapa_handler", // Implies `interrupt_handler`.
.high => "interrupt_handler, nosave_low_regs",
.full => "interrupt_handler",
.bank => "interrupt_handler, resbank",
},
.m68k_rtd => "m68k_rtd", .m68k_rtd => "m68k_rtd",
.avr_interrupt, .avr_interrupt,
.csky_interrupt, .csky_interrupt,
.m68k_interrupt, .m68k_interrupt,
.msp430_interrupt,
.x86_interrupt, .x86_interrupt,
.x86_64_interrupt, .x86_64_interrupt,
=> "interrupt", => "interrupt",

View file

@ -106,9 +106,18 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8
.wasm64 => "wasm64", .wasm64 => "wasm64",
.ve => "ve", .ve => "ve",
.alpha,
.arceb,
.hppa,
.hppa64,
.kalimba, .kalimba,
.microblaze,
.microblazeel,
.or1k, .or1k,
.propeller, .propeller,
.sh,
.sheb,
.xtensaeb,
=> unreachable, // Gated by hasLlvmSupport(). => unreachable, // Gated by hasLlvmSupport().
}; };
@ -473,9 +482,18 @@ pub fn dataLayout(target: *const std.Target) []const u8 {
.loongarch64 => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", .loongarch64 => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
.xtensa => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32", .xtensa => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32",
.alpha,
.arceb,
.hppa,
.hppa64,
.kalimba, .kalimba,
.microblaze,
.microblazeel,
.or1k, .or1k,
.propeller, .propeller,
.sh,
.sheb,
.xtensaeb,
=> unreachable, // Gated by hasLlvmSupport(). => unreachable, // Gated by hasLlvmSupport().
}; };
} }
@ -11819,6 +11837,8 @@ pub fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: *const std.Targ
std.builtin.CallingConvention.ArcInterruptOptions, std.builtin.CallingConvention.ArcInterruptOptions,
std.builtin.CallingConvention.ArmInterruptOptions, std.builtin.CallingConvention.ArmInterruptOptions,
std.builtin.CallingConvention.RiscvInterruptOptions, std.builtin.CallingConvention.RiscvInterruptOptions,
std.builtin.CallingConvention.ShInterruptOptions,
std.builtin.CallingConvention.MicroblazeInterruptOptions,
std.builtin.CallingConvention.MipsInterruptOptions, std.builtin.CallingConvention.MipsInterruptOptions,
std.builtin.CallingConvention.CommonOptions, std.builtin.CallingConvention.CommonOptions,
=> .{ pl.incoming_stack_alignment, 0 }, => .{ pl.incoming_stack_alignment, 0 },
@ -11882,6 +11902,7 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *const s
.avr_interrupt => .avr_intrcc, .avr_interrupt => .avr_intrcc,
.m68k_rtd => .m68k_rtdcc, .m68k_rtd => .m68k_rtdcc,
.m68k_interrupt => .m68k_intrcc, .m68k_interrupt => .m68k_intrcc,
.msp430_interrupt => .msp430_intrcc,
.amdgcn_kernel => .amdgpu_kernel, .amdgcn_kernel => .amdgpu_kernel,
.amdgcn_cs => .amdgpu_cs, .amdgcn_cs => .amdgpu_cs,
.nvptx_device => .ptx_device, .nvptx_device => .ptx_device,
@ -11901,9 +11922,13 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *const s
.x86_sysv, .x86_sysv,
.x86_win, .x86_win,
.x86_thiscall_mingw, .x86_thiscall_mingw,
.x86_64_x32,
.aarch64_aapcs, .aarch64_aapcs,
.aarch64_aapcs_darwin, .aarch64_aapcs_darwin,
.aarch64_aapcs_win, .aarch64_aapcs_win,
.alpha_osf,
.microblaze_std,
.microblaze_interrupt,
.mips64_n64, .mips64_n64,
.mips64_n32, .mips64_n32,
.mips_o32, .mips_o32,
@ -11926,6 +11951,8 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *const s
.csky_sysv, .csky_sysv,
.hexagon_sysv, .hexagon_sysv,
.hexagon_sysv_hvx, .hexagon_sysv_hvx,
.hppa_elf,
.hppa64_elf,
.lanai_sysv, .lanai_sysv,
.loongarch64_lp64, .loongarch64_lp64,
.loongarch32_ilp32, .loongarch32_ilp32,
@ -11936,6 +11963,9 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *const s
.propeller_sysv, .propeller_sysv,
.s390x_sysv, .s390x_sysv,
.s390x_sysv_vx, .s390x_sysv_vx,
.sh_gnu,
.sh_renesas,
.sh_interrupt,
.ve_sysv, .ve_sysv,
.xcore_xs1, .xcore_xs1,
.xcore_xs2, .xcore_xs2,
@ -13107,9 +13137,18 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
}, },
// LLVM does does not have a backend for these. // LLVM does does not have a backend for these.
.alpha,
.arceb,
.hppa,
.hppa64,
.kalimba, .kalimba,
.microblaze,
.microblazeel,
.or1k, .or1k,
.propeller, .propeller,
.sh,
.sheb,
.xtensaeb,
=> unreachable, => unreachable,
} }
} }

View file

@ -3905,6 +3905,8 @@ fn updateLazyType(
.m68k_rtd => .LLVM_M68kRTD, .m68k_rtd => .LLVM_M68kRTD,
.sh_renesas => .GNU_renesas_sh,
.amdgcn_kernel => .LLVM_OpenCLKernel, .amdgcn_kernel => .LLVM_OpenCLKernel,
.nvptx_kernel, .nvptx_kernel,
.spirv_kernel, .spirv_kernel,
@ -3917,12 +3919,15 @@ fn updateLazyType(
.mips_interrupt, .mips_interrupt,
.riscv64_interrupt, .riscv64_interrupt,
.riscv32_interrupt, .riscv32_interrupt,
.sh_interrupt,
.arc_interrupt, .arc_interrupt,
.avr_builtin, .avr_builtin,
.avr_signal, .avr_signal,
.avr_interrupt, .avr_interrupt,
.csky_interrupt, .csky_interrupt,
.m68k_interrupt, .m68k_interrupt,
.microblaze_interrupt,
.msp430_interrupt,
=> .normal, => .normal,
else => .nocall, else => .nocall,

View file

@ -216,9 +216,18 @@ pub fn hasLlvmSupport(target: *const std.Target, ofmt: std.Target.ObjectFormat)
=> false, => false,
// No LLVM backend exists. // No LLVM backend exists.
.alpha,
.arceb,
.hppa,
.hppa64,
.kalimba, .kalimba,
.microblaze,
.microblazeel,
.or1k, .or1k,
.propeller, .propeller,
.sh,
.sheb,
.xtensaeb,
=> false, => false,
}; };
} }
@ -549,31 +558,35 @@ pub fn addrSpaceCastIsValid(
} }
} }
/// Under SPIR-V with Vulkan, pointers are not 'real' (physical), but rather 'logical'. Effectively, /// Returns whether pointer operations (arithmetic, indexing, etc.) should be blocked
/// this means that all such pointers have to be resolvable to a location at compile time, and places /// for the given address space on the target architecture.
/// a number of restrictions on usage of such pointers. For example, a logical pointer may not be ///
/// part of a merge (result of a branch) and may not be stored in memory at all. This function returns /// Under SPIR-V with Vulkan
/// for a particular architecture and address space wether such pointers are logical. /// (a) all physical pointers (.physical_storage_buffer, .global) always support pointer operations,
pub fn arePointersLogical(target: *const std.Target, as: AddressSpace) bool { /// (b) by default logical pointers (.constant, .input, .output, etc.) never support operations
/// (c) some logical pointers (.storage_buffer, .shared) do support operations when
/// the VariablePointers capability is enabled (which enables OpPtrAccessChain).
pub fn shouldBlockPointerOps(target: *const std.Target, as: AddressSpace) bool {
if (target.os.tag != .vulkan) return false; if (target.os.tag != .vulkan) return false;
return switch (as) { return switch (as) {
// TODO: Vulkan doesn't support pointers in the generic address space, we // TODO: Vulkan doesn't support pointers in the generic address space, we
// should remove this case but this requires a change in defaultAddressSpace(). // should remove this case but this requires a change in defaultAddressSpace().
// For now, at least disable them from being regarded as physical.
.generic => true, .generic => true,
// For now, all global pointers are represented using StorageBuffer or CrossWorkgroup, // For now, all global pointers are represented using StorageBuffer or CrossWorkgroup,
// so these are real pointers. // so these are real pointers.
.global => false, // Physical pointers always support operations
.physical_storage_buffer => false, .global, .physical_storage_buffer => false,
// Logical pointers that support operations with VariablePointers capability
.shared => !target.cpu.features.isEnabled(@intFromEnum(std.Target.spirv.Feature.variable_pointers)), .shared => !target.cpu.features.isEnabled(@intFromEnum(std.Target.spirv.Feature.variable_pointers)),
.storage_buffer => !target.cpu.features.isEnabled(@intFromEnum(std.Target.spirv.Feature.variable_pointers)),
// Logical pointers that never support operations
.constant, .constant,
.local, .local,
.input, .input,
.output, .output,
.uniform, .uniform,
.push_constant, .push_constant,
.storage_buffer,
=> true, => true,
else => unreachable, else => unreachable,
}; };
@ -707,18 +720,26 @@ pub fn minFunctionAlignment(target: *const std.Target) Alignment {
.csky, .csky,
.m68k, .m68k,
.msp430, .msp430,
.sh,
.sheb,
.s390x, .s390x,
.xcore, .xcore,
=> .@"2", => .@"2",
.arc,
.arm,
.armeb,
.aarch64, .aarch64,
.aarch64_be, .aarch64_be,
.alpha,
.arc,
.arceb,
.arm,
.armeb,
.hexagon, .hexagon,
.hppa,
.hppa64,
.lanai, .lanai,
.loongarch32, .loongarch32,
.loongarch64, .loongarch64,
.microblaze,
.microblazeel,
.mips, .mips,
.mipsel, .mipsel,
.powerpc, .powerpc,
@ -728,9 +749,10 @@ pub fn minFunctionAlignment(target: *const std.Target) Alignment {
.sparc, .sparc,
.sparc64, .sparc64,
.xtensa, .xtensa,
.xtensaeb,
=> .@"4", => .@"4",
.bpfel,
.bpfeb, .bpfeb,
.bpfel,
.mips64, .mips64,
.mips64el, .mips64el,
=> .@"8", => .@"8",

View file

@ -12,6 +12,6 @@ comptime {
// target=x86_64-linux // target=x86_64-linux
// //
// :1:8: error: variadic function does not support 'auto' calling convention // :1:8: error: variadic function does not support 'auto' calling convention
// :1:8: note: supported calling conventions: 'x86_64_sysv', 'x86_64_win' // :1:8: note: supported calling conventions: 'x86_64_sysv', 'x86_64_x32', 'x86_64_win'
// :2:16: error: variadic function does not support 'inline' calling convention // :2:16: error: variadic function does not support 'inline' calling convention
// :2:16: note: supported calling conventions: 'x86_64_sysv', 'x86_64_win' // :2:16: note: supported calling conventions: 'x86_64_sysv', 'x86_64_x32', 'x86_64_win'

View file

@ -15,4 +15,4 @@ comptime {
// target=x86_64-linux // target=x86_64-linux
// //
// :1:13: error: variadic function does not support 'auto' calling convention // :1:13: error: variadic function does not support 'auto' calling convention
// :1:13: note: supported calling conventions: 'x86_64_sysv', 'x86_64_win' // :1:13: note: supported calling conventions: 'x86_64_sysv', 'x86_64_x32', 'x86_64_win'

View file

@ -40,7 +40,7 @@ const test_targets = blk: {
// getBaselineCpuFeatures calls populateDependencies which has a O(N ^ 2) algorithm // getBaselineCpuFeatures calls populateDependencies which has a O(N ^ 2) algorithm
// (where N is roughly 160, which technically makes it O(1), but it adds up to a // (where N is roughly 160, which technically makes it O(1), but it adds up to a
// lot of branches) // lot of branches)
@setEvalBranchQuota(50000); @setEvalBranchQuota(60000);
break :blk [_]TestTarget{ break :blk [_]TestTarget{
// Native Targets // Native Targets
@ -397,16 +397,15 @@ const test_targets = blk: {
}) catch unreachable, }) catch unreachable,
.link_libc = true, .link_libc = true,
}, },
// Currently crashes in qemu-hexagon. .{
// .{ .target = std.Target.Query.parse(.{
// .target = std.Target.Query.parse(.{ .arch_os_abi = "hexagon-linux-musl",
// .arch_os_abi = "hexagon-linux-musl", .cpu_features = "baseline+long_calls",
// .cpu_features = "baseline+long_calls", }) catch unreachable,
// }) catch unreachable, .linkage = .dynamic,
// .linkage = .dynamic, .link_libc = true,
// .link_libc = true, .extra_target = true,
// .extra_target = true, },
// },
.{ .{
.target = .{ .target = .{
@ -1551,7 +1550,7 @@ const CAbiTarget = struct {
}; };
const c_abi_targets = blk: { const c_abi_targets = blk: {
@setEvalBranchQuota(20000); @setEvalBranchQuota(30000);
break :blk [_]CAbiTarget{ break :blk [_]CAbiTarget{
// Native Targets // Native Targets