Skip to content

Commit 38caa49

Browse files
authored
Merge pull request #25623 from alexrp/or1k
Add `or1k-linux` support (via CBE)
2 parents c37d23f + 0801458 commit 38caa49

11 files changed

Lines changed: 242 additions & 9 deletions

File tree

lib/std/Thread.zig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,18 @@ const LinuxThreadImpl = struct {
12881288
: [ptr] "r" (@intFromPtr(self.mapped.ptr)),
12891289
[len] "r" (self.mapped.len),
12901290
: .{ .memory = true }),
1291+
.or1k => asm volatile (
1292+
\\ l.ori r11, r0, 215 # SYS_munmap
1293+
\\ l.ori r3, %[ptr]
1294+
\\ l.ori r4, %[len]
1295+
\\ l.sys 1
1296+
\\ l.ori r11, r0, 93 # SYS_exit
1297+
\\ l.ori r3, r0, r0
1298+
\\ l.sys 1
1299+
:
1300+
: [ptr] "r" (@intFromPtr(self.mapped.ptr)),
1301+
[len] "r" (self.mapped.len),
1302+
: .{ .memory = true }),
12911303
.powerpc, .powerpcle, .powerpc64, .powerpc64le => asm volatile (
12921304
\\ li 0, 91 # SYS_munmap
12931305
\\ mr 3, %[ptr]

lib/std/atomic.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,9 @@ pub fn cacheLineForCpu(cpu: std.Target.Cpu) u16 {
445445
=> 32,
446446

447447
// - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/m68k/include/asm/cache.h#L10
448+
// - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/openrisc/include/asm/cache.h#L24
448449
.m68k,
450+
.or1k,
449451
=> 16,
450452

451453
// - https://www.ti.com/lit/pdf/slaa498

lib/std/debug.zig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,8 @@ const StackIterator = union(enum) {
988988
// On LoongArch and RISC-V, the frame pointer points to the top of the saved register area,
989989
// in which the base pointer is the first word.
990990
if (native_arch.isLoongArch() or native_arch.isRISCV()) break :off -2 * @sizeOf(usize);
991+
// On OpenRISC, the frame pointer is stored below the return address.
992+
if (native_arch == .or1k) break :off -2 * @sizeOf(usize);
991993
// On SPARC, the frame pointer points to the save area which holds 16 slots for the local
992994
// and incoming registers. The base pointer (i6) is stored in its customary save slot.
993995
if (native_arch.isSPARC()) break :off 14 * @sizeOf(usize);
@@ -999,7 +1001,9 @@ const StackIterator = union(enum) {
9991001
const fp_to_ra_offset = off: {
10001002
// On LoongArch and RISC-V, the frame pointer points to the top of the saved register area,
10011003
// in which the return address is the second word.
1002-
if (native_arch.isRISCV() or native_arch.isLoongArch()) break :off -1 * @sizeOf(usize);
1004+
if (native_arch.isLoongArch() or native_arch.isRISCV()) break :off -1 * @sizeOf(usize);
1005+
// On OpenRISC, the return address is stored below the stack parameter area.
1006+
if (native_arch == .or1k) break :off -1 * @sizeOf(usize);
10031007
if (native_arch.isPowerPC64()) break :off 2 * @sizeOf(usize);
10041008
// On s390x, r14 is the link register and we need to grab it from its customary slot in the
10051009
// register save area (ELF ABI s390x Supplement §1.2.2.2).

lib/std/heap.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,7 @@ const page_size_min_default: ?usize = switch (builtin.os.tag) {
832832
.loongarch32, .loongarch64 => 4 << 10,
833833
.m68k => 4 << 10,
834834
.mips, .mipsel, .mips64, .mips64el => 4 << 10,
835+
.or1k => 8 << 10,
835836
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10,
836837
.riscv32, .riscv64 => 4 << 10,
837838
.s390x => 4 << 10,
@@ -979,6 +980,7 @@ const page_size_max_default: ?usize = switch (builtin.os.tag) {
979980
.loongarch32, .loongarch64 => 64 << 10,
980981
.m68k => 8 << 10,
981982
.mips, .mipsel, .mips64, .mips64el => 64 << 10,
983+
.or1k => 8 << 10,
982984
.powerpc, .powerpc64, .powerpc64le, .powerpcle => 256 << 10,
983985
.riscv32, .riscv64 => 4 << 10,
984986
.s390x => 4 << 10,

lib/std/os/linux.zig

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const arch_bits = switch (native_arch) {
4242
.gnuabin32, .muslabin32 => @import("linux/mipsn32.zig"),
4343
else => @import("linux/mips64.zig"),
4444
},
45+
.or1k => @import("linux/or1k.zig"),
4546
.powerpc, .powerpcle => @import("linux/powerpc.zig"),
4647
.powerpc64, .powerpc64le => @import("linux/powerpc64.zig"),
4748
.riscv32 => @import("linux/riscv32.zig"),
@@ -273,7 +274,7 @@ pub const MAP = switch (native_arch) {
273274
UNINITIALIZED: bool = false,
274275
_: u5 = 0,
275276
},
276-
.hexagon, .m68k, .s390x => packed struct(u32) {
277+
.hexagon, .m68k, .or1k, .s390x => packed struct(u32) {
277278
TYPE: MAP_TYPE,
278279
FIXED: bool = false,
279280
ANONYMOUS: bool = false,
@@ -444,7 +445,7 @@ pub const O = switch (native_arch) {
444445
TMPFILE: bool = false,
445446
_23: u9 = 0,
446447
},
447-
.hexagon, .s390x => packed struct(u32) {
448+
.hexagon, .or1k, .s390x => packed struct(u32) {
448449
ACCMODE: ACCMODE = .RDONLY,
449450
_2: u4 = 0,
450451
CREAT: bool = false,
@@ -1931,7 +1932,7 @@ pub fn sigaction(sig: u8, noalias act: ?*const Sigaction, noalias oact: ?*Sigact
19311932
const mask_size = @sizeOf(@TypeOf(ksa.mask));
19321933

19331934
if (act) |new| {
1934-
if (native_arch == .hexagon or is_loongarch or is_mips or is_riscv) {
1935+
if (native_arch == .hexagon or is_loongarch or is_mips or native_arch == .or1k or is_riscv) {
19351936
ksa = .{
19361937
.handler = new.handler.handler,
19371938
.flags = new.flags,
@@ -3747,7 +3748,7 @@ pub const SA = if (is_mips) struct {
37473748
pub const ONSTACK = 0x1;
37483749
pub const NODEFER = 0x20;
37493750
pub const RESTORER = 0x04000000;
3750-
} else if (native_arch == .hexagon or is_loongarch or is_riscv) struct {
3751+
} else if (native_arch == .hexagon or is_loongarch or native_arch == .or1k or is_riscv) struct {
37513752
pub const NOCLDSTOP = 1;
37523753
pub const NOCLDWAIT = 2;
37533754
pub const SIGINFO = 4;
@@ -5828,7 +5829,7 @@ pub const k_sigaction = switch (native_arch) {
58285829
handler: k_sigaction_funcs.handler,
58295830
mask: sigset_t,
58305831
},
5831-
.hexagon, .loongarch32, .loongarch64, .riscv32, .riscv64 => extern struct {
5832+
.hexagon, .loongarch32, .loongarch64, .or1k, .riscv32, .riscv64 => extern struct {
58325833
handler: k_sigaction_funcs.handler,
58335834
flags: c_ulong,
58345835
mask: sigset_t,
@@ -6161,6 +6162,7 @@ pub const MINSIGSTKSZ = switch (native_arch) {
61616162
.mipsel,
61626163
.mips64,
61636164
.mips64el,
6165+
.or1k,
61646166
.powerpc,
61656167
.powerpcle,
61666168
.riscv32,
@@ -6195,6 +6197,7 @@ pub const SIGSTKSZ = switch (native_arch) {
61956197
.mipsel,
61966198
.mips64,
61976199
.mips64el,
6200+
.or1k,
61986201
.powerpc,
61996202
.powerpcle,
62006203
.riscv32,
@@ -9744,6 +9747,7 @@ pub const AUDIT = struct {
97449747
.gnuabin32, .muslabin32 => .MIPSEL64N32,
97459748
else => .MIPSEL64,
97469749
},
9750+
.or1k => .OPENRISC,
97479751
.powerpc => .PPC,
97489752
.powerpc64 => .PPC64,
97499753
.powerpc64le => .PPC64LE,

lib/std/os/linux/or1k.zig

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
const builtin = @import("builtin");
2+
const std = @import("../../std.zig");
3+
const SYS = std.os.linux.SYS;
4+
5+
pub fn syscall0(number: SYS) u32 {
6+
return asm volatile (
7+
\\ l.sys 1
8+
: [ret] "={r11}" (-> u32),
9+
: [number] "{r11}" (@intFromEnum(number)),
10+
: .{ .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 });
11+
}
12+
13+
pub fn syscall1(number: SYS, arg1: u32) u32 {
14+
return asm volatile (
15+
\\ l.sys 1
16+
: [ret] "={r11}" (-> u32),
17+
: [number] "{r11}" (@intFromEnum(number)),
18+
[arg1] "{r3}" (arg1),
19+
: .{ .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 });
20+
}
21+
22+
pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
23+
return asm volatile (
24+
\\ l.sys 1
25+
: [ret] "={r11}" (-> u32),
26+
: [number] "{r11}" (@intFromEnum(number)),
27+
[arg1] "{r3}" (arg1),
28+
[arg2] "{r4}" (arg2),
29+
: .{ .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 });
30+
}
31+
32+
pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
33+
return asm volatile (
34+
\\ l.sys 1
35+
: [ret] "={r11}" (-> u32),
36+
: [number] "{r11}" (@intFromEnum(number)),
37+
[arg1] "{r3}" (arg1),
38+
[arg2] "{r4}" (arg2),
39+
[arg3] "{r5}" (arg3),
40+
: .{ .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 });
41+
}
42+
43+
pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
44+
return asm volatile (
45+
\\ l.sys 1
46+
: [ret] "={r11}" (-> u32),
47+
: [number] "{r11}" (@intFromEnum(number)),
48+
[arg1] "{r3}" (arg1),
49+
[arg2] "{r4}" (arg2),
50+
[arg3] "{r5}" (arg3),
51+
[arg4] "{r6}" (arg4),
52+
: .{ .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 });
53+
}
54+
55+
pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
56+
return asm volatile (
57+
\\ l.sys 1
58+
: [ret] "={r11}" (-> u32),
59+
: [number] "{r11}" (@intFromEnum(number)),
60+
[arg1] "{r3}" (arg1),
61+
[arg2] "{r4}" (arg2),
62+
[arg3] "{r5}" (arg3),
63+
[arg4] "{r6}" (arg4),
64+
[arg5] "{r7}" (arg5),
65+
: .{ .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 });
66+
}
67+
68+
pub fn syscall6(
69+
number: SYS,
70+
arg1: u32,
71+
arg2: u32,
72+
arg3: u32,
73+
arg4: u32,
74+
arg5: u32,
75+
arg6: u32,
76+
) u32 {
77+
return asm volatile (
78+
\\ l.sys 1
79+
: [ret] "={r11}" (-> u32),
80+
: [number] "{r11}" (@intFromEnum(number)),
81+
[arg1] "{r3}" (arg1),
82+
[arg2] "{r4}" (arg2),
83+
[arg3] "{r5}" (arg3),
84+
[arg4] "{r6}" (arg4),
85+
[arg5] "{r7}" (arg5),
86+
[arg6] "{r8}" (arg6),
87+
: .{ .r12 = true, .r13 = true, .r15 = true, .r17 = true, .r19 = true, .r21 = true, .r23 = true, .r25 = true, .r27 = true, .r29 = true, .r31 = true, .memory = true });
88+
}
89+
90+
pub fn clone() callconv(.naked) u32 {
91+
// __clone(func, stack, flags, arg, ptid, tls, ctid)
92+
// r3, r4, r5, r6, r7, r8, +0
93+
//
94+
// syscall(SYS_clone, flags, stack, ptid, tls, ctid)
95+
// r11 r3, r4, r5, r6, r7
96+
asm volatile (
97+
\\ # Save function pointer and argument pointer on new thread stack
98+
\\ l.andi r4, r4, -4
99+
\\ l.addi r4, r4, -8
100+
\\ l.sw 0(r4), r3
101+
\\ l.sw 4(r4), r6
102+
\\
103+
\\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
104+
\\ l.ori r11, r0, 220 # SYS_clone
105+
\\ l.ori r3, r5, 0
106+
\\ l.ori r5, r7, 0
107+
\\ l.ori r6, r8, 0
108+
\\ l.lwz r7, 0(r1)
109+
\\ l.sys 1
110+
\\ l.sfeqi r11, 0
111+
\\ l.bf 1f
112+
\\ l.jr r9
113+
\\1:
114+
);
115+
if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
116+
\\ .cfi_undefined r9
117+
);
118+
asm volatile (
119+
\\ l.ori r2, r0, 0
120+
\\ l.ori r9, r0, 0
121+
\\
122+
\\ l.lwz r11, 0(r1)
123+
\\ l.lwz r3, 4(r1)
124+
\\ l.jalr r11
125+
\\
126+
\\ l.ori r3, r11, 0
127+
\\ l.ori r11, r0, 93 # SYS_exit
128+
\\ l.sys 1
129+
);
130+
}
131+
132+
pub const VDSO = void;
133+
134+
pub const blksize_t = u32;
135+
pub const nlink_t = u32;
136+
pub const time_t = i32;
137+
pub const mode_t = u32;
138+
pub const off_t = i64;
139+
pub const ino_t = u64;
140+
pub const dev_t = u64;
141+
pub const blkcnt_t = i64;
142+
143+
// The `stat64` definition used by the Linux kernel.
144+
pub const Stat = extern struct {
145+
dev: dev_t,
146+
ino: ino_t,
147+
mode: mode_t,
148+
nlink: nlink_t,
149+
uid: std.os.linux.uid_t,
150+
gid: std.os.linux.gid_t,
151+
rdev: dev_t,
152+
_pad0: [2]u32,
153+
size: off_t,
154+
blksize: blksize_t,
155+
_pad1: u32,
156+
blocks: blkcnt_t,
157+
atim: std.os.linux.timespec,
158+
mtim: std.os.linux.timespec,
159+
ctim: std.os.linux.timespec,
160+
_pad2: [2]u32,
161+
162+
pub fn atime(self: @This()) std.os.linux.timespec {
163+
return self.atim;
164+
}
165+
166+
pub fn mtime(self: @This()) std.os.linux.timespec {
167+
return self.mtim;
168+
}
169+
170+
pub fn ctime(self: @This()) std.os.linux.timespec {
171+
return self.ctim;
172+
}
173+
};

lib/std/os/linux/tls.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ const current_variant: Variant = switch (native_arch) {
7979
.mipsel,
8080
.mips64,
8181
.mips64el,
82+
.or1k,
8283
.powerpc,
8384
.powerpcle,
8485
.powerpc64,
@@ -285,6 +286,13 @@ pub fn setThreadPointer(addr: usize) void {
285286
const rc = @call(.always_inline, linux.syscall1, .{ .set_thread_area, addr });
286287
assert(rc == 0);
287288
},
289+
.or1k => {
290+
asm volatile (
291+
\\ l.ori r10, %[addr], 0
292+
:
293+
: [addr] "r" (addr),
294+
);
295+
},
288296
.powerpc, .powerpcle => {
289297
asm volatile (
290298
\\ mr 2, %[addr]

lib/std/pie.zig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const R_HEXAGON_RELATIVE = 35;
1313
const R_LARCH_RELATIVE = 3;
1414
const R_68K_RELATIVE = 22;
1515
const R_MIPS_RELATIVE = 128;
16+
const R_OR1K_RELATIVE = 21;
1617
const R_PPC_RELATIVE = 22;
1718
const R_RISCV_RELATIVE = 3;
1819
const R_390_RELATIVE = 12;
@@ -29,6 +30,7 @@ const R_RELATIVE = switch (builtin.cpu.arch) {
2930
.loongarch32, .loongarch64 => R_LARCH_RELATIVE,
3031
.m68k => R_68K_RELATIVE,
3132
.mips, .mipsel, .mips64, .mips64el => R_MIPS_RELATIVE,
33+
.or1k => R_OR1K_RELATIVE,
3234
.powerpc, .powerpcle, .powerpc64, .powerpc64le => R_PPC_RELATIVE,
3335
.riscv32, .riscv32be, .riscv64, .riscv64be => R_RISCV_RELATIVE,
3436
.s390x => R_390_RELATIVE,
@@ -153,6 +155,17 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
153155
:
154156
: .{ .lr = true }),
155157
},
158+
.or1k => asm volatile (
159+
\\ .weak _DYNAMIC
160+
\\ .hidden _DYNAMIC
161+
\\ l.jal 1f
162+
\\ .word _DYNAMIC - .
163+
\\1:
164+
\\ l.lwz %[ret], 0(r9)
165+
\\ l.add %[ret], %[ret], r9
166+
: [ret] "=r" (-> [*]const elf.Dyn),
167+
:
168+
: .{ .r9 = true }),
156169
.powerpc, .powerpcle => asm volatile (
157170
\\ .weak _DYNAMIC
158171
\\ .hidden _DYNAMIC

0 commit comments

Comments
 (0)