diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 809ff0665ad7c0d607808c49d14bee2ab79151f6..4cdbddcaec2821e6396c1499a20ff63bedcb3661 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -72,6 +72,7 @@ pub const Os = struct { // LLVM tags deliberately omitted: // - bridgeos + // - cheriotrtos // - darwin // - kfreebsd // - nacl @@ -732,6 +733,7 @@ pub const Os = struct { }; pub const aarch64 = @import("Target/aarch64.zig"); +pub const alpha = @import("Target/generic.zig"); pub const amdgcn = @import("Target/amdgcn.zig"); pub const arc = @import("Target/arc.zig"); pub const arm = @import("Target/arm.zig"); @@ -739,10 +741,12 @@ pub const avr = @import("Target/avr.zig"); pub const bpf = @import("Target/bpf.zig"); pub const csky = @import("Target/csky.zig"); pub const hexagon = @import("Target/hexagon.zig"); +pub const hppa = @import("Target/generic.zig"); pub const kalimba = @import("Target/generic.zig"); pub const lanai = @import("Target/lanai.zig"); pub const loongarch = @import("Target/loongarch.zig"); pub const m68k = @import("Target/m68k.zig"); +pub const microblaze = @import("Target/generic.zig"); pub const mips = @import("Target/mips.zig"); pub const msp430 = @import("Target/msp430.zig"); pub const nvptx = @import("Target/nvptx.zig"); @@ -751,6 +755,7 @@ pub const powerpc = @import("Target/powerpc.zig"); pub const propeller = @import("Target/propeller.zig"); pub const riscv = @import("Target/riscv.zig"); pub const s390x = @import("Target/s390x.zig"); +pub const sh = @import("Target/generic.zig"); pub const sparc = @import("Target/sparc.zig"); pub const spirv = @import("Target/spirv.zig"); pub const ve = @import("Target/ve.zig"); @@ -800,14 +805,22 @@ pub const Abi = enum { // - coreclr // - domain // - geometry + // - gnueabit64 + // - gnueabihft64 // - gnuf64 + // - gnut64 // - hull // - intersection // - library + // - llvm // - mesh // - miss + // - mlibc + // - mtia + // - pauthtest // - pixel // - raygeneration + // - rootsignature // - vertex pub fn default(arch: Cpu.Arch, os_tag: Os.Tag) Abi { @@ -816,13 +829,16 @@ pub const Abi = enum { // Soft float is usually a sane default for freestanding. .arm, .armeb, - .thumb, - .thumbeb, .csky, + .hppa, .mips, .mipsel, .powerpc, .powerpcle, + .sh, + .sheb, + .thumb, + .thumbeb, => .eabi, else => .none, }, @@ -837,20 +853,34 @@ pub const Abi = enum { .linux => switch (arch) { .arm, .armeb, - .thumb, - .thumbeb, .powerpc, .powerpcle, + .thumb, + .thumbeb, => .musleabihf, - // Soft float tends to be more common for CSKY and MIPS. - .csky, - => .gnueabi, // No musl support. .mips, .mipsel, => .musleabi, .mips64, .mips64el, => .muslabi64, + + // No musl support. + .arc, + .arceb, + => .gnu, + .csky, + => .gnueabi, + .hppa, + .sh, + .sheb, + => .gnueabihf, + + // No glibc or musl support. + .xtensa, + .xtensaeb, + => .none, + else => .musl, }, .rtems => switch (arch) { @@ -1044,18 +1074,21 @@ pub const ObjectFormat = enum { pub fn toElfMachine(target: *const Target) std.elf.EM { return switch (target.cpu.arch) { + .aarch64, .aarch64_be => .AARCH64, + .alpha => .ALPHA, .amdgcn => .AMDGPU, - .arc => .ARC_COMPACT, + .arc, .arceb => .ARC_COMPACT, .arm, .armeb, .thumb, .thumbeb => .ARM, - .aarch64, .aarch64_be => .AARCH64, .avr => .AVR, - .bpfel, .bpfeb => .BPF, + .bpfeb, .bpfel => .BPF, .csky => .CSKY, .hexagon => .QDSP6, + .hppa, .hppa64 => .PARISC, .kalimba => .CSR_KALIMBA, .lanai => .LANAI, .loongarch32, .loongarch64 => .LOONGARCH, .m68k => .@"68K", + .microblaze, .microblazeel => .MICROBLAZE, .mips, .mips64, .mipsel, .mips64el => .MIPS, .msp430 => .MSP430, .or1k => .OR1K, @@ -1064,13 +1097,14 @@ pub fn toElfMachine(target: *const Target) std.elf.EM { .propeller => .PROPELLER, .riscv32, .riscv32be, .riscv64, .riscv64be => .RISCV, .s390x => .S390, + .sh, .sheb => .SH, .sparc => if (target.cpu.has(.sparc, .v9)) .SPARC32PLUS else .SPARC, .sparc64 => .SPARCV9, .ve => .VE, .x86 => .@"386", .x86_64 => .X86_64, .xcore => .XCORE, - .xtensa => .XTENSA, + .xtensa, .xtensaeb => .XTENSA, .nvptx, .nvptx64, @@ -1084,54 +1118,63 @@ pub fn toElfMachine(target: *const Target) std.elf.EM { pub fn toCoffMachine(target: *const Target) std.coff.IMAGE.FILE.MACHINE { return switch (target.cpu.arch) { + .alpha => .ALPHA64, .arm => .ARM, .thumb => .ARMNT, .aarch64 => .ARM64, .loongarch32 => .LOONGARCH32, .loongarch64 => .LOONGARCH64, + .mips => .R3000BE, + .mipsel => .R3000, + .mips64el => .R4000, + .powerpcle => .POWERPC, .riscv32 => .RISCV32, .riscv64 => .RISCV64, + .sh => .SH3, .x86 => .I386, .x86_64 => .AMD64, + .aarch64_be, .amdgcn, .arc, + .arceb, .armeb, - .thumbeb, - .aarch64_be, .avr, - .bpfel, .bpfeb, + .bpfel, .csky, .hexagon, + .hppa, + .hppa64, .kalimba, .lanai, .m68k, - .mips, - .mipsel, + .microblaze, + .microblazeel, .mips64, - .mips64el, .msp430, - .or1k, .nvptx, .nvptx64, + .or1k, .powerpc, - .powerpcle, .powerpc64, .powerpc64le, + .propeller, .riscv32be, .riscv64be, .s390x, + .sheb, .sparc, .sparc64, .spirv32, .spirv64, + .thumbeb, .ve, .wasm32, .wasm64, .xcore, .xtensa, - .propeller, + .xtensaeb, => .UNKNOWN, }; } @@ -1300,32 +1343,36 @@ pub const Cpu = struct { }; pub const Arch = enum { + aarch64, + aarch64_be, + alpha, amdgcn, arc, + arceb, arm, armeb, - thumb, - thumbeb, - aarch64, - aarch64_be, avr, - bpfel, bpfeb, + bpfel, csky, hexagon, + hppa, + hppa64, kalimba, lanai, loongarch32, loongarch64, m68k, + microblaze, + microblazeel, mips, mipsel, mips64, mips64el, msp430, - or1k, nvptx, nvptx64, + or1k, powerpc, powerpcle, powerpc64, @@ -1336,10 +1383,14 @@ pub const Cpu = struct { riscv64, riscv64be, s390x, + sh, + sheb, sparc, sparc64, spirv32, spirv64, + thumb, + thumbeb, ve, wasm32, wasm64, @@ -1347,14 +1398,13 @@ pub const Cpu = struct { x86_64, xcore, xtensa, + xtensaeb, // LLVM tags deliberately omitted: // - aarch64_32 // - amdil // - amdil64 // - dxil - // - le32 - // - le64 // - r600 // - hsail // - hsail64 @@ -1372,18 +1422,21 @@ pub const Cpu = struct { /// For a given family tag, it is guaranteed that an `std.Target.` namespace exists /// containing CPU model and feature data. pub const Family = enum { + aarch64, + alpha, amdgcn, arc, arm, - aarch64, avr, bpf, csky, hexagon, + hppa, kalimba, lanai, loongarch, m68k, + microblaze, mips, msp430, nvptx, @@ -1392,6 +1445,7 @@ pub const Cpu = struct { propeller, riscv, s390x, + sh, sparc, spirv, ve, @@ -1403,18 +1457,21 @@ pub const Cpu = struct { pub inline fn family(arch: Arch) Family { return switch (arch) { + .aarch64, .aarch64_be => .aarch64, + .alpha => .alpha, .amdgcn => .amdgcn, - .arc => .arc, + .arc, .arceb => .arc, .arm, .armeb, .thumb, .thumbeb => .arm, - .aarch64, .aarch64_be => .aarch64, .avr => .avr, - .bpfel, .bpfeb => .bpf, + .bpfeb, .bpfel => .bpf, .csky => .csky, .hexagon => .hexagon, + .hppa, .hppa64 => .hppa, .kalimba => .kalimba, .lanai => .lanai, .loongarch32, .loongarch64 => .loongarch, .m68k => .m68k, + .microblaze, .microblazeel => .microblaze, .mips, .mipsel, .mips64, .mips64el => .mips, .msp430 => .msp430, .or1k => .or1k, @@ -1423,13 +1480,14 @@ pub const Cpu = struct { .propeller => .propeller, .riscv32, .riscv32be, .riscv64, .riscv64be => .riscv, .s390x => .s390x, + .sh, .sheb => .sh, .sparc, .sparc64 => .sparc, .spirv32, .spirv64 => .spirv, .ve => .ve, .wasm32, .wasm64 => .wasm, .x86, .x86_64 => .x86, .xcore => .xcore, - .xtensa => .xtensa, + .xtensa, .xtensaeb => .xtensa, }; } @@ -1462,6 +1520,20 @@ pub const Cpu = struct { }; } + pub inline fn isArc(arch: Arch) bool { + return switch (arch) { + .arc, .arceb => true, + else => false, + }; + } + + pub inline fn isHppa(arch: Arch) bool { + return switch (arch) { + .hppa, .hppa64 => true, + else => false, + }; + } + pub inline fn isWasm(arch: Arch) bool { return switch (arch) { .wasm32, .wasm64 => true, @@ -1494,6 +1566,13 @@ pub const Cpu = struct { }; } + pub inline fn isMicroblaze(arch: Arch) bool { + return switch (arch) { + .microblaze, .microblazeel => true, + else => false, + }; + } + pub inline fn isMIPS(arch: Arch) bool { return arch.isMIPS32() or arch.isMIPS64(); } @@ -1544,6 +1623,13 @@ pub const Cpu = struct { }; } + pub inline fn isSh(arch: Arch) bool { + return switch (arch) { + .sh, .sheb => true, + else => false, + }; + } + pub inline fn isBpf(arch: Arch) bool { return switch (arch) { .bpfel, .bpfeb => true, @@ -1558,6 +1644,13 @@ pub const Cpu = struct { }; } + pub inline fn isXtensa(arch: Arch) bool { + return switch (arch) { + .xtensa, .xtensaeb => true, + else => false, + }; + } + pub fn parseCpuModel(arch: Arch, cpu_name: []const u8) !*const Cpu.Model { for (arch.allCpuModels()) |cpu| { if (std.mem.eql(u8, cpu_name, cpu.name)) { @@ -1569,44 +1662,46 @@ pub const Cpu = struct { pub fn endian(arch: Arch) std.builtin.Endian { return switch (arch) { + .aarch64, + .alpha, + .arm, + .arc, .avr, - .arm, - .aarch64, - .amdgcn, .bpfel, .csky, - .xtensa, .hexagon, .kalimba, + .loongarch32, + .loongarch64, + .microblazeel, .mipsel, .mips64el, .msp430, - .nvptx, - .nvptx64, .powerpcle, .powerpc64le, + .propeller, .riscv32, .riscv64, - .x86, - .x86_64, + .sh, + .thumb, + .ve, .wasm32, .wasm64, + .x86, + .x86_64, .xcore, - .thumb, - .ve, - // GPU bitness is opaque. For now, assume little endian. - .spirv32, - .spirv64, - .loongarch32, - .loongarch64, - .arc, - .propeller, + .xtensa, => .little, - .armeb, .aarch64_be, + .arceb, + .armeb, .bpfeb, + .hppa, + .hppa64, + .lanai, .m68k, + .microblaze, .mips, .mips64, .or1k, @@ -1614,12 +1709,21 @@ pub const Cpu = struct { .powerpc64, .riscv32be, .riscv64be, - .thumbeb, - .sparc, - .sparc64, - .lanai, .s390x, + .sheb, + .thumbeb, + .sparc, + .sparc64, + .xtensaeb, => .big, + + // GPU endianness is opaque. For now, assume little endian. + .amdgcn, + .nvptx, + .nvptx64, + .spirv32, + .spirv64, + => .little, }; } @@ -1683,6 +1787,7 @@ pub const Cpu = struct { => unreachable, .x86_64_sysv, + .x86_64_x32, .x86_64_win, .x86_64_regcall_v3_sysv, .x86_64_regcall_v4_win, @@ -1709,6 +1814,9 @@ pub const Cpu = struct { .aarch64_vfabi_sve, => &.{ .aarch64, .aarch64_be }, + .alpha_osf, + => &.{.alpha}, + .arm_aapcs, .arm_aapcs_vfp, .arm_interrupt, @@ -1755,7 +1863,7 @@ pub const Cpu = struct { .arc_sysv, .arc_interrupt, - => &.{.arc}, + => &.{ .arc, .arceb }, .avr_gnu, .avr_builtin, @@ -1774,6 +1882,12 @@ pub const Cpu = struct { .hexagon_sysv_hvx, => &.{.hexagon}, + .hppa_elf, + => &.{.hppa}, + + .hppa64_elf, + => &.{.hppa64}, + .lanai_sysv, => &.{.lanai}, @@ -1789,7 +1903,12 @@ pub const Cpu = struct { .m68k_interrupt, => &.{.m68k}, + .microblaze_std, + .microblaze_interrupt, + => &.{ .microblaze, .microblazeel }, + .msp430_eabi, + .msp430_interrupt, => &.{.msp430}, .or1k_sysv, @@ -1802,6 +1921,11 @@ pub const Cpu = struct { .s390x_sysv_vx, => &.{.s390x}, + .sh_gnu, + .sh_renesas, + .sh_interrupt, + => &.{ .sh, .sheb }, + .ve_sysv, => &.{.ve}, @@ -1811,7 +1935,7 @@ pub const Cpu = struct { .xtensa_call0, .xtensa_windowed, - => &.{.xtensa}, + => &.{ .xtensa, .xtensaeb }, .amdgcn_device, .amdgcn_kernel, @@ -2104,6 +2228,21 @@ pub fn requiresLibC(target: *const Target) bool { }; } +/// The places where a user can specify an address space attribute +pub const AddressSpaceContext = 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, +}; + /// Returns whether this target supports `address_space`. If `context` is `null`, this /// function simply answers the general question of whether the target has any concept /// of `address_space`; if non-`null`, the function additionally checks whether @@ -2111,7 +2250,7 @@ pub fn requiresLibC(target: *const Target) bool { pub fn supportsAddressSpace( target: Target, address_space: std.builtin.AddressSpace, - context: ?std.builtin.AddressSpace.Context, + context: ?AddressSpaceContext, ) bool { const arch = target.cpu.arch; @@ -2343,7 +2482,10 @@ pub const DynamicLinker = struct { .aarch64, .aarch64_be, + .hexagon, .m68k, + .microblaze, + .microblazeel, .powerpc64, .powerpc64le, .s390x, @@ -2379,6 +2521,17 @@ pub const DynamicLinker = struct { else => return none, }}), + .sh, + .sheb, + => |arch| initFmt("/lib/ld-musl-{t}{s}.so.1", .{ + arch, + switch (abi) { + .musleabi => "-nofpu", + .musleabihf => "", + else => return none, + }, + }), + .riscv32, .riscv64, => |arch| if (abi == .musl) initFmt("/lib/ld-musl-{s}{s}.so.1", .{ @@ -2392,6 +2545,7 @@ pub const DynamicLinker = struct { }) else none, .x86 => if (abi == .musl) init("/lib/ld-musl-i386.so.1") else none, + .x86_64 => initFmt("/lib/ld-musl-{s}.so.1", .{switch (abi) { .musl => "x86_64", .muslx32 => "x32", @@ -2402,9 +2556,10 @@ pub const DynamicLinker = struct { } else if (abi.isGnu()) switch (cpu.arch) { - // TODO: `eb` architecture support. // TODO: `700` ABI support. - .arc => if (abi == .gnu) init("/lib/ld-linux-arc.so.2") else none, + .arc, + .arceb, + => |arch| if (abi == .gnu) initFmt("/lib/ld-linux-{t}.so.2", .{arch}) else none, .arm, .armeb, @@ -2434,7 +2589,13 @@ pub const DynamicLinker = struct { else => return none, }}), - .m68k => if (abi == .gnu) init("/lib/ld.so.1") else none, + .hppa, + .m68k, + .microblaze, + .microblazeel, + .xtensa, + .xtensaeb, + => if (abi == .gnu) init("/lib/ld.so.1") else none, .mips, .mipsel, @@ -2464,6 +2625,7 @@ pub const DynamicLinker = struct { => init("/lib/ld.so.1"), else => none, }, + .powerpc64, .powerpc64le, => if (abi == .gnu) init("/lib64/ld64.so.2") else none, @@ -2486,18 +2648,28 @@ pub const DynamicLinker = struct { .s390x => if (abi == .gnu) init("/lib/ld64.so.1") else none, - .sparc => if (abi == .gnu) init("/lib/ld-linux.so.2") else none, + .sh, + .sheb, + => switch (abi) { + .gnueabi, + .gnueabihf, + => init("/lib/ld-linux.so.2"), + else => none, + }, + + .alpha, + .sparc, + .x86, + => if (abi == .gnu) init("/lib/ld-linux.so.2") else none, + .sparc64 => if (abi == .gnu) init("/lib64/ld-linux.so.2") else none, - .x86 => if (abi == .gnu) init("/lib/ld-linux.so.2") else none, .x86_64 => switch (abi) { .gnu => init("/lib64/ld-linux-x86-64.so.2"), .gnux32 => init("/libx32/ld-linux-x32.so.2"), else => none, }, - .xtensa => if (abi == .gnu) init("/lib/ld.so.1") else none, - else => none, } else @@ -2664,52 +2836,61 @@ pub fn ptrBitWidth_arch_abi(cpu_arch: Cpu.Arch, abi: Abi) u16 { => 16, .arc, + .arceb, .arm, .armeb, .csky, .hexagon, + .hppa, + .kalimba, + .lanai, + .loongarch32, .m68k, + .microblaze, + .microblazeel, .mips, .mipsel, + .nvptx, .or1k, .powerpc, .powerpcle, + .propeller, .riscv32, .riscv32be, + .sh, + .sheb, + .sparc, + .spirv32, .thumb, .thumbeb, + .wasm32, .x86, .xcore, - .nvptx, - .kalimba, - .lanai, - .wasm32, - .sparc, - .spirv32, - .loongarch32, .xtensa, - .propeller, + .xtensaeb, => 32, .aarch64, .aarch64_be, + .alpha, + .amdgcn, + .bpfeb, + .bpfel, + .hppa64, + .loongarch64, .mips64, .mips64el, + .nvptx64, .powerpc64, .powerpc64le, .riscv64, .riscv64be, - .x86_64, - .nvptx64, - .wasm64, - .amdgcn, - .bpfel, - .bpfeb, - .sparc64, .s390x, - .ve, + .sparc64, .spirv64, - .loongarch64, + .ve, + .wasm64, + .x86_64, => 64, }; } @@ -2727,17 +2908,20 @@ pub fn stackAlignment(target: *const Target) u16 { => return 4, .arm, .armeb, - .thumb, - .thumbeb, + .hppa, .lanai, .mips, .mipsel, .sparc, + .thumb, + .thumbeb, => return 8, .aarch64, .aarch64_be, + .alpha, .bpfeb, .bpfel, + .hppa64, .loongarch32, .loongarch64, .mips64, @@ -2765,6 +2949,24 @@ pub fn stackAlignment(target: *const Target) u16 { return @divExact(target.ptrBitWidth(), 8); } +pub const StackGrowth = enum { + down, + up, +}; + +pub fn stackGrowth(target: *const Target) StackGrowth { + // Strictly speaking, most architectures don't inherently define the stack growth direction; you + // could quite easily argue that it is in fact a property of the ABI. However, that's just not + // really how it plays out in the real world. And besides, we have no mechanism for indicating + // a different stack growth ABI, nor a compelling use case for creating such a mechanism. + return switch (target.cpu.arch) { + .hppa, + .hppa64, + => .up, + else => .down, + }; +} + /// Default signedness of `char` for the native C compiler for this target /// Note that char signedness is implementation-defined and many compilers provide /// an option to override the default signedness e.g. GCC's -funsigned-char / -fsigned-char @@ -2772,13 +2974,12 @@ pub fn cCharSignedness(target: *const Target) std.builtin.Signedness { if (target.os.tag.isDarwin() or target.os.tag == .windows or target.os.tag == .uefi) return .signed; return switch (target.cpu.arch) { - .arm, - .armeb, - .thumb, - .thumbeb, .aarch64, .aarch64_be, + .arm, + .armeb, .arc, + .arceb, .csky, .hexagon, .msp430, @@ -2791,8 +2992,11 @@ pub fn cCharSignedness(target: *const Target) std.builtin.Signedness { .riscv32be, .riscv64, .riscv64be, + .thumb, + .thumbeb, .xcore, .xtensa, + .xtensaeb, => .unsigned, else => .signed, }; @@ -2903,6 +3107,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 { else => return 128, }, + .alpha, .riscv32, .riscv32be, .riscv64, @@ -2946,18 +3151,6 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 { .wasi, .emscripten, => switch (target.cpu.arch) { - .msp430 => switch (c_type) { - .char => return 8, - .short, .ushort, .int, .uint => return 16, - .long, .ulong, .float => return 32, - .longlong, .ulonglong, .double, .longdouble => return 64, - }, - .avr => switch (c_type) { - .char => return 8, - .short, .ushort, .int, .uint => return 16, - .long, .ulong, .float, .double, .longdouble => return 32, - .longlong, .ulonglong => return 64, - }, .mips64, .mips64el => switch (c_type) { .char => return 8, .short, .ushort => return 16, @@ -3024,6 +3217,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 { }, }, + .alpha, .riscv32, .riscv32be, .riscv64, @@ -3213,35 +3407,44 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 { => 2, .arc, + .arceb, .csky, + .kalimba, + .microblaze, + .microblazeel, + .or1k, + .propeller, + .sh, + .sheb, .x86, .xcore, - .or1k, - .kalimba, .xtensa, - .propeller, + .xtensaeb, => 4, + .amdgcn, .arm, .armeb, - .thumb, - .thumbeb, - .amdgcn, - .bpfel, .bpfeb, + .bpfel, .hexagon, + .hppa, + .lanai, .m68k, .mips, .mipsel, - .sparc, - .lanai, .nvptx, .nvptx64, .s390x, + .sparc, + .thumb, + .thumbeb, => 8, .aarch64, .aarch64_be, + .alpha, + .hppa64, .loongarch32, .loongarch64, .mips64, @@ -3257,10 +3460,10 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 { .sparc64, .spirv32, .spirv64, - .x86_64, .ve, .wasm32, .wasm64, + .x86_64, => 16, .avr, @@ -3272,7 +3475,7 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 { pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 { // Overrides for unusual alignments switch (target.cpu.arch) { - .arc => switch (c_type) { + .arc, .arceb => switch (c_type) { .longdouble => return 4, else => {}, }, @@ -3310,36 +3513,45 @@ pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 { @as(u16, switch (target.cpu.arch) { .msp430 => 2, + .arc, + .arceb, .csky, - .xcore, - .or1k, .kalimba, - .xtensa, + .microblaze, + .microblazeel, + .or1k, .propeller, + .sh, + .sheb, + .xcore, + .xtensa, + .xtensaeb, => 4, - .arc, + .amdgcn, .arm, .armeb, - .thumb, - .thumbeb, - .amdgcn, - .bpfel, .bpfeb, + .bpfel, .hexagon, - .x86, + .hppa, + .lanai, .m68k, .mips, .mipsel, - .sparc, - .lanai, .nvptx, .nvptx64, .s390x, + .sparc, + .thumb, + .thumbeb, + .x86, => 8, .aarch64, .aarch64_be, + .alpha, + .hppa64, .loongarch32, .loongarch64, .mips64, @@ -3355,10 +3567,10 @@ pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 { .sparc64, .spirv32, .spirv64, - .x86_64, .ve, .wasm32, .wasm64, + .x86_64, => 16, .avr, @@ -3373,32 +3585,49 @@ pub fn cMaxIntAlignment(target: *const Target) u16 { .msp430 => 2, - .xcore, + .arc, + .arceb, + .csky, + .kalimba, + .microblaze, + .microblazeel, + .or1k, .propeller, + .sh, + .sheb, + .xcore, => 4, - .amdgcn, .arm, .armeb, - .thumb, - .thumbeb, - .lanai, .hexagon, + .hppa, + .lanai, + .loongarch32, + .m68k, .mips, .mipsel, - .or1k, .powerpc, .powerpcle, .riscv32, .riscv32be, .s390x, + .sparc, + .thumb, + .thumbeb, + .x86, + .xtensa, + .xtensaeb, => 8, - // Even LLVMABIAlignmentOfType(i128) agrees on these targets. .aarch64, .aarch64_be, + .alpha, + .amdgcn, .bpfel, .bpfeb, + .hppa64, + .loongarch64, .mips64, .mips64el, .nvptx, @@ -3407,26 +3636,13 @@ pub fn cMaxIntAlignment(target: *const Target) u16 { .powerpc64le, .riscv64, .riscv64be, - .sparc, .sparc64, - .wasm32, - .wasm64, - .x86, - .x86_64, - => 16, - - // Below this comment are unverified but based on the fact that C requires - // int128_t to be 16 bytes aligned, it's a safe default. - .arc, - .csky, - .kalimba, - .loongarch32, - .loongarch64, - .m68k, .spirv32, .spirv64, .ve, - .xtensa, + .wasm32, + .wasm64, + .x86_64, => 16, }; } @@ -3435,24 +3651,28 @@ pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention return switch (target.cpu.arch) { .x86_64 => switch (target.os.tag) { .windows, .uefi => .{ .x86_64_win = .{} }, - else => .{ .x86_64_sysv = .{} }, + else => switch (target.abi) { + .gnuabin32, .muslabin32 => .{ .x86_64_x32 = .{} }, + else => .{ .x86_64_sysv = .{} }, + }, }, .x86 => switch (target.os.tag) { .windows, .uefi => .{ .x86_win = .{} }, else => .{ .x86_sysv = .{} }, }, - .aarch64, .aarch64_be => if (target.os.tag.isDarwin()) cc: { - break :cc .{ .aarch64_aapcs_darwin = .{} }; - } else switch (target.os.tag) { + .aarch64, .aarch64_be => if (target.os.tag.isDarwin()) + .{ .aarch64_aapcs_darwin = .{} } + else switch (target.os.tag) { .windows => .{ .aarch64_aapcs_win = .{} }, else => .{ .aarch64_aapcs = .{} }, }, + .alpha => .{ .alpha_osf = .{} }, .arm, .armeb, .thumb, .thumbeb => switch (target.abi.float()) { .soft => .{ .arm_aapcs = .{} }, .hard => .{ .arm_aapcs_vfp = .{} }, }, .mips64, .mips64el => switch (target.abi) { - .gnuabin32 => .{ .mips64_n32 = .{} }, + .gnuabin32, .muslabin32 => .{ .mips64_n32 = .{} }, else => .{ .mips64_n64 = .{} }, }, .mips, .mipsel => .{ .mips_o32 = .{} }, @@ -3470,11 +3690,13 @@ pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention else => .{ .powerpc_sysv = .{} }, }, .wasm32, .wasm64 => .{ .wasm_mvp = .{} }, - .arc => .{ .arc_sysv = .{} }, + .arc, .arceb => .{ .arc_sysv = .{} }, .avr => .avr_gnu, .bpfel, .bpfeb => .{ .bpf_std = .{} }, .csky => .{ .csky_sysv = .{} }, .hexagon => .{ .hexagon_sysv = .{} }, + .hppa => .{ .hppa_elf = .{} }, + .hppa64 => .{ .hppa64_elf = .{} }, .kalimba => null, .lanai => .{ .lanai_sysv = .{} }, .loongarch64 => .{ .loongarch64_lp64 = .{} }, @@ -3483,13 +3705,15 @@ pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention .{ .m68k_gnu = .{} } else .{ .m68k_sysv = .{} }, + .microblaze, .microblazeel => .{ .microblaze_std = .{} }, .msp430 => .{ .msp430_eabi = .{} }, .or1k => .{ .or1k_sysv = .{} }, .propeller => .{ .propeller_sysv = .{} }, .s390x => .{ .s390x_sysv = .{} }, + .sh, .sheb => .{ .sh_gnu = .{} }, .ve => .{ .ve_sysv = .{} }, .xcore => .{ .xcore_xs1 = .{} }, - .xtensa => .{ .xtensa_call0 = .{} }, + .xtensa, .xtensaeb => .{ .xtensa_windowed = .{} }, .amdgcn => .{ .amdgcn_device = .{} }, .nvptx, .nvptx64 => .nvptx_device, .spirv32, .spirv64 => .spirv_device, diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index ce4abada7decf0fa1ee519eade54a1568784cb0a..dfefeceea02a23a1ec5f99999de53be7622405d3 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -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: diff --git a/lib/std/atomic.zig b/lib/std/atomic.zig index 7853d042143a6451825a1bfcd4a782ecdc3d3591..0b35b61e9babe01ab206756ce129451ee95806e9 100644 --- a/lib/std/atomic.zig +++ b/lib/std/atomic.zig @@ -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, }; diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index fbd65c5574299096cfefb74080e0534ec1dd2b35..3e1413cd99e1d8ca6985e1e33719c01695bca133 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -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"), }; diff --git a/lib/std/builtin/assembly.zig b/lib/std/builtin/assembly.zig index ba0f7ceb4e378760ea831864fc1f6749108c5600..12a0757ebfa807a551c61c95ab289f48916c89c1 100644 --- a/lib/std/builtin/assembly.zig +++ b/lib/std/builtin/assembly.zig @@ -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. diff --git a/lib/std/debug.zig b/lib/std/debug.zig index ec082443836b55c1b44a92766988f881035f6b39..57d6f45111ee653cd6414e51f1f23361fecbd4ab 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -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); diff --git a/lib/std/debug/Dwarf.zig b/lib/std/debug/Dwarf.zig index 7229dcdf4cc9860f4557bfb34369bec5f3704969..11dc6e5429b9a1cf1fe28ee9b4b244bad24f28bf 100644 --- a/lib/std/debug/Dwarf.zig +++ b/lib/std/debug/Dwarf.zig @@ -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, diff --git a/lib/std/debug/SelfInfo/Elf.zig b/lib/std/debug/SelfInfo/Elf.zig index 57135425105e98293473b3f31182601766bb31ca..d9f48281dee935519e9aecbc549ece734286a88c 100644 --- a/lib/std/debug/SelfInfo/Elf.zig +++ b/lib/std/debug/SelfInfo/Elf.zig @@ -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, diff --git a/lib/std/debug/cpu_context.zig b/lib/std/debug/cpu_context.zig index caed9e3289293d7e254c897c2e3806911e6bbbd6..1ff61ee2a25ed3a3a0b048458d58d0e4ab580fc5 100644 --- a/lib/std/debug/cpu_context.zig +++ b/lib/std/debug/cpu_context.zig @@ -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, diff --git a/lib/std/heap.zig b/lib/std/heap.zig index 382e763ef2fdb4e70852bf06c594b14280a334cc..c99395c38953334269924ad4a3eceb16adf7ff6d 100644 --- a/lib/std/heap.zig +++ b/lib/std/heap.zig @@ -739,8 +739,10 @@ const page_size_min_default: ?usize = switch (builtin.os.tag) { .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 +756,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 +829,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) { @@ -888,8 +897,10 @@ const page_size_max_default: ?usize = switch (builtin.os.tag) { .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 +913,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 +986,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) { diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 10feead2ae94956465b4581109bc8c5cf35c59a2..11add50a057be77375e85885ba6fce63a6c9ef0c 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -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, diff --git a/lib/std/os/linux/tls.zig b/lib/std/os/linux/tls.zig index abac4318e446625aed88895f71d0589f72fe4c73..3f3e6f987de5b502cfde392b99982ad7470b3e83 100644 --- a/lib/std/os/linux/tls.zig +++ b/lib/std/os/linux/tls.zig @@ -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) { + .aarch64, + .aarch64_be, + .alpha, .arc, + .arceb, .arm, .armeb, - .aarch64, - .aarch64_be, .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 diff --git a/lib/std/pie.zig b/lib/std/pie.zig index 1b028930c75b61e7e9e2ee5db2b47d99a93920b2..a37c03fbf260fcef4f3777bc1a7ad95c9a44ae1e 100644 --- a/lib/std/pie.zig +++ b/lib/std/pie.zig @@ -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 ( diff --git a/lib/std/start.zig b/lib/std/start.zig index c6f65aae25d43e6b6e028cd2a34bbcf20a329e01..4cf2a0956b97fca90c406a41eb9968b6b1b6cd31 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -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 diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index e237cecd5904faf1d2f81f0aef705ca551fb9fb0..f5fae5581a7084ff5687a2cd3a8fc72aac533904 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -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, diff --git a/src/InternPool.zig b/src/InternPool.zig index 445245fbe912641b2cc68cea8af899261d7b3025..a595fa502c0ba5f4ba9b88de2f2207e6558c08be 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -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, }, ), diff --git a/src/Sema.zig b/src/Sema.zig index 69e35853cf931ea1691b787c1ba6517c15edbafd..b94e172b45ac509b5abbc56bd1f3f8ba1f400c2e 100644 --- a/src/Sema.zig +++ b/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, @@ -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)}); @@ -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, diff --git a/src/Zcu.zig b/src/Zcu.zig index ea030905ebbf737fae281daad917356db6f1d2a1..0eb37668cf37cb47be855ba8aab702f5a346d29b 100644 --- a/src/Zcu.zig +++ b/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, diff --git a/src/codegen/c.zig b/src/codegen/c.zig index bf9be70529f1864cdf67cace0a478598941d47bb..86669aea931d083a90cd38b0588d97a93d4547e5 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -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", diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 8fae998492aa84af750dbda77c6aa9f07618860a..50fed0c2d457365c68c281a4f93982e3b045e97b 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -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, } } diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index a9cfefa2c4aca4c63cfc53c50b8bd34f786b2d03..e03517f97a2c9f66ecb7c361c00005b7d6beca0f 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -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, diff --git a/src/target.zig b/src/target.zig index 134aa36c55d07196a6e05c58599b48f29201c450..f878f8e6bc31630b50bb57deb080044ee0d09b2b 100644 --- a/src/target.zig +++ b/src/target.zig @@ -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, }; } @@ -711,18 +720,26 @@ pub fn minFunctionAlignment(target: *const std.Target) Alignment { .csky, .m68k, .msp430, + .sh, + .sheb, .s390x, .xcore, => .@"2", + .aarch64, + .aarch64_be, + .alpha, .arc, + .arceb, .arm, .armeb, - .aarch64, - .aarch64_be, .hexagon, + .hppa, + .hppa64, .lanai, .loongarch32, .loongarch64, + .microblaze, + .microblazeel, .mips, .mipsel, .powerpc, @@ -732,9 +749,10 @@ pub fn minFunctionAlignment(target: *const std.Target) Alignment { .sparc, .sparc64, .xtensa, + .xtensaeb, => .@"4", - .bpfel, .bpfeb, + .bpfel, .mips64, .mips64el, => .@"8", diff --git a/test/cases/compile_errors/invalid_variadic_function.zig b/test/cases/compile_errors/invalid_variadic_function.zig index 08e1eb0148eae16e6bebacab859cc55f5d9f5f43..a5f2c2f89324a38609d0f39a0b85212bdf824ccc 100644 --- a/test/cases/compile_errors/invalid_variadic_function.zig +++ b/test/cases/compile_errors/invalid_variadic_function.zig @@ -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' diff --git a/test/cases/compile_errors/reify_type.Fn_with_is_var_args_true_and_non-C_callconv.zig b/test/cases/compile_errors/reify_type.Fn_with_is_var_args_true_and_non-C_callconv.zig index e72dc41b6ea87368681a9dc424b3183122dcafa9..f74b89ae87194056e22b4c923be5d39273a4372f 100644 --- a/test/cases/compile_errors/reify_type.Fn_with_is_var_args_true_and_non-C_callconv.zig +++ b/test/cases/compile_errors/reify_type.Fn_with_is_var_args_true_and_non-C_callconv.zig @@ -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' diff --git a/test/tests.zig b/test/tests.zig index 3625b560cdf623aacfe07ea70fc553e4e00ec276..c7fe8a7e7885e7f155697dca1b77ce9daf90ce76 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -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