authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-11 10:12:02-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-04-11 10:12:02-07:00
log82a31aac9b955213f47ff3b2a2c7eb932fdbe294
treeedb40bb52389fb9dcd34a3794978f46f8199baee
parentcab1d5c1a320239af5be88571d7989ba230b90be
parent073d8e55c321db585d71534a94124100582860f7
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #8483 from fengb/powerpc

Improve PowerPC support

6 files changed, 848 insertions(+), 0 deletions(-)

lib/std/os/bits/linux.zig+1
......@@ -21,6 +21,7 @@ pub usingnamespace switch (builtin.arch) {
2121 .riscv64 => @import("linux/riscv64.zig"),
2222 .sparcv9 => @import("linux/sparc64.zig"),
2323 .mips, .mipsel => @import("linux/mips.zig"),
24 .powerpc => @import("linux/powerpc.zig"),
2425 .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"),
2526 else => struct {},
2627};
lib/std/os/bits/linux/powerpc.zig created+635
......@@ -0,0 +1,635 @@
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2015-2021 Zig Contributors
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.
6
7const std = @import("../../../std.zig");
8const linux = std.os.linux;
9const socklen_t = linux.socklen_t;
10const iovec = linux.iovec;
11const iovec_const = linux.iovec_const;
12const uid_t = linux.uid_t;
13const gid_t = linux.gid_t;
14const pid_t = linux.pid_t;
15const stack_t = linux.stack_t;
16const sigset_t = linux.sigset_t;
17pub const SYS = extern enum(usize) {
18 restart_syscall = 0,
19 exit = 1,
20 fork = 2,
21 read = 3,
22 write = 4,
23 open = 5,
24 close = 6,
25 waitpid = 7,
26 creat = 8,
27 link = 9,
28 unlink = 10,
29 execve = 11,
30 chdir = 12,
31 time = 13,
32 mknod = 14,
33 chmod = 15,
34 lchown = 16,
35 @"break" = 17,
36 oldstat = 18,
37 lseek = 19,
38 getpid = 20,
39 mount = 21,
40 umount = 22,
41 setuid = 23,
42 getuid = 24,
43 stime = 25,
44 ptrace = 26,
45 alarm = 27,
46 oldfstat = 28,
47 pause = 29,
48 utime = 30,
49 stty = 31,
50 gtty = 32,
51 access = 33,
52 nice = 34,
53 ftime = 35,
54 sync = 36,
55 kill = 37,
56 rename = 38,
57 mkdir = 39,
58 rmdir = 40,
59 dup = 41,
60 pipe = 42,
61 times = 43,
62 prof = 44,
63 brk = 45,
64 setgid = 46,
65 getgid = 47,
66 signal = 48,
67 geteuid = 49,
68 getegid = 50,
69 acct = 51,
70 umount2 = 52,
71 lock = 53,
72 ioctl = 54,
73 fcntl = 55,
74 mpx = 56,
75 setpgid = 57,
76 ulimit = 58,
77 oldolduname = 59,
78 umask = 60,
79 chroot = 61,
80 ustat = 62,
81 dup2 = 63,
82 getppid = 64,
83 getpgrp = 65,
84 setsid = 66,
85 sigaction = 67,
86 sgetmask = 68,
87 ssetmask = 69,
88 setreuid = 70,
89 setregid = 71,
90 sigsuspend = 72,
91 sigpending = 73,
92 sethostname = 74,
93 setrlimit = 75,
94 getrlimit = 76,
95 getrusage = 77,
96 gettimeofday = 78,
97 settimeofday = 79,
98 getgroups = 80,
99 setgroups = 81,
100 select = 82,
101 symlink = 83,
102 oldlstat = 84,
103 readlink = 85,
104 uselib = 86,
105 swapon = 87,
106 reboot = 88,
107 readdir = 89,
108 mmap = 90,
109 munmap = 91,
110 truncate = 92,
111 ftruncate = 93,
112 fchmod = 94,
113 fchown = 95,
114 getpriority = 96,
115 setpriority = 97,
116 profil = 98,
117 statfs = 99,
118 fstatfs = 100,
119 ioperm = 101,
120 socketcall = 102,
121 syslog = 103,
122 setitimer = 104,
123 getitimer = 105,
124 stat = 106,
125 lstat = 107,
126 fstat = 108,
127 olduname = 109,
128 iopl = 110,
129 vhangup = 111,
130 idle = 112,
131 vm86 = 113,
132 wait4 = 114,
133 swapoff = 115,
134 sysinfo = 116,
135 ipc = 117,
136 fsync = 118,
137 sigreturn = 119,
138 clone = 120,
139 setdomainname = 121,
140 uname = 122,
141 modify_ldt = 123,
142 adjtimex = 124,
143 mprotect = 125,
144 sigprocmask = 126,
145 create_module = 127,
146 init_module = 128,
147 delete_module = 129,
148 get_kernel_syms = 130,
149 quotactl = 131,
150 getpgid = 132,
151 fchdir = 133,
152 bdflush = 134,
153 sysfs = 135,
154 personality = 136,
155 afs_syscall = 137,
156 setfsuid = 138,
157 setfsgid = 139,
158 _llseek = 140,
159 getdents = 141,
160 _newselect = 142,
161 flock = 143,
162 msync = 144,
163 readv = 145,
164 writev = 146,
165 getsid = 147,
166 fdatasync = 148,
167 _sysctl = 149,
168 mlock = 150,
169 munlock = 151,
170 mlockall = 152,
171 munlockall = 153,
172 sched_setparam = 154,
173 sched_getparam = 155,
174 sched_setscheduler = 156,
175 sched_getscheduler = 157,
176 sched_yield = 158,
177 sched_get_priority_max = 159,
178 sched_get_priority_min = 160,
179 sched_rr_get_interval = 161,
180 nanosleep = 162,
181 mremap = 163,
182 setresuid = 164,
183 getresuid = 165,
184 query_module = 166,
185 poll = 167,
186 nfsservctl = 168,
187 setresgid = 169,
188 getresgid = 170,
189 prctl = 171,
190 rt_sigreturn = 172,
191 rt_sigaction = 173,
192 rt_sigprocmask = 174,
193 rt_sigpending = 175,
194 rt_sigtimedwait = 176,
195 rt_sigqueueinfo = 177,
196 rt_sigsuspend = 178,
197 pread64 = 179,
198 pwrite64 = 180,
199 chown = 181,
200 getcwd = 182,
201 capget = 183,
202 capset = 184,
203 sigaltstack = 185,
204 sendfile = 186,
205 getpmsg = 187,
206 putpmsg = 188,
207 vfork = 189,
208 ugetrlimit = 190,
209 readahead = 191,
210 mmap2 = 192,
211 truncate64 = 193,
212 ftruncate64 = 194,
213 stat64 = 195,
214 lstat64 = 196,
215 fstat64 = 197,
216 pciconfig_read = 198,
217 pciconfig_write = 199,
218 pciconfig_iobase = 200,
219 multiplexer = 201,
220 getdents64 = 202,
221 pivot_root = 203,
222 fcntl64 = 204,
223 madvise = 205,
224 mincore = 206,
225 gettid = 207,
226 tkill = 208,
227 setxattr = 209,
228 lsetxattr = 210,
229 fsetxattr = 211,
230 getxattr = 212,
231 lgetxattr = 213,
232 fgetxattr = 214,
233 listxattr = 215,
234 llistxattr = 216,
235 flistxattr = 217,
236 removexattr = 218,
237 lremovexattr = 219,
238 fremovexattr = 220,
239 futex = 221,
240 sched_setaffinity = 222,
241 sched_getaffinity = 223,
242 tuxcall = 225,
243 sendfile64 = 226,
244 io_setup = 227,
245 io_destroy = 228,
246 io_getevents = 229,
247 io_submit = 230,
248 io_cancel = 231,
249 set_tid_address = 232,
250 fadvise64 = 233,
251 exit_group = 234,
252 lookup_dcookie = 235,
253 epoll_create = 236,
254 epoll_ctl = 237,
255 epoll_wait = 238,
256 remap_file_pages = 239,
257 timer_create = 240,
258 timer_settime = 241,
259 timer_gettime = 242,
260 timer_getoverrun = 243,
261 timer_delete = 244,
262 clock_settime = 245,
263 clock_gettime = 246,
264 clock_getres = 247,
265 clock_nanosleep = 248,
266 swapcontext = 249,
267 tgkill = 250,
268 utimes = 251,
269 statfs64 = 252,
270 fstatfs64 = 253,
271 fadvise64_64 = 254,
272 rtas = 255,
273 sys_debug_setcontext = 256,
274 migrate_pages = 258,
275 mbind = 259,
276 get_mempolicy = 260,
277 set_mempolicy = 261,
278 mq_open = 262,
279 mq_unlink = 263,
280 mq_timedsend = 264,
281 mq_timedreceive = 265,
282 mq_notify = 266,
283 mq_getsetattr = 267,
284 kexec_load = 268,
285 add_key = 269,
286 request_key = 270,
287 keyctl = 271,
288 waitid = 272,
289 ioprio_set = 273,
290 ioprio_get = 274,
291 inotify_init = 275,
292 inotify_add_watch = 276,
293 inotify_rm_watch = 277,
294 spu_run = 278,
295 spu_create = 279,
296 pselect6 = 280,
297 ppoll = 281,
298 unshare = 282,
299 splice = 283,
300 tee = 284,
301 vmsplice = 285,
302 openat = 286,
303 mkdirat = 287,
304 mknodat = 288,
305 fchownat = 289,
306 futimesat = 290,
307 fstatat64 = 291,
308 unlinkat = 292,
309 renameat = 293,
310 linkat = 294,
311 symlinkat = 295,
312 readlinkat = 296,
313 fchmodat = 297,
314 faccessat = 298,
315 get_robust_list = 299,
316 set_robust_list = 300,
317 move_pages = 301,
318 getcpu = 302,
319 epoll_pwait = 303,
320 utimensat = 304,
321 signalfd = 305,
322 timerfd_create = 306,
323 eventfd = 307,
324 sync_file_range2 = 308,
325 fallocate = 309,
326 subpage_prot = 310,
327 timerfd_settime = 311,
328 timerfd_gettime = 312,
329 signalfd4 = 313,
330 eventfd2 = 314,
331 epoll_create1 = 315,
332 dup3 = 316,
333 pipe2 = 317,
334 inotify_init1 = 318,
335 perf_event_open = 319,
336 preadv = 320,
337 pwritev = 321,
338 rt_tgsigqueueinfo = 322,
339 fanotify_init = 323,
340 fanotify_mark = 324,
341 prlimit64 = 325,
342 socket = 326,
343 bind = 327,
344 connect = 328,
345 listen = 329,
346 accept = 330,
347 getsockname = 331,
348 getpeername = 332,
349 socketpair = 333,
350 send = 334,
351 sendto = 335,
352 recv = 336,
353 recvfrom = 337,
354 shutdown = 338,
355 setsockopt = 339,
356 getsockopt = 340,
357 sendmsg = 341,
358 recvmsg = 342,
359 recvmmsg = 343,
360 accept4 = 344,
361 name_to_handle_at = 345,
362 open_by_handle_at = 346,
363 clock_adjtime = 347,
364 syncfs = 348,
365 sendmmsg = 349,
366 setns = 350,
367 process_vm_readv = 351,
368 process_vm_writev = 352,
369 finit_module = 353,
370 kcmp = 354,
371 sched_setattr = 355,
372 sched_getattr = 356,
373 renameat2 = 357,
374 seccomp = 358,
375 getrandom = 359,
376 memfd_create = 360,
377 bpf = 361,
378 execveat = 362,
379 switch_endian = 363,
380 userfaultfd = 364,
381 membarrier = 365,
382 mlock2 = 378,
383 copy_file_range = 379,
384 preadv2 = 380,
385 pwritev2 = 381,
386 kexec_file_load = 382,
387 statx = 383,
388 pkey_alloc = 384,
389 pkey_free = 385,
390 pkey_mprotect = 386,
391 rseq = 387,
392 io_pgetevents = 388,
393 semget = 393,
394 semctl = 394,
395 shmget = 395,
396 shmctl = 396,
397 shmat = 397,
398 shmdt = 398,
399 msgget = 399,
400 msgsnd = 400,
401 msgrcv = 401,
402 msgctl = 402,
403 clock_gettime64 = 403,
404 clock_settime64 = 404,
405 clock_adjtime64 = 405,
406 clock_getres_time64 = 406,
407 clock_nanosleep_time64 = 407,
408 timer_gettime64 = 408,
409 timer_settime64 = 409,
410 timerfd_gettime64 = 410,
411 timerfd_settime64 = 411,
412 utimensat_time64 = 412,
413 pselect6_time64 = 413,
414 ppoll_time64 = 414,
415 io_pgetevents_time64 = 416,
416 recvmmsg_time64 = 417,
417 mq_timedsend_time64 = 418,
418 mq_timedreceive_time64 = 419,
419 semtimedop_time64 = 420,
420 rt_sigtimedwait_time64 = 421,
421 futex_time64 = 422,
422 sched_rr_get_interval_time64 = 423,
423 pidfd_send_signal = 424,
424 io_uring_setup = 425,
425 io_uring_enter = 426,
426 io_uring_register = 427,
427 open_tree = 428,
428 move_mount = 429,
429 fsopen = 430,
430 fsconfig = 431,
431 fsmount = 432,
432 fspick = 433,
433 pidfd_open = 434,
434 clone3 = 435,
435 close_range = 436,
436 openat2 = 437,
437 pidfd_getfd = 438,
438 faccessat2 = 439,
439 process_madvise = 440,
440};
441
442pub const O_CREAT = 0o100;
443pub const O_EXCL = 0o200;
444pub const O_NOCTTY = 0o400;
445pub const O_TRUNC = 0o1000;
446pub const O_APPEND = 0o2000;
447pub const O_NONBLOCK = 0o4000;
448pub const O_DSYNC = 0o10000;
449pub const O_SYNC = 0o4010000;
450pub const O_RSYNC = 0o4010000;
451pub const O_DIRECTORY = 0o40000;
452pub const O_NOFOLLOW = 0o100000;
453pub const O_CLOEXEC = 0o2000000;
454
455pub const O_ASYNC = 0o20000;
456pub const O_DIRECT = 0o400000;
457pub const O_LARGEFILE = 0o200000;
458pub const O_NOATIME = 0o1000000;
459pub const O_PATH = 0o10000000;
460pub const O_TMPFILE = 0o20040000;
461pub const O_NDELAY = O_NONBLOCK;
462
463pub const F_DUPFD = 0;
464pub const F_GETFD = 1;
465pub const F_SETFD = 2;
466pub const F_GETFL = 3;
467pub const F_SETFL = 4;
468
469pub const F_SETOWN = 8;
470pub const F_GETOWN = 9;
471pub const F_SETSIG = 10;
472pub const F_GETSIG = 11;
473
474pub const F_GETLK = 12;
475pub const F_SETLK = 13;
476pub const F_SETLKW = 14;
477
478pub const F_SETOWN_EX = 15;
479pub const F_GETOWN_EX = 16;
480
481pub const F_GETOWNER_UIDS = 17;
482
483pub const F_RDLCK = 0;
484pub const F_WRLCK = 1;
485pub const F_UNLCK = 2;
486
487pub const LOCK_SH = 1;
488pub const LOCK_EX = 2;
489pub const LOCK_UN = 8;
490pub const LOCK_NB = 4;
491
492/// stack-like segment
493pub const MAP_GROWSDOWN = 0x0100;
494
495/// ETXTBSY
496pub const MAP_DENYWRITE = 0x0800;
497
498/// mark it as an executable
499pub const MAP_EXECUTABLE = 0x1000;
500
501/// pages are locked
502pub const MAP_LOCKED = 0x0080;
503
504/// don't check for reservations
505pub const MAP_NORESERVE = 0x0040;
506
507pub const VDSO_CGT_SYM = "__kernel_clock_gettime";
508pub const VDSO_CGT_VER = "LINUX_2.6.15";
509
510pub const Flock = extern struct {
511 l_type: i16,
512 l_whence: i16,
513 l_start: off_t,
514 l_len: off_t,
515 l_pid: pid_t,
516};
517
518pub const msghdr = extern struct {
519 msg_name: ?*sockaddr,
520 msg_namelen: socklen_t,
521 msg_iov: [*]iovec,
522 msg_iovlen: usize,
523 msg_control: ?*c_void,
524 msg_controllen: socklen_t,
525 msg_flags: i32,
526};
527
528pub const msghdr_const = extern struct {
529 msg_name: ?*const sockaddr,
530 msg_namelen: socklen_t,
531 msg_iov: [*]iovec_const,
532 msg_iovlen: usize,
533 msg_control: ?*c_void,
534 msg_controllen: socklen_t,
535 msg_flags: i32,
536};
537
538pub const blksize_t = i32;
539pub const nlink_t = u32;
540pub const time_t = isize;
541pub const mode_t = u32;
542pub const off_t = i64;
543pub const ino_t = u64;
544pub const dev_t = u64;
545pub const blkcnt_t = i64;
546
547// The `stat` definition used by the Linux kernel.
548pub const kernel_stat = extern struct {
549 dev: dev_t,
550 ino: ino_t,
551 mode: mode_t,
552 nlink: nlink_t,
553 uid: uid_t,
554 gid: gid_t,
555 rdev: dev_t,
556 __rdev_padding: i16,
557 size: off_t,
558 blksize: blksize_t,
559 blocks: blkcnt_t,
560 __atim32: timespec32,
561 __mtim32: timespec32,
562 __ctim32: timespec32,
563 __unused: [2]u32,
564 atim: timespec,
565 mtim: timespec,
566 ctim: timespec,
567
568 const timespec32 = extern struct {
569 tv_sec: i32,
570 tv_nsec: i32,
571 };
572
573 pub fn atime(self: @This()) timespec {
574 return self.atim;
575 }
576
577 pub fn mtime(self: @This()) timespec {
578 return self.mtim;
579 }
580
581 pub fn ctime(self: @This()) timespec {
582 return self.ctim;
583 }
584};
585
586// The `stat64` definition used by the libc.
587pub const libc_stat = kernel_stat;
588
589pub const timespec = extern struct {
590 tv_sec: time_t,
591 tv_nsec: isize,
592};
593
594pub const timeval = extern struct {
595 tv_sec: time_t,
596 tv_usec: isize,
597};
598
599pub const timezone = extern struct {
600 tz_minuteswest: i32,
601 tz_dsttime: i32,
602};
603
604pub const greg_t = u32;
605pub const gregset_t = [48]greg_t;
606pub const fpregset_t = [33]f64;
607
608pub const vrregset = extern struct {
609 vrregs: [32][4]u32,
610 vrsave: u32,
611 _pad: [2]u32,
612 vscr: u32,
613};
614pub const vrregset_t = vrregset;
615
616pub const mcontext_t = extern struct {
617 gp_regs: gregset_t,
618 fp_regs: fpregset_t,
619 v_regs: vrregset_t align(16),
620};
621
622pub const ucontext_t = extern struct {
623 flags: u32,
624 link: *ucontext_t,
625 stack: stack_t,
626 pad: [7]i32,
627 regs: *mcontext_t,
628 sigmask: sigset_t,
629 pad2: [3]i32,
630 mcontext: mcontext_t,
631};
632
633pub const Elf_Symndx = u32;
634
635pub const MMAP2_UNIT = 4096;
lib/std/os/linux.zig+1
......@@ -26,6 +26,7 @@ pub usingnamespace switch (builtin.arch) {
2626 .riscv64 => @import("linux/riscv64.zig"),
2727 .sparcv9 => @import("linux/sparc64.zig"),
2828 .mips, .mipsel => @import("linux/mips.zig"),
29 .powerpc => @import("linux/powerpc.zig"),
2930 .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"),
3031 else => struct {},
3132};
lib/std/os/linux/powerpc.zig created+133
......@@ -0,0 +1,133 @@
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2015-2021 Zig Contributors
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.
6
7usingnamespace @import("../bits.zig");
8
9pub fn syscall0(number: SYS) usize {
10 return asm volatile (
11 \\ sc
12 \\ bns+ 1f
13 \\ neg 3, 3
14 \\ 1:
15 : [ret] "={r3}" (-> usize)
16 : [number] "{r0}" (@enumToInt(number))
17 : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
18 );
19}
20
21pub fn syscall1(number: SYS, arg1: usize) usize {
22 return asm volatile (
23 \\ sc
24 \\ bns+ 1f
25 \\ neg 3, 3
26 \\ 1:
27 : [ret] "={r3}" (-> usize)
28 : [number] "{r0}" (@enumToInt(number)),
29 [arg1] "{r3}" (arg1)
30 : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
31 );
32}
33
34pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
35 return asm volatile (
36 \\ sc
37 \\ bns+ 1f
38 \\ neg 3, 3
39 \\ 1:
40 : [ret] "={r3}" (-> usize)
41 : [number] "{r0}" (@enumToInt(number)),
42 [arg1] "{r3}" (arg1),
43 [arg2] "{r4}" (arg2)
44 : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
45 );
46}
47
48pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
49 return asm volatile (
50 \\ sc
51 \\ bns+ 1f
52 \\ neg 3, 3
53 \\ 1:
54 : [ret] "={r3}" (-> usize)
55 : [number] "{r0}" (@enumToInt(number)),
56 [arg1] "{r3}" (arg1),
57 [arg2] "{r4}" (arg2),
58 [arg3] "{r5}" (arg3)
59 : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
60 );
61}
62
63pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
64 return asm volatile (
65 \\ sc
66 \\ bns+ 1f
67 \\ neg 3, 3
68 \\ 1:
69 : [ret] "={r3}" (-> usize)
70 : [number] "{r0}" (@enumToInt(number)),
71 [arg1] "{r3}" (arg1),
72 [arg2] "{r4}" (arg2),
73 [arg3] "{r5}" (arg3),
74 [arg4] "{r6}" (arg4)
75 : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
76 );
77}
78
79pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
80 return asm volatile (
81 \\ sc
82 \\ bns+ 1f
83 \\ neg 3, 3
84 \\ 1:
85 : [ret] "={r3}" (-> usize)
86 : [number] "{r0}" (@enumToInt(number)),
87 [arg1] "{r3}" (arg1),
88 [arg2] "{r4}" (arg2),
89 [arg3] "{r5}" (arg3),
90 [arg4] "{r6}" (arg4),
91 [arg5] "{r7}" (arg5)
92 : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
93 );
94}
95
96pub fn syscall6(
97 number: SYS,
98 arg1: usize,
99 arg2: usize,
100 arg3: usize,
101 arg4: usize,
102 arg5: usize,
103 arg6: usize,
104) usize {
105 return asm volatile (
106 \\ sc
107 \\ bns+ 1f
108 \\ neg 3, 3
109 \\ 1:
110 : [ret] "={r3}" (-> usize)
111 : [number] "{r0}" (@enumToInt(number)),
112 [arg1] "{r3}" (arg1),
113 [arg2] "{r4}" (arg2),
114 [arg3] "{r5}" (arg3),
115 [arg4] "{r6}" (arg4),
116 [arg5] "{r7}" (arg5),
117 [arg6] "{r8}" (arg6)
118 : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
119 );
120}
121
122/// This matches the libc clone function.
123pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
124
125pub const restore = restore_rt;
126
127pub fn restore_rt() callconv(.Naked) void {
128 return asm volatile ("sc"
129 :
130 : [number] "{r0}" (@enumToInt(SYS.rt_sigreturn))
131 : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
132 );
133}
lib/std/special/c.zig+65
......@@ -491,6 +491,71 @@ fn clone() callconv(.Naked) void {
491491 \\ syscall
492492 );
493493 },
494 .powerpc => {
495 // __clone(func, stack, flags, arg, ptid, tls, ctid)
496 // 3, 4, 5, 6, 7, 8, 9
497
498 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
499 // 0 3, 4, 5, 6, 7
500 asm volatile (
501 \\# store non-volatile regs r30, r31 on stack in order to put our
502 \\# start func and its arg there
503 \\stwu 30, -16(1)
504 \\stw 31, 4(1)
505 \\
506 \\# save r3 (func) into r30, and r6(arg) into r31
507 \\mr 30, 3
508 \\mr 31, 6
509 \\
510 \\# create initial stack frame for new thread
511 \\clrrwi 4, 4, 4
512 \\li 0, 0
513 \\stwu 0, -16(4)
514 \\
515 \\#move c into first arg
516 \\mr 3, 5
517 \\#mr 4, 4
518 \\mr 5, 7
519 \\mr 6, 8
520 \\mr 7, 9
521 \\
522 \\# move syscall number into r0
523 \\li 0, 120
524 \\
525 \\sc
526 \\
527 \\# check for syscall error
528 \\bns+ 1f # jump to label 1 if no summary overflow.
529 \\#else
530 \\neg 3, 3 #negate the result (errno)
531 \\1:
532 \\# compare sc result with 0
533 \\cmpwi cr7, 3, 0
534 \\
535 \\# if not 0, jump to end
536 \\bne cr7, 2f
537 \\
538 \\#else: we're the child
539 \\#call funcptr: move arg (d) into r3
540 \\mr 3, 31
541 \\#move r30 (funcptr) into CTR reg
542 \\mtctr 30
543 \\# call CTR reg
544 \\bctrl
545 \\# mov SYS_exit into r0 (the exit param is already in r3)
546 \\li 0, 1
547 \\sc
548 \\
549 \\2:
550 \\
551 \\# restore stack
552 \\lwz 30, 0(1)
553 \\lwz 31, 4(1)
554 \\addi 1, 1, 16
555 \\
556 \\blr
557 );
558 },
494559 .powerpc64, .powerpc64le => {
495560 // __clone(func, stack, flags, arg, ptid, tls, ctid)
496561 // 3, 4, 5, 6, 7, 8, 9
lib/std/start.zig+13
......@@ -197,6 +197,19 @@ fn _start() callconv(.Naked) noreturn {
197197 : [argc] "={sp}" (-> [*]usize)
198198 );
199199 },
200 .powerpc => {
201 // Setup the initial stack frame and clear the back chain pointer.
202 argc_argv_ptr = asm volatile (
203 \\ mr 4, 1
204 \\ li 0, 0
205 \\ stwu 1,-16(1)
206 \\ stw 0, 0(1)
207 \\ mtlr 0
208 : [argc] "={r4}" (-> [*]usize)
209 :
210 : "r0"
211 );
212 },
200213 .powerpc64le => {
201214 // Setup the initial stack frame and clear the back chain pointer.
202215 // TODO: Support powerpc64 (big endian) on ELFv2.