diff options
| author | Alex Rønne Petersen <alex@alexrp.com> | 2025-10-19 11:50:06 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-19 11:50:06 +0200 |
| commit | 38caa4902f87f63246d8bef9596f2cb7ad8bbbda (patch) | |
| tree | 06f9267cb6af6629221a32f858281ef5bbe946ef | |
| parent | c37d23f45ae6bd0db6b072180d7b84566c7dc8a2 (diff) | |
| parent | 08014589e291d9ffc8ba4d7abc9a669bfd0c3bec (diff) | |
| download | zig-38caa4902f87f63246d8bef9596f2cb7ad8bbbda.tar.gz zig-38caa4902f87f63246d8bef9596f2cb7ad8bbbda.zip | |
Merge pull request #25623 from alexrp/or1k
Add `or1k-linux` support (via CBE)
| -rw-r--r-- | lib/std/Thread.zig | 12 | ||||
| -rw-r--r-- | lib/std/atomic.zig | 2 | ||||
| -rw-r--r-- | lib/std/debug.zig | 6 | ||||
| -rw-r--r-- | lib/std/heap.zig | 2 | ||||
| -rw-r--r-- | lib/std/os/linux.zig | 14 | ||||
| -rw-r--r-- | lib/std/os/linux/or1k.zig | 173 | ||||
| -rw-r--r-- | lib/std/os/linux/tls.zig | 8 | ||||
| -rw-r--r-- | lib/std/pie.zig | 13 | ||||
| -rw-r--r-- | lib/std/start.zig | 14 | ||||
| -rw-r--r-- | lib/zig.h | 6 | ||||
| -rw-r--r-- | src/Sema.zig | 1 |
11 files changed, 242 insertions, 9 deletions
diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index c299fb626c..cd019329d3 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -1288,6 +1288,18 @@ const LinuxThreadImpl = struct { : [ptr] "r" (@intFromPtr(self.mapped.ptr)), [len] "r" (self.mapped.len), : .{ .memory = true }), + .or1k => asm volatile ( + \\ l.ori r11, r0, 215 # SYS_munmap + \\ l.ori r3, %[ptr] + \\ l.ori r4, %[len] + \\ l.sys 1 + \\ l.ori r11, r0, 93 # SYS_exit + \\ l.ori r3, r0, r0 + \\ l.sys 1 + : + : [ptr] "r" (@intFromPtr(self.mapped.ptr)), + [len] "r" (self.mapped.len), + : .{ .memory = true }), .powerpc, .powerpcle, .powerpc64, .powerpc64le => asm volatile ( \\ li 0, 91 # SYS_munmap \\ mr 3, %[ptr] diff --git a/lib/std/atomic.zig b/lib/std/atomic.zig index 64926dbc4f..7853d04214 100644 --- a/lib/std/atomic.zig +++ b/lib/std/atomic.zig @@ -445,7 +445,9 @@ pub fn cacheLineForCpu(cpu: std.Target.Cpu) u16 { => 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 .m68k, + .or1k, => 16, // - https://www.ti.com/lit/pdf/slaa498 diff --git a/lib/std/debug.zig b/lib/std/debug.zig index b58bb315db..ec08244383 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -988,6 +988,8 @@ const StackIterator = union(enum) { // 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); + // On OpenRISC, the frame pointer is stored below the return address. + if (native_arch == .or1k) break :off -2 * @sizeOf(usize); // On SPARC, the frame pointer points to the save area which holds 16 slots for the local // and incoming registers. The base pointer (i6) is stored in its customary save slot. if (native_arch.isSPARC()) break :off 14 * @sizeOf(usize); @@ -999,7 +1001,9 @@ const StackIterator = union(enum) { const fp_to_ra_offset = off: { // 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.isRISCV() or native_arch.isLoongArch()) break :off -1 * @sizeOf(usize); + if (native_arch.isLoongArch() or native_arch.isRISCV()) break :off -1 * @sizeOf(usize); + // On OpenRISC, the return address is stored below the stack parameter area. + if (native_arch == .or1k) break :off -1 * @sizeOf(usize); if (native_arch.isPowerPC64()) break :off 2 * @sizeOf(usize); // On s390x, r14 is the link register and we need to grab it from its customary slot in the // register save area (ELF ABI s390x Supplement §1.2.2.2). diff --git a/lib/std/heap.zig b/lib/std/heap.zig index b5fd822959..382e763ef2 100644 --- a/lib/std/heap.zig +++ b/lib/std/heap.zig @@ -832,6 +832,7 @@ const page_size_min_default: ?usize = switch (builtin.os.tag) { .loongarch32, .loongarch64 => 4 << 10, .m68k => 4 << 10, .mips, .mipsel, .mips64, .mips64el => 4 << 10, + .or1k => 8 << 10, .powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10, .riscv32, .riscv64 => 4 << 10, .s390x => 4 << 10, @@ -979,6 +980,7 @@ const page_size_max_default: ?usize = switch (builtin.os.tag) { .loongarch32, .loongarch64 => 64 << 10, .m68k => 8 << 10, .mips, .mipsel, .mips64, .mips64el => 64 << 10, + .or1k => 8 << 10, .powerpc, .powerpc64, .powerpc64le, .powerpcle => 256 << 10, .riscv32, .riscv64 => 4 << 10, .s390x => 4 << 10, diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 707a1b840a..be8237107c 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -42,6 +42,7 @@ const arch_bits = switch (native_arch) { .gnuabin32, .muslabin32 => @import("linux/mipsn32.zig"), else => @import("linux/mips64.zig"), }, + .or1k => @import("linux/or1k.zig"), .powerpc, .powerpcle => @import("linux/powerpc.zig"), .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"), .riscv32 => @import("linux/riscv32.zig"), @@ -273,7 +274,7 @@ pub const MAP = switch (native_arch) { UNINITIALIZED: bool = false, _: u5 = 0, }, - .hexagon, .m68k, .s390x => packed struct(u32) { + .hexagon, .m68k, .or1k, .s390x => packed struct(u32) { TYPE: MAP_TYPE, FIXED: bool = false, ANONYMOUS: bool = false, @@ -444,7 +445,7 @@ pub const O = switch (native_arch) { TMPFILE: bool = false, _23: u9 = 0, }, - .hexagon, .s390x => packed struct(u32) { + .hexagon, .or1k, .s390x => packed struct(u32) { ACCMODE: ACCMODE = .RDONLY, _2: u4 = 0, CREAT: bool = false, @@ -1931,7 +1932,7 @@ pub fn sigaction(sig: u8, noalias act: ?*const Sigaction, noalias oact: ?*Sigact const mask_size = @sizeOf(@TypeOf(ksa.mask)); if (act) |new| { - if (native_arch == .hexagon or is_loongarch or is_mips or is_riscv) { + if (native_arch == .hexagon or is_loongarch or is_mips or native_arch == .or1k or is_riscv) { ksa = .{ .handler = new.handler.handler, .flags = new.flags, @@ -3747,7 +3748,7 @@ pub const SA = if (is_mips) struct { pub const ONSTACK = 0x1; pub const NODEFER = 0x20; pub const RESTORER = 0x04000000; -} else if (native_arch == .hexagon or is_loongarch or is_riscv) struct { +} else if (native_arch == .hexagon or is_loongarch or native_arch == .or1k or is_riscv) struct { pub const NOCLDSTOP = 1; pub const NOCLDWAIT = 2; pub const SIGINFO = 4; @@ -5828,7 +5829,7 @@ pub const k_sigaction = switch (native_arch) { handler: k_sigaction_funcs.handler, mask: sigset_t, }, - .hexagon, .loongarch32, .loongarch64, .riscv32, .riscv64 => extern struct { + .hexagon, .loongarch32, .loongarch64, .or1k, .riscv32, .riscv64 => extern struct { handler: k_sigaction_funcs.handler, flags: c_ulong, mask: sigset_t, @@ -6161,6 +6162,7 @@ pub const MINSIGSTKSZ = switch (native_arch) { .mipsel, .mips64, .mips64el, + .or1k, .powerpc, .powerpcle, .riscv32, @@ -6195,6 +6197,7 @@ pub const SIGSTKSZ = switch (native_arch) { .mipsel, .mips64, .mips64el, + .or1k, .powerpc, .powerpcle, .riscv32, @@ -9744,6 +9747,7 @@ pub const AUDIT = struct { .gnuabin32, .muslabin32 => .MIPSEL64N32, else => .MIPSEL64, }, + .or1k => .OPENRISC, .powerpc => .PPC, .powerpc64 => .PPC64, .powerpc64le => .PPC64LE, diff --git a/lib/std/os/linux/or1k.zig b/lib/std/os/linux/or1k.zig new file mode 100644 index 0000000000..1054e52d19 --- /dev/null +++ b/lib/std/os/linux/or1k.zig @@ -0,0 +1,173 @@ +const builtin = @import("builtin"); +const std = @import("../../std.zig"); +const SYS = std.os.linux.SYS; + +pub fn syscall0(number: SYS) u32 { + return asm volatile ( + \\ l.sys 1 + : [ret] "={r11}" (-> u32), + : [number] "{r11}" (@intFromEnum(number)), + : .{ .r3 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true }); +} + +pub fn syscall1(number: SYS, arg1: u32) u32 { + return asm volatile ( + \\ l.sys 1 + : [ret] "={r11}" (-> u32), + : [number] "{r11}" (@intFromEnum(number)), + [arg1] "{r3}" (arg1), + : .{ .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true }); +} + +pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 { + return asm volatile ( + \\ l.sys 1 + : [ret] "={r11}" (-> u32), + : [number] "{r11}" (@intFromEnum(number)), + [arg1] "{r3}" (arg1), + [arg2] "{r4}" (arg2), + : .{ .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true }); +} + +pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 { + return asm volatile ( + \\ l.sys 1 + : [ret] "={r11}" (-> u32), + : [number] "{r11}" (@intFromEnum(number)), + [arg1] "{r3}" (arg1), + [arg2] "{r4}" (arg2), + [arg3] "{r5}" (arg3), + : .{ .r6 = true, .r7 = true, .r8 = true, .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true }); +} + +pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 { + return asm volatile ( + \\ l.sys 1 + : [ret] "={r11}" (-> u32), + : [number] "{r11}" (@intFromEnum(number)), + [arg1] "{r3}" (arg1), + [arg2] "{r4}" (arg2), + [arg3] "{r5}" (arg3), + [arg4] "{r6}" (arg4), + : .{ .r7 = true, .r8 = true, .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true }); +} + +pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 { + return asm volatile ( + \\ l.sys 1 + : [ret] "={r11}" (-> u32), + : [number] "{r11}" (@intFromEnum(number)), + [arg1] "{r3}" (arg1), + [arg2] "{r4}" (arg2), + [arg3] "{r5}" (arg3), + [arg4] "{r6}" (arg4), + [arg5] "{r7}" (arg5), + : .{ .r8 = true, .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true }); +} + +pub fn syscall6( + number: SYS, + arg1: u32, + arg2: u32, + arg3: u32, + arg4: u32, + arg5: u32, + arg6: u32, +) u32 { + return asm volatile ( + \\ l.sys 1 + : [ret] "={r11}" (-> u32), + : [number] "{r11}" (@intFromEnum(number)), + [arg1] "{r3}" (arg1), + [arg2] "{r4}" (arg2), + [arg3] "{r5}" (arg3), + [arg4] "{r6}" (arg4), + [arg5] "{r7}" (arg5), + [arg6] "{r8}" (arg6), + : .{ .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true }); +} + +pub fn clone() callconv(.naked) u32 { + // __clone(func, stack, flags, arg, ptid, tls, ctid) + // r3, r4, r5, r6, r7, r8, +0 + // + // syscall(SYS_clone, flags, stack, ptid, tls, ctid) + // r11 r3, r4, r5, r6, r7 + asm volatile ( + \\ # Save function pointer and argument pointer on new thread stack + \\ l.andi r4, r4, -4 + \\ l.addi r4, r4, -8 + \\ l.sw 0(r4), r3 + \\ l.sw 4(r4), r6 + \\ + \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid) + \\ l.ori r11, r0, 220 # SYS_clone + \\ l.ori r3, r5, 0 + \\ l.ori r5, r7, 0 + \\ l.ori r6, r8, 0 + \\ l.lwz r7, 0(r1) + \\ l.sys 1 + \\ l.sfeqi r11, 0 + \\ l.bf 1f + \\ l.jr r9 + \\1: + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( + \\ .cfi_undefined r9 + ); + asm volatile ( + \\ l.ori r2, r0, 0 + \\ l.ori r9, r0, 0 + \\ + \\ l.lwz r11, 0(r1) + \\ l.lwz r3, 4(r1) + \\ l.jalr r11 + \\ + \\ l.ori r3, r11, 0 + \\ l.ori r11, r0, 93 # SYS_exit + \\ l.sys 1 + ); +} + +pub const VDSO = void; + +pub const blksize_t = u32; +pub const nlink_t = u32; +pub const time_t = i32; +pub const mode_t = u32; +pub const off_t = i64; +pub const ino_t = u64; +pub const dev_t = u64; +pub const blkcnt_t = i64; + +// The `stat64` definition used by the Linux kernel. +pub const Stat = extern struct { + dev: dev_t, + ino: ino_t, + mode: mode_t, + nlink: nlink_t, + uid: std.os.linux.uid_t, + gid: std.os.linux.gid_t, + rdev: dev_t, + _pad0: [2]u32, + size: off_t, + blksize: blksize_t, + _pad1: u32, + blocks: blkcnt_t, + atim: std.os.linux.timespec, + mtim: std.os.linux.timespec, + ctim: std.os.linux.timespec, + _pad2: [2]u32, + + pub fn atime(self: @This()) std.os.linux.timespec { + return self.atim; + } + + pub fn mtime(self: @This()) std.os.linux.timespec { + return self.mtim; + } + + pub fn ctime(self: @This()) std.os.linux.timespec { + return self.ctim; + } +}; diff --git a/lib/std/os/linux/tls.zig b/lib/std/os/linux/tls.zig index 0c063e6df2..abac4318e4 100644 --- a/lib/std/os/linux/tls.zig +++ b/lib/std/os/linux/tls.zig @@ -79,6 +79,7 @@ const current_variant: Variant = switch (native_arch) { .mipsel, .mips64, .mips64el, + .or1k, .powerpc, .powerpcle, .powerpc64, @@ -285,6 +286,13 @@ pub fn setThreadPointer(addr: usize) void { const rc = @call(.always_inline, linux.syscall1, .{ .set_thread_area, addr }); assert(rc == 0); }, + .or1k => { + asm volatile ( + \\ l.ori r10, %[addr], 0 + : + : [addr] "r" (addr), + ); + }, .powerpc, .powerpcle => { asm volatile ( \\ mr 2, %[addr] diff --git a/lib/std/pie.zig b/lib/std/pie.zig index de8c63fc87..1b028930c7 100644 --- a/lib/std/pie.zig +++ b/lib/std/pie.zig @@ -13,6 +13,7 @@ const R_HEXAGON_RELATIVE = 35; const R_LARCH_RELATIVE = 3; const R_68K_RELATIVE = 22; 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; @@ -29,6 +30,7 @@ const R_RELATIVE = switch (builtin.cpu.arch) { .loongarch32, .loongarch64 => R_LARCH_RELATIVE, .m68k => R_68K_RELATIVE, .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, @@ -153,6 +155,17 @@ inline fn getDynamicSymbol() [*]const elf.Dyn { : : .{ .lr = true }), }, + .or1k => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ l.jal 1f + \\ .word _DYNAMIC - . + \\1: + \\ l.lwz %[ret], 0(r9) + \\ l.add %[ret], %[ret], r9 + : [ret] "=r" (-> [*]const elf.Dyn), + : + : .{ .r9 = true }), .powerpc, .powerpcle => asm volatile ( \\ .weak _DYNAMIC \\ .hidden _DYNAMIC diff --git a/lib/std/start.zig b/lib/std/start.zig index 318d819d2e..c6f65aae25 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -203,6 +203,7 @@ fn _start() callconv(.naked) noreturn { .loongarch32, .loongarch64 => ".cfi_undefined 1", .m68k => ".cfi_undefined %%pc", .mips, .mipsel, .mips64, .mips64el => ".cfi_undefined $ra", + .or1k => ".cfi_undefined r9", .powerpc, .powerpcle, .powerpc64, .powerpc64le => ".cfi_undefined lr", .riscv32, .riscv32be, .riscv64, .riscv64be => if (builtin.zig_backend == .stage2_riscv64) "" @@ -253,12 +254,11 @@ fn _start() callconv(.naked) noreturn { \\ b %[posixCallMainAndExit] , .arc => - // The `arc` tag currently means ARC v1 and v2, which have an unusually low stack - // alignment requirement. ARC v3 increases it from 4 to 16, but we don't support v3 yet. + // ARC v1 and v2 had a very low stack alignment requirement of 4; v3 increased it to 16. \\ mov fp, 0 \\ mov blink, 0 \\ mov r0, sp - \\ and sp, sp, -4 + \\ and sp, sp, -16 \\ b %[posixCallMainAndExit] , .arm, .armeb, .thumb, .thumbeb => @@ -306,6 +306,14 @@ fn _start() callconv(.naked) noreturn { \\ bstrins.d $sp, $zero, 3, 0 \\ b %[posixCallMainAndExit] , + .or1k => + // r1 = SP, r2 = FP, r9 = LR + \\ l.ori r2, r0, 0 + \\ l.ori r9, r0, 0 + \\ l.ori r3, r1, 0 + \\ l.andi r1, r1, -4 + \\ l.jal %[posixCallMainAndExit] + , .riscv32, .riscv32be, .riscv64, .riscv64be => \\ li fp, 0 \\ li ra, 0 @@ -40,6 +40,8 @@ #elif defined(__mips__) #define zig_mips32 #define zig_mips +#elif defined(__or1k__) +#define zig_or1k #elif defined(__powerpc64__) #define zig_powerpc64 #define zig_powerpc @@ -390,6 +392,8 @@ #define zig_trap() __asm__ volatile(".word 0x0") #elif defined(zig_mips) #define zig_trap() __asm__ volatile(".word 0x3d") +#elif defined(zig_or1k) +#define zig_trap() __asm__ volatile("l.cust8") #elif defined(zig_riscv) #define zig_trap() __asm__ volatile("unimp") #elif defined(zig_s390x) @@ -422,6 +426,8 @@ #define zig_breakpoint() __asm__ volatile("break 0x0") #elif defined(zig_mips) #define zig_breakpoint() __asm__ volatile("break") +#elif defined(zig_or1k) +#define zig_breakpoint() __asm__ volatile("l.trap 0x0") #elif defined(zig_powerpc) #define zig_breakpoint() __asm__ volatile("trap") #elif defined(zig_riscv) diff --git a/src/Sema.zig b/src/Sema.zig index 209d012b24..aef98a4dcd 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -9075,6 +9075,7 @@ const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention .m68k_gnu, .m68k_rtd, .msp430_eabi, + .or1k_sysv, .s390x_sysv, .s390x_sysv_vx, .ve_sysv, |
