mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
Merge branch 'master' into zon/serializer-unicode-escaping
This commit is contained in:
commit
a57a46d86f
25 changed files with 1349 additions and 309 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1235,6 +1235,18 @@ const LinuxThreadImpl = struct {
|
|||
: [ptr] "r" (@intFromPtr(self.mapped.ptr)),
|
||||
[len] "r" (self.mapped.len),
|
||||
: .{ .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 (
|
||||
\\ r6 = #215 // SYS_munmap
|
||||
\\ r0 = %[ptr]
|
||||
|
|
@ -1247,6 +1259,42 @@ const LinuxThreadImpl = struct {
|
|||
: [ptr] "r" (@intFromPtr(self.mapped.ptr)),
|
||||
[len] "r" (self.mapped.len),
|
||||
: .{ .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
|
||||
// kernel bug that caused syscalls to return EFAULT if the stack pointer is invalid.
|
||||
// The bug was introduced in 46e12c07b3b9603c60fc1d421ff18618241cb081 and fixed in
|
||||
|
|
@ -1335,6 +1383,28 @@ const LinuxThreadImpl = struct {
|
|||
: [ptr] "r" (@intFromPtr(self.mapped.ptr)),
|
||||
[len] "r" (self.mapped.len),
|
||||
: .{ .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 (
|
||||
\\ # See sparc64 comments below.
|
||||
\\ 1:
|
||||
|
|
|
|||
|
|
@ -419,6 +419,7 @@ pub fn cacheLineForCpu(cpu: std.Target.Cpu) u16 {
|
|||
.aarch64,
|
||||
.aarch64_be,
|
||||
.arc,
|
||||
.arceb,
|
||||
.powerpc64,
|
||||
.powerpc64le,
|
||||
=> 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_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/microblaze/include/asm/cache.h#L15
|
||||
// - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/sh/include/cpu-sh4/cpu/cache.h#L10
|
||||
.arm,
|
||||
.armeb,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
.microblaze,
|
||||
.microblazeel,
|
||||
.mips,
|
||||
.mipsel,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
.sh,
|
||||
.sheb,
|
||||
.sparc,
|
||||
.sparc64,
|
||||
=> 32,
|
||||
|
||||
// - 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/parisc/include/asm/cache.h#L16
|
||||
.hppa,
|
||||
.hppa64,
|
||||
.m68k,
|
||||
.or1k,
|
||||
=> 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/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/alpha/include/asm/cache.h#L11
|
||||
// - https://www.xmos.com/download/The-XMOS-XS3-Architecture.pdf
|
||||
else => 64,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ pub const CallingConvention = union(enum(u8)) {
|
|||
|
||||
// Calling conventions for the `x86_64` architecture.
|
||||
x86_64_sysv: CommonOptions,
|
||||
x86_64_x32: CommonOptions,
|
||||
x86_64_win: CommonOptions,
|
||||
x86_64_regcall_v3_sysv: CommonOptions,
|
||||
x86_64_regcall_v4_win: CommonOptions,
|
||||
|
|
@ -229,6 +230,9 @@ pub const CallingConvention = union(enum(u8)) {
|
|||
aarch64_vfabi: CommonOptions,
|
||||
aarch64_vfabi_sve: CommonOptions,
|
||||
|
||||
/// The standard `alpha` calling convention.
|
||||
alpha_osf: CommonOptions,
|
||||
|
||||
// Calling convetions for the `arm`, `armeb`, `thumb`, and `thumbeb` architectures.
|
||||
/// ARM Architecture Procedure Call Standard
|
||||
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.
|
||||
wasm_mvp: CommonOptions,
|
||||
|
||||
/// The standard `arc` calling convention.
|
||||
/// The standard `arc`/`arceb` calling convention.
|
||||
arc_sysv: CommonOptions,
|
||||
arc_interrupt: ArcInterruptOptions,
|
||||
|
||||
|
|
@ -296,6 +300,12 @@ pub const CallingConvention = union(enum(u8)) {
|
|||
hexagon_sysv: 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.
|
||||
lanai_sysv: CommonOptions,
|
||||
|
||||
|
|
@ -311,8 +321,13 @@ pub const CallingConvention = union(enum(u8)) {
|
|||
m68k_rtd: CommonOptions,
|
||||
m68k_interrupt: CommonOptions,
|
||||
|
||||
/// The standard `microblaze`/`microblazeel` calling convention.
|
||||
microblaze_std: CommonOptions,
|
||||
microblaze_interrupt: MicroblazeInterruptOptions,
|
||||
|
||||
/// The standard `msp430` calling convention.
|
||||
msp430_eabi: CommonOptions,
|
||||
msp430_interrupt: CommonOptions,
|
||||
|
||||
/// The standard `or1k` calling convention.
|
||||
or1k_sysv: CommonOptions,
|
||||
|
|
@ -324,6 +339,11 @@ pub const CallingConvention = union(enum(u8)) {
|
|||
s390x_sysv: 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.
|
||||
ve_sysv: CommonOptions,
|
||||
|
||||
|
|
@ -331,7 +351,7 @@ pub const CallingConvention = union(enum(u8)) {
|
|||
xcore_xs1: CommonOptions,
|
||||
xcore_xs2: CommonOptions,
|
||||
|
||||
// Calling conventions for the `xtensa` architecture.
|
||||
// Calling conventions for the `xtensa`/`xtensaeb` architecture.
|
||||
xtensa_call0: 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.
|
||||
pub const MipsInterruptOptions = struct {
|
||||
/// 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.
|
||||
/// Asserts that `cc` is not `.auto`, `.@"async"`, `.naked`, or `.@"inline"`.
|
||||
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
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
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.
|
||||
generic,
|
||||
gs,
|
||||
|
|
@ -858,6 +901,13 @@ pub const VaListAarch64 = extern struct {
|
|||
__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
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const VaListArm = extern struct {
|
||||
|
|
@ -891,6 +941,16 @@ pub const VaListS390x = extern struct {
|
|||
__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
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const VaListX86_64 = extern struct {
|
||||
|
|
@ -920,14 +980,19 @@ pub const VaList = switch (builtin.cpu.arch) {
|
|||
.x86,
|
||||
=> *u8,
|
||||
.arc,
|
||||
.arceb,
|
||||
.avr,
|
||||
.bpfel,
|
||||
.bpfeb,
|
||||
.csky,
|
||||
.hppa,
|
||||
.hppa64,
|
||||
.lanai,
|
||||
.loongarch32,
|
||||
.loongarch64,
|
||||
.m68k,
|
||||
.microblaze,
|
||||
.microblazeel,
|
||||
.mips,
|
||||
.mipsel,
|
||||
.mips64,
|
||||
|
|
@ -952,6 +1017,7 @@ pub const VaList = switch (builtin.cpu.arch) {
|
|||
.stage2_llvm => @compileError("disabled due to miscompilations"),
|
||||
},
|
||||
},
|
||||
.alpha => VaListAlpha,
|
||||
.arm, .armeb, .thumb, .thumbeb => VaListArm,
|
||||
.hexagon => if (builtin.target.abi.isMusl()) VaListHexagon else *u8,
|
||||
.powerpc, .powerpcle => switch (builtin.os.tag) {
|
||||
|
|
@ -959,6 +1025,7 @@ pub const VaList = switch (builtin.cpu.arch) {
|
|||
else => VaListPowerPc,
|
||||
},
|
||||
.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) {
|
||||
.uefi, .windows => switch (builtin.zig_backend) {
|
||||
else => *u8,
|
||||
|
|
@ -966,7 +1033,7 @@ pub const VaList = switch (builtin.cpu.arch) {
|
|||
},
|
||||
else => VaListX86_64,
|
||||
},
|
||||
.xtensa => VaListXtensa,
|
||||
.xtensa, .xtensaeb => VaListXtensa,
|
||||
else => @compileError("VaList not supported for this target yet"),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -779,7 +779,7 @@ pub const Clobbers = switch (@import("builtin").cpu.arch) {
|
|||
lr: bool = false,
|
||||
sr: bool = false,
|
||||
},
|
||||
.xtensa => packed struct {
|
||||
.xtensa, .xtensaeb => packed struct {
|
||||
/// Whether the inline assembly code may perform stores to memory
|
||||
/// addresses other than those derived from input pointer provenance.
|
||||
memory: bool = false,
|
||||
|
|
@ -1591,7 +1591,7 @@ pub const Clobbers = switch (@import("builtin").cpu.arch) {
|
|||
vr30: bool = false,
|
||||
vr31: bool = false,
|
||||
},
|
||||
.arc => packed struct {
|
||||
.arc, .arceb => packed struct {
|
||||
/// Whether the inline assembly code may perform stores to memory
|
||||
/// addresses other than those derived from input pointer provenance.
|
||||
memory: bool = false,
|
||||
|
|
@ -2197,6 +2197,321 @@ pub const Clobbers = switch (@import("builtin").cpu.arch) {
|
|||
msa_map: 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 {
|
||||
/// Whether the inline assembly code may perform stores to memory
|
||||
/// addresses other than those derived from input pointer provenance.
|
||||
|
|
|
|||
|
|
@ -872,13 +872,18 @@ const StackIterator = union(enum) {
|
|||
};
|
||||
|
||||
const fp_usability: FpUsability = switch (builtin.target.cpu.arch) {
|
||||
.alpha,
|
||||
.avr,
|
||||
.csky,
|
||||
.microblaze,
|
||||
.microblazeel,
|
||||
.mips,
|
||||
.mipsel,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
.msp430,
|
||||
.sh,
|
||||
.sheb,
|
||||
.xcore,
|
||||
=> .useless,
|
||||
.hexagon,
|
||||
|
|
@ -969,11 +974,15 @@ const StackIterator = union(enum) {
|
|||
const ra_ptr: *const usize = @ptrFromInt(ra_addr);
|
||||
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
|
||||
// frame is invalid, so we'll treat it as though it we reached end of stack. The
|
||||
// If the stack grows downwards, `bp > fp` should always hold; conversely, if it
|
||||
// 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
|
||||
// *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;
|
||||
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.
|
||||
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,
|
||||
// in which the base pointer is the first word.
|
||||
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.
|
||||
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,
|
||||
// in which the return address is the second word.
|
||||
if (native_arch.isLoongArch() or native_arch.isRISCV()) break :off -1 * @sizeOf(usize);
|
||||
|
|
|
|||
|
|
@ -1430,7 +1430,7 @@ pub fn compactUnwindToDwarfRegNumber(unwind_reg_number: u3) !u16 {
|
|||
pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
|
||||
return switch (arch) {
|
||||
.aarch64, .aarch64_be => 32,
|
||||
.arc => 160,
|
||||
.arc, .arceb => 160,
|
||||
.arm, .armeb, .thumb, .thumbeb => 15,
|
||||
.csky => 64,
|
||||
.hexagon => 76,
|
||||
|
|
@ -1453,7 +1453,7 @@ pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
|
|||
pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
|
||||
return switch (arch) {
|
||||
.aarch64, .aarch64_be => 29,
|
||||
.arc => 27,
|
||||
.arc, .arceb => 27,
|
||||
.arm, .armeb, .thumb, .thumbeb => 11,
|
||||
.csky => 14,
|
||||
.hexagon => 30,
|
||||
|
|
@ -1476,7 +1476,7 @@ pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
|
|||
pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {
|
||||
return switch (arch) {
|
||||
.aarch64, .aarch64_be => 31,
|
||||
.arc => 28,
|
||||
.arc, .arceb => 28,
|
||||
.arm, .armeb, .thumb, .thumbeb => 13,
|
||||
.csky => 14,
|
||||
.hexagon => 29,
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ pub const can_unwind: bool = s: {
|
|||
.x86,
|
||||
.x86_64,
|
||||
},
|
||||
// Not supported yet: arm/armeb/thumb/thumbeb, xtensa
|
||||
// Not supported yet: arm/armeb/thumb/thumbeb, xtensa/xtensaeb
|
||||
.linux => &.{
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuCont
|
|||
root.debug.CpuContext
|
||||
else switch (native_arch) {
|
||||
.aarch64, .aarch64_be => Aarch64,
|
||||
.arc => Arc,
|
||||
.arc, .arceb => Arc,
|
||||
.arm, .armeb, .thumb, .thumbeb => Arm,
|
||||
.csky => Csky,
|
||||
.hexagon => Hexagon,
|
||||
|
|
@ -36,7 +36,7 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
|
|||
const uc: *const signal_ucontext_t = @ptrCast(@alignCast(ctx_ptr));
|
||||
|
||||
// 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 = .{
|
||||
.r = [_]u32{ uc.mcontext.r31, uc.mcontext.r30, 0, uc.mcontext.r28 } ++
|
||||
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.
|
||||
const signal_ucontext_t = switch (native_os) {
|
||||
.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
|
||||
.aarch64,
|
||||
.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
|
||||
.arc,
|
||||
.arceb,
|
||||
.csky,
|
||||
.hexagon,
|
||||
.m68k,
|
||||
|
|
@ -1565,13 +1581,14 @@ const signal_ucontext_t = switch (native_os) {
|
|||
.x86,
|
||||
.x86_64,
|
||||
.xtensa,
|
||||
.xtensaeb,
|
||||
=> extern struct {
|
||||
_flags: usize,
|
||||
_link: ?*signal_ucontext_t,
|
||||
_stack: std.os.linux.stack_t,
|
||||
mcontext: switch (native_arch) {
|
||||
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/arc/include/uapi/asm/sigcontext.h
|
||||
.arc => extern struct {
|
||||
.arc, .arceb => extern struct {
|
||||
_pad1: u32,
|
||||
_bta: u32,
|
||||
_lp: extern struct {
|
||||
|
|
@ -1616,6 +1633,21 @@ const signal_ucontext_t = switch (native_os) {
|
|||
_ugp: 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
|
||||
.m68k => extern struct {
|
||||
_version: i32,
|
||||
|
|
@ -1623,6 +1655,11 @@ const signal_ucontext_t = switch (native_os) {
|
|||
a: [8]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
|
||||
.mips, .mipsel => extern struct {
|
||||
_regmask: u32,
|
||||
|
|
@ -1652,6 +1689,13 @@ const signal_ucontext_t = switch (native_os) {
|
|||
},
|
||||
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
|
||||
.x86 => extern struct {
|
||||
_gs: u32,
|
||||
|
|
@ -1691,7 +1735,7 @@ const signal_ucontext_t = switch (native_os) {
|
|||
rip: u64,
|
||||
},
|
||||
// https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/xtensa/include/uapi/asm/sigcontext.h
|
||||
.xtensa => extern struct {
|
||||
.xtensa, .xtensaeb => extern struct {
|
||||
pc: u32,
|
||||
_ps: u32,
|
||||
_l: extern struct {
|
||||
|
|
@ -1948,6 +1992,7 @@ const signal_ucontext_t = switch (native_os) {
|
|||
_err: i32,
|
||||
eip: u32,
|
||||
},
|
||||
// https://github.com/illumos/illumos-gate/blob/d4ce137bba3bd16823db6374d9e9a643264ce245/usr/src/uts/intel/sys/mcontext.h
|
||||
.x86_64 => extern struct {
|
||||
r15: u64,
|
||||
r14: u64,
|
||||
|
|
@ -1984,6 +2029,14 @@ const signal_ucontext_t = switch (native_os) {
|
|||
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
|
||||
.arm => extern struct {
|
||||
_cookie: i32,
|
||||
|
|
@ -1995,6 +2048,22 @@ const signal_ucontext_t = switch (native_os) {
|
|||
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
|
||||
.mips64, .mips64el => extern struct {
|
||||
_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
|
||||
.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
|
||||
.x86 => extern struct {
|
||||
mcontext: extern struct {
|
||||
|
|
@ -2100,6 +2181,12 @@ const signal_ucontext_t = switch (native_os) {
|
|||
sp: 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 {
|
||||
r: [15]u32 align(8),
|
||||
pc: u32,
|
||||
|
|
@ -2118,6 +2205,7 @@ const signal_ucontext_t = switch (native_os) {
|
|||
_cause: i32,
|
||||
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"),
|
||||
// https://github.com/NetBSD/src/blob/861008c62187bf7bc0aac4d81e52ed6eee4d0c74/sys/arch/powerpc/include/mcontext.h
|
||||
.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
|
||||
.sparc => @compileError("sparc-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
|
||||
.x86 => extern struct {
|
||||
_gs: i32,
|
||||
|
|
|
|||
|
|
@ -736,11 +736,14 @@ const page_size_min_default: ?usize = switch (builtin.os.tag) {
|
|||
},
|
||||
.netbsd => switch (builtin.cpu.arch) {
|
||||
// NetBSD/sys/arch/*
|
||||
.alpha => 8 << 10,
|
||||
.x86, .x86_64 => 4 << 10,
|
||||
.thumb, .thumbeb, .arm, .armeb => 4 << 10,
|
||||
.aarch64, .aarch64_be => 4 << 10,
|
||||
.hppa => 4 << 10,
|
||||
.mips, .mipsel, .mips64, .mips64el => 4 << 10,
|
||||
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10,
|
||||
.sh, .sheb => 4 << 10,
|
||||
.sparc => 4 << 10,
|
||||
.sparc64 => 8 << 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/sys/arch/*
|
||||
.alpha => 8 << 10,
|
||||
.hppa => 4 << 10,
|
||||
.x86, .x86_64 => 4 << 10,
|
||||
.thumb, .thumbeb, .arm, .armeb, .aarch64, .aarch64_be => 4 << 10,
|
||||
.mips64, .mips64el => 4 << 10,
|
||||
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10,
|
||||
.riscv64 => 4 << 10,
|
||||
.sh, .sheb => 4 << 10,
|
||||
.sparc64 => 8 << 10,
|
||||
else => null,
|
||||
},
|
||||
|
|
@ -824,22 +830,26 @@ const page_size_min_default: ?usize = switch (builtin.os.tag) {
|
|||
.emscripten => 64 << 10,
|
||||
.linux => switch (builtin.cpu.arch) {
|
||||
// Linux/arch/*/Kconfig
|
||||
.arc => 4 << 10,
|
||||
.alpha => 8 << 10,
|
||||
.arc, .arceb => 4 << 10,
|
||||
.thumb, .thumbeb, .arm, .armeb => 4 << 10,
|
||||
.aarch64, .aarch64_be => 4 << 10,
|
||||
.csky => 4 << 10,
|
||||
.hexagon => 4 << 10,
|
||||
.hppa => 4 << 10,
|
||||
.loongarch32, .loongarch64 => 4 << 10,
|
||||
.m68k => 4 << 10,
|
||||
.microblaze, .microblazeel => 4 << 10,
|
||||
.mips, .mipsel, .mips64, .mips64el => 4 << 10,
|
||||
.or1k => 8 << 10,
|
||||
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10,
|
||||
.riscv32, .riscv64 => 4 << 10,
|
||||
.s390x => 4 << 10,
|
||||
.sh, .sheb => 4 << 10,
|
||||
.sparc => 4 << 10,
|
||||
.sparc64 => 8 << 10,
|
||||
.x86, .x86_64 => 4 << 10,
|
||||
.xtensa => 4 << 10,
|
||||
.xtensa, .xtensaeb => 4 << 10,
|
||||
else => null,
|
||||
},
|
||||
.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/sys/arch/*
|
||||
.alpha => 8 << 10,
|
||||
.x86, .x86_64 => 4 << 10,
|
||||
.thumb, .thumbeb, .arm, .armeb => 4 << 10,
|
||||
.aarch64, .aarch64_be => 64 << 10,
|
||||
.hppa => 4 << 10,
|
||||
.mips, .mipsel, .mips64, .mips64el => 16 << 10,
|
||||
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 16 << 10,
|
||||
.sh, .sheb => 4 << 10,
|
||||
.sparc => 8 << 10,
|
||||
.sparc64 => 8 << 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/sys/arch/*
|
||||
.alpha => 8 << 10,
|
||||
.hppa => 4 << 10,
|
||||
.x86, .x86_64 => 4 << 10,
|
||||
.thumb, .thumbeb, .arm, .armeb, .aarch64, .aarch64_be => 4 << 10,
|
||||
.mips64, .mips64el => 16 << 10,
|
||||
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10,
|
||||
.riscv64 => 4 << 10,
|
||||
.sh, .sheb => 4 << 10,
|
||||
.sparc64 => 8 << 10,
|
||||
else => null,
|
||||
},
|
||||
|
|
@ -972,22 +988,26 @@ const page_size_max_default: ?usize = switch (builtin.os.tag) {
|
|||
.emscripten => 64 << 10,
|
||||
.linux => switch (builtin.cpu.arch) {
|
||||
// Linux/arch/*/Kconfig
|
||||
.arc => 16 << 10,
|
||||
.alpha => 8 << 10,
|
||||
.arc, .arceb => 16 << 10,
|
||||
.thumb, .thumbeb, .arm, .armeb => 4 << 10,
|
||||
.aarch64, .aarch64_be => 64 << 10,
|
||||
.csky => 4 << 10,
|
||||
.hexagon => 256 << 10,
|
||||
.hppa => 64 << 10,
|
||||
.loongarch32, .loongarch64 => 64 << 10,
|
||||
.m68k => 8 << 10,
|
||||
.microblaze, .microblazeel => 4 << 10,
|
||||
.mips, .mipsel, .mips64, .mips64el => 64 << 10,
|
||||
.or1k => 8 << 10,
|
||||
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 256 << 10,
|
||||
.riscv32, .riscv64 => 4 << 10,
|
||||
.s390x => 4 << 10,
|
||||
.sh, .sheb => 64 << 10,
|
||||
.sparc => 4 << 10,
|
||||
.sparc64 => 8 << 10,
|
||||
.x86, .x86_64 => 4 << 10,
|
||||
.xtensa => 4 << 10,
|
||||
.xtensa, .xtensaeb => 4 << 10,
|
||||
else => null,
|
||||
},
|
||||
.freestanding => switch (builtin.cpu.arch) {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ pub const SECCOMP = @import("linux/seccomp.zig");
|
|||
|
||||
pub const syscalls = @import("linux/syscalls.zig");
|
||||
pub const SYS = switch (native_arch) {
|
||||
.arc => syscalls.Arc,
|
||||
.arc, .arceb => syscalls.Arc,
|
||||
.aarch64, .aarch64_be => syscalls.Arm64,
|
||||
.arm, .armeb, .thumb, .thumbeb => syscalls.Arm,
|
||||
.csky => syscalls.CSky,
|
||||
|
|
@ -141,7 +141,7 @@ pub const SYS = switch (native_arch) {
|
|||
.gnux32, .muslx32 => syscalls.X32,
|
||||
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"),
|
||||
};
|
||||
|
||||
|
|
@ -3686,7 +3686,7 @@ pub const PROT = struct {
|
|||
pub const EXEC = 0x4;
|
||||
/// page may be used for atomic ops
|
||||
pub const SEM = switch (native_arch) {
|
||||
.mips, .mipsel, .mips64, .mips64el, .xtensa => 0x10,
|
||||
.mips, .mipsel, .mips64, .mips64el, .xtensa, .xtensaeb => 0x10,
|
||||
else => 0x8,
|
||||
};
|
||||
/// 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) {
|
||||
.arc,
|
||||
.arceb,
|
||||
.arm,
|
||||
.armeb,
|
||||
.csky,
|
||||
|
|
@ -6181,6 +6182,7 @@ pub const MINSIGSTKSZ = switch (native_arch) {
|
|||
.x86,
|
||||
.x86_64,
|
||||
.xtensa,
|
||||
.xtensaeb,
|
||||
=> 2048,
|
||||
.loongarch64,
|
||||
.sparc,
|
||||
|
|
@ -6196,6 +6198,7 @@ pub const MINSIGSTKSZ = switch (native_arch) {
|
|||
};
|
||||
pub const SIGSTKSZ = switch (native_arch) {
|
||||
.arc,
|
||||
.arceb,
|
||||
.arm,
|
||||
.armeb,
|
||||
.csky,
|
||||
|
|
@ -6216,6 +6219,7 @@ pub const SIGSTKSZ = switch (native_arch) {
|
|||
.x86,
|
||||
.x86_64,
|
||||
.xtensa,
|
||||
.xtensaeb,
|
||||
=> 8192,
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
|
|
@ -9740,6 +9744,7 @@ pub const AUDIT = struct {
|
|||
.armeb, .thumbeb => .ARMEB,
|
||||
.aarch64 => .AARCH64,
|
||||
.arc => .ARCV2,
|
||||
.arceb => .ARCV2BE,
|
||||
.csky => .CSKY,
|
||||
.hexagon => .HEXAGON,
|
||||
.loongarch32 => .LOONGARCH32,
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ const Variant = enum {
|
|||
/// -------------------------------------^-------------
|
||||
/// `-- 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.
|
||||
///
|
||||
/// 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) {
|
||||
.arc,
|
||||
.arm,
|
||||
.armeb,
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
.alpha,
|
||||
.arc,
|
||||
.arceb,
|
||||
.arm,
|
||||
.armeb,
|
||||
.csky,
|
||||
.hppa,
|
||||
.microblaze,
|
||||
.microblazeel,
|
||||
.sh,
|
||||
.sheb,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
=> .I_original,
|
||||
|
|
@ -133,18 +140,22 @@ const current_dtv_offset = switch (native_arch) {
|
|||
/// Per-thread storage for the ELF TLS ABI.
|
||||
const AbiTcb = switch (current_variant) {
|
||||
.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_be,
|
||||
.alpha,
|
||||
.arm,
|
||||
.armeb,
|
||||
.hppa,
|
||||
.microblaze,
|
||||
.microblazeel,
|
||||
.sh,
|
||||
.sheb,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
=> extern struct {
|
||||
/// This is offset by `current_dtv_offset`.
|
||||
dtv: usize,
|
||||
reserved: ?*anyopaque,
|
||||
_reserved: ?*anyopaque,
|
||||
},
|
||||
else => extern struct {
|
||||
/// This is offset by `current_dtv_offset`.
|
||||
|
|
@ -243,7 +254,15 @@ pub fn setThreadPointer(addr: usize) void {
|
|||
: [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...
|
||||
asm volatile (
|
||||
\\ mov r25, %[addr]
|
||||
|
|
@ -268,6 +287,13 @@ pub fn setThreadPointer(addr: usize) void {
|
|||
: [addr] "r" (addr),
|
||||
);
|
||||
},
|
||||
.hppa => {
|
||||
asm volatile (
|
||||
\\ ble 0xe0(%%sr2, %%r0)
|
||||
:
|
||||
: [addr] "={r26}" (addr),
|
||||
: .{ .r29 = true });
|
||||
},
|
||||
.loongarch32, .loongarch64 => {
|
||||
asm volatile (
|
||||
\\ move $tp, %[addr]
|
||||
|
|
@ -286,6 +312,13 @@ pub fn setThreadPointer(addr: usize) void {
|
|||
const rc = @call(.always_inline, linux.syscall1, .{ .set_thread_area, addr });
|
||||
assert(rc == 0);
|
||||
},
|
||||
.microblaze, .microblazeel => {
|
||||
asm volatile (
|
||||
\\ ori r21, %[addr], 0
|
||||
:
|
||||
: [addr] "r" (addr),
|
||||
);
|
||||
},
|
||||
.or1k => {
|
||||
asm volatile (
|
||||
\\ l.ori r10, %[addr], 0
|
||||
|
|
@ -317,6 +350,13 @@ pub fn setThreadPointer(addr: usize) void {
|
|||
: [addr] "r" (addr),
|
||||
: .{ .r0 = true });
|
||||
},
|
||||
.sh, .sheb => {
|
||||
asm volatile (
|
||||
\\ ldc gbr, %[addr]
|
||||
:
|
||||
: [addr] "r" (addr),
|
||||
);
|
||||
},
|
||||
.sparc, .sparc64 => {
|
||||
asm volatile (
|
||||
\\ mov %[addr], %%g7
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ const builtin = @import("builtin");
|
|||
const elf = std.elf;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const R_ALPHA_RELATIVE = 27;
|
||||
const R_AMD64_RELATIVE = 8;
|
||||
const R_386_RELATIVE = 8;
|
||||
const R_ARC_RELATIVE = 56;
|
||||
|
|
@ -12,28 +13,33 @@ const R_CSKY_RELATIVE = 9;
|
|||
const R_HEXAGON_RELATIVE = 35;
|
||||
const R_LARCH_RELATIVE = 3;
|
||||
const R_68K_RELATIVE = 22;
|
||||
const R_MICROBLAZE_REL = 16;
|
||||
const R_MIPS_RELATIVE = 128;
|
||||
const R_OR1K_RELATIVE = 21;
|
||||
const R_PPC_RELATIVE = 22;
|
||||
const R_RISCV_RELATIVE = 3;
|
||||
const R_390_RELATIVE = 12;
|
||||
const R_SH_RELATIVE = 165;
|
||||
const R_SPARC_RELATIVE = 22;
|
||||
|
||||
const R_RELATIVE = switch (builtin.cpu.arch) {
|
||||
.x86 => R_386_RELATIVE,
|
||||
.x86_64 => R_AMD64_RELATIVE,
|
||||
.arc => R_ARC_RELATIVE,
|
||||
.arc, .arceb => R_ARC_RELATIVE,
|
||||
.arm, .armeb, .thumb, .thumbeb => R_ARM_RELATIVE,
|
||||
.aarch64, .aarch64_be => R_AARCH64_RELATIVE,
|
||||
.alpha => R_ALPHA_RELATIVE,
|
||||
.csky => R_CSKY_RELATIVE,
|
||||
.hexagon => R_HEXAGON_RELATIVE,
|
||||
.loongarch32, .loongarch64 => R_LARCH_RELATIVE,
|
||||
.m68k => R_68K_RELATIVE,
|
||||
.microblaze, .microblazeel => R_MICROBLAZE_REL,
|
||||
.mips, .mipsel, .mips64, .mips64el => R_MIPS_RELATIVE,
|
||||
.or1k => R_OR1K_RELATIVE,
|
||||
.powerpc, .powerpcle, .powerpc64, .powerpc64le => R_PPC_RELATIVE,
|
||||
.riscv32, .riscv32be, .riscv64, .riscv64be => R_RISCV_RELATIVE,
|
||||
.s390x => R_390_RELATIVE,
|
||||
.sh, .sheb => R_SH_RELATIVE,
|
||||
.sparc, .sparc64 => R_SPARC_RELATIVE,
|
||||
else => @compileError("Missing R_RELATIVE definition for this target"),
|
||||
};
|
||||
|
|
@ -58,7 +64,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
|
|||
\\ lea _DYNAMIC(%%rip), %[ret]
|
||||
: [ret] "=r" (-> [*]const elf.Dyn),
|
||||
),
|
||||
.arc => asm volatile (
|
||||
.arc, .arceb => asm volatile (
|
||||
\\ .weak _DYNAMIC
|
||||
\\ .hidden _DYNAMIC
|
||||
\\ add %[ret], pcl, _DYNAMIC@pcl
|
||||
|
|
@ -83,6 +89,15 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
|
|||
\\ add %[ret], %[ret], #:lo12:_DYNAMIC
|
||||
: [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
|
||||
// entry in the GOT is defined to hold the address of _DYNAMIC.
|
||||
.csky => asm volatile (
|
||||
|
|
@ -118,6 +133,10 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
|
|||
\\ lea (%[ret], %%pc), %[ret]
|
||||
: [ret] "=r" (-> [*]const elf.Dyn),
|
||||
),
|
||||
.microblaze, .microblazeel => asm volatile (
|
||||
\\ lwi %[ret], r20, 0
|
||||
: [ret] "=r" (-> [*]const elf.Dyn),
|
||||
),
|
||||
.mips, .mipsel => asm volatile (
|
||||
\\ .weak _DYNAMIC
|
||||
\\ .hidden _DYNAMIC
|
||||
|
|
@ -206,6 +225,20 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
|
|||
\\ 2:
|
||||
: [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
|
||||
// to the GOT), so do it ourselves just in case.
|
||||
.sparc, .sparc64 => asm volatile (
|
||||
|
|
|
|||
|
|
@ -195,13 +195,15 @@ fn _start() callconv(.naked) noreturn {
|
|||
// 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.
|
||||
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",
|
||||
.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",
|
||||
.hexagon => ".cfi_undefined r31",
|
||||
.loongarch32, .loongarch64 => ".cfi_undefined 1",
|
||||
.m68k => ".cfi_undefined %%pc",
|
||||
.microblaze, .microblazeel => ".cfi_undefined r15",
|
||||
.mips, .mipsel, .mips64, .mips64el => ".cfi_undefined $ra",
|
||||
.or1k => ".cfi_undefined r9",
|
||||
.powerpc, .powerpcle, .powerpc64, .powerpc64le => ".cfi_undefined lr",
|
||||
|
|
@ -210,6 +212,7 @@ fn _start() callconv(.naked) noreturn {
|
|||
else
|
||||
".cfi_undefined ra",
|
||||
.s390x => ".cfi_undefined %%r14",
|
||||
.sh, .sheb => ".cfi_undefined pr",
|
||||
.sparc, .sparc64 => ".cfi_undefined %%i7",
|
||||
.x86 => ".cfi_undefined %%eip",
|
||||
.x86_64 => ".cfi_undefined %%rip",
|
||||
|
|
@ -253,7 +256,19 @@ fn _start() callconv(.naked) noreturn {
|
|||
\\ and sp, x0, #-16
|
||||
\\ 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.
|
||||
\\ mov fp, 0
|
||||
\\ mov blink, 0
|
||||
|
|
@ -333,6 +348,16 @@ fn _start() callconv(.naked) noreturn {
|
|||
\\ lea %[posixCallMainAndExit] - . - 8, %%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 =>
|
||||
\\ move $fp, $zero
|
||||
\\ bal 1f
|
||||
|
|
@ -431,6 +456,21 @@ fn _start() callconv(.naked) noreturn {
|
|||
\\ stg %%r0, 0(%%r15)
|
||||
\\ 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 =>
|
||||
// argc is stored after a register window (16 registers * 4 bytes).
|
||||
// i7 = LR
|
||||
|
|
|
|||
|
|
@ -100,10 +100,14 @@ pub fn getExternalExecutor(
|
|||
else => bad_result,
|
||||
},
|
||||
inline .aarch64_be,
|
||||
.alpha,
|
||||
.armeb,
|
||||
.hexagon,
|
||||
.hppa,
|
||||
.loongarch64,
|
||||
.m68k,
|
||||
.microblaze,
|
||||
.microblazeel,
|
||||
.mips,
|
||||
.mipsel,
|
||||
.mips64,
|
||||
|
|
@ -114,26 +118,34 @@ pub fn getExternalExecutor(
|
|||
.powerpc64le,
|
||||
.riscv32,
|
||||
.s390x,
|
||||
.sh,
|
||||
.sheb,
|
||||
.sparc,
|
||||
.sparc64,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
.xtensa,
|
||||
.xtensaeb,
|
||||
=> |t| switch (candidate.os.tag) {
|
||||
.linux,
|
||||
=> .{ .qemu = switch (t) {
|
||||
.powerpc => "qemu-ppc",
|
||||
.powerpc64 => "qemu-ppc64",
|
||||
.powerpc64le => "qemu-ppc64le",
|
||||
.mips64, .mips64el => switch (candidate.abi) {
|
||||
.gnuabin32, .muslabin32 => if (t == .mips64el) "qemu-mipsn32el" else "qemu-mipsn32",
|
||||
=> .{
|
||||
.qemu = switch (t) {
|
||||
.powerpc => "qemu-ppc",
|
||||
.powerpc64 => "qemu-ppc64",
|
||||
.powerpc64le => "qemu-ppc64le",
|
||||
.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),
|
||||
},
|
||||
.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,
|
||||
|
|
|
|||
|
|
@ -12960,6 +12960,11 @@ const PackedCallingConvention = packed struct(u18) {
|
|||
.incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
|
||||
.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 => .{
|
||||
.tag = tag,
|
||||
.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),
|
||||
.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,
|
||||
},
|
||||
};
|
||||
|
|
@ -12997,6 +13007,10 @@ const PackedCallingConvention = packed struct(u18) {
|
|||
.incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
|
||||
.type = @enumFromInt(cc.extra),
|
||||
},
|
||||
std.builtin.CallingConvention.MicroblazeInterruptOptions => .{
|
||||
.incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
|
||||
.type = @enumFromInt(cc.extra),
|
||||
},
|
||||
std.builtin.CallingConvention.MipsInterruptOptions => .{
|
||||
.incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
|
||||
.mode = @enumFromInt(cc.extra),
|
||||
|
|
@ -13005,6 +13019,10 @@ const PackedCallingConvention = packed struct(u18) {
|
|||
.incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
|
||||
.mode = @enumFromInt(cc.extra),
|
||||
},
|
||||
std.builtin.CallingConvention.ShInterruptOptions => .{
|
||||
.incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
|
||||
.save = @enumFromInt(cc.extra),
|
||||
},
|
||||
else => comptime unreachable,
|
||||
},
|
||||
),
|
||||
|
|
|
|||
36
src/Sema.zig
36
src/Sema.zig
|
|
@ -9035,6 +9035,7 @@ pub fn handleExternLibName(
|
|||
/// functions or there are no more other calling conventions that support variadic functions.
|
||||
const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention.Tag{
|
||||
.x86_64_sysv,
|
||||
.x86_64_x32,
|
||||
.x86_64_win,
|
||||
.x86_sysv,
|
||||
.x86_win,
|
||||
|
|
@ -9043,8 +9044,10 @@ const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention
|
|||
.aarch64_aapcs_win,
|
||||
.aarch64_vfabi,
|
||||
.aarch64_vfabi_sve,
|
||||
.alpha_osf,
|
||||
.arm_aapcs,
|
||||
.arm_aapcs_vfp,
|
||||
.microblaze_std,
|
||||
.mips64_n64,
|
||||
.mips64_n32,
|
||||
.mips_o32,
|
||||
|
|
@ -9068,6 +9071,8 @@ const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention
|
|||
.csky_sysv,
|
||||
.hexagon_sysv,
|
||||
.hexagon_sysv_hvx,
|
||||
.hppa_elf,
|
||||
.hppa64_elf,
|
||||
.lanai_sysv,
|
||||
.loongarch64_lp64,
|
||||
.loongarch32_ilp32,
|
||||
|
|
@ -9078,6 +9083,8 @@ const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention
|
|||
.or1k_sysv,
|
||||
.s390x_sysv,
|
||||
.s390x_sysv_vx,
|
||||
.sh_gnu,
|
||||
.sh_renesas,
|
||||
.ve_sysv,
|
||||
.xcore_xs1,
|
||||
.xcore_xs2,
|
||||
|
|
@ -9128,10 +9135,13 @@ fn callConvIsCallable(cc: std.builtin.CallingConvention.Tag) bool {
|
|||
.avr_signal,
|
||||
.csky_interrupt,
|
||||
.m68k_interrupt,
|
||||
.microblaze_interrupt,
|
||||
.mips_interrupt,
|
||||
.mips64_interrupt,
|
||||
.msp430_interrupt,
|
||||
.riscv32_interrupt,
|
||||
.riscv64_interrupt,
|
||||
.sh_interrupt,
|
||||
.x86_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);
|
||||
if (!target_util.arePointersLogical(target, as)) {
|
||||
if (!target_util.shouldBlockPointerOps(target, as)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -9287,13 +9297,16 @@ fn funcCommon(
|
|||
},
|
||||
.arc_interrupt,
|
||||
.arm_interrupt,
|
||||
.microblaze_interrupt,
|
||||
.mips64_interrupt,
|
||||
.mips_interrupt,
|
||||
.riscv64_interrupt,
|
||||
.riscv32_interrupt,
|
||||
.sh_interrupt,
|
||||
.avr_interrupt,
|
||||
.csky_interrupt,
|
||||
.m68k_interrupt,
|
||||
.msp430_interrupt,
|
||||
.avr_signal,
|
||||
=> return sema.fail(block, param_src, "parameters are not allowed with '{s}' calling convention", .{@tagName(cc)}),
|
||||
else => {},
|
||||
|
|
@ -9517,10 +9530,13 @@ fn finishFunc(
|
|||
.mips_interrupt,
|
||||
.riscv64_interrupt,
|
||||
.riscv32_interrupt,
|
||||
.sh_interrupt,
|
||||
.arc_interrupt,
|
||||
.avr_interrupt,
|
||||
.csky_interrupt,
|
||||
.m68k_interrupt,
|
||||
.microblaze_interrupt,
|
||||
.msp430_interrupt,
|
||||
.avr_signal,
|
||||
=> 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)});
|
||||
|
|
@ -22669,7 +22685,7 @@ fn ptrCastFull(
|
|||
|
||||
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_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) {
|
||||
const target = zcu.getTarget();
|
||||
const as = ty.ptrAddressSpace(zcu);
|
||||
if (target_util.arePointersLogical(target, as)) {
|
||||
if (target_util.shouldBlockPointerOps(target, as)) {
|
||||
return sema.failWithOwnedErrorMsg(block, msg: {
|
||||
const msg = try sema.errMsg(src, "illegal operation on logical pointer of type '{f}'", .{ty.fmt(pt)});
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
|
|
@ -28100,7 +28116,7 @@ fn validateRuntimeElemAccess(
|
|||
if (zcu.intern_pool.indexToKey(parent_ty.toIntern()) == .ptr_type) {
|
||||
const target = zcu.getTarget();
|
||||
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)});
|
||||
}
|
||||
}
|
||||
|
|
@ -30047,12 +30063,18 @@ fn callconvCoerceAllowed(
|
|||
std.builtin.CallingConvention.ArmInterruptOptions => {
|
||||
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 => {
|
||||
if (src_data.mode != dest_data.mode) return false;
|
||||
},
|
||||
std.builtin.CallingConvention.RiscvInterruptOptions => {
|
||||
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,
|
||||
}
|
||||
},
|
||||
|
|
@ -36495,7 +36517,7 @@ fn resolveAddressSpace(
|
|||
block: *Block,
|
||||
src: LazySrcLoc,
|
||||
zir_ref: Zir.Inst.Ref,
|
||||
ctx: std.builtin.AddressSpace.Context,
|
||||
ctx: std.Target.AddressSpaceContext,
|
||||
) !std.builtin.AddressSpace {
|
||||
const air_ref = try sema.resolveInst(zir_ref);
|
||||
return sema.analyzeAsAddressSpace(block, src, air_ref, ctx);
|
||||
|
|
@ -36506,7 +36528,7 @@ pub fn analyzeAsAddressSpace(
|
|||
block: *Block,
|
||||
src: LazySrcLoc,
|
||||
air_ref: Air.Inst.Ref,
|
||||
ctx: std.builtin.AddressSpace.Context,
|
||||
ctx: std.Target.AddressSpaceContext,
|
||||
) !std.builtin.AddressSpace {
|
||||
const pt = sema.pt;
|
||||
const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
|
||||
|
|
@ -37631,7 +37653,7 @@ pub fn resolveNavPtrModifiers(
|
|||
};
|
||||
|
||||
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,
|
||||
else => switch (nav_ty.zigTypeTag(zcu)) {
|
||||
.@"fn" => .function,
|
||||
|
|
|
|||
65
src/Zcu.zig
65
src/Zcu.zig
|
|
@ -3836,61 +3836,17 @@ pub fn atomicPtrAlignment(
|
|||
) AtomicPtrAlignmentError!Alignment {
|
||||
const target = zcu.getTarget();
|
||||
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_be,
|
||||
=> 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;
|
||||
|
|
@ -4470,6 +4426,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
|
|||
.riscv32_ilp32_v,
|
||||
.m68k_rtd,
|
||||
.m68k_interrupt,
|
||||
.msp430_interrupt,
|
||||
=> |opts| opts.incoming_stack_alignment == null,
|
||||
|
||||
.arm_aapcs_vfp,
|
||||
|
|
@ -4481,6 +4438,9 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
|
|||
.arm_interrupt,
|
||||
=> |opts| opts.incoming_stack_alignment == null,
|
||||
|
||||
.microblaze_interrupt,
|
||||
=> |opts| opts.incoming_stack_alignment == null,
|
||||
|
||||
.mips_interrupt,
|
||||
.mips64_interrupt,
|
||||
=> |opts| opts.incoming_stack_alignment == null,
|
||||
|
|
@ -4489,6 +4449,9 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
|
|||
.riscv64_interrupt,
|
||||
=> |opts| opts.incoming_stack_alignment == null,
|
||||
|
||||
.sh_interrupt,
|
||||
=> |opts| opts.incoming_stack_alignment == null,
|
||||
|
||||
.x86_sysv,
|
||||
.x86_win,
|
||||
.x86_stdcall,
|
||||
|
|
|
|||
|
|
@ -8092,6 +8092,13 @@ fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8
|
|||
|
||||
.avr_signal => "signal",
|
||||
|
||||
.microblaze_interrupt => |opts| switch (opts.type) {
|
||||
.user => "save_volatiles",
|
||||
.regular => "interrupt_handler",
|
||||
.fast => "fast_interrupt",
|
||||
.breakpoint => "break_handler",
|
||||
},
|
||||
|
||||
.mips_interrupt,
|
||||
.mips64_interrupt,
|
||||
=> |opts| switch (opts.mode) {
|
||||
|
|
@ -8106,11 +8113,20 @@ fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8
|
|||
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",
|
||||
|
||||
.avr_interrupt,
|
||||
.csky_interrupt,
|
||||
.m68k_interrupt,
|
||||
.msp430_interrupt,
|
||||
.x86_interrupt,
|
||||
.x86_64_interrupt,
|
||||
=> "interrupt",
|
||||
|
|
|
|||
|
|
@ -106,9 +106,18 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8
|
|||
.wasm64 => "wasm64",
|
||||
.ve => "ve",
|
||||
|
||||
.alpha,
|
||||
.arceb,
|
||||
.hppa,
|
||||
.hppa64,
|
||||
.kalimba,
|
||||
.microblaze,
|
||||
.microblazeel,
|
||||
.or1k,
|
||||
.propeller,
|
||||
.sh,
|
||||
.sheb,
|
||||
.xtensaeb,
|
||||
=> 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",
|
||||
.xtensa => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32",
|
||||
|
||||
.alpha,
|
||||
.arceb,
|
||||
.hppa,
|
||||
.hppa64,
|
||||
.kalimba,
|
||||
.microblaze,
|
||||
.microblazeel,
|
||||
.or1k,
|
||||
.propeller,
|
||||
.sh,
|
||||
.sheb,
|
||||
.xtensaeb,
|
||||
=> 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.ArmInterruptOptions,
|
||||
std.builtin.CallingConvention.RiscvInterruptOptions,
|
||||
std.builtin.CallingConvention.ShInterruptOptions,
|
||||
std.builtin.CallingConvention.MicroblazeInterruptOptions,
|
||||
std.builtin.CallingConvention.MipsInterruptOptions,
|
||||
std.builtin.CallingConvention.CommonOptions,
|
||||
=> .{ pl.incoming_stack_alignment, 0 },
|
||||
|
|
@ -11882,6 +11902,7 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *const s
|
|||
.avr_interrupt => .avr_intrcc,
|
||||
.m68k_rtd => .m68k_rtdcc,
|
||||
.m68k_interrupt => .m68k_intrcc,
|
||||
.msp430_interrupt => .msp430_intrcc,
|
||||
.amdgcn_kernel => .amdgpu_kernel,
|
||||
.amdgcn_cs => .amdgpu_cs,
|
||||
.nvptx_device => .ptx_device,
|
||||
|
|
@ -11901,9 +11922,13 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *const s
|
|||
.x86_sysv,
|
||||
.x86_win,
|
||||
.x86_thiscall_mingw,
|
||||
.x86_64_x32,
|
||||
.aarch64_aapcs,
|
||||
.aarch64_aapcs_darwin,
|
||||
.aarch64_aapcs_win,
|
||||
.alpha_osf,
|
||||
.microblaze_std,
|
||||
.microblaze_interrupt,
|
||||
.mips64_n64,
|
||||
.mips64_n32,
|
||||
.mips_o32,
|
||||
|
|
@ -11926,6 +11951,8 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *const s
|
|||
.csky_sysv,
|
||||
.hexagon_sysv,
|
||||
.hexagon_sysv_hvx,
|
||||
.hppa_elf,
|
||||
.hppa64_elf,
|
||||
.lanai_sysv,
|
||||
.loongarch64_lp64,
|
||||
.loongarch32_ilp32,
|
||||
|
|
@ -11936,6 +11963,9 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *const s
|
|||
.propeller_sysv,
|
||||
.s390x_sysv,
|
||||
.s390x_sysv_vx,
|
||||
.sh_gnu,
|
||||
.sh_renesas,
|
||||
.sh_interrupt,
|
||||
.ve_sysv,
|
||||
.xcore_xs1,
|
||||
.xcore_xs2,
|
||||
|
|
@ -13107,9 +13137,18 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
|
|||
},
|
||||
|
||||
// LLVM does does not have a backend for these.
|
||||
.alpha,
|
||||
.arceb,
|
||||
.hppa,
|
||||
.hppa64,
|
||||
.kalimba,
|
||||
.microblaze,
|
||||
.microblazeel,
|
||||
.or1k,
|
||||
.propeller,
|
||||
.sh,
|
||||
.sheb,
|
||||
.xtensaeb,
|
||||
=> unreachable,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3905,6 +3905,8 @@ fn updateLazyType(
|
|||
|
||||
.m68k_rtd => .LLVM_M68kRTD,
|
||||
|
||||
.sh_renesas => .GNU_renesas_sh,
|
||||
|
||||
.amdgcn_kernel => .LLVM_OpenCLKernel,
|
||||
.nvptx_kernel,
|
||||
.spirv_kernel,
|
||||
|
|
@ -3917,12 +3919,15 @@ fn updateLazyType(
|
|||
.mips_interrupt,
|
||||
.riscv64_interrupt,
|
||||
.riscv32_interrupt,
|
||||
.sh_interrupt,
|
||||
.arc_interrupt,
|
||||
.avr_builtin,
|
||||
.avr_signal,
|
||||
.avr_interrupt,
|
||||
.csky_interrupt,
|
||||
.m68k_interrupt,
|
||||
.microblaze_interrupt,
|
||||
.msp430_interrupt,
|
||||
=> .normal,
|
||||
|
||||
else => .nocall,
|
||||
|
|
|
|||
|
|
@ -216,9 +216,18 @@ pub fn hasLlvmSupport(target: *const std.Target, ofmt: std.Target.ObjectFormat)
|
|||
=> false,
|
||||
|
||||
// No LLVM backend exists.
|
||||
.alpha,
|
||||
.arceb,
|
||||
.hppa,
|
||||
.hppa64,
|
||||
.kalimba,
|
||||
.microblaze,
|
||||
.microblazeel,
|
||||
.or1k,
|
||||
.propeller,
|
||||
.sh,
|
||||
.sheb,
|
||||
.xtensaeb,
|
||||
=> false,
|
||||
};
|
||||
}
|
||||
|
|
@ -549,31 +558,35 @@ pub fn addrSpaceCastIsValid(
|
|||
}
|
||||
}
|
||||
|
||||
/// Under SPIR-V with Vulkan, pointers are not 'real' (physical), but rather 'logical'. Effectively,
|
||||
/// this means that all such pointers have to be resolvable to a location at compile time, and places
|
||||
/// 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
|
||||
/// for a particular architecture and address space wether such pointers are logical.
|
||||
pub fn arePointersLogical(target: *const std.Target, as: AddressSpace) bool {
|
||||
/// Returns whether pointer operations (arithmetic, indexing, etc.) should be blocked
|
||||
/// for the given address space on the target architecture.
|
||||
///
|
||||
/// Under SPIR-V with Vulkan
|
||||
/// (a) all physical pointers (.physical_storage_buffer, .global) always support pointer operations,
|
||||
/// (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;
|
||||
|
||||
return switch (as) {
|
||||
// TODO: Vulkan doesn't support pointers in the generic address space, we
|
||||
// should remove this case but this requires a change in defaultAddressSpace().
|
||||
// For now, at least disable them from being regarded as physical.
|
||||
.generic => true,
|
||||
// For now, all global pointers are represented using StorageBuffer or CrossWorkgroup,
|
||||
// so these are real pointers.
|
||||
.global => false,
|
||||
.physical_storage_buffer => false,
|
||||
// Physical pointers always support operations
|
||||
.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)),
|
||||
.storage_buffer => !target.cpu.features.isEnabled(@intFromEnum(std.Target.spirv.Feature.variable_pointers)),
|
||||
// Logical pointers that never support operations
|
||||
.constant,
|
||||
.local,
|
||||
.input,
|
||||
.output,
|
||||
.uniform,
|
||||
.push_constant,
|
||||
.storage_buffer,
|
||||
=> true,
|
||||
else => unreachable,
|
||||
};
|
||||
|
|
@ -707,18 +720,26 @@ pub fn minFunctionAlignment(target: *const std.Target) Alignment {
|
|||
.csky,
|
||||
.m68k,
|
||||
.msp430,
|
||||
.sh,
|
||||
.sheb,
|
||||
.s390x,
|
||||
.xcore,
|
||||
=> .@"2",
|
||||
.arc,
|
||||
.arm,
|
||||
.armeb,
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
.alpha,
|
||||
.arc,
|
||||
.arceb,
|
||||
.arm,
|
||||
.armeb,
|
||||
.hexagon,
|
||||
.hppa,
|
||||
.hppa64,
|
||||
.lanai,
|
||||
.loongarch32,
|
||||
.loongarch64,
|
||||
.microblaze,
|
||||
.microblazeel,
|
||||
.mips,
|
||||
.mipsel,
|
||||
.powerpc,
|
||||
|
|
@ -728,9 +749,10 @@ pub fn minFunctionAlignment(target: *const std.Target) Alignment {
|
|||
.sparc,
|
||||
.sparc64,
|
||||
.xtensa,
|
||||
.xtensaeb,
|
||||
=> .@"4",
|
||||
.bpfel,
|
||||
.bpfeb,
|
||||
.bpfel,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
=> .@"8",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,6 @@ comptime {
|
|||
// target=x86_64-linux
|
||||
//
|
||||
// :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: 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'
|
||||
|
|
|
|||
|
|
@ -15,4 +15,4 @@ comptime {
|
|||
// target=x86_64-linux
|
||||
//
|
||||
// :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'
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ const test_targets = blk: {
|
|||
// 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
|
||||
// lot of branches)
|
||||
@setEvalBranchQuota(50000);
|
||||
@setEvalBranchQuota(60000);
|
||||
break :blk [_]TestTarget{
|
||||
// Native Targets
|
||||
|
||||
|
|
@ -397,16 +397,15 @@ const test_targets = blk: {
|
|||
}) catch unreachable,
|
||||
.link_libc = true,
|
||||
},
|
||||
// Currently crashes in qemu-hexagon.
|
||||
// .{
|
||||
// .target = std.Target.Query.parse(.{
|
||||
// .arch_os_abi = "hexagon-linux-musl",
|
||||
// .cpu_features = "baseline+long_calls",
|
||||
// }) catch unreachable,
|
||||
// .linkage = .dynamic,
|
||||
// .link_libc = true,
|
||||
// .extra_target = true,
|
||||
// },
|
||||
.{
|
||||
.target = std.Target.Query.parse(.{
|
||||
.arch_os_abi = "hexagon-linux-musl",
|
||||
.cpu_features = "baseline+long_calls",
|
||||
}) catch unreachable,
|
||||
.linkage = .dynamic,
|
||||
.link_libc = true,
|
||||
.extra_target = true,
|
||||
},
|
||||
|
||||
.{
|
||||
.target = .{
|
||||
|
|
@ -1551,7 +1550,7 @@ const CAbiTarget = struct {
|
|||
};
|
||||
|
||||
const c_abi_targets = blk: {
|
||||
@setEvalBranchQuota(20000);
|
||||
@setEvalBranchQuota(30000);
|
||||
break :blk [_]CAbiTarget{
|
||||
// Native Targets
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue