Skip to content

Commit 8cd1cb6

Browse files
yxd-ymalexrp
authored and
Igor Stojkovic
committedAug 11, 2024
std: add loongarch64 support (ziglang#20915)
Co-authored-by: Alex Rønne Petersen <[email protected]>
1 parent 640fb80 commit 8cd1cb6

File tree

4 files changed

+220
-2
lines changed

4 files changed

+220
-2
lines changed
 

‎CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ set(ZIG_STAGE2_SOURCES
381381
lib/std/Target/avr.zig
382382
lib/std/Target/bpf.zig
383383
lib/std/Target/hexagon.zig
384+
lib/std/Target/loongarch.zig
384385
lib/std/Target/mips.zig
385386
lib/std/Target/msp430.zig
386387
lib/std/Target/nvptx.zig

‎lib/std/Thread.zig

+13
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,19 @@ const LinuxThreadImpl = struct {
12241224
[len] "r" (self.mapped.len),
12251225
: "memory"
12261226
),
1227+
.loongarch64 => asm volatile (
1228+
\\ or $a0, $zero, %[ptr]
1229+
\\ or $a1, $zero, %[len]
1230+
\\ ori $a7, $zero, 215 # SYS_munmap
1231+
\\ syscall 0 # call munmap
1232+
\\ ori $a0, $zero, 0
1233+
\\ ori $a7, $zero, 93 # SYS_exit
1234+
\\ syscall 0 # call exit
1235+
:
1236+
: [ptr] "r" (@intFromPtr(self.mapped.ptr)),
1237+
[len] "r" (self.mapped.len),
1238+
: "memory"
1239+
),
12271240
else => |cpu_arch| @compileError("Unsupported linux arch: " ++ @tagName(cpu_arch)),
12281241
}
12291242
unreachable;

‎lib/std/os/linux.zig

+3-2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const arch_bits = switch (native_arch) {
4242
.riscv32 => @import("linux/riscv32.zig"),
4343
.riscv64 => @import("linux/riscv64.zig"),
4444
.sparc64 => @import("linux/sparc64.zig"),
45+
.loongarch64 => @import("linux/loongarch64.zig"),
4546
.mips, .mipsel => @import("linux/mips.zig"),
4647
.mips64, .mips64el => @import("linux/mips64.zig"),
4748
.powerpc, .powerpcle => @import("linux/powerpc.zig"),
@@ -196,7 +197,7 @@ pub const MAP = switch (native_arch) {
196197
UNINITIALIZED: bool = false,
197198
_: u5 = 0,
198199
},
199-
.riscv32, .riscv64 => packed struct(u32) {
200+
.riscv32, .riscv64, .loongarch64 => packed struct(u32) {
200201
TYPE: MAP_TYPE,
201202
FIXED: bool = false,
202203
ANONYMOUS: bool = false,
@@ -301,7 +302,7 @@ pub const O = switch (native_arch) {
301302
TMPFILE: bool = false,
302303
_: u9 = 0,
303304
},
304-
.x86, .riscv32, .riscv64 => packed struct(u32) {
305+
.x86, .riscv32, .riscv64, .loongarch64 => packed struct(u32) {
305306
ACCMODE: ACCMODE = .RDONLY,
306307
_2: u4 = 0,
307308
CREAT: bool = false,

‎lib/std/os/linux/loongarch64.zig

+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
const std = @import("../../std.zig");
2+
const linux = std.os.linux;
3+
const SYS = linux.SYS;
4+
const iovec = std.os.iovec;
5+
const uid_t = linux.uid_t;
6+
const gid_t = linux.gid_t;
7+
const stack_t = linux.stack_t;
8+
const sigset_t = linux.sigset_t;
9+
10+
pub fn syscall0(number: SYS) usize {
11+
return asm volatile (
12+
\\ syscall 0
13+
: [ret] "={$r4}" (-> usize),
14+
: [number] "{$r11}" (@intFromEnum(number)),
15+
: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "memory"
16+
);
17+
}
18+
19+
pub fn syscall1(number: SYS, arg1: usize) usize {
20+
return asm volatile (
21+
\\ syscall 0
22+
: [ret] "={$r4}" (-> usize),
23+
: [number] "{$r11}" (@intFromEnum(number)),
24+
[arg1] "{$r4}" (arg1),
25+
: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "memory"
26+
);
27+
}
28+
29+
pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
30+
return asm volatile (
31+
\\ syscall 0
32+
: [ret] "={$r4}" (-> usize),
33+
: [number] "{$r11}" (@intFromEnum(number)),
34+
[arg1] "{$r4}" (arg1),
35+
[arg2] "{$r5}" (arg2),
36+
: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "memory"
37+
);
38+
}
39+
40+
pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
41+
return asm volatile (
42+
\\ syscall 0
43+
: [ret] "={$r4}" (-> usize),
44+
: [number] "{$r11}" (@intFromEnum(number)),
45+
[arg1] "{$r4}" (arg1),
46+
[arg2] "{$r5}" (arg2),
47+
[arg3] "{$r6}" (arg3),
48+
: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "memory"
49+
);
50+
}
51+
52+
pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
53+
return asm volatile (
54+
\\ syscall 0
55+
: [ret] "={$r4}" (-> usize),
56+
: [number] "{$r11}" (@intFromEnum(number)),
57+
[arg1] "{$r4}" (arg1),
58+
[arg2] "{$r5}" (arg2),
59+
[arg3] "{$r6}" (arg3),
60+
[arg4] "{$r7}" (arg4),
61+
: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "memory"
62+
);
63+
}
64+
65+
pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
66+
return asm volatile (
67+
\\ syscall 0
68+
: [ret] "={$r4}" (-> usize),
69+
: [number] "{$r11}" (@intFromEnum(number)),
70+
[arg1] "{$r4}" (arg1),
71+
[arg2] "{$r5}" (arg2),
72+
[arg3] "{$r6}" (arg3),
73+
[arg4] "{$r7}" (arg4),
74+
[arg5] "{$r8}" (arg5),
75+
: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "memory"
76+
);
77+
}
78+
79+
pub fn syscall6(
80+
number: SYS,
81+
arg1: usize,
82+
arg2: usize,
83+
arg3: usize,
84+
arg4: usize,
85+
arg5: usize,
86+
arg6: usize,
87+
) usize {
88+
return asm volatile (
89+
\\ syscall 0
90+
: [ret] "={$r4}" (-> usize),
91+
: [number] "{$r11}" (@intFromEnum(number)),
92+
[arg1] "{$r4}" (arg1),
93+
[arg2] "{$r5}" (arg2),
94+
[arg3] "{$r6}" (arg3),
95+
[arg4] "{$r7}" (arg4),
96+
[arg5] "{$r8}" (arg5),
97+
[arg6] "{$r9}" (arg6),
98+
: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "memory"
99+
);
100+
}
101+
102+
pub fn clone() callconv(.Naked) usize {
103+
// __clone(func, stack, flags, arg, ptid, tls, ctid)
104+
// a0, a1, a2, a3, a4, a5, a6
105+
// sys_clone(flags, stack, ptid, ctid, tls)
106+
// a0, a1, a2, a3, a4
107+
asm volatile (
108+
\\ bstrins.d $a1, $zero, 3, 0 # stack to 16 align
109+
\\
110+
\\ # Save function pointer and argument pointer on new thread stack
111+
\\ addi.d $a1, $a1, -16
112+
\\ st.d $a0, $a1, 0 # save function pointer
113+
\\ st.d $a3, $a1, 8 # save argument pointer
114+
\\ or $a0, $a2, $zero
115+
\\ or $a2, $a4, $zero
116+
\\ or $a3, $a6, $zero
117+
\\ or $a4, $a5, $zero
118+
\\ ori $a7, $zero, 220 # SYS_clone
119+
\\ syscall 0 # call clone
120+
\\
121+
\\ beqz $a0, 1f # whether child process
122+
\\ jirl $zero, $ra, 0 # parent process return
123+
\\1:
124+
\\ ld.d $t8, $sp, 0 # function pointer
125+
\\ ld.d $a0, $sp, 8 # argument pointer
126+
\\ jirl $ra, $t8, 0 # call the user's function
127+
\\ ori $a7, $zero, 93 # SYS_exit
128+
\\ syscall 0 # child process exit
129+
);
130+
}
131+
132+
pub const restore = restore_rt;
133+
134+
pub fn restore_rt() callconv(.Naked) noreturn {
135+
asm volatile (
136+
\\ or $a7, $zero, %[number]
137+
\\ syscall 0
138+
:
139+
: [number] "r" (@intFromEnum(SYS.rt_sigreturn)),
140+
: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "memory"
141+
);
142+
}
143+
144+
pub const blksize_t = i32;
145+
pub const nlink_t = u32;
146+
pub const time_t = i64;
147+
pub const mode_t = u32;
148+
pub const off_t = i64;
149+
pub const ino_t = u64;
150+
pub const dev_t = u32;
151+
pub const blkcnt_t = i64;
152+
153+
pub const timeval = extern struct {
154+
tv_sec: time_t,
155+
tv_usec: i64,
156+
};
157+
158+
pub const F = struct {
159+
pub const DUPFD = 0;
160+
pub const GETFD = 1;
161+
pub const SETFD = 2;
162+
pub const GETFL = 3;
163+
pub const SETFL = 4;
164+
pub const GETLK = 5;
165+
pub const SETLK = 6;
166+
pub const SETLKW = 7;
167+
pub const SETOWN = 8;
168+
pub const GETOWN = 9;
169+
pub const SETSIG = 10;
170+
pub const GETSIG = 11;
171+
172+
pub const RDLCK = 0;
173+
pub const WRLCK = 1;
174+
pub const UNLCK = 2;
175+
176+
pub const SETOWN_EX = 15;
177+
pub const GETOWN_EX = 16;
178+
179+
pub const GETOWNER_UIDS = 17;
180+
};
181+
182+
pub const VDSO = struct {
183+
pub const CGT_SYM = "__vdso_clock_gettime";
184+
pub const CGT_VER = "LINUX_5.10";
185+
};
186+
187+
pub const mcontext_t = extern struct {
188+
pc: u64,
189+
regs: [32]u64,
190+
flags: u32,
191+
extcontext: [0]u64 align(16),
192+
};
193+
194+
pub const ucontext_t = extern struct {
195+
flags: c_ulong,
196+
link: ?*ucontext_t,
197+
stack: stack_t,
198+
sigmask: sigset_t,
199+
_pad: [1024 / 8 - @sizeOf(sigset_t)]u8,
200+
mcontext: mcontext_t,
201+
};
202+
203+
pub const Elf_Symndx = u32;

0 commit comments

Comments
 (0)
Please sign in to comment.