mailing list of musl libc
 help / color / mirror / code / Atom feed
* [PATCH v2] add powerpc64 port
@ 2016-04-04  5:26 Bobby Bingham
  2016-04-13 23:05 ` Szabolcs Nagy
  0 siblings, 1 reply; 14+ messages in thread
From: Bobby Bingham @ 2016-04-04  5:26 UTC (permalink / raw)
  To: musl

---
 arch/powerpc64/atomic_arch.h             |  63 +++
 arch/powerpc64/bits/alltypes.h.in        |  26 ++
 arch/powerpc64/bits/endian.h             |   5 +
 arch/powerpc64/bits/errno.h              | 134 ++++++
 arch/powerpc64/bits/fcntl.h              |  40 ++
 arch/powerpc64/bits/fenv.h               |  31 ++
 arch/powerpc64/bits/float.h              |  16 +
 arch/powerpc64/bits/ioctl.h              | 229 ++++++++++
 arch/powerpc64/bits/ipc.h                |  16 +
 arch/powerpc64/bits/limits.h             |   7 +
 arch/powerpc64/bits/mman.h               |   8 +
 arch/powerpc64/bits/msg.h                |  13 +
 arch/powerpc64/bits/posix.h              |   2 +
 arch/powerpc64/bits/reg.h                |   3 +
 arch/powerpc64/bits/sem.h                |  13 +
 arch/powerpc64/bits/setjmp.h             |   1 +
 arch/powerpc64/bits/shm.h                |  25 ++
 arch/powerpc64/bits/signal.h             | 108 +++++
 arch/powerpc64/bits/socket.h             |  62 +++
 arch/powerpc64/bits/stat.h               |  17 +
 arch/powerpc64/bits/stdint.h             |  20 +
 arch/powerpc64/bits/syscall.h            | 718 +++++++++++++++++++++++++++++++
 arch/powerpc64/bits/termios.h            | 170 ++++++++
 arch/powerpc64/bits/user.h               |  25 ++
 arch/powerpc64/crt_arch.h                |  19 +
 arch/powerpc64/pthread_arch.h            |  17 +
 arch/powerpc64/reloc.h                   |  32 ++
 arch/powerpc64/syscall_arch.h            |  87 ++++
 configure                                |   7 +-
 crt/powerpc64/crti.s                     |  21 +
 crt/powerpc64/crtn.s                     |  13 +
 src/fenv/powerpc64/fenv.c                |  68 +++
 src/internal/powerpc64/syscall.s         |  17 +
 src/ldso/powerpc64/dlsym.s               |  12 +
 src/setjmp/powerpc64/longjmp.S           |  98 +++++
 src/setjmp/powerpc64/setjmp.S            | 103 +++++
 src/signal/powerpc64/restore.s           |  11 +
 src/signal/powerpc64/sigsetjmp.s         |  30 ++
 src/thread/powerpc64/__set_thread_area.s |   8 +
 src/thread/powerpc64/__unmapself.s       |   9 +
 src/thread/powerpc64/clone.s             |  53 +++
 src/thread/powerpc64/syscall_cp.s        |  37 ++
 42 files changed, 2393 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc64/atomic_arch.h
 create mode 100644 arch/powerpc64/bits/alltypes.h.in
 create mode 100644 arch/powerpc64/bits/endian.h
 create mode 100644 arch/powerpc64/bits/errno.h
 create mode 100644 arch/powerpc64/bits/fcntl.h
 create mode 100644 arch/powerpc64/bits/fenv.h
 create mode 100644 arch/powerpc64/bits/float.h
 create mode 100644 arch/powerpc64/bits/ioctl.h
 create mode 100644 arch/powerpc64/bits/ipc.h
 create mode 100644 arch/powerpc64/bits/limits.h
 create mode 100644 arch/powerpc64/bits/mman.h
 create mode 100644 arch/powerpc64/bits/msg.h
 create mode 100644 arch/powerpc64/bits/posix.h
 create mode 100644 arch/powerpc64/bits/reg.h
 create mode 100644 arch/powerpc64/bits/sem.h
 create mode 100644 arch/powerpc64/bits/setjmp.h
 create mode 100644 arch/powerpc64/bits/shm.h
 create mode 100644 arch/powerpc64/bits/signal.h
 create mode 100644 arch/powerpc64/bits/socket.h
 create mode 100644 arch/powerpc64/bits/stat.h
 create mode 100644 arch/powerpc64/bits/stdint.h
 create mode 100644 arch/powerpc64/bits/syscall.h
 create mode 100644 arch/powerpc64/bits/termios.h
 create mode 100644 arch/powerpc64/bits/user.h
 create mode 100644 arch/powerpc64/crt_arch.h
 create mode 100644 arch/powerpc64/pthread_arch.h
 create mode 100644 arch/powerpc64/reloc.h
 create mode 100644 arch/powerpc64/syscall_arch.h
 create mode 100644 crt/powerpc64/crti.s
 create mode 100644 crt/powerpc64/crtn.s
 create mode 100644 src/fenv/powerpc64/fenv.c
 create mode 100644 src/internal/powerpc64/syscall.s
 create mode 100644 src/ldso/powerpc64/dlsym.s
 create mode 100644 src/setjmp/powerpc64/longjmp.S
 create mode 100644 src/setjmp/powerpc64/setjmp.S
 create mode 100644 src/signal/powerpc64/restore.s
 create mode 100644 src/signal/powerpc64/sigsetjmp.s
 create mode 100644 src/thread/powerpc64/__set_thread_area.s
 create mode 100644 src/thread/powerpc64/__unmapself.s
 create mode 100644 src/thread/powerpc64/clone.s
 create mode 100644 src/thread/powerpc64/syscall_cp.s

diff --git a/arch/powerpc64/atomic_arch.h b/arch/powerpc64/atomic_arch.h
new file mode 100644
index 0000000..269d79c
--- /dev/null
+++ b/arch/powerpc64/atomic_arch.h
@@ -0,0 +1,63 @@
+#define a_ll a_ll
+static inline int a_ll(volatile int *p)
+{
+	int v;
+	__asm__ __volatile__ ("lwarx %0, 0, %2" : "=r"(v) : "m"(*p), "r"(p));
+	return v;
+}
+
+#define a_sc a_sc
+static inline int a_sc(volatile int *p, int v)
+{
+	int r;
+	__asm__ __volatile__ (
+		"stwcx. %2, 0, %3 ; mfcr %0"
+		: "=r"(r), "=m"(*p) : "r"(v), "r"(p) : "memory", "cc");
+	return r & 0x20000000; /* "bit 2" of "cr0" (backwards bit order) */
+}
+
+#define a_ll_p a_ll_p
+static inline void *a_ll_p(volatile void *p)
+{
+	void *v;
+	__asm__ __volatile__ ("ldarx %0, 0, %2" : "=r"(v) : "m"(*(void *volatile *)p), "r"(p));
+	return v;
+}
+
+#define a_sc_p a_sc_p
+static inline int a_sc_p(volatile void *p, void *v)
+{
+	int r;
+	__asm__ __volatile__ (
+		"stdcx. %2, 0, %3 ; mfcr %0"
+		: "=r"(r), "=m"(*(void *volatile *)p) : "r"(v), "r"(p) : "memory", "cc");
+	return r & 0x20000000; /* "bit 2" of "cr0" (backwards bit order) */
+}
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__ ("sync" : : : "memory");
+}
+
+#define a_pre_llsc a_barrier
+
+#define a_post_llsc a_post_llsc
+static inline void a_post_llsc()
+{
+	__asm__ __volatile__ ("isync" : : : "memory");
+}
+
+#define a_store a_store
+static inline void a_store(volatile int *p, int v)
+{
+	a_pre_llsc();
+	*p = v;
+	a_post_llsc();
+}
+
+#define a_crash a_crash
+static inline void a_crash()
+{
+	__asm__ __volatile__ (".long 0");
+}
diff --git a/arch/powerpc64/bits/alltypes.h.in b/arch/powerpc64/bits/alltypes.h.in
new file mode 100644
index 0000000..5b20585
--- /dev/null
+++ b/arch/powerpc64/bits/alltypes.h.in
@@ -0,0 +1,26 @@
+#define _Addr long
+#define _Int64 long
+#define _Reg long
+
+TYPEDEF __builtin_va_list va_list;
+TYPEDEF __builtin_va_list __isoc_va_list;
+
+#ifndef __cplusplus
+TYPEDEF int wchar_t;
+#endif
+
+TYPEDEF float float_t;
+TYPEDEF double double_t;
+
+TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
+
+TYPEDEF long time_t;
+TYPEDEF long suseconds_t;
+
+TYPEDEF struct { union { int __i[14]; volatile int __vi[14]; unsigned long __s[7]; } __u; } pthread_attr_t;
+TYPEDEF struct { union { int __i[10]; volatile int __vi[10]; volatile void *volatile __p[5]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[10]; volatile int __vi[10]; volatile void *volatile __p[5]; } __u; } mtx_t;
+TYPEDEF struct { union { int __i[12]; volatile int __vi[12]; void *__p[6]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; volatile int __vi[12]; void *__p[6]; } __u; } cnd_t;
+TYPEDEF struct { union { int __i[14]; volatile int __vi[14]; void *__p[7]; } __u; } pthread_rwlock_t;
+TYPEDEF struct { union { int __i[8]; volatile int __vi[8]; void *__p[4]; } __u; } pthread_barrier_t;
diff --git a/arch/powerpc64/bits/endian.h b/arch/powerpc64/bits/endian.h
new file mode 100644
index 0000000..2016cb2
--- /dev/null
+++ b/arch/powerpc64/bits/endian.h
@@ -0,0 +1,5 @@
+#if __BIG_ENDIAN__
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
diff --git a/arch/powerpc64/bits/errno.h b/arch/powerpc64/bits/errno.h
new file mode 100644
index 0000000..36ad2f9
--- /dev/null
+++ b/arch/powerpc64/bits/errno.h
@@ -0,0 +1,134 @@
+#define EPERM            1
+#define ENOENT           2
+#define ESRCH            3
+#define EINTR            4
+#define EIO              5
+#define ENXIO            6
+#define E2BIG            7
+#define ENOEXEC          8
+#define EBADF            9
+#define ECHILD          10
+#define EAGAIN          11
+#define ENOMEM          12
+#define EACCES          13
+#define EFAULT          14
+#define ENOTBLK         15
+#define EBUSY           16
+#define EEXIST          17
+#define EXDEV           18
+#define ENODEV          19
+#define ENOTDIR         20
+#define EISDIR          21
+#define EINVAL          22
+#define ENFILE          23
+#define EMFILE          24
+#define ENOTTY          25
+#define ETXTBSY         26
+#define EFBIG           27
+#define ENOSPC          28
+#define ESPIPE          29
+#define EROFS           30
+#define EMLINK          31
+#define EPIPE           32
+#define EDOM            33
+#define ERANGE          34
+#define EDEADLK         35
+#define ENAMETOOLONG    36
+#define ENOLCK          37
+#define ENOSYS          38
+#define ENOTEMPTY       39
+#define ELOOP           40
+#define EWOULDBLOCK     EAGAIN
+#define ENOMSG          42
+#define EIDRM           43
+#define ECHRNG          44
+#define EL2NSYNC        45
+#define EL3HLT          46
+#define EL3RST          47
+#define ELNRNG          48
+#define EUNATCH         49
+#define ENOCSI          50
+#define EL2HLT          51
+#define EBADE           52
+#define EBADR           53
+#define EXFULL          54
+#define ENOANO          55
+#define EBADRQC         56
+#define EBADSLT         57
+#define EDEADLOCK       58 
+#define EBFONT          59
+#define ENOSTR          60
+#define ENODATA         61
+#define ETIME           62
+#define ENOSR           63
+#define ENONET          64
+#define ENOPKG          65
+#define EREMOTE         66
+#define ENOLINK         67
+#define EADV            68
+#define ESRMNT          69
+#define ECOMM           70
+#define EPROTO          71
+#define EMULTIHOP       72
+#define EDOTDOT         73
+#define EBADMSG         74
+#define EOVERFLOW       75
+#define ENOTUNIQ        76
+#define EBADFD          77
+#define EREMCHG         78
+#define ELIBACC         79
+#define ELIBBAD         80
+#define ELIBSCN         81
+#define ELIBMAX         82
+#define ELIBEXEC        83
+#define EILSEQ          84
+#define ERESTART        85
+#define ESTRPIPE        86
+#define EUSERS          87
+#define ENOTSOCK        88
+#define EDESTADDRREQ    89
+#define EMSGSIZE        90
+#define EPROTOTYPE      91
+#define ENOPROTOOPT     92
+#define EPROTONOSUPPORT 93
+#define ESOCKTNOSUPPORT 94
+#define EOPNOTSUPP      95
+#define ENOTSUP         EOPNOTSUPP
+#define EPFNOSUPPORT    96
+#define EAFNOSUPPORT    97
+#define EADDRINUSE      98
+#define EADDRNOTAVAIL   99
+#define ENETDOWN        100
+#define ENETUNREACH     101
+#define ENETRESET       102
+#define ECONNABORTED    103
+#define ECONNRESET      104
+#define ENOBUFS         105
+#define EISCONN         106
+#define ENOTCONN        107
+#define ESHUTDOWN       108
+#define ETOOMANYREFS    109
+#define ETIMEDOUT       110
+#define ECONNREFUSED    111
+#define EHOSTDOWN       112
+#define EHOSTUNREACH    113
+#define EALREADY        114
+#define EINPROGRESS     115
+#define ESTALE          116
+#define EUCLEAN         117
+#define ENOTNAM         118
+#define ENAVAIL         119
+#define EISNAM          120
+#define EREMOTEIO       121
+#define EDQUOT          122
+#define ENOMEDIUM       123
+#define EMEDIUMTYPE     124
+#define ECANCELED       125
+#define ENOKEY          126
+#define EKEYEXPIRED     127
+#define EKEYREVOKED     128
+#define EKEYREJECTED    129
+#define EOWNERDEAD      130
+#define ENOTRECOVERABLE 131
+#define ERFKILL         132
+#define EHWPOISON       133
diff --git a/arch/powerpc64/bits/fcntl.h b/arch/powerpc64/bits/fcntl.h
new file mode 100644
index 0000000..6f20bac
--- /dev/null
+++ b/arch/powerpc64/bits/fcntl.h
@@ -0,0 +1,40 @@
+#define O_CREAT        0100
+#define O_EXCL         0200
+#define O_NOCTTY       0400
+#define O_TRUNC       01000
+#define O_APPEND      02000
+#define O_NONBLOCK    04000
+#define O_DSYNC      010000
+#define O_SYNC     04010000
+#define O_RSYNC    04010000
+#define O_DIRECTORY  040000
+#define O_NOFOLLOW  0100000
+#define O_CLOEXEC  02000000
+
+#define O_ASYNC      020000
+#define O_DIRECT    0400000
+#define O_LARGEFILE 0200000
+#define O_NOATIME  01000000
+#define O_PATH    010000000
+#define O_TMPFILE 020040000
+#define O_NDELAY O_NONBLOCK
+
+#define F_DUPFD  0
+#define F_GETFD  1
+#define F_SETFD  2
+#define F_GETFL  3
+#define F_SETFL  4
+
+#define F_GETLK  5
+#define F_SETLK  6
+#define F_SETLKW 7
+
+#define F_SETOWN 8
+#define F_GETOWN 9
+#define F_SETSIG 10
+#define F_GETSIG 11
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+
+#define F_GETOWNER_UIDS 17
diff --git a/arch/powerpc64/bits/fenv.h b/arch/powerpc64/bits/fenv.h
new file mode 100644
index 0000000..4db4638
--- /dev/null
+++ b/arch/powerpc64/bits/fenv.h
@@ -0,0 +1,31 @@
+#define FE_TONEAREST	0
+#define FE_TOWARDZERO	1
+#define FE_UPWARD	2
+#define FE_DOWNWARD	3
+
+#define FE_INEXACT	0x02000000
+#define FE_DIVBYZERO	0x04000000
+#define FE_UNDERFLOW	0x08000000
+#define FE_OVERFLOW	0x10000000
+#define FE_INVALID	0x20000000
+
+#define FE_ALL_EXCEPT	0x3e000000
+
+#ifdef _GNU_SOURCE
+#define FE_INVALID_SNAN		0x01000000
+#define FE_INVALID_ISI		0x00800000
+#define FE_INVALID_IDI		0x00400000
+#define FE_INVALID_ZDZ		0x00200000
+#define FE_INVALID_IMZ		0x00100000
+#define FE_INVALID_COMPARE	0x00080000
+#define FE_INVALID_SOFTWARE	0x00000400
+#define FE_INVALID_SQRT		0x00000200
+#define FE_INVALID_INTEGER_CONVERSION	0x00000100
+
+#define FE_ALL_INVALID		0x01f80700
+#endif
+
+typedef unsigned long fexcept_t;
+typedef double fenv_t;
+
+#define FE_DFL_ENV ((const fenv_t *)-1)
diff --git a/arch/powerpc64/bits/float.h b/arch/powerpc64/bits/float.h
new file mode 100644
index 0000000..c4a655e
--- /dev/null
+++ b/arch/powerpc64/bits/float.h
@@ -0,0 +1,16 @@
+#define FLT_EVAL_METHOD 0
+
+#define LDBL_TRUE_MIN 4.94065645841246544177e-324L
+#define LDBL_MIN 2.22507385850720138309e-308L
+#define LDBL_MAX 1.79769313486231570815e+308L
+#define LDBL_EPSILON 2.22044604925031308085e-16L
+
+#define LDBL_MANT_DIG 53
+#define LDBL_MIN_EXP (-1021)
+#define LDBL_MAX_EXP 1024
+
+#define LDBL_DIG 15
+#define LDBL_MIN_10_EXP (-307)
+#define LDBL_MAX_10_EXP 308
+
+#define DECIMAL_DIG 17
diff --git a/arch/powerpc64/bits/ioctl.h b/arch/powerpc64/bits/ioctl.h
new file mode 100644
index 0000000..44a6cb6
--- /dev/null
+++ b/arch/powerpc64/bits/ioctl.h
@@ -0,0 +1,229 @@
+#define _IOC(a,b,c,d) ( ((a)<<29) | ((b)<<8) | (c) | ((d)<<16) )
+#define _IOC_NONE  1U
+#define _IOC_WRITE 4U
+#define _IOC_READ  2U
+
+#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
+#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
+#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
+#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
+
+#define FIONCLEX	_IO('f', 2)
+#define FIOCLEX		_IO('f', 1)
+#define FIOASYNC	_IOW('f', 125, int)
+#define FIONBIO		_IOW('f', 126, int)
+#define FIONREAD	_IOR('f', 127, int)
+#define TIOCINQ		FIONREAD
+#define FIOQSIZE	_IOR('f', 128, char[8])
+#define TIOCGETP	_IOR('t', 8, char[6])
+#define TIOCSETP	_IOW('t', 9, char[6])
+#define TIOCSETN	_IOW('t', 10, char[6])
+
+#define TIOCSETC	_IOW('t', 17, char[6])
+#define TIOCGETC	_IOR('t', 18, char[6])
+#define TCGETS		_IOR('t', 19, char[44])
+#define TCSETS		_IOW('t', 20, char[44])
+#define TCSETSW		_IOW('t', 21, char[44])
+#define TCSETSF		_IOW('t', 22, char[44])
+
+#define TCGETA		_IOR('t', 23, char[20])
+#define TCSETA		_IOW('t', 24, char[20])
+#define TCSETAW		_IOW('t', 25, char[20])
+#define TCSETAF		_IOW('t', 28, char[20])
+
+#define TCSBRK		_IO('t', 29)
+#define TCXONC		_IO('t', 30)
+#define TCFLSH		_IO('t', 31)
+
+#define TIOCSWINSZ	_IOW('t', 103, char[8])
+#define TIOCGWINSZ	_IOR('t', 104, char[8])
+#define TIOCSTART	_IO('t', 110)
+#define TIOCSTOP	_IO('t', 111)
+
+#define TIOCOUTQ	_IOR('t', 115, int)
+
+#define TIOCGLTC	_IOR('t', 116, char[6])
+#define TIOCSLTC	_IOW('t', 117, char[6])
+#define TIOCSPGRP	_IOW('t', 118, int)
+#define TIOCGPGRP	_IOR('t', 119, int)
+
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+
+#define TIOCSTI		0x5412
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT	0x5420
+#define TIOCPKT_DATA		0
+#define TIOCPKT_FLUSHREAD	1
+#define TIOCPKT_FLUSHWRITE	2
+#define TIOCPKT_STOP		4
+#define TIOCPKT_START		8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+#define TIOCPKT_IOCTL		64
+
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425
+#define TIOCSBRK	0x5427
+#define TIOCCBRK	0x5428
+#define TIOCGSID	0x5429
+#define TIOCGRS485	0x542e
+#define TIOCSRS485	0x542f
+#define TIOCGPTN	_IOR('T',0x30, unsigned int)
+#define TIOCSPTLCK	_IOW('T',0x31, int)
+#define TIOCGDEV	_IOR('T',0x32, unsigned int)
+#define TIOCSIG		_IOW('T',0x36, int)
+#define TIOCVHANGUP	0x5437
+#define TIOCGPKT	_IOR('T',0x38, int)
+#define TIOCGPTLCK	_IOR('T',0x39, int)
+#define TIOCGEXCL	_IOR('T',0x40, int)
+
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458
+#define TIOCSERGETLSR	0x5459
+#define TIOCSER_TEMT	0x01
+#define TIOCSERGETMULTI	0x545A
+#define TIOCSERSETMULTI	0x545B
+
+#define TIOCMIWAIT	0x545C
+#define TIOCGICOUNT	0x545D
+
+
+/* end kernel header ioctls.h */
+
+
+#define TIOCTTYGSTRUCT	0x5426
+
+#define TCGETX		0x5432
+#define TCSETX		0x5433
+#define TCSETXF		0x5434
+#define TCSETXW		0x5435
+
+#define TIOCGHAYESESP   0x545E
+#define TIOCSHAYESESP   0x545F
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define TIOCM_MODEM_BITS TIOCM_OUT2
+
+#define N_TTY           0
+#define N_SLIP          1
+#define N_MOUSE         2
+#define N_PPP           3
+#define N_STRIP         4
+#define N_AX25          5
+#define N_X25           6
+#define N_6PACK         7
+#define N_MASC          8
+#define N_R3964         9
+#define N_PROFIBUS_FDL  10
+#define N_IRDA          11
+#define N_SMSBLOCK      12
+#define N_HDLC          13
+#define N_SYNC_PPP      14
+#define N_HCI           15
+
+#define FIOSETOWN       0x8901
+#define SIOCSPGRP       0x8902
+#define FIOGETOWN       0x8903
+#define SIOCGPGRP       0x8904
+#define SIOCATMARK      0x8905
+#define SIOCGSTAMP      0x8906
+
+#define SIOCADDRT       0x890B
+#define SIOCDELRT       0x890C
+#define SIOCRTMSG       0x890D
+
+#define SIOCGIFNAME     0x8910
+#define SIOCSIFLINK     0x8911
+#define SIOCGIFCONF     0x8912
+#define SIOCGIFFLAGS    0x8913
+#define SIOCSIFFLAGS    0x8914
+#define SIOCGIFADDR     0x8915
+#define SIOCSIFADDR     0x8916
+#define SIOCGIFDSTADDR  0x8917
+#define SIOCSIFDSTADDR  0x8918
+#define SIOCGIFBRDADDR  0x8919
+#define SIOCSIFBRDADDR  0x891a
+#define SIOCGIFNETMASK  0x891b
+#define SIOCSIFNETMASK  0x891c
+#define SIOCGIFMETRIC   0x891d
+#define SIOCSIFMETRIC   0x891e
+#define SIOCGIFMEM      0x891f
+#define SIOCSIFMEM      0x8920
+#define SIOCGIFMTU      0x8921
+#define SIOCSIFMTU      0x8922
+#define SIOCSIFHWADDR   0x8924
+#define SIOCGIFENCAP    0x8925
+#define SIOCSIFENCAP    0x8926
+#define SIOCGIFHWADDR   0x8927
+#define SIOCGIFSLAVE    0x8929
+#define SIOCSIFSLAVE    0x8930
+#define SIOCADDMULTI    0x8931
+#define SIOCDELMULTI    0x8932
+#define SIOCGIFINDEX    0x8933
+#define SIOGIFINDEX     SIOCGIFINDEX
+#define SIOCSIFPFLAGS   0x8934
+#define SIOCGIFPFLAGS   0x8935
+#define SIOCDIFADDR     0x8936
+#define SIOCSIFHWBROADCAST 0x8937
+#define SIOCGIFCOUNT    0x8938
+
+#define SIOCGIFBR       0x8940
+#define SIOCSIFBR       0x8941
+
+#define SIOCGIFTXQLEN   0x8942
+#define SIOCSIFTXQLEN   0x8943
+
+#define SIOCDARP        0x8953
+#define SIOCGARP        0x8954
+#define SIOCSARP        0x8955
+
+#define SIOCDRARP       0x8960
+#define SIOCGRARP       0x8961
+#define SIOCSRARP       0x8962
+
+#define SIOCGIFMAP      0x8970
+#define SIOCSIFMAP      0x8971
+
+#define SIOCADDDLCI     0x8980
+#define SIOCDELDLCI     0x8981
+
+#define SIOCDEVPRIVATE		0x89F0
+#define SIOCPROTOPRIVATE	0x89E0
diff --git a/arch/powerpc64/bits/ipc.h b/arch/powerpc64/bits/ipc.h
new file mode 100644
index 0000000..e1bfe2f
--- /dev/null
+++ b/arch/powerpc64/bits/ipc.h
@@ -0,0 +1,16 @@
+struct ipc_perm
+{
+	key_t __ipc_perm_key;
+	uid_t uid;
+	gid_t gid;
+	uid_t cuid;
+	gid_t cgid;
+	mode_t mode;
+	int __ipc_perm_seq;
+	int __pad1;
+	long long __pad2;
+	long long __pad3;
+};
+
+#define IPC_64 0x100
+
diff --git a/arch/powerpc64/bits/limits.h b/arch/powerpc64/bits/limits.h
new file mode 100644
index 0000000..0226588
--- /dev/null
+++ b/arch/powerpc64/bits/limits.h
@@ -0,0 +1,7 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define LONG_BIT 64
+#endif
+
+#define LONG_MAX  0x7fffffffffffffffL
+#define LLONG_MAX  0x7fffffffffffffffLL
diff --git a/arch/powerpc64/bits/mman.h b/arch/powerpc64/bits/mman.h
new file mode 100644
index 0000000..f5974f8
--- /dev/null
+++ b/arch/powerpc64/bits/mman.h
@@ -0,0 +1,8 @@
+#define PROT_SAO       0x10
+
+#undef MCL_CURRENT
+#define MCL_CURRENT     0x2000
+#undef MCL_FUTURE
+#define MCL_FUTURE      0x4000
+#undef MCL_ONFAULT
+#define MCL_ONFAULT     0x8000
diff --git a/arch/powerpc64/bits/msg.h b/arch/powerpc64/bits/msg.h
new file mode 100644
index 0000000..badcf16
--- /dev/null
+++ b/arch/powerpc64/bits/msg.h
@@ -0,0 +1,13 @@
+struct msqid_ds
+{
+	struct ipc_perm msg_perm;
+	time_t msg_stime;
+	time_t msg_rtime;
+	time_t msg_ctime;
+	unsigned long msg_cbytes;
+	msgqnum_t msg_qnum;
+	msglen_t msg_qbytes;
+	pid_t msg_lspid;
+	pid_t msg_lrpid;
+	unsigned long __unused[2];
+};
diff --git a/arch/powerpc64/bits/posix.h b/arch/powerpc64/bits/posix.h
new file mode 100644
index 0000000..c37b94c
--- /dev/null
+++ b/arch/powerpc64/bits/posix.h
@@ -0,0 +1,2 @@
+#define _POSIX_V6_LP64_OFF64  1
+#define _POSIX_V7_LP64_OFF64  1
diff --git a/arch/powerpc64/bits/reg.h b/arch/powerpc64/bits/reg.h
new file mode 100644
index 0000000..49382c8
--- /dev/null
+++ b/arch/powerpc64/bits/reg.h
@@ -0,0 +1,3 @@
+#undef __WORDSIZE
+#define __WORDSIZE 64
+/* FIXME */
diff --git a/arch/powerpc64/bits/sem.h b/arch/powerpc64/bits/sem.h
new file mode 100644
index 0000000..558184d
--- /dev/null
+++ b/arch/powerpc64/bits/sem.h
@@ -0,0 +1,13 @@
+#include <endian.h>
+
+struct semid_ds {
+	struct ipc_perm sem_perm;
+	time_t sem_otime;
+	time_t sem_ctime;
+#if __BYTE_ORDER == __BIG_ENDIAN
+	unsigned short __pad[3], sem_nsems;
+#else
+	unsigned short sem_nsems, __pad[3];
+#endif
+	unsigned long __unused[2];
+};
diff --git a/arch/powerpc64/bits/setjmp.h b/arch/powerpc64/bits/setjmp.h
new file mode 100644
index 0000000..589b675
--- /dev/null
+++ b/arch/powerpc64/bits/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long long __jmp_buf[66];
diff --git a/arch/powerpc64/bits/shm.h b/arch/powerpc64/bits/shm.h
new file mode 100644
index 0000000..9126851
--- /dev/null
+++ b/arch/powerpc64/bits/shm.h
@@ -0,0 +1,25 @@
+#define SHMLBA 4096
+
+struct shmid_ds
+{
+	struct ipc_perm shm_perm;
+	time_t shm_atime;
+	time_t shm_dtime;
+	time_t shm_ctime;
+	size_t shm_segsz;
+	pid_t shm_cpid;
+	pid_t shm_lpid;
+	unsigned long shm_nattch;
+	unsigned long __unused[2];
+};
+
+struct shminfo {
+	unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
+};
+
+struct shm_info {
+	int __used_ids;
+	unsigned long shm_tot, shm_rss, shm_swp;
+	unsigned long __swap_attempts, __swap_successes;
+};
+
diff --git a/arch/powerpc64/bits/signal.h b/arch/powerpc64/bits/signal.h
new file mode 100644
index 0000000..2a48508
--- /dev/null
+++ b/arch/powerpc64/bits/signal.h
@@ -0,0 +1,108 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ    8192
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+typedef unsigned long greg_t, gregset_t[48];
+
+typedef struct {
+	double fpregs[32];
+	double fpscr;
+} fpregset_t;
+
+typedef struct {
+	unsigned long vrregs[32][2];
+	unsigned _pad[3];
+	unsigned vrsave;
+	unsigned vscr;
+	unsigned _pad2[3];
+} vrregset_t;
+
+typedef struct sigcontext
+{
+	unsigned long _unused[4];
+	int signal;
+	int _pad0;
+	unsigned long handler;
+	unsigned long oldmask;
+	void *regs;
+	gregset_t gp_regs;
+	fpregset_t fp_regs;
+	vrregset_t *v_regs;
+	long vmx_reserve[34+34+32+1];
+} mcontext_t;
+
+#else
+
+typedef struct {
+	long __regs[4+4+48+33+1+34+34+32+1];
+} mcontext_t;
+
+#endif
+
+struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+};
+
+typedef struct __ucontext {
+	unsigned long uc_flags;
+	struct __ucontext *uc_link;
+	stack_t uc_stack;
+	sigset_t uc_sigmask;
+	mcontext_t uc_mcontext;
+} ucontext_t;
+
+#define SA_NOCLDSTOP  1U
+#define SA_NOCLDWAIT  2U
+#define SA_SIGINFO    4U
+#define SA_ONSTACK    0x08000000U
+#define SA_RESTART    0x10000000U
+#define SA_NODEFER    0x40000000U
+#define SA_RESETHAND  0x80000000U
+#define SA_RESTORER   0x04000000U
+
+#endif
+
+#define SIGHUP    1
+#define SIGINT    2
+#define SIGQUIT   3
+#define SIGILL    4
+#define SIGTRAP   5
+#define SIGABRT   6
+#define SIGIOT    SIGABRT
+#define SIGBUS    7
+#define SIGFPE    8
+#define SIGKILL   9
+#define SIGUSR1   10
+#define SIGSEGV   11
+#define SIGUSR2   12
+#define SIGPIPE   13
+#define SIGALRM   14
+#define SIGTERM   15
+#define SIGSTKFLT 16
+#define SIGCHLD   17
+#define SIGCONT   18
+#define SIGSTOP   19
+#define SIGTSTP   20
+#define SIGTTIN   21
+#define SIGTTOU   22
+#define SIGURG    23
+#define SIGXCPU   24
+#define SIGXFSZ   25
+#define SIGVTALRM 26
+#define SIGPROF   27
+#define SIGWINCH  28
+#define SIGIO     29
+#define SIGPOLL   SIGIO
+#define SIGPWR    30
+#define SIGSYS    31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
diff --git a/arch/powerpc64/bits/socket.h b/arch/powerpc64/bits/socket.h
new file mode 100644
index 0000000..ec3590c
--- /dev/null
+++ b/arch/powerpc64/bits/socket.h
@@ -0,0 +1,62 @@
+#include <endian.h>
+
+struct msghdr
+{
+	void *msg_name;
+	socklen_t msg_namelen;
+	struct iovec *msg_iov;
+#if __BYTE_ORDER == __BIG_ENDIAN
+	int __pad1, msg_iovlen;
+#else
+	int msg_iovlen, __pad1;
+#endif
+	void *msg_control;
+#if __BYTE_ORDER == __BIG_ENDIAN
+	int __pad2;
+	socklen_t msg_controllen;
+#else
+	socklen_t msg_controllen;
+	int __pad2;
+#endif
+	int msg_flags;
+};
+
+struct cmsghdr
+{
+#if __BYTE_ORDER == __BIG_ENDIAN
+	int __pad1;
+	socklen_t cmsg_len;
+#else
+	socklen_t cmsg_len;
+	int __pad1;
+#endif
+	int cmsg_level;
+	int cmsg_type;
+};
+
+#define SO_DEBUG        1
+#define SO_REUSEADDR    2
+#define SO_TYPE         3
+#define SO_ERROR        4
+#define SO_DONTROUTE    5
+#define SO_BROADCAST    6
+#define SO_SNDBUF       7
+#define SO_RCVBUF       8
+#define SO_KEEPALIVE    9
+#define SO_OOBINLINE    10
+#define SO_NO_CHECK     11
+#define SO_PRIORITY     12
+#define SO_LINGER       13
+#define SO_BSDCOMPAT    14
+#define SO_REUSEPORT    15
+#define SO_RCVLOWAT     16
+#define SO_SNDLOWAT     17
+#define SO_RCVTIMEO     18
+#define SO_SNDTIMEO     19
+#define SO_PASSCRED     20
+#define SO_PEERCRED     21
+#define SO_ACCEPTCONN   30
+#define SO_SNDBUFFORCE  32
+#define SO_RCVBUFFORCE  33
+#define SO_PROTOCOL     38
+#define SO_DOMAIN       39
diff --git a/arch/powerpc64/bits/stat.h b/arch/powerpc64/bits/stat.h
new file mode 100644
index 0000000..8172cff
--- /dev/null
+++ b/arch/powerpc64/bits/stat.h
@@ -0,0 +1,17 @@
+struct stat
+{
+	dev_t st_dev;
+	ino_t st_ino;
+	nlink_t st_nlink;
+	mode_t st_mode;
+	uid_t st_uid;
+	gid_t st_gid;
+	dev_t st_rdev;
+	off_t st_size;
+	blksize_t st_blksize;
+	blkcnt_t st_blocks;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	unsigned long __unused[3];
+};
diff --git a/arch/powerpc64/bits/stdint.h b/arch/powerpc64/bits/stdint.h
new file mode 100644
index 0000000..1bb147f
--- /dev/null
+++ b/arch/powerpc64/bits/stdint.h
@@ -0,0 +1,20 @@
+typedef int32_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef uint32_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+
+#define INT_FAST16_MIN  INT32_MIN
+#define INT_FAST32_MIN  INT32_MIN
+
+#define INT_FAST16_MAX  INT32_MAX
+#define INT_FAST32_MAX  INT32_MAX
+
+#define UINT_FAST16_MAX UINT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INTPTR_MIN      INT64_MIN
+#define INTPTR_MAX      INT64_MAX
+#define UINTPTR_MAX     UINT64_MAX
+#define PTRDIFF_MIN     INT64_MIN
+#define PTRDIFF_MAX     INT64_MAX
+#define SIZE_MAX        UINT64_MAX
diff --git a/arch/powerpc64/bits/syscall.h b/arch/powerpc64/bits/syscall.h
new file mode 100644
index 0000000..bf0161d
--- /dev/null
+++ b/arch/powerpc64/bits/syscall.h
@@ -0,0 +1,718 @@
+#define __NR_restart_syscall          0
+#define __NR_exit                     1
+#define __NR_fork                     2
+#define __NR_read                     3
+#define __NR_write                    4
+#define __NR_open                     5
+#define __NR_close                    6
+#define __NR_waitpid                  7
+#define __NR_creat                    8
+#define __NR_link                     9
+#define __NR_unlink                  10
+#define __NR_execve                  11
+#define __NR_chdir                   12
+#define __NR_time                    13
+#define __NR_mknod                   14
+#define __NR_chmod                   15
+#define __NR_lchown                  16
+#define __NR_break                   17
+#define __NR_oldstat                 18
+#define __NR_lseek                   19
+#define __NR_getpid                  20
+#define __NR_mount                   21
+#define __NR_umount                  22
+#define __NR_setuid                  23
+#define __NR_getuid                  24
+#define __NR_stime                   25
+#define __NR_ptrace                  26
+#define __NR_alarm                   27
+#define __NR_oldfstat                28
+#define __NR_pause                   29
+#define __NR_utime                   30
+#define __NR_stty                    31
+#define __NR_gtty                    32
+#define __NR_access                  33
+#define __NR_nice                    34
+#define __NR_ftime                   35
+#define __NR_sync                    36
+#define __NR_kill                    37
+#define __NR_rename                  38
+#define __NR_mkdir                   39
+#define __NR_rmdir                   40
+#define __NR_dup                     41
+#define __NR_pipe                    42
+#define __NR_times                   43
+#define __NR_prof                    44
+#define __NR_brk                     45
+#define __NR_setgid                  46
+#define __NR_getgid                  47
+#define __NR_signal                  48
+#define __NR_geteuid                 49
+#define __NR_getegid                 50
+#define __NR_acct                    51
+#define __NR_umount2                 52
+#define __NR_lock                    53
+#define __NR_ioctl                   54
+#define __NR_fcntl                   55
+#define __NR_mpx                     56
+#define __NR_setpgid                 57
+#define __NR_ulimit                  58
+#define __NR_oldolduname             59
+#define __NR_umask                   60
+#define __NR_chroot                  61
+#define __NR_ustat                   62
+#define __NR_dup2                    63
+#define __NR_getppid                 64
+#define __NR_getpgrp                 65
+#define __NR_setsid                  66
+#define __NR_sigaction               67
+#define __NR_sgetmask                68
+#define __NR_ssetmask                69
+#define __NR_setreuid                70
+#define __NR_setregid                71
+#define __NR_sigsuspend              72
+#define __NR_sigpending              73
+#define __NR_sethostname             74
+#define __NR_setrlimit               75
+#define __NR_getrlimit               76
+#define __NR_getrusage               77
+#define __NR_gettimeofday            78
+#define __NR_settimeofday            79
+#define __NR_getgroups               80
+#define __NR_setgroups               81
+#define __NR_select                  82
+#define __NR_symlink                 83
+#define __NR_oldlstat                84
+#define __NR_readlink                85
+#define __NR_uselib                  86
+#define __NR_swapon                  87
+#define __NR_reboot                  88
+#define __NR_readdir                 89
+#define __NR_mmap                    90
+#define __NR_munmap                  91
+#define __NR_truncate                92
+#define __NR_ftruncate               93
+#define __NR_fchmod                  94
+#define __NR_fchown                  95
+#define __NR_getpriority             96
+#define __NR_setpriority             97
+#define __NR_profil                  98
+#define __NR_statfs                  99
+#define __NR_fstatfs                100
+#define __NR_ioperm                 101
+#define __NR_socketcall             102
+#define __NR_syslog                 103
+#define __NR_setitimer              104
+#define __NR_getitimer              105
+#define __NR_stat                   106
+#define __NR_lstat                  107
+#define __NR_fstat                  108
+#define __NR_olduname               109
+#define __NR_iopl                   110
+#define __NR_vhangup                111
+#define __NR_idle                   112
+#define __NR_vm86                   113
+#define __NR_wait4                  114
+#define __NR_swapoff                115
+#define __NR_sysinfo                116
+#define __NR_ipc                    117
+#define __NR_fsync                  118
+#define __NR_sigreturn              119
+#define __NR_clone                  120
+#define __NR_setdomainname          121
+#define __NR_uname                  122
+#define __NR_modify_ldt             123
+#define __NR_adjtimex               124
+#define __NR_mprotect               125
+#define __NR_sigprocmask            126
+#define __NR_create_module          127
+#define __NR_init_module            128
+#define __NR_delete_module          129
+#define __NR_get_kernel_syms        130
+#define __NR_quotactl               131
+#define __NR_getpgid                132
+#define __NR_fchdir                 133
+#define __NR_bdflush                134
+#define __NR_sysfs                  135
+#define __NR_personality            136
+#define __NR_afs_syscall            137
+#define __NR_setfsuid               138
+#define __NR_setfsgid               139
+#define __NR__llseek                140
+#define __NR_getdents               141
+#define __NR__newselect             142
+#define __NR_flock                  143
+#define __NR_msync                  144
+#define __NR_readv                  145
+#define __NR_writev                 146
+#define __NR_getsid                 147
+#define __NR_fdatasync              148
+#define __NR__sysctl                149
+#define __NR_mlock                  150
+#define __NR_munlock                151
+#define __NR_mlockall               152
+#define __NR_munlockall             153
+#define __NR_sched_setparam         154
+#define __NR_sched_getparam         155
+#define __NR_sched_setscheduler     156
+#define __NR_sched_getscheduler     157
+#define __NR_sched_yield            158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval  161
+#define __NR_nanosleep              162
+#define __NR_mremap                 163
+#define __NR_setresuid              164
+#define __NR_getresuid              165
+#define __NR_query_module           166
+#define __NR_poll                   167
+#define __NR_nfsservctl             168
+#define __NR_setresgid              169
+#define __NR_getresgid              170
+#define __NR_prctl                  171
+#define __NR_rt_sigreturn           172
+#define __NR_rt_sigaction           173
+#define __NR_rt_sigprocmask         174
+#define __NR_rt_sigpending          175
+#define __NR_rt_sigtimedwait        176
+#define __NR_rt_sigqueueinfo        177
+#define __NR_rt_sigsuspend          178
+#define __NR_pread64                179
+#define __NR_pwrite64               180
+#define __NR_chown                  181
+#define __NR_getcwd                 182
+#define __NR_capget                 183
+#define __NR_capset                 184
+#define __NR_sigaltstack            185
+#define __NR_sendfile               186
+#define __NR_getpmsg                187
+#define __NR_putpmsg                188
+#define __NR_vfork                  189
+#define __NR_ugetrlimit             190
+#define __NR_readahead              191
+#define __NR_pciconfig_read         198
+#define __NR_pciconfig_write        199
+#define __NR_pciconfig_iobase       200
+#define __NR_multiplexer            201
+#define __NR_getdents64             202
+#define __NR_pivot_root             203
+#define __NR_madvise                205
+#define __NR_mincore                206
+#define __NR_gettid                 207
+#define __NR_tkill                  208
+#define __NR_setxattr               209
+#define __NR_lsetxattr              210
+#define __NR_fsetxattr              211
+#define __NR_getxattr               212
+#define __NR_lgetxattr              213
+#define __NR_fgetxattr              214
+#define __NR_listxattr              215
+#define __NR_llistxattr             216
+#define __NR_flistxattr             217
+#define __NR_removexattr            218
+#define __NR_lremovexattr           219
+#define __NR_fremovexattr           220
+#define __NR_futex                  221
+#define __NR_sched_setaffinity      222
+#define __NR_sched_getaffinity      223
+#define __NR_tuxcall                225
+#define __NR_io_setup               227
+#define __NR_io_destroy             228
+#define __NR_io_getevents           229
+#define __NR_io_submit              230
+#define __NR_io_cancel              231
+#define __NR_set_tid_address        232
+#define __NR_fadvise64              233
+#define __NR_exit_group             234
+#define __NR_lookup_dcookie         235
+#define __NR_epoll_create           236
+#define __NR_epoll_ctl              237
+#define __NR_epoll_wait             238
+#define __NR_remap_file_pages       239
+#define __NR_timer_create           240
+#define __NR_timer_settime          241
+#define __NR_timer_gettime          242
+#define __NR_timer_getoverrun       243
+#define __NR_timer_delete           244
+#define __NR_clock_settime          245
+#define __NR_clock_gettime          246
+#define __NR_clock_getres           247
+#define __NR_clock_nanosleep        248
+#define __NR_swapcontext            249
+#define __NR_tgkill                 250
+#define __NR_utimes                 251
+#define __NR_statfs64               252
+#define __NR_fstatfs64              253
+#define __NR_rtas                   255
+#define __NR_sys_debug_setcontext   256
+#define __NR_migrate_pages          258
+#define __NR_mbind                  259
+#define __NR_get_mempolicy          260
+#define __NR_set_mempolicy          261
+#define __NR_mq_open                262
+#define __NR_mq_unlink              263
+#define __NR_mq_timedsend           264
+#define __NR_mq_timedreceive        265
+#define __NR_mq_notify              266
+#define __NR_mq_getsetattr          267
+#define __NR_kexec_load             268
+#define __NR_add_key                269
+#define __NR_request_key            270
+#define __NR_keyctl                 271
+#define __NR_waitid                 272
+#define __NR_ioprio_set             273
+#define __NR_ioprio_get             274
+#define __NR_inotify_init           275
+#define __NR_inotify_add_watch      276
+#define __NR_inotify_rm_watch       277
+#define __NR_spu_run                278
+#define __NR_spu_create             279
+#define __NR_pselect6               280
+#define __NR_ppoll                  281
+#define __NR_unshare                282
+#define __NR_splice                 283
+#define __NR_tee                    284
+#define __NR_vmsplice               285
+#define __NR_openat                 286
+#define __NR_mkdirat                287
+#define __NR_mknodat                288
+#define __NR_fchownat               289
+#define __NR_futimesat              290
+#define __NR_newfstatat             291
+#define __NR_unlinkat               292
+#define __NR_renameat               293
+#define __NR_linkat                 294
+#define __NR_symlinkat              295
+#define __NR_readlinkat             296
+#define __NR_fchmodat               297
+#define __NR_faccessat              298
+#define __NR_get_robust_list        299
+#define __NR_set_robust_list        300
+#define __NR_move_pages             301
+#define __NR_getcpu                 302
+#define __NR_epoll_pwait            303
+#define __NR_utimensat              304
+#define __NR_signalfd               305
+#define __NR_timerfd_create         306
+#define __NR_eventfd                307
+#define __NR_sync_file_range2       308
+#define __NR_fallocate              309
+#define __NR_subpage_prot           310
+#define __NR_timerfd_settime        311
+#define __NR_timerfd_gettime        312
+#define __NR_signalfd4              313
+#define __NR_eventfd2               314
+#define __NR_epoll_create1          315
+#define __NR_dup3                   316
+#define __NR_pipe2                  317
+#define __NR_inotify_init1          318
+#define __NR_perf_event_open        319
+#define __NR_preadv                 320
+#define __NR_pwritev                321
+#define __NR_rt_tgsigqueueinfo      322
+#define __NR_fanotify_init          323
+#define __NR_fanotify_mark          324
+#define __NR_prlimit64              325
+#define __NR_socket                 326
+#define __NR_bind                   327
+#define __NR_connect                328
+#define __NR_listen                 329
+#define __NR_accept                 330
+#define __NR_getsockname            331
+#define __NR_getpeername            332
+#define __NR_socketpair             333
+#define __NR_send                   334
+#define __NR_sendto                 335
+#define __NR_recv                   336
+#define __NR_recvfrom               337
+#define __NR_shutdown               338
+#define __NR_setsockopt             339
+#define __NR_getsockopt             340
+#define __NR_sendmsg                341
+#define __NR_recvmsg                342
+#define __NR_recvmmsg               343
+#define __NR_accept4                344
+#define __NR_name_to_handle_at      345
+#define __NR_open_by_handle_at      346
+#define __NR_clock_adjtime          347
+#define __NR_syncfs                 348
+#define __NR_sendmmsg               349
+#define __NR_setns                  350
+#define __NR_process_vm_readv       351
+#define __NR_process_vm_writev      352
+#define __NR_finit_module           353
+#define __NR_kcmp                   354
+#define __NR_sched_setattr          355
+#define __NR_sched_getattr          356
+#define __NR_renameat2              357
+#define __NR_seccomp                358
+#define __NR_getrandom              359
+#define __NR_memfd_create           360
+#define __NR_bpf                    361
+#define __NR_execveat               362
+#define __NR_switch_endian          363
+#define __NR_userfaultfd            364
+#define __NR_membarrier             365
+#define __NR_mlock2                 378
+#define __NR_copy_file_range        379
+
+/*
+ * repeated with SYS prefix
+ */
+#define SYS_restart_syscall __NR_restart_syscall
+#define SYS_exit __NR_exit
+#define SYS_fork __NR_fork
+#define SYS_read __NR_read
+#define SYS_write __NR_write
+#define SYS_open __NR_open
+#define SYS_close __NR_close
+#define SYS_waitpid __NR_waitpid
+#define SYS_creat __NR_creat
+#define SYS_link __NR_link
+#define SYS_unlink __NR_unlink
+#define SYS_execve __NR_execve
+#define SYS_chdir __NR_chdir
+#define SYS_time __NR_time
+#define SYS_mknod __NR_mknod
+#define SYS_chmod __NR_chmod
+#define SYS_lchown __NR_lchown
+#define SYS_break __NR_break
+#define SYS_oldstat __NR_oldstat
+#define SYS_lseek __NR_lseek
+#define SYS_getpid __NR_getpid
+#define SYS_mount __NR_mount
+#define SYS_umount __NR_umount
+#define SYS_setuid __NR_setuid
+#define SYS_getuid __NR_getuid
+#define SYS_stime __NR_stime
+#define SYS_ptrace __NR_ptrace
+#define SYS_alarm __NR_alarm
+#define SYS_oldfstat __NR_oldfstat
+#define SYS_pause __NR_pause
+#define SYS_utime __NR_utime
+#define SYS_stty __NR_stty
+#define SYS_gtty __NR_gtty
+#define SYS_access __NR_access
+#define SYS_nice __NR_nice
+#define SYS_ftime __NR_ftime
+#define SYS_sync __NR_sync
+#define SYS_kill __NR_kill
+#define SYS_rename __NR_rename
+#define SYS_mkdir __NR_mkdir
+#define SYS_rmdir __NR_rmdir
+#define SYS_dup __NR_dup
+#define SYS_pipe __NR_pipe
+#define SYS_times __NR_times
+#define SYS_prof __NR_prof
+#define SYS_brk __NR_brk
+#define SYS_setgid __NR_setgid
+#define SYS_getgid __NR_getgid
+#define SYS_signal __NR_signal
+#define SYS_geteuid __NR_geteuid
+#define SYS_getegid __NR_getegid
+#define SYS_acct __NR_acct
+#define SYS_umount2 __NR_umount2
+#define SYS_lock __NR_lock
+#define SYS_ioctl __NR_ioctl
+#define SYS_fcntl __NR_fcntl
+#define SYS_mpx __NR_mpx
+#define SYS_setpgid __NR_setpgid
+#define SYS_ulimit __NR_ulimit
+#define SYS_oldolduname __NR_oldolduname
+#define SYS_umask __NR_umask
+#define SYS_chroot __NR_chroot
+#define SYS_ustat __NR_ustat
+#define SYS_dup2 __NR_dup2
+#define SYS_getppid __NR_getppid
+#define SYS_getpgrp __NR_getpgrp
+#define SYS_setsid __NR_setsid
+#define SYS_sigaction __NR_sigaction
+#define SYS_sgetmask __NR_sgetmask
+#define SYS_ssetmask __NR_ssetmask
+#define SYS_setreuid __NR_setreuid
+#define SYS_setregid __NR_setregid
+#define SYS_sigsuspend __NR_sigsuspend
+#define SYS_sigpending __NR_sigpending
+#define SYS_sethostname __NR_sethostname
+#define SYS_setrlimit __NR_setrlimit
+#define SYS_getrlimit __NR_getrlimit
+#define SYS_getrusage __NR_getrusage
+#define SYS_gettimeofday __NR_gettimeofday
+#define SYS_settimeofday __NR_settimeofday
+#define SYS_getgroups __NR_getgroups
+#define SYS_setgroups __NR_setgroups
+#define SYS_select __NR_select
+#define SYS_symlink __NR_symlink
+#define SYS_oldlstat __NR_oldlstat
+#define SYS_readlink __NR_readlink
+#define SYS_uselib __NR_uselib
+#define SYS_swapon __NR_swapon
+#define SYS_reboot __NR_reboot
+#define SYS_readdir __NR_readdir
+#define SYS_mmap __NR_mmap
+#define SYS_munmap __NR_munmap
+#define SYS_truncate __NR_truncate
+#define SYS_ftruncate __NR_ftruncate
+#define SYS_fchmod __NR_fchmod
+#define SYS_fchown __NR_fchown
+#define SYS_getpriority __NR_getpriority
+#define SYS_setpriority __NR_setpriority
+#define SYS_profil __NR_profil
+#define SYS_statfs __NR_statfs
+#define SYS_fstatfs __NR_fstatfs
+#define SYS_ioperm __NR_ioperm
+#define SYS_socketcall __NR_socketcall
+#define SYS_syslog __NR_syslog
+#define SYS_setitimer __NR_setitimer
+#define SYS_getitimer __NR_getitimer
+#define SYS_stat __NR_stat
+#define SYS_lstat __NR_lstat
+#define SYS_fstat __NR_fstat
+#define SYS_olduname __NR_olduname
+#define SYS_iopl __NR_iopl
+#define SYS_vhangup __NR_vhangup
+#define SYS_idle __NR_idle
+#define SYS_vm86 __NR_vm86
+#define SYS_wait4 __NR_wait4
+#define SYS_swapoff __NR_swapoff
+#define SYS_sysinfo __NR_sysinfo
+#define SYS_ipc __NR_ipc
+#define SYS_fsync __NR_fsync
+#define SYS_sigreturn __NR_sigreturn
+#define SYS_clone __NR_clone
+#define SYS_setdomainname __NR_setdomainname
+#define SYS_uname __NR_uname
+#define SYS_modify_ldt __NR_modify_ldt
+#define SYS_adjtimex __NR_adjtimex
+#define SYS_mprotect __NR_mprotect
+#define SYS_sigprocmask __NR_sigprocmask
+#define SYS_create_module __NR_create_module
+#define SYS_init_module __NR_init_module
+#define SYS_delete_module __NR_delete_module
+#define SYS_get_kernel_syms __NR_get_kernel_syms
+#define SYS_quotactl __NR_quotactl
+#define SYS_getpgid __NR_getpgid
+#define SYS_fchdir __NR_fchdir
+#define SYS_bdflush __NR_bdflush
+#define SYS_sysfs __NR_sysfs
+#define SYS_personality __NR_personality
+#define SYS_afs_syscall __NR_afs_syscall
+#define SYS_setfsuid __NR_setfsuid
+#define SYS_setfsgid __NR_setfsgid
+#define SYS__llseek __NR__llseek
+#define SYS_getdents __NR_getdents
+#define SYS__newselect __NR__newselect
+#define SYS_flock __NR_flock
+#define SYS_msync __NR_msync
+#define SYS_readv __NR_readv
+#define SYS_writev __NR_writev
+#define SYS_getsid __NR_getsid
+#define SYS_fdatasync __NR_fdatasync
+#define SYS__sysctl __NR__sysctl
+#define SYS_mlock __NR_mlock
+#define SYS_munlock __NR_munlock
+#define SYS_mlockall __NR_mlockall
+#define SYS_munlockall __NR_munlockall
+#define SYS_sched_setparam __NR_sched_setparam
+#define SYS_sched_getparam __NR_sched_getparam
+#define SYS_sched_setscheduler __NR_sched_setscheduler
+#define SYS_sched_getscheduler __NR_sched_getscheduler
+#define SYS_sched_yield __NR_sched_yield
+#define SYS_sched_get_priority_max __NR_sched_get_priority_max
+#define SYS_sched_get_priority_min __NR_sched_get_priority_min
+#define SYS_sched_rr_get_interval __NR_sched_rr_get_interval
+#define SYS_nanosleep __NR_nanosleep
+#define SYS_mremap __NR_mremap
+#define SYS_setresuid __NR_setresuid
+#define SYS_getresuid __NR_getresuid
+#define SYS_query_module __NR_query_module
+#define SYS_poll __NR_poll
+#define SYS_nfsservctl __NR_nfsservctl
+#define SYS_setresgid __NR_setresgid
+#define SYS_getresgid __NR_getresgid
+#define SYS_prctl __NR_prctl
+#define SYS_rt_sigreturn __NR_rt_sigreturn
+#define SYS_rt_sigaction __NR_rt_sigaction
+#define SYS_rt_sigprocmask __NR_rt_sigprocmask
+#define SYS_rt_sigpending __NR_rt_sigpending
+#define SYS_rt_sigtimedwait __NR_rt_sigtimedwait
+#define SYS_rt_sigqueueinfo __NR_rt_sigqueueinfo
+#define SYS_rt_sigsuspend __NR_rt_sigsuspend
+#define SYS_pread64 __NR_pread64
+#define SYS_pwrite64 __NR_pwrite64
+#define SYS_chown __NR_chown
+#define SYS_getcwd __NR_getcwd
+#define SYS_capget __NR_capget
+#define SYS_capset __NR_capset
+#define SYS_sigaltstack __NR_sigaltstack
+#define SYS_sendfile __NR_sendfile
+#define SYS_getpmsg __NR_getpmsg
+#define SYS_putpmsg __NR_putpmsg
+#define SYS_vfork __NR_vfork
+#define SYS_ugetrlimit __NR_ugetrlimit
+#define SYS_readahead __NR_readahead
+#define SYS_pciconfig_read __NR_pciconfig_read
+#define SYS_pciconfig_write __NR_pciconfig_write
+#define SYS_pciconfig_iobase __NR_pciconfig_iobase
+#define SYS_multiplexer __NR_multiplexer
+#define SYS_getdents64 __NR_getdents64
+#define SYS_pivot_root __NR_pivot_root
+#define SYS_madvise __NR_madvise
+#define SYS_mincore __NR_mincore
+#define SYS_gettid __NR_gettid
+#define SYS_tkill __NR_tkill
+#define SYS_setxattr __NR_setxattr
+#define SYS_lsetxattr __NR_lsetxattr
+#define SYS_fsetxattr __NR_fsetxattr
+#define SYS_getxattr __NR_getxattr
+#define SYS_lgetxattr __NR_lgetxattr
+#define SYS_fgetxattr __NR_fgetxattr
+#define SYS_listxattr __NR_listxattr
+#define SYS_llistxattr __NR_llistxattr
+#define SYS_flistxattr __NR_flistxattr
+#define SYS_removexattr __NR_removexattr
+#define SYS_lremovexattr __NR_lremovexattr
+#define SYS_fremovexattr __NR_fremovexattr
+#define SYS_futex __NR_futex
+#define SYS_sched_setaffinity __NR_sched_setaffinity
+#define SYS_sched_getaffinity __NR_sched_getaffinity
+#define SYS_tuxcall __NR_tuxcall
+#define SYS_io_setup __NR_io_setup
+#define SYS_io_destroy __NR_io_destroy
+#define SYS_io_getevents __NR_io_getevents
+#define SYS_io_submit __NR_io_submit
+#define SYS_io_cancel __NR_io_cancel
+#define SYS_set_tid_address __NR_set_tid_address
+#define SYS_fadvise64 __NR_fadvise64
+#define SYS_exit_group __NR_exit_group
+#define SYS_lookup_dcookie __NR_lookup_dcookie
+#define SYS_epoll_create __NR_epoll_create
+#define SYS_epoll_ctl __NR_epoll_ctl
+#define SYS_epoll_wait __NR_epoll_wait
+#define SYS_remap_file_pages __NR_remap_file_pages
+#define SYS_timer_create __NR_timer_create
+#define SYS_timer_settime __NR_timer_settime
+#define SYS_timer_gettime __NR_timer_gettime
+#define SYS_timer_getoverrun __NR_timer_getoverrun
+#define SYS_timer_delete __NR_timer_delete
+#define SYS_clock_settime __NR_clock_settime
+#define SYS_clock_gettime __NR_clock_gettime
+#define SYS_clock_getres __NR_clock_getres
+#define SYS_clock_nanosleep __NR_clock_nanosleep
+#define SYS_swapcontext __NR_swapcontext
+#define SYS_tgkill __NR_tgkill
+#define SYS_utimes __NR_utimes
+#define SYS_statfs64 __NR_statfs64
+#define SYS_fstatfs64 __NR_fstatfs64
+#define SYS_rtas __NR_rtas
+#define SYS_sys_debug_setcontext __NR_sys_debug_setcontext
+#define SYS_migrate_pages __NR_migrate_pages
+#define SYS_mbind __NR_mbind
+#define SYS_get_mempolicy __NR_get_mempolicy
+#define SYS_set_mempolicy __NR_set_mempolicy
+#define SYS_mq_open __NR_mq_open
+#define SYS_mq_unlink __NR_mq_unlink
+#define SYS_mq_timedsend __NR_mq_timedsend
+#define SYS_mq_timedreceive __NR_mq_timedreceive
+#define SYS_mq_notify __NR_mq_notify
+#define SYS_mq_getsetattr __NR_mq_getsetattr
+#define SYS_kexec_load __NR_kexec_load
+#define SYS_add_key __NR_add_key
+#define SYS_request_key __NR_request_key
+#define SYS_keyctl __NR_keyctl
+#define SYS_waitid __NR_waitid
+#define SYS_ioprio_set __NR_ioprio_set
+#define SYS_ioprio_get __NR_ioprio_get
+#define SYS_inotify_init __NR_inotify_init
+#define SYS_inotify_add_watch __NR_inotify_add_watch
+#define SYS_inotify_rm_watch __NR_inotify_rm_watch
+#define SYS_spu_run __NR_spu_run
+#define SYS_spu_create __NR_spu_create
+#define SYS_pselect6 __NR_pselect6
+#define SYS_ppoll __NR_ppoll
+#define SYS_unshare __NR_unshare
+#define SYS_splice __NR_splice
+#define SYS_tee __NR_tee
+#define SYS_vmsplice __NR_vmsplice
+#define SYS_openat __NR_openat
+#define SYS_mkdirat __NR_mkdirat
+#define SYS_mknodat __NR_mknodat
+#define SYS_fchownat __NR_fchownat
+#define SYS_futimesat __NR_futimesat
+#define SYS_newfstatat __NR_newfstatat
+#define SYS_unlinkat __NR_unlinkat
+#define SYS_renameat __NR_renameat
+#define SYS_linkat __NR_linkat
+#define SYS_symlinkat __NR_symlinkat
+#define SYS_readlinkat __NR_readlinkat
+#define SYS_fchmodat __NR_fchmodat
+#define SYS_faccessat __NR_faccessat
+#define SYS_get_robust_list __NR_get_robust_list
+#define SYS_set_robust_list __NR_set_robust_list
+#define SYS_move_pages __NR_move_pages
+#define SYS_getcpu __NR_getcpu
+#define SYS_epoll_pwait __NR_epoll_pwait
+#define SYS_utimensat __NR_utimensat
+#define SYS_signalfd __NR_signalfd
+#define SYS_timerfd_create __NR_timerfd_create
+#define SYS_eventfd __NR_eventfd
+#define SYS_sync_file_range2 __NR_sync_file_range2
+#define SYS_fallocate __NR_fallocate
+#define SYS_subpage_prot __NR_subpage_prot
+#define SYS_timerfd_settime __NR_timerfd_settime
+#define SYS_timerfd_gettime __NR_timerfd_gettime
+#define SYS_signalfd4 __NR_signalfd4
+#define SYS_eventfd2 __NR_eventfd2
+#define SYS_epoll_create1 __NR_epoll_create1
+#define SYS_dup3 __NR_dup3
+#define SYS_pipe2 __NR_pipe2
+#define SYS_inotify_init1 __NR_inotify_init1
+#define SYS_perf_event_open __NR_perf_event_open
+#define SYS_preadv __NR_preadv
+#define SYS_pwritev __NR_pwritev
+#define SYS_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo
+#define SYS_fanotify_init __NR_fanotify_init
+#define SYS_fanotify_mark __NR_fanotify_mark
+#define SYS_prlimit64 __NR_prlimit64
+#define SYS_socket __NR_socket
+#define SYS_bind __NR_bind
+#define SYS_connect __NR_connect
+#define SYS_listen __NR_listen
+#define SYS_accept __NR_accept
+#define SYS_getsockname __NR_getsockname
+#define SYS_getpeername __NR_getpeername
+#define SYS_socketpair __NR_socketpair
+#define SYS_send __NR_send
+#define SYS_sendto __NR_sendto
+#define SYS_recv __NR_recv
+#define SYS_recvfrom __NR_recvfrom
+#define SYS_shutdown __NR_shutdown
+#define SYS_setsockopt __NR_setsockopt
+#define SYS_getsockopt __NR_getsockopt
+#define SYS_sendmsg __NR_sendmsg
+#define SYS_recvmsg __NR_recvmsg
+#define SYS_recvmmsg __NR_recvmmsg
+#define SYS_accept4 __NR_accept4
+#define SYS_name_to_handle_at __NR_name_to_handle_at
+#define SYS_open_by_handle_at __NR_open_by_handle_at
+#define SYS_clock_adjtime __NR_clock_adjtime
+#define SYS_syncfs __NR_syncfs
+#define SYS_sendmmsg __NR_sendmmsg
+#define SYS_setns __NR_setns
+#define SYS_process_vm_readv __NR_process_vm_readv
+#define SYS_process_vm_writev __NR_process_vm_writev
+#define SYS_finit_module __NR_finit_module
+#define SYS_kcmp __NR_kcmp
+#define SYS_sched_setattr __NR_sched_setattr
+#define SYS_sched_getattr __NR_sched_getattr
+#define SYS_renameat2 __NR_renameat2
+#define SYS_seccomp __NR_seccomp
+#define SYS_getrandom __NR_getrandom
+#define SYS_memfd_create __NR_memfd_create
+#define SYS_bpf __NR_bpf
+#define SYS_execveat __NR_execveat
+#define SYS_switch_endian __NR_switch_endian
+#define SYS_userfaultfd __NR_userfaultfd
+#define SYS_membarrier __NR_membarrier
+#define SYS_mlock2 __NR_mlock2
+#define SYS_copy_file_range __NR_copy_file_range
diff --git a/arch/powerpc64/bits/termios.h b/arch/powerpc64/bits/termios.h
new file mode 100644
index 0000000..7feaf49
--- /dev/null
+++ b/arch/powerpc64/bits/termios.h
@@ -0,0 +1,170 @@
+#undef NCCS
+#define NCCS 19
+struct termios
+{
+	tcflag_t c_iflag;
+	tcflag_t c_oflag;
+	tcflag_t c_cflag;
+	tcflag_t c_lflag;
+	cc_t c_cc[NCCS];
+	cc_t c_line;
+	speed_t __c_ispeed;
+	speed_t __c_ospeed;
+};
+
+#define VINTR     0
+#define VQUIT     1
+#define VERASE    2
+#define VKILL     3
+#define VEOF      4
+#define VMIN      5
+#define VEOL      6
+#define VTIME     7
+#define VEOL2     8
+#define VSWTC     9
+#define VWERASE  10
+#define VREPRINT 11
+#define VSUSP    12
+#define VSTART   13
+#define VSTOP    14
+#define VLNEXT   15
+#define VDISCARD 16
+
+#define IGNBRK  0000001
+#define BRKINT  0000002
+#define IGNPAR  0000004
+#define PARMRK  0000010
+#define INPCK   0000020
+#define ISTRIP  0000040
+#define INLCR   0000100
+#define IGNCR   0000200
+#define ICRNL   0000400
+#define IXON    0001000
+#define IXOFF   0002000
+#define IXANY   0004000
+#define IUCLC   0010000
+#define IMAXBEL 0020000
+#define IUTF8   0040000
+
+#define OPOST  0000001
+#define ONLCR  0000002
+#define OLCUC  0000004
+#define OCRNL  0000010
+#define ONOCR  0000020
+#define ONLRET 0000040
+#define OFILL  0000100
+#define OFDEL  0000200
+#define NLDLY  0001400
+#define NL0    0000000
+#define NL1    0000400
+#define NL2    0001000
+#define NL3    0001400
+#define TABDLY 0006000
+#define TAB0   0000000
+#define TAB1   0002000
+#define TAB2   0004000
+#define TAB3   0006000
+#define CRDLY  0030000
+#define CR0    0000000
+#define CR1    0010000
+#define CR2    0020000
+#define CR3    0030000
+#define FFDLY  0040000
+#define FF0    0000000
+#define FF1    0040000
+#define BSDLY  0100000
+#define BS0    0000000
+#define BS1    0100000
+
+#define VTDLY  0200000
+#define VT0    0000000
+#define VT1    0200000
+
+#define B0       0000000
+#define B50      0000001
+#define B75      0000002
+#define B110     0000003
+#define B134     0000004
+#define B150     0000005
+#define B200     0000006
+#define B300     0000007
+#define B600     0000010
+#define B1200    0000011
+#define B1800    0000012
+#define B2400    0000013
+#define B4800    0000014
+#define B9600    0000015
+#define B19200   0000016
+#define B38400   0000017
+#define EXTA     0000016
+#define EXTB     0000017
+
+#define B57600   00020
+#define B115200  00021
+#define B230400  00022
+#define B460800  00023
+#define B500000  00024
+#define B576000  00025
+#define B921600  00026
+#define B1000000 00027
+#define B1152000 00030
+#define B1500000 00031
+#define B2000000 00032
+#define B2500000 00033
+#define B3000000 00034
+#define B3500000 00035
+#define B4000000 00036
+#define BOTHER   00037
+
+#define CBAUD    00377
+
+#define CSIZE  00001400
+#define CS5    00000000
+#define CS6    00000400
+#define CS7    00001000
+#define CS8    00001400
+#define CSTOPB 00002000
+#define CREAD  00004000
+#define PARENB 00010000
+#define PARODD 00020000
+#define HUPCL  00040000
+#define CLOCAL 00100000
+
+#define ECHOKE  0x00000001
+#define ECHOE   0x00000002
+#define ECHOK   0x00000004
+#define ECHO    0x00000008
+#define ECHONL  0x00000010
+#define ECHOPRT 0x00000020
+#define ECHOCTL 0x00000040
+#define ISIG    0x00000080
+#define ICANON  0x00000100
+#define IEXTEN  0x00000400
+#define XCASE   0x00004000
+#define TOSTOP  0x00400000
+#define FLUSHO  0x00800000
+#define PENDIN  0x20000000
+#define NOFLSH  0x80000000
+
+#define TCOOFF 0
+#define TCOON  1
+#define TCIOFF 2
+#define TCION  3
+
+#define TCIFLUSH  0
+#define TCOFLUSH  1
+#define TCIOFLUSH 2
+
+#define TCSANOW   0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define CBAUDEX 0000000
+#define CIBAUD  077600000
+#define IBSHIFT 16
+#define CMSPAR  010000000000
+#define CRTSCTS 020000000000
+#define EXTPROC 0x10000000
+#define XTABS   00006000
+#endif
diff --git a/arch/powerpc64/bits/user.h b/arch/powerpc64/bits/user.h
new file mode 100644
index 0000000..7ca459b
--- /dev/null
+++ b/arch/powerpc64/bits/user.h
@@ -0,0 +1,25 @@
+struct pt_regs {
+	unsigned long gpr[32], nip, msr, orig_gpr3, ctr, link, xer, ccr, softe;
+	unsigned long trap, dar, dsisr, result;
+};
+
+struct user {
+	struct pt_regs regs;
+	unsigned long u_tsize, u_dsize, u_ssize;
+	unsigned long start_code, start_data, start_stack;
+	long signal;
+	void *u_ar0;
+	unsigned long magic;
+	char u_comm[32];
+};
+
+#define ELF_NGREG 48
+#define ELF_NFPREG 33
+#define ELF_NVRREG 34
+typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];
+typedef double elf_fpreg_t, elf_fpregset_t[ELF_NFPREG];
+typedef struct { unsigned u[4]; }
+#ifdef __GNUC__
+__attribute__((__aligned__(16)))
+#endif
+	elf_vrreg_t, elf_vrregset_t[ELF_NVRREG];
diff --git a/arch/powerpc64/crt_arch.h b/arch/powerpc64/crt_arch.h
new file mode 100644
index 0000000..168669a
--- /dev/null
+++ b/arch/powerpc64/crt_arch.h
@@ -0,0 +1,19 @@
+__asm__(
+".text \n"
+".global " START " \n"
+".type   " START ", %function \n"
+START ": \n"
+"	addis  2, 12, .TOC.-" START "@ha \n"
+"	addi   2,  2, .TOC.-" START "@l \n"
+"	lwz    4, 1f-" START "(12)\n"
+"	add    4, 4, 12 \n"
+"	mr     3, 1 \n"
+"	clrrdi 1, 1, 4 \n"
+"	li     0, 0 \n"
+"	stdu   0, -32(1) \n"
+"	mtlr   0 \n"
+"	bl " START "_c \n"
+".weak   _DYNAMIC \n"
+".hidden _DYNAMIC \n"
+"1:	.long _DYNAMIC-" START "\n"
+);
diff --git a/arch/powerpc64/pthread_arch.h b/arch/powerpc64/pthread_arch.h
new file mode 100644
index 0000000..2f976fe
--- /dev/null
+++ b/arch/powerpc64/pthread_arch.h
@@ -0,0 +1,17 @@
+static inline struct pthread *__pthread_self()
+{
+	register char *tp __asm__("r13");
+	__asm__ __volatile__ ("" : "=r" (tp) );
+	return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
+}
+
+#define TLS_ABOVE_TP
+#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
+
+#define DTP_OFFSET 0x8000
+
+// the kernel calls the ip "nip", it's the first saved value after the 32
+// GPRs.
+#define MC_PC gp_regs[32]
+
+#define CANARY canary_at_end
diff --git a/arch/powerpc64/reloc.h b/arch/powerpc64/reloc.h
new file mode 100644
index 0000000..e1bad00
--- /dev/null
+++ b/arch/powerpc64/reloc.h
@@ -0,0 +1,32 @@
+#include <endian.h>
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define ENDIAN_SUFFIX "le"
+#else
+#define ENDIAN_SUFFIX ""
+#endif
+
+#define LDSO_ARCH "powerpc64" ENDIAN_SUFFIX
+
+#define TPOFF_K (-0x7000)
+
+#define REL_SYMBOLIC    R_PPC64_ADDR64
+#define REL_GOT         R_PPC64_GLOB_DAT
+#define REL_PLT         R_PPC64_JMP_SLOT
+#define REL_RELATIVE    R_PPC64_RELATIVE
+#define REL_COPY        R_PPC64_COPY
+#define REL_DTPMOD      R_PPC64_DTPMOD64
+#define REL_DTPOFF      R_PPC64_DTPREL64
+#define REL_TPOFF       R_PPC64_TPREL64
+
+#define CRTJMP(pc,sp) __asm__ __volatile__( \
+	"mr 1,%1; mr 12,%0; mtctr 12; bctrl" : : "r"(pc), "r"(sp) : "memory" )
+
+#define GETFUNCSYM(fp, sym, got) __asm__ ( \
+	".hidden " #sym " \n" \
+	"	bl 1f \n" \
+	"	.long " #sym "-. \n" \
+	"1:	mflr %1 \n" \
+	"	lwz %0, 0(%1) \n" \
+	"	add %0, %0, %1 \n" \
+	: "=r"(*(fp)), "=r"((long){0}) : : "memory", "lr" )
diff --git a/arch/powerpc64/syscall_arch.h b/arch/powerpc64/syscall_arch.h
new file mode 100644
index 0000000..1e73062
--- /dev/null
+++ b/arch/powerpc64/syscall_arch.h
@@ -0,0 +1,87 @@
+#define __SYSCALL_LL_E(x) (x)
+#define __SYSCALL_LL_O(x) (x)
+
+static inline long __syscall0(long n)
+{
+	register long r0 __asm__("r0") = n;
+	register long r3 __asm__("r3");
+	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"
+	: "+r"(r0), "=r"(r3)
+	:: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12");
+	return r3;
+}
+
+static inline long __syscall1(long n, long a)
+{
+	register long r0 __asm__("r0") = n;
+	register long r3 __asm__("r3") = a;
+	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"
+	: "+r"(r0), "+r"(r3)
+	:: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12");
+	return r3;
+}
+
+static inline long __syscall2(long n, long a, long b)
+{
+	register long r0 __asm__("r0") = n;
+	register long r3 __asm__("r3") = a;
+	register long r4 __asm__("r4") = b;
+	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"
+	: "+r"(r0), "+r"(r3), "+r"(r4)
+	:: "memory", "cr0", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12");
+	return r3;
+}
+
+static inline long __syscall3(long n, long a, long b, long c)
+{
+	register long r0 __asm__("r0") = n;
+	register long r3 __asm__("r3") = a;
+	register long r4 __asm__("r4") = b;
+	register long r5 __asm__("r5") = c;
+	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"
+	: "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5)
+	:: "memory", "cr0", "r6", "r7", "r8", "r9", "r10", "r11", "r12");
+	return r3;
+}
+
+static inline long __syscall4(long n, long a, long b, long c, long d)
+{
+	register long r0 __asm__("r0") = n;
+	register long r3 __asm__("r3") = a;
+	register long r4 __asm__("r4") = b;
+	register long r5 __asm__("r5") = c;
+	register long r6 __asm__("r6") = d;
+	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"
+	: "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6)
+	:: "memory", "cr0", "r7", "r8", "r9", "r10", "r11", "r12");
+	return r3;
+}
+
+static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+{
+	register long r0 __asm__("r0") = n;
+	register long r3 __asm__("r3") = a;
+	register long r4 __asm__("r4") = b;
+	register long r5 __asm__("r5") = c;
+	register long r6 __asm__("r6") = d;
+	register long r7 __asm__("r7") = e;
+	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"
+	: "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6), "+r"(r7)
+	:: "memory", "cr0", "r8", "r9", "r10", "r11", "r12");
+	return r3;
+}
+
+static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+{
+	register long r0 __asm__("r0") = n;
+	register long r3 __asm__("r3") = a;
+	register long r4 __asm__("r4") = b;
+	register long r5 __asm__("r5") = c;
+	register long r6 __asm__("r6") = d;
+	register long r7 __asm__("r7") = e;
+	register long r8 __asm__("r8") = f;
+	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"
+	: "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6), "+r"(r7), "+r"(r8)
+	:: "memory", "cr0", "r9", "r10", "r11", "r12");
+	return r3;
+}
diff --git a/configure b/configure
index 969671d..cb86726 100755
--- a/configure
+++ b/configure
@@ -299,7 +299,6 @@ printf "%s\n" "$target"
 #
 case "$target" in
 # Catch these early to simplify matching for 32-bit archs
-powerpc64*) fail "$0: unsupported target \"$target\"" ;;
 arm*) ARCH=arm ;;
 aarch64*) ARCH=aarch64 ;;
 i?86-nt32*) ARCH=nt32 ;;
@@ -311,6 +310,7 @@ mips64*) ARCH=mips64 ;;
 mips*) ARCH=mips ;;
 microblaze*) ARCH=microblaze ;;
 or1k*) ARCH=or1k ;;
+powerpc64*) ARCH=powerpc64 ;;
 powerpc*) ARCH=powerpc ;;
 sh[1-9bel-]*|sh|superh*) ARCH=sh ;;
 unknown) fail "$0: unable to detect target arch; try $0 --target=..." ;;
@@ -632,6 +632,11 @@ fi
 test "$ARCH" = "microblaze" && trycppif __MICROBLAZEEL__ "$t" \
 && SUBARCH=${SUBARCH}el
 
+if test "$ARCH" = "powerpc64" ; then
+trycppif "_CALL_ELF == 2" "$t" || fail "$0: error: unsupported powerpc64 ABI"
+trycppif __LITTLE_ENDIAN__ "$t" && SUBARCH=${SUBARCH}le
+fi
+
 if test "$ARCH" = "sh" ; then
 tryflag CFLAGS_AUTO -Wa,--isa=any
 trycppif __BIG_ENDIAN__ "$t" && SUBARCH=${SUBARCH}eb
diff --git a/crt/powerpc64/crti.s b/crt/powerpc64/crti.s
new file mode 100644
index 0000000..9f712f0
--- /dev/null
+++ b/crt/powerpc64/crti.s
@@ -0,0 +1,21 @@
+.section .init
+.align 2
+.global _init
+_init:
+	addis 2, 12, .TOC.-_init@ha
+	addi  2,  2, .TOC.-_init@l
+	.localentry _init,.-_init
+	mflr 0
+	std  0, 16(1)
+	stdu 1,-32(1)
+
+.section .fini
+.align 2
+.global _fini
+_fini:
+	addis 2, 12, .TOC.-_fini@ha
+	addi  2,  2, .TOC.-_fini@l
+	.localentry _fini,.-_fini
+	mflr 0
+	std  0, 16(1)
+	stdu 1,-32(1)
diff --git a/crt/powerpc64/crtn.s b/crt/powerpc64/crtn.s
new file mode 100644
index 0000000..a7a9f4a
--- /dev/null
+++ b/crt/powerpc64/crtn.s
@@ -0,0 +1,13 @@
+.section .init
+.align 2
+	addi 1, 1, 32
+	ld   0, 16(1)
+	mtlr 0
+	blr
+
+.section .fini
+.align 2
+	addi 1, 1, 32
+	ld   0, 16(1)
+	mtlr 0
+	blr
diff --git a/src/fenv/powerpc64/fenv.c b/src/fenv/powerpc64/fenv.c
new file mode 100644
index 0000000..739420b
--- /dev/null
+++ b/src/fenv/powerpc64/fenv.c
@@ -0,0 +1,68 @@
+#define _GNU_SOURCE
+#include <fenv.h>
+
+static inline double get_fpscr_f(void)
+{
+	double d;
+	__asm__ __volatile__("mffs %0" : "=d"(d));
+	return d;
+}
+
+static inline long get_fpscr(void)
+{
+	return (union {double f; long i;}) {get_fpscr_f()}.i;
+}
+
+static inline void set_fpscr_f(double fpscr)
+{
+	__asm__ __volatile__("mtfsf 255, %0" : : "d"(fpscr));
+}
+
+static void set_fpscr(long fpscr)
+{
+	set_fpscr_f((union {long i; double f;}) {fpscr}.f);
+}
+
+int feclearexcept(int mask)
+{
+	mask &= FE_ALL_EXCEPT;
+	if (mask & FE_INVALID) mask |= FE_ALL_INVALID;
+	set_fpscr(get_fpscr() & ~mask);
+	return 0;
+}
+
+int feraiseexcept(int mask)
+{
+	mask &= FE_ALL_EXCEPT;
+	if (mask & FE_INVALID) mask |= FE_INVALID_SOFTWARE;
+	set_fpscr(get_fpscr() | mask);
+	return 0;
+}
+
+int fetestexcept(int mask)
+{
+	return get_fpscr() & mask & FE_ALL_EXCEPT;
+}
+
+int fegetround(void)
+{
+	return get_fpscr() & 3;
+}
+
+int __fesetround(int r)
+{
+	set_fpscr(get_fpscr() & ~3L | r);
+	return 0;
+}
+
+int fegetenv(fenv_t *envp)
+{
+	*envp = get_fpscr_f();
+	return 0;
+}
+
+int fesetenv(const fenv_t *envp)
+{
+	set_fpscr_f(envp != FE_DFL_ENV ? *envp : 0);
+	return 0;
+}
diff --git a/src/internal/powerpc64/syscall.s b/src/internal/powerpc64/syscall.s
new file mode 100644
index 0000000..fe21f9e
--- /dev/null
+++ b/src/internal/powerpc64/syscall.s
@@ -0,0 +1,17 @@
+	.global __syscall
+	.hidden __syscall
+	.type   __syscall,@function
+__syscall:
+	mr      0, 3                  # Save the system call number
+	mr      3, 4                  # Shift the arguments: arg1
+	mr      4, 5                  # arg2
+	mr      5, 6                  # arg3
+	mr      6, 7                  # arg4
+	mr      7, 8                  # arg5
+	mr      8, 9                  # arg6
+	sc
+	bnslr+       # return if not summary overflow
+	neg     3, 3 # otherwise error: return negated value.
+	blr
+	.end    __syscall
+	.size   __syscall, .-__syscall
diff --git a/src/ldso/powerpc64/dlsym.s b/src/ldso/powerpc64/dlsym.s
new file mode 100644
index 0000000..7eb691d
--- /dev/null
+++ b/src/ldso/powerpc64/dlsym.s
@@ -0,0 +1,12 @@
+	.text
+	.global dlsym
+	.hidden __dlsym
+	.type   dlsym,@function
+dlsym:
+	addis   2, 12, .TOC.-dlsym@ha
+	addi    2,  2, .TOC.-dlsym@l
+	.localentry dlsym,.-dlsym
+	mflr    5                      # The return address is arg3.
+	b       __dlsym
+	.end    dlsym
+	.size   dlsym, .-dlsym
diff --git a/src/setjmp/powerpc64/longjmp.S b/src/setjmp/powerpc64/longjmp.S
new file mode 100644
index 0000000..e424563
--- /dev/null
+++ b/src/setjmp/powerpc64/longjmp.S
@@ -0,0 +1,98 @@
+	.global _longjmp
+	.global longjmp
+	.type   _longjmp,@function
+	.type   longjmp,@function
+_longjmp:
+longjmp:
+	# 0) move old return address into the link register
+	ld   0,  0*8(3)
+	mtlr 0
+	# 1) restore cr
+	ld   0,  1*8(3)
+	mtcr 0
+	# 2) restore r1-r2 (SP and TOC)
+	ld   1,  2*8(3)
+	ld   2,  3*8(3)
+	# 3) restore r14-r31
+	ld  14,  4*8(3)
+	ld  15,  5*8(3)
+	ld  16,  6*8(3)
+	ld  17,  7*8(3)
+	ld  18,  8*8(3)
+	ld  19,  9*8(3)
+	ld  20, 10*8(3)
+	ld  21, 11*8(3)
+	ld  22, 12*8(3)
+	ld  23, 13*8(3)
+	ld  24, 14*8(3)
+	ld  25, 15*8(3)
+	ld  26, 16*8(3)
+	ld  27, 17*8(3)
+	ld  28, 18*8(3)
+	ld  29, 19*8(3)
+	ld  30, 20*8(3)
+	ld  31, 21*8(3)
+	# 4) restore floating point registers f14-f31
+	lfd 14, 22*8(3)
+	lfd 15, 23*8(3)
+	lfd 16, 24*8(3)
+	lfd 17, 25*8(3)
+	lfd 18, 26*8(3)
+	lfd 19, 27*8(3)
+	lfd 20, 28*8(3)
+	lfd 21, 29*8(3)
+	lfd 22, 30*8(3)
+	lfd 23, 31*8(3)
+	lfd 24, 32*8(3)
+	lfd 25, 33*8(3)
+	lfd 26, 34*8(3)
+	lfd 27, 35*8(3)
+	lfd 28, 36*8(3)
+	lfd 29, 37*8(3)
+	lfd 30, 38*8(3)
+	lfd 31, 39*8(3)
+
+	# 5) restore vector registers v20-v31
+	addi  3, 3, 40*8
+	lvx   2, 0, 3
+
+#if __BIG_ENDIAN__
+	lvsl  0, 0, 3
+
+	addi  3, 3, 16 ; lvx 3, 0, 3 ; vperm 20, 2, 3, 0
+	addi  3, 3, 16 ; lvx 2, 0, 3 ; vperm 21, 3, 2, 0
+	addi  3, 3, 16 ; lvx 3, 0, 3 ; vperm 22, 2, 3, 0
+	addi  3, 3, 16 ; lvx 2, 0, 3 ; vperm 23, 3, 2, 0
+	addi  3, 3, 16 ; lvx 3, 0, 3 ; vperm 24, 2, 3, 0
+	addi  3, 3, 16 ; lvx 2, 0, 3 ; vperm 25, 3, 2, 0
+	addi  3, 3, 16 ; lvx 3, 0, 3 ; vperm 26, 2, 3, 0
+	addi  3, 3, 16 ; lvx 2, 0, 3 ; vperm 27, 3, 2, 0
+	addi  3, 3, 16 ; lvx 3, 0, 3 ; vperm 28, 2, 3, 0
+	addi  3, 3, 16 ; lvx 2, 0, 3 ; vperm 29, 3, 2, 0
+	addi  3, 3, 16 ; lvx 3, 0, 3 ; vperm 30, 2, 3, 0
+	addi  3, 3, 16 ; lvx 2, 0, 3 ; vperm 31, 3, 2, 0
+#else
+	lvsr  0, 0, 3
+
+	addi  3, 3, 16 ; lvx 3, 0, 3 ; vperm 20, 3, 2, 0
+	addi  3, 3, 16 ; lvx 2, 0, 3 ; vperm 21, 2, 3, 0
+	addi  3, 3, 16 ; lvx 3, 0, 3 ; vperm 22, 3, 2, 0
+	addi  3, 3, 16 ; lvx 2, 0, 3 ; vperm 23, 2, 3, 0
+	addi  3, 3, 16 ; lvx 3, 0, 3 ; vperm 24, 3, 2, 0
+	addi  3, 3, 16 ; lvx 2, 0, 3 ; vperm 25, 2, 3, 0
+	addi  3, 3, 16 ; lvx 3, 0, 3 ; vperm 26, 3, 2, 0
+	addi  3, 3, 16 ; lvx 2, 0, 3 ; vperm 27, 2, 3, 0
+	addi  3, 3, 16 ; lvx 3, 0, 3 ; vperm 28, 3, 2, 0
+	addi  3, 3, 16 ; lvx 2, 0, 3 ; vperm 29, 2, 3, 0
+	addi  3, 3, 16 ; lvx 3, 0, 3 ; vperm 30, 3, 2, 0
+	addi  3, 3, 16 ; lvx 2, 0, 3 ; vperm 31, 2, 3, 0
+#endif
+
+	# 6) return r4 ? r4 : 1
+	mr    3,   4
+	cmpwi cr7, 4, 0
+	bne   cr7, 1f
+	li    3,   1
+1:
+	blr
+
diff --git a/src/setjmp/powerpc64/setjmp.S b/src/setjmp/powerpc64/setjmp.S
new file mode 100644
index 0000000..0ad0699
--- /dev/null
+++ b/src/setjmp/powerpc64/setjmp.S
@@ -0,0 +1,103 @@
+	.global ___setjmp
+	.hidden ___setjmp
+	.global __setjmp
+	.global _setjmp
+	.global setjmp
+	.type   __setjmp,@function
+	.type   _setjmp,@function
+	.type   setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	# 0) store IP into 0, then into the jmpbuf pointed to by r3 (first arg)
+	mflr  0
+	std   0,  0*8(3)
+	# 1) store cr
+	mfcr  0
+	std   0,  1*8(3)
+	# 2) store r1-r2 (SP and TOC)
+	std   1,  2*8(3)
+	std   2,  3*8(3)
+	# 3) store r14-31
+	std  14,  4*8(3)
+	std  15,  5*8(3)
+	std  16,  6*8(3)
+	std  17,  7*8(3)
+	std  18,  8*8(3)
+	std  19,  9*8(3)
+	std  20, 10*8(3)
+	std  21, 11*8(3)
+	std  22, 12*8(3)
+	std  23, 13*8(3)
+	std  24, 14*8(3)
+	std  25, 15*8(3)
+	std  26, 16*8(3)
+	std  27, 17*8(3)
+	std  28, 18*8(3)
+	std  29, 19*8(3)
+	std  30, 20*8(3)
+	std  31, 21*8(3)
+	# 4) store floating point registers f14-f31
+	stfd 14, 22*8(3)
+	stfd 15, 23*8(3)
+	stfd 16, 24*8(3)
+	stfd 17, 25*8(3)
+	stfd 18, 26*8(3)
+	stfd 19, 27*8(3)
+	stfd 20, 28*8(3)
+	stfd 21, 29*8(3)
+	stfd 22, 30*8(3)
+	stfd 23, 31*8(3)
+	stfd 24, 32*8(3)
+	stfd 25, 33*8(3)
+	stfd 26, 34*8(3)
+	stfd 27, 35*8(3)
+	stfd 28, 36*8(3)
+	stfd 29, 37*8(3)
+	stfd 30, 38*8(3)
+	stfd 31, 39*8(3)
+
+	# 5) store vector registers v20-v31
+	addi  3, 3, 40*8
+	lvx   1, 0, 3
+
+#if __BIG_ENDIAN__
+	lvsr  0, 0, 3
+	vperm 1, 1, 1, 0
+
+	vperm 2,  1, 20, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 20, 21, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 21, 22, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 22, 23, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 23, 24, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 24, 25, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 25, 26, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 26, 27, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 27, 28, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 28, 29, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 29, 30, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 30, 31, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 31, 31, 0 ; stvx 2, 0, 3
+#else
+	lvsl  0, 0, 3
+	vperm 1, 1, 1, 0
+
+	vperm 2, 20,  1, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 21, 20, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 22, 21, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 23, 22, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 24, 23, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 25, 24, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 26, 25, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 27, 26, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 28, 27, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 29, 28, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 30, 29, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 31, 30, 0 ; stvx 2, 0, 3 ; addi 3, 3, 16
+	vperm 2, 31, 31, 0 ; stvx 2, 0, 3
+#endif
+
+	# 6) return 0
+	li 3, 0
+	blr
diff --git a/src/signal/powerpc64/restore.s b/src/signal/powerpc64/restore.s
new file mode 100644
index 0000000..4d41c27
--- /dev/null
+++ b/src/signal/powerpc64/restore.s
@@ -0,0 +1,11 @@
+	.global __restore
+	.type __restore,%function
+__restore:
+	li      0, 119 #__NR_sigreturn
+	sc
+
+	.global __restore_rt
+	.type __restore_rt,%function
+__restore_rt:
+	li      0, 172 # __NR_rt_sigreturn
+	sc
diff --git a/src/signal/powerpc64/sigsetjmp.s b/src/signal/powerpc64/sigsetjmp.s
new file mode 100644
index 0000000..ce59b60
--- /dev/null
+++ b/src/signal/powerpc64/sigsetjmp.s
@@ -0,0 +1,30 @@
+	.global sigsetjmp
+	.global __sigsetjmp
+	.type sigsetjmp,%function
+	.type __sigsetjmp,%function
+	.hidden ___setjmp
+sigsetjmp:
+__sigsetjmp:
+	addis 2, 12, .TOC.-__sigsetjmp@ha
+	addi  2,  2, .TOC.-__sigsetjmp@l
+	.localentry sigsetjmp,.-sigsetjmp
+	.localentry __sigsetjmp,.-__sigsetjmp
+
+	cmpwi cr7, 4, 0
+	beq-  cr7, ___setjmp
+
+	mflr  5
+	std   5, 528(3)
+	std  16, 528+8+8(3)
+	mr   16, 3
+
+	bl ___setjmp
+
+	mr   4,  3
+	mr   3, 16
+	ld   5, 528(3)
+	mtlr 5
+	ld  16, 528+8+8(3)
+
+.hidden __sigsetjmp_tail
+	b __sigsetjmp_tail
diff --git a/src/thread/powerpc64/__set_thread_area.s b/src/thread/powerpc64/__set_thread_area.s
new file mode 100644
index 0000000..9622826
--- /dev/null
+++ b/src/thread/powerpc64/__set_thread_area.s
@@ -0,0 +1,8 @@
+.text
+.global __set_thread_area
+.type   __set_thread_area, %function
+__set_thread_area:
+	mr 13, 3
+	li  3, 0
+	blr
+
diff --git a/src/thread/powerpc64/__unmapself.s b/src/thread/powerpc64/__unmapself.s
new file mode 100644
index 0000000..c9360b4
--- /dev/null
+++ b/src/thread/powerpc64/__unmapself.s
@@ -0,0 +1,9 @@
+	.text
+	.global __unmapself
+	.type   __unmapself,%function
+__unmapself:
+	li      0, 91 # __NR_munmap
+	sc
+	li      0, 1 #__NR_exit
+	sc
+	blr
diff --git a/src/thread/powerpc64/clone.s b/src/thread/powerpc64/clone.s
new file mode 100644
index 0000000..a3cd5ce
--- /dev/null
+++ b/src/thread/powerpc64/clone.s
@@ -0,0 +1,53 @@
+.text
+.global __clone
+.type __clone, %function
+__clone:
+	# int clone(fn, stack, flags, arg, ptid, tls, ctid)
+	#            a  b       c     d     e    f    g
+	#            3  4       5     6     7    8    9
+	# pseudo C code:
+	# tid = syscall(SYS_clone,c,b,e,f,g);
+	# if (!tid) syscall(SYS_exit, a(d));
+	# return tid;
+
+	# save r30/r31 on stack so we can put fn/arg in them
+	stdu 30, -32(1)
+	std  31,   8(1)
+
+	# save r3 (func) into r30, and r6(arg) into r31
+	mr   30, 3
+	mr   31, 6
+
+	# shuffle args into correct registers and call SYS_clone
+	mr    3, 5
+	#mr   4, 4
+	mr    5, 7
+	mr    6, 8
+	mr    7, 9
+	li    0, 120  # SYS_clone = 120
+	sc
+
+	# if error, negate return (errno)
+	bns+  1f
+	neg   3, 3
+
+1:	# if we're the parent, goto cleanup
+	cmpwi cr7, 3, 0
+	bne   cr7, 2f
+
+	# we're the child. call fn(arg)
+	mr     3, 31
+	mr    12, 30
+	mtctr 12
+	bctrl
+
+	# call SYS_exit. exit code is already in r3 from fn return value
+	li    0, 1    # SYS_exit = 1
+	sc
+
+2:	# cleanup: restore r30/r31 from stack and return
+	ld   30, 0(1)
+	ld   31, 8(1)
+	addi  1, 1, 32
+	blr
+
diff --git a/src/thread/powerpc64/syscall_cp.s b/src/thread/powerpc64/syscall_cp.s
new file mode 100644
index 0000000..d420dbd
--- /dev/null
+++ b/src/thread/powerpc64/syscall_cp.s
@@ -0,0 +1,37 @@
+	.global __cp_begin
+	.hidden __cp_begin
+	.global __cp_end
+	.hidden __cp_end
+	.global __cp_cancel
+	.hidden __cp_cancel
+	.hidden __cancel
+	.global __syscall_cp_asm
+	.hidden __syscall_cp_asm
+	.text
+	.type   __syscall_cp_asm,%function
+__syscall_cp_asm:
+	# at enter: r3 = pointer to self->cancel, r4: syscall no, r5: first arg, r6: 2nd, r7: 3rd, r8: 4th, r9: 5th, r10: 6th
+__cp_begin:
+	# if (self->cancel) goto __cp_cancel
+	lwz   0, 0(3)
+	cmpwi cr7, 0, 0
+	bne-  cr7, __cp_cancel
+
+	# make syscall
+	mr    0,  4
+	mr    3,  5
+	mr    4,  6
+	mr    5,  7
+	mr    6,  8
+	mr    7,  9
+	mr    8, 10
+	sc
+
+__cp_end:
+	# return error ? -r3 : r3
+	bnslr+
+	neg 3, 3
+	blr
+
+__cp_cancel:
+	b __cancel
-- 
2.8.0



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-04  5:26 [PATCH v2] add powerpc64 port Bobby Bingham
@ 2016-04-13 23:05 ` Szabolcs Nagy
  2016-04-13 23:13   ` Rich Felker
  2016-04-14  8:01   ` Bobby Bingham
  0 siblings, 2 replies; 14+ messages in thread
From: Szabolcs Nagy @ 2016-04-13 23:05 UTC (permalink / raw)
  To: musl

* Bobby Bingham <koorogi@koorogi.info> [2016-04-04 00:26:11 -0500]:
> +++ b/arch/powerpc64/bits/setjmp.h
> @@ -0,0 +1 @@
> +typedef unsigned long long __jmp_buf[66];

hm glibc seems to use long[64] with 16byte alignment,
is the size diff because of alignment?

> +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
> +#define MINSIGSTKSZ 2048
> +#define SIGSTKSZ    8192
> +#endif

i think these should be bigger, e.g. follow ppc 4k, 10k

> +typedef struct {
> +	unsigned long vrregs[32][2];
> +	unsigned _pad[3];
> +	unsigned vrsave;
> +	unsigned vscr;
> +	unsigned _pad2[3];
> +} vrregset_t;

it seems this type should be 16 byte aligned like elf_vrreg_t

(aarch64 has a similar issue i plan to fix: there we use
128bit long double to get correct alignment, but kernel
and glibc uses __int128 which is visible in public headers.
in powerpc64 at least __vector128 is not exposed in glibc,
only 16byte aligned structs.)

> +++ b/arch/powerpc64/bits/syscall.h
> @@ -0,0 +1,718 @@
> +#define __NR_restart_syscall          0
> +#define __NR_exit                     1
> +#define __NR_fork                     2
...
> +#define SYS_restart_syscall __NR_restart_syscall
> +#define SYS_exit __NR_exit
> +#define SYS_fork __NR_fork

i prefer SYS_ to use numbers too (easier to update for me),
but it should be probably fixed together across archs.

> +++ b/arch/powerpc64/reloc.h
> @@ -0,0 +1,32 @@
> +#include <endian.h>
> +
> +#if __BYTE_ORDER == __LITTLE_ENDIAN
> +#define ENDIAN_SUFFIX "le"
> +#else
> +#define ENDIAN_SUFFIX ""
> +#endif
> +
> +#define LDSO_ARCH "powerpc64" ENDIAN_SUFFIX
> +

gcc also has -sf, i'm not sure if we should care about
ppc64 soft-float

> +#define TPOFF_K (-0x7000)
> +
> +#define REL_SYMBOLIC    R_PPC64_ADDR64
> +#define REL_GOT         R_PPC64_GLOB_DAT
> +#define REL_PLT         R_PPC64_JMP_SLOT
> +#define REL_RELATIVE    R_PPC64_RELATIVE
> +#define REL_COPY        R_PPC64_COPY
> +#define REL_DTPMOD      R_PPC64_DTPMOD64
> +#define REL_DTPOFF      R_PPC64_DTPREL64
> +#define REL_TPOFF       R_PPC64_TPREL64

this reminds me that ppc(64) now has a tls optimization
if the module is tagged with DT_PPC(64)_OPT, we don't
need to implement it yet, but eventually elf.h should
be updated.

> +++ b/src/fenv/powerpc64/fenv.c
> @@ -0,0 +1,68 @@
> +#define _GNU_SOURCE
> +#include <fenv.h>
> +
> +static inline double get_fpscr_f(void)
> +{
> +	double d;
> +	__asm__ __volatile__("mffs %0" : "=d"(d));
> +	return d;
> +}
> +
> +static inline long get_fpscr(void)
> +{
> +	return (union {double f; long i;}) {get_fpscr_f()}.i;
> +}
> +
> +static inline void set_fpscr_f(double fpscr)
> +{
> +	__asm__ __volatile__("mtfsf 255, %0" : : "d"(fpscr));
> +}
> +
> +static void set_fpscr(long fpscr)
> +{
> +	set_fpscr_f((union {long i; double f;}) {fpscr}.f);
> +}
> +

yes now that .c is allowed under arch/ dirs, it
makes sense to do fenv with such set/get_fpscr

otherwise the patch looked good.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-13 23:05 ` Szabolcs Nagy
@ 2016-04-13 23:13   ` Rich Felker
  2016-04-14  0:58     ` Szabolcs Nagy
  2016-04-14  8:01   ` Bobby Bingham
  1 sibling, 1 reply; 14+ messages in thread
From: Rich Felker @ 2016-04-13 23:13 UTC (permalink / raw)
  To: musl

On Thu, Apr 14, 2016 at 01:05:07AM +0200, Szabolcs Nagy wrote:
> * Bobby Bingham <koorogi@koorogi.info> [2016-04-04 00:26:11 -0500]:
> > +++ b/arch/powerpc64/bits/setjmp.h
> > @@ -0,0 +1 @@
> > +typedef unsigned long long __jmp_buf[66];
> 
> hm glibc seems to use long[64] with 16byte alignment,
> is the size diff because of alignment?

Good catch.

> > +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
> > +#define MINSIGSTKSZ 2048
> > +#define SIGSTKSZ    8192
> > +#endif
> 
> i think these should be bigger, e.g. follow ppc 4k, 10k

Agreed.

> > +typedef struct {
> > +	unsigned long vrregs[32][2];
> > +	unsigned _pad[3];
> > +	unsigned vrsave;
> > +	unsigned vscr;
> > +	unsigned _pad2[3];
> > +} vrregset_t;
> 
> it seems this type should be 16 byte aligned like elf_vrreg_t
> 
> (aarch64 has a similar issue i plan to fix: there we use
> 128bit long double to get correct alignment, but kernel
> and glibc uses __int128 which is visible in public headers.
> in powerpc64 at least __vector128 is not exposed in glibc,
> only 16byte aligned structs.)

I don't know what the best solution here is.

> > +++ b/arch/powerpc64/bits/syscall.h
> > @@ -0,0 +1,718 @@
> > +#define __NR_restart_syscall          0
> > +#define __NR_exit                     1
> > +#define __NR_fork                     2
> ....
> > +#define SYS_restart_syscall __NR_restart_syscall
> > +#define SYS_exit __NR_exit
> > +#define SYS_fork __NR_fork
> 
> i prefer SYS_ to use numbers too (easier to update for me),
> but it should be probably fixed together across archs.

I want to replace arch/*/bits/syscall.h with .in files that get
processed as something like:

	sed -e p -e s/__NR_/SYS_/ < $< > $@

This would reduce the source tree size a lot and eliminate the risk of
inconsistency.

> > +++ b/arch/powerpc64/reloc.h
> > @@ -0,0 +1,32 @@
> > +#include <endian.h>
> > +
> > +#if __BYTE_ORDER == __LITTLE_ENDIAN
> > +#define ENDIAN_SUFFIX "le"
> > +#else
> > +#define ENDIAN_SUFFIX ""
> > +#endif
> > +
> > +#define LDSO_ARCH "powerpc64" ENDIAN_SUFFIX
> > +
> 
> gcc also has -sf, i'm not sure if we should care about
> ppc64 soft-float

Probably not, but perhaps we should test in configure and reject it if
it's not supported correctly.

> > +#define TPOFF_K (-0x7000)
> > +
> > +#define REL_SYMBOLIC    R_PPC64_ADDR64
> > +#define REL_GOT         R_PPC64_GLOB_DAT
> > +#define REL_PLT         R_PPC64_JMP_SLOT
> > +#define REL_RELATIVE    R_PPC64_RELATIVE
> > +#define REL_COPY        R_PPC64_COPY
> > +#define REL_DTPMOD      R_PPC64_DTPMOD64
> > +#define REL_DTPOFF      R_PPC64_DTPREL64
> > +#define REL_TPOFF       R_PPC64_TPREL64
> 
> this reminds me that ppc(64) now has a tls optimization
> if the module is tagged with DT_PPC(64)_OPT, we don't
> need to implement it yet, but eventually elf.h should
> be updated.

Details?

> > +++ b/src/fenv/powerpc64/fenv.c
> > @@ -0,0 +1,68 @@
> > +#define _GNU_SOURCE
> > +#include <fenv.h>
> > +
> > +static inline double get_fpscr_f(void)
> > +{
> > +	double d;
> > +	__asm__ __volatile__("mffs %0" : "=d"(d));
> > +	return d;
> > +}
> > +
> > +static inline long get_fpscr(void)
> > +{
> > +	return (union {double f; long i;}) {get_fpscr_f()}.i;
> > +}
> > +
> > +static inline void set_fpscr_f(double fpscr)
> > +{
> > +	__asm__ __volatile__("mtfsf 255, %0" : : "d"(fpscr));
> > +}
> > +
> > +static void set_fpscr(long fpscr)
> > +{
> > +	set_fpscr_f((union {long i; double f;}) {fpscr}.f);
> > +}
> > +
> 
> yes now that .c is allowed under arch/ dirs, it
> makes sense to do fenv with such set/get_fpscr

Yes. At some point it would be nice to make it so most archs can just
define inline functions to load/store their fpu control/status
registers, and a generic fenv.c can implement all the functions. A few
weird archs (x86) would still need custom versions to be efficient but
most could use the generic framework. But this change should not be a
blocker for ppc64. I like the above approach fine for now.

Rich


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-13 23:13   ` Rich Felker
@ 2016-04-14  0:58     ` Szabolcs Nagy
  0 siblings, 0 replies; 14+ messages in thread
From: Szabolcs Nagy @ 2016-04-14  0:58 UTC (permalink / raw)
  To: musl

* Rich Felker <dalias@libc.org> [2016-04-13 19:13:59 -0400]:
> On Thu, Apr 14, 2016 at 01:05:07AM +0200, Szabolcs Nagy wrote:
> > this reminds me that ppc(64) now has a tls optimization
> > if the module is tagged with DT_PPC(64)_OPT, we don't
> > need to implement it yet, but eventually elf.h should
> > be updated.
> 
> Details?
> 

http://www.sourceware.org/ml/libc-alpha/2015-03/msg00580.html
http://sourceware.org/git/?p=glibc.git;a=commit;h=afcd9480feca651eef436d8438b783dde5c3bbb2

elf.h is missing new macros added in the last 2 years or so,
like DT_PCC_OPT. i assumed the tls optimization is backward
compatible so it's not critical.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-13 23:05 ` Szabolcs Nagy
  2016-04-13 23:13   ` Rich Felker
@ 2016-04-14  8:01   ` Bobby Bingham
  2016-04-14 13:42     ` Szabolcs Nagy
  2016-04-14 19:14     ` Rich Felker
  1 sibling, 2 replies; 14+ messages in thread
From: Bobby Bingham @ 2016-04-14  8:01 UTC (permalink / raw)
  To: musl

On Thu, Apr 14, 2016 at 01:05:07AM +0200, Szabolcs Nagy wrote:
> * Bobby Bingham <koorogi@koorogi.info> [2016-04-04 00:26:11 -0500]:
> > +++ b/arch/powerpc64/bits/setjmp.h
> > @@ -0,0 +1 @@
> > +typedef unsigned long long __jmp_buf[66];
> 
> hm glibc seems to use long[64] with 16byte alignment,
> is the size diff because of alignment?

Yes.  Though apparently the glibc setjmp asm has code to detect a
misaligned jmp_buf, but its handling of that case ends up overflowing
the jmp_buf.

I can make some changes to get our jmp_buf down to 65, but the only ways
to get it down to 64 are either with 16 byte alignment, or to have setjmp
spill vector registers to the stack first so it can copy them from there
to the jmp_buf through a gpr.

How important is it to match glibc here?

> 
> > +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
> > +#define MINSIGSTKSZ 2048
> > +#define SIGSTKSZ    8192
> > +#endif
> 
> i think these should be bigger, e.g. follow ppc 4k, 10k
> 

Ok.

> > +typedef struct {
> > +	unsigned long vrregs[32][2];
> > +	unsigned _pad[3];
> > +	unsigned vrsave;
> > +	unsigned vscr;
> > +	unsigned _pad2[3];
> > +} vrregset_t;
> 
> it seems this type should be 16 byte aligned like elf_vrreg_t
> 
> (aarch64 has a similar issue i plan to fix: there we use
> 128bit long double to get correct alignment, but kernel
> and glibc uses __int128 which is visible in public headers.
> in powerpc64 at least __vector128 is not exposed in glibc,
> only 16byte aligned structs.)
> 
> > +++ b/arch/powerpc64/bits/syscall.h
> > @@ -0,0 +1,718 @@
> > +#define __NR_restart_syscall          0
> > +#define __NR_exit                     1
> > +#define __NR_fork                     2
> ...
> > +#define SYS_restart_syscall __NR_restart_syscall
> > +#define SYS_exit __NR_exit
> > +#define SYS_fork __NR_fork
> 
> i prefer SYS_ to use numbers too (easier to update for me),
> but it should be probably fixed together across archs.

I can do this for now, but I like Rich's suggestion to remove this
duplication.
> 
> > +++ b/arch/powerpc64/reloc.h
> > @@ -0,0 +1,32 @@
> > +#include <endian.h>
> > +
> > +#if __BYTE_ORDER == __LITTLE_ENDIAN
> > +#define ENDIAN_SUFFIX "le"
> > +#else
> > +#define ENDIAN_SUFFIX ""
> > +#endif
> > +
> > +#define LDSO_ARCH "powerpc64" ENDIAN_SUFFIX
> > +
> 
> gcc also has -sf, i'm not sure if we should care about
> ppc64 soft-float

I'll see if we can at least detect it in configure and error out.

> 
> > +#define TPOFF_K (-0x7000)
> > +
> > +#define REL_SYMBOLIC    R_PPC64_ADDR64
> > +#define REL_GOT         R_PPC64_GLOB_DAT
> > +#define REL_PLT         R_PPC64_JMP_SLOT
> > +#define REL_RELATIVE    R_PPC64_RELATIVE
> > +#define REL_COPY        R_PPC64_COPY
> > +#define REL_DTPMOD      R_PPC64_DTPMOD64
> > +#define REL_DTPOFF      R_PPC64_DTPREL64
> > +#define REL_TPOFF       R_PPC64_TPREL64
> 
> this reminds me that ppc(64) now has a tls optimization
> if the module is tagged with DT_PPC(64)_OPT, we don't
> need to implement it yet, but eventually elf.h should
> be updated.
> 
> > +++ b/src/fenv/powerpc64/fenv.c
> > @@ -0,0 +1,68 @@
> > +#define _GNU_SOURCE
> > +#include <fenv.h>
> > +
> > +static inline double get_fpscr_f(void)
> > +{
> > +	double d;
> > +	__asm__ __volatile__("mffs %0" : "=d"(d));
> > +	return d;
> > +}
> > +
> > +static inline long get_fpscr(void)
> > +{
> > +	return (union {double f; long i;}) {get_fpscr_f()}.i;
> > +}
> > +
> > +static inline void set_fpscr_f(double fpscr)
> > +{
> > +	__asm__ __volatile__("mtfsf 255, %0" : : "d"(fpscr));
> > +}
> > +
> > +static void set_fpscr(long fpscr)
> > +{
> > +	set_fpscr_f((union {long i; double f;}) {fpscr}.f);
> > +}
> > +
> 
> yes now that .c is allowed under arch/ dirs, it
> makes sense to do fenv with such set/get_fpscr
> 
> otherwise the patch looked good.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-14  8:01   ` Bobby Bingham
@ 2016-04-14 13:42     ` Szabolcs Nagy
  2016-04-15 20:38       ` Szabolcs Nagy
  2016-04-14 19:14     ` Rich Felker
  1 sibling, 1 reply; 14+ messages in thread
From: Szabolcs Nagy @ 2016-04-14 13:42 UTC (permalink / raw)
  To: musl

* Bobby Bingham <koorogi@koorogi.info> [2016-04-14 03:01:38 -0500]:
> On Thu, Apr 14, 2016 at 01:05:07AM +0200, Szabolcs Nagy wrote:
> > * Bobby Bingham <koorogi@koorogi.info> [2016-04-04 00:26:11 -0500]:
> > > +++ b/arch/powerpc64/bits/setjmp.h
> > > @@ -0,0 +1 @@
> > > +typedef unsigned long long __jmp_buf[66];
> > 
> > hm glibc seems to use long[64] with 16byte alignment,
> > is the size diff because of alignment?
> 
> Yes.  Though apparently the glibc setjmp asm has code to detect a
> misaligned jmp_buf, but its handling of that case ends up overflowing
> the jmp_buf.
> 
> I can make some changes to get our jmp_buf down to 65, but the only ways
> to get it down to 64 are either with 16 byte alignment, or to have setjmp
> spill vector registers to the stack first so it can copy them from there
> to the jmp_buf through a gpr.
> 
> How important is it to match glibc here?
> 

i think we don't care about abi compat
(but it might be interesting to check how much abi
difference there is between glibc and musl, i can
do this if i can build a musl+glibc toolchain)

i just wanted to make sure we understand the
cause of the difference.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-14  8:01   ` Bobby Bingham
  2016-04-14 13:42     ` Szabolcs Nagy
@ 2016-04-14 19:14     ` Rich Felker
  2016-04-15  0:55       ` Bobby Bingham
  1 sibling, 1 reply; 14+ messages in thread
From: Rich Felker @ 2016-04-14 19:14 UTC (permalink / raw)
  To: musl

On Thu, Apr 14, 2016 at 03:01:38AM -0500, Bobby Bingham wrote:
> On Thu, Apr 14, 2016 at 01:05:07AM +0200, Szabolcs Nagy wrote:
> > * Bobby Bingham <koorogi@koorogi.info> [2016-04-04 00:26:11 -0500]:
> > > +++ b/arch/powerpc64/bits/setjmp.h
> > > @@ -0,0 +1 @@
> > > +typedef unsigned long long __jmp_buf[66];
> > 
> > hm glibc seems to use long[64] with 16byte alignment,
> > is the size diff because of alignment?
> 
> Yes.  Though apparently the glibc setjmp asm has code to detect a
> misaligned jmp_buf, but its handling of that case ends up overflowing
> the jmp_buf.
> 
> I can make some changes to get our jmp_buf down to 65, but the only ways
> to get it down to 64 are either with 16 byte alignment, or to have setjmp
> spill vector registers to the stack first so it can copy them from there
> to the jmp_buf through a gpr.
> 
> How important is it to match glibc here?

I think you could avoid the need for alignment or increased buffer
size by positioning the vector registers at
jmp_buf_end-vector_save_size rounded _down_ to alignment, then
positioning the grps around them (so, putting the last gpr at the end
rather than before the vectors if the buffer as a whole is
misaligned).

But it might be preferable to have the alignment match ABI too. Is
there any way it can be achieved with just things guaranteed to exist
by the psABI (is __int128 required by the psABI?) or does it require
C11 and/or GNUC attributes to get 16-byte alignment?

Rich


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-14 19:14     ` Rich Felker
@ 2016-04-15  0:55       ` Bobby Bingham
  2016-04-15  2:08         ` Rich Felker
  0 siblings, 1 reply; 14+ messages in thread
From: Bobby Bingham @ 2016-04-15  0:55 UTC (permalink / raw)
  To: musl

On Thu, Apr 14, 2016 at 03:14:00PM -0400, Rich Felker wrote:
> On Thu, Apr 14, 2016 at 03:01:38AM -0500, Bobby Bingham wrote:
> > On Thu, Apr 14, 2016 at 01:05:07AM +0200, Szabolcs Nagy wrote:
> > > * Bobby Bingham <koorogi@koorogi.info> [2016-04-04 00:26:11 -0500]:
> > > > +++ b/arch/powerpc64/bits/setjmp.h
> > > > @@ -0,0 +1 @@
> > > > +typedef unsigned long long __jmp_buf[66];
> > > 
> > > hm glibc seems to use long[64] with 16byte alignment,
> > > is the size diff because of alignment?
> > 
> > Yes.  Though apparently the glibc setjmp asm has code to detect a
> > misaligned jmp_buf, but its handling of that case ends up overflowing
> > the jmp_buf.
> > 
> > I can make some changes to get our jmp_buf down to 65, but the only ways
> > to get it down to 64 are either with 16 byte alignment, or to have setjmp
> > spill vector registers to the stack first so it can copy them from there
> > to the jmp_buf through a gpr.
> > 
> > How important is it to match glibc here?
> 
> I think you could avoid the need for alignment or increased buffer
> size by positioning the vector registers at
> jmp_buf_end-vector_save_size rounded _down_ to alignment, then
> positioning the grps around them (so, putting the last gpr at the end
> rather than before the vectors if the buffer as a whole is
> misaligned).

Is it valid to do the following?

	jmp_buf a, b;
	if (!setjmp(a)) {
		memcpy(b, a, sizeof a);
		longjmp(b, 1);
	}

If that's valid, and the two jmp_bufs might be aligned differently, then
this wouldn't work.

> 
> But it might be preferable to have the alignment match ABI too. Is
> there any way it can be achieved with just things guaranteed to exist
> by the psABI (is __int128 required by the psABI?) or does it require
> C11 and/or GNUC attributes to get 16-byte alignment?

The ABI does specify __int128.  I can switch jmp_buf to this.

> 
> Rich


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-15  0:55       ` Bobby Bingham
@ 2016-04-15  2:08         ` Rich Felker
  0 siblings, 0 replies; 14+ messages in thread
From: Rich Felker @ 2016-04-15  2:08 UTC (permalink / raw)
  To: musl

On Thu, Apr 14, 2016 at 07:55:51PM -0500, Bobby Bingham wrote:
> On Thu, Apr 14, 2016 at 03:14:00PM -0400, Rich Felker wrote:
> > On Thu, Apr 14, 2016 at 03:01:38AM -0500, Bobby Bingham wrote:
> > > On Thu, Apr 14, 2016 at 01:05:07AM +0200, Szabolcs Nagy wrote:
> > > > * Bobby Bingham <koorogi@koorogi.info> [2016-04-04 00:26:11 -0500]:
> > > > > +++ b/arch/powerpc64/bits/setjmp.h
> > > > > @@ -0,0 +1 @@
> > > > > +typedef unsigned long long __jmp_buf[66];
> > > > 
> > > > hm glibc seems to use long[64] with 16byte alignment,
> > > > is the size diff because of alignment?
> > > 
> > > Yes.  Though apparently the glibc setjmp asm has code to detect a
> > > misaligned jmp_buf, but its handling of that case ends up overflowing
> > > the jmp_buf.
> > > 
> > > I can make some changes to get our jmp_buf down to 65, but the only ways
> > > to get it down to 64 are either with 16 byte alignment, or to have setjmp
> > > spill vector registers to the stack first so it can copy them from there
> > > to the jmp_buf through a gpr.
> > > 
> > > How important is it to match glibc here?
> > 
> > I think you could avoid the need for alignment or increased buffer
> > size by positioning the vector registers at
> > jmp_buf_end-vector_save_size rounded _down_ to alignment, then
> > positioning the grps around them (so, putting the last gpr at the end
> > rather than before the vectors if the buffer as a whole is
> > misaligned).
> 
> Is it valid to do the following?
> 
> 	jmp_buf a, b;
> 	if (!setjmp(a)) {
> 		memcpy(b, a, sizeof a);
> 		longjmp(b, 1);
> 	}
> 
> If that's valid, and the two jmp_bufs might be aligned differently, then
> this wouldn't work.

No, jmp_buf's are not values. You have to pass the same object that
was passed when calling setjmp when you call longjmp. The relevant
text is 7.13.2.1, paragraph 2:

"The longjmp function restores the environment saved by the most
recent invocation of the setjmp macro in the same invocation of the
program with the corresponding jmp_buf argument. If there has been no
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
such invocation, or ... the behavior is undefined."

> > But it might be preferable to have the alignment match ABI too. Is
> > there any way it can be achieved with just things guaranteed to exist
> > by the psABI (is __int128 required by the psABI?) or does it require
> > C11 and/or GNUC attributes to get 16-byte alignment?
> 
> The ABI does specify __int128.  I can switch jmp_buf to this.

That's probably the right thing to do, then. Anyone else have an
opinion on it?

Rich


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-14 13:42     ` Szabolcs Nagy
@ 2016-04-15 20:38       ` Szabolcs Nagy
  2016-04-16 17:09         ` Rich Felker
  0 siblings, 1 reply; 14+ messages in thread
From: Szabolcs Nagy @ 2016-04-15 20:38 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 857 bytes --]

* Szabolcs Nagy <nsz@port70.net> [2016-04-14 15:42:13 +0200]:
> * Bobby Bingham <koorogi@koorogi.info> [2016-04-14 03:01:38 -0500]:
> > 
> > How important is it to match glibc here?
> > 
> 
> i think we don't care about abi compat
> (but it might be interesting to check how much abi
> difference there is between glibc and musl, i can
> do this if i can build a musl+glibc toolchain)
> 

attached some c++ abi comparisions

(the comparision was not entirely clean, it involved
various manual hacks, but most types and functions
should be compared correctly glibc vs musl)

two interesting gcc warnings:

powerpc64 elf_vrreg_t (both musl and glibc):
note: the ABI of passing aggregates with 16-byte alignment has changed in GCC 5

x86_64 struct inotify_event (musl only):
note: the ABI of passing struct with a flexible array member has changed in GCC 4.4


[-- Attachment #2: abi_type.powerpc64le.diff --]
[-- Type: text/x-diff, Size: 5984 bytes --]

--- abi_type.powerpc64le.glibc	2016-04-15 21:00:27.432246225 +0100
+++ abi_type.powerpc64le.musl	2016-04-15 20:57:39.000149371 +0100
@@ -1 +0,0 @@
-std::piecewise_construct
@@ -3 +2 @@
-CODE: _code, _code*, size (*) [16], align (*) [8]
+CODE: CODE, CODE*, size (*) [16], align (*) [8]
@@ -69 +68 @@
-__jmp_buf: long*, long (*) [64], size (*) [512], align (*) [16]
+__jmp_buf: unsigned long long*, unsigned long long (*) [66], size (*) [528], align (*) [8]
@@ -90,2 +89,2 @@
-elf_vrreg_t: __vector128, __vector128*, size (*) [16], align (*) [16]
-elf_vrregset_t: __vector128*, __vector128 (*) [34], size (*) [544], align (*) [16]
+elf_vrreg_t: elf_vrreg_t, elf_vrreg_t*, size (*) [16], align (*) [16]
+elf_vrregset_t: elf_vrreg_t*, elf_vrreg_t (*) [34], size (*) [544], align (*) [16]
@@ -94 +93 @@
-fd_mask: long, long*, size (*) [8], align (*) [8]
+fd_mask: unsigned long, unsigned long*, size (*) [8], align (*) [8]
@@ -97 +96 @@
-fexcept_t: unsigned int, unsigned int*, size (*) [4], align (*) [4]
+fexcept_t: unsigned long, unsigned long*, size (*) [8], align (*) [8]
@@ -100,2 +99,2 @@
-fpos_t: _G_fpos_t, _G_fpos_t*, size (*) [16], align (*) [8]
-fpregset_t: double*, double (*) [33], size (*) [264], align (*) [8]
+fpos_t: _G_fpos64_t, _G_fpos64_t*, size (*) [16], align (*) [8]
+fpregset_t: fpregset_t, fpregset_t*, size (*) [264], align (*) [8]
@@ -106,0 +106 @@
+greg_t: unsigned long, unsigned long*, size (*) [8], align (*) [8]
@@ -120,2 +120,2 @@
-int_fast16_t: long, long*, size (*) [8], align (*) [8]
-int_fast32_t: long, long*, size (*) [8], align (*) [8]
+int_fast16_t: int, int*, size (*) [4], align (*) [4]
+int_fast32_t: int, int*, size (*) [4], align (*) [4]
@@ -130 +130 @@
-jmp_buf: __jmp_buf_tag*, __jmp_buf_tag (*) [1], size (*) [656], align (*) [16]
+jmp_buf: __jmp_buf_tag*, __jmp_buf_tag (*) [1], size (*) [664], align (*) [8]
@@ -141 +141 @@
-mcontext_t: mcontext_t, mcontext_t*, size (*) [1272], align (*) [8]
+mcontext_t: sigcontext, sigcontext*, size (*) [1528], align (*) [8]
@@ -183,2 +183,2 @@
-pthread_rwlockattr_t: pthread_rwlockattr_t, pthread_rwlockattr_t*, size (*) [8], align (*) [8]
-pthread_spinlock_t: int, int volatile*, size (*) [4], align (*) [4]
+pthread_rwlockattr_t: pthread_rwlockattr_t, pthread_rwlockattr_t*, size (*) [8], align (*) [4]
+pthread_spinlock_t: int, int*, size (*) [4], align (*) [4]
@@ -187 +187 @@
-quad_t: long, long*, size (*) [8], align (*) [8]
+quad_t: long long, long long*, size (*) [8], align (*) [8]
@@ -190,2 +190,2 @@
-regmatch_t: regmatch_t, regmatch_t*, size (*) [8], align (*) [4]
-regoff_t: int, int*, size (*) [4], align (*) [4]
+regmatch_t: regmatch_t, regmatch_t*, size (*) [16], align (*) [8]
+regoff_t: long, long*, size (*) [8], align (*) [8]
@@ -193 +193 @@
-rlim_t: unsigned long, unsigned long*, size (*) [8], align (*) [8]
+rlim_t: unsigned long long, unsigned long long*, size (*) [8], align (*) [8]
@@ -195 +195 @@
-sem_t: sem_t, sem_t*, size (*) [32], align (*) [8]
+sem_t: sem_t, sem_t*, size (*) [32], align (*) [4]
@@ -205 +205 @@
-sigjmp_buf: __jmp_buf_tag*, __jmp_buf_tag (*) [1], size (*) [656], align (*) [16]
+sigjmp_buf: __jmp_buf_tag*, __jmp_buf_tag (*) [1], size (*) [664], align (*) [8]
@@ -213 +213 @@
-__jmp_buf_tag: __jmp_buf_tag, __jmp_buf_tag*, size (*) [656], align (*) [16]
+__jmp_buf_tag: __jmp_buf_tag, __jmp_buf_tag*, size (*) [664], align (*) [8]
@@ -229,2 +229,2 @@
-cmsghdr: cmsghdr, cmsghdr*, size (*) [16], align (*) [8]
-crypt_data: crypt_data, crypt_data*, size (*) [131232], align (*) [8]
+cmsghdr: cmsghdr, cmsghdr*, size (*) [16], align (*) [4]
+crypt_data: crypt_data, crypt_data*, size (*) [260], align (*) [4]
@@ -242,2 +242,2 @@
-ether_header: ether_header, ether_header*, size (*) [14], align (*) [1]
-ethhdr: ethhdr, ethhdr*, size (*) [14], align (*) [1]
+ether_header: ether_header, ether_header*, size (*) [14], align (*) [2]
+ethhdr: ethhdr, ethhdr*, size (*) [14], align (*) [2]
@@ -299 +299 @@
-lastlog: lastlog, lastlog*, size (*) [292], align (*) [4]
+lastlog: lastlog, lastlog*, size (*) [296], align (*) [8]
@@ -330 +330 @@
-ntptimeval: ntptimeval, ntptimeval*, size (*) [72], align (*) [8]
+ntptimeval: ntptimeval, ntptimeval*, size (*) [32], align (*) [8]
@@ -334,0 +335 @@
+prctl_mm_map: prctl_mm_map, prctl_mm_map*, size (*) [104], align (*) [8]
@@ -346,2 +347,2 @@
-rusage: rusage, rusage*, size (*) [144], align (*) [8]
-sched_param: sched_param, sched_param*, size (*) [4], align (*) [4]
+rusage: rusage, rusage*, size (*) [272], align (*) [8]
+sched_param: sched_param, sched_param*, size (*) [48], align (*) [8]
@@ -382,2 +383,2 @@
-sysinfo: sysinfo, sysinfo*, size (*) [112], align (*) [8]
-tcp_info: tcp_info, tcp_info*, size (*) [104], align (*) [4]
+sysinfo: sysinfo, sysinfo*, size (*) [368], align (*) [8]
+tcp_info: tcp_info, tcp_info*, size (*) [144], align (*) [8]
@@ -386,2 +387,2 @@
-termios: termios, termios*, size (*) [60], align (*) [4]
-tftphdr: tftphdr, tftphdr*, size (*) [5], align (*) [1]
+termios: termios, termios*, size (*) [44], align (*) [4]
+tftphdr: tftphdr, tftphdr*, size (*) [6], align (*) [2]
@@ -400 +401 @@
-utmpx: utmpx, utmpx*, size (*) [384], align (*) [4]
+utmpx: utmpx, utmpx*, size (*) [400], align (*) [8]
@@ -414 +415 @@
-u_quad_t: unsigned long, unsigned long*, size (*) [8], align (*) [8]
+u_quad_t: unsigned long long, unsigned long long*, size (*) [8], align (*) [8]
@@ -416 +417 @@
-ucontext_t: ucontext, ucontext*, size (*) [1440], align (*) [8]
+ucontext_t: ucontext, ucontext*, size (*) [1696], align (*) [8]
@@ -423,2 +424,2 @@
-uint_fast16_t: unsigned long, unsigned long*, size (*) [8], align (*) [8]
-uint_fast32_t: unsigned long, unsigned long*, size (*) [8], align (*) [8]
+uint_fast16_t: unsigned int, unsigned int*, size (*) [4], align (*) [4]
+uint_fast32_t: unsigned int, unsigned int*, size (*) [4], align (*) [4]
@@ -440 +441 @@
-vrregset_t: _libc_vrstate, _libc_vrstate*, size (*) [544], align (*) [16]
+vrregset_t: vrregset_t, vrregset_t*, size (*) [544], align (*) [8]

[-- Attachment #3: abi_func.powerpc64le.diff --]
[-- Type: text/x-diff, Size: 5518 bytes --]

--- abi_func.powerpc64le.glibc	2016-04-15 20:53:34.364008400 +0100
+++ abi_func.powerpc64le.musl	2016-04-15 20:11:08.522531385 +0100
@@ -1 +0,0 @@
-std::piecewise_construct
@@ -3 +2 @@
-void __assert_fail(char const*, char const*, unsigned int, char const*)
+void __assert_fail(char const*, char const*, int, char const*)
@@ -7,0 +7 @@
+int __flt_rounds()
@@ -12 +12 @@
-void __fpurge(_IO_FILE*)
+int __fpurge(_IO_FILE*)
@@ -13,0 +14 @@
+unsigned long __freadahead(_IO_FILE*)
@@ -14,0 +16,3 @@
+char const* __freadptr(_IO_FILE*, unsigned long*)
+void __freadptrinc(_IO_FILE*, unsigned long)
+void __fseterr(_IO_FILE*)
@@ -26,0 +31 @@
+int _flush_cache(void*, int, int)
@@ -28,0 +34,2 @@
+void _pthread_cleanup_pop(__ptcb*, int)
+void _pthread_cleanup_push(__ptcb*, void (*)(void*), void*)
@@ -96,0 +104,2 @@
+int cachectl(void*, int, int)
+int cacheflush(void*, int, int)
@@ -102,0 +112 @@
+void call_once(int*, void (*)())
@@ -166,0 +177,6 @@
+int cnd_broadcast(cnd_t*)
+void cnd_destroy(cnd_t*)
+int cnd_init(cnd_t*)
+int cnd_signal(cnd_t*)
+int cnd_timedwait(cnd_t*, mtx_t*, timespec const*)
+int cnd_wait(cnd_t*, mtx_t*)
@@ -300 +316 @@
-int fanotify_mark(int, unsigned int, unsigned long, int, char const*)
+int fanotify_mark(int, unsigned int, unsigned long long, int, char const*)
@@ -317 +333 @@
-int fegetexceptflag(unsigned int*, int)
+int fegetexceptflag(unsigned long*, int)
@@ -326 +342 @@
-int fesetexceptflag(unsigned int const*, int)
+int fesetexceptflag(unsigned long const*, int)
@@ -339 +355,2 @@
-int fgetpos(_IO_FILE*, _G_fpos_t*)
+char* fgetln(_IO_FILE*, unsigned long*)
+int fgetpos(_IO_FILE*, _G_fpos64_t*)
@@ -397 +414 @@
-int fsetpos(_IO_FILE*, _G_fpos_t const*)
+int fsetpos(_IO_FILE*, _G_fpos64_t const*)
@@ -436,0 +454 @@
+int getdents(int, dirent*, unsigned long)
@@ -493,0 +512 @@
+char* gets(char*)
@@ -506 +525 @@
-int gettimeofday(timeval*, timezone*)
+int gettimeofday(timeval*, void*)
@@ -509,3 +528,3 @@
-utmp* getutent()
-utmp* getutid(utmp const*)
-utmp* getutline(utmp const*)
+utmpx* getutent()
+utmpx* getutid(utmpx const*)
+utmpx* getutline(utmpx const*)
@@ -549,0 +569 @@
+char* index(char const*, int)
@@ -566 +586,3 @@
-int ioctl(int, unsigned long, ...)
+int ioctl(int, int, ...)
+int ioperm(unsigned long, unsigned long, int)
+int iopl(int)
@@ -587,0 +610 @@
+int issetugid()
@@ -650 +673 @@
-int lio_listio(int, aiocb* const*, int, sigevent*)
+int lio_listio(int, aiocb* const restrict*, int, sigevent*)
@@ -711,0 +735 @@
+void* memchr(void const*, int, unsigned long)
@@ -716,0 +741 @@
+void* memrchr(void const*, int, unsigned long)
@@ -756,0 +782,6 @@
+void mtx_destroy(mtx_t*)
+int mtx_init(mtx_t*, int)
+int mtx_lock(mtx_t*)
+int mtx_timedlock(mtx_t*, timespec const*)
+int mtx_trylock(mtx_t*)
+int mtx_unlock(mtx_t*)
@@ -804,0 +836 @@
+int posix_close(int, int)
@@ -842 +874 @@
-int prlimit(int, __rlimit_resource, rlimit const*, rlimit*)
+int prlimit(int, int, rlimit const*, rlimit*)
@@ -945,5 +977,5 @@
-int pthread_spin_destroy(int volatile*)
-int pthread_spin_init(int volatile*, int)
-int pthread_spin_lock(int volatile*)
-int pthread_spin_trylock(int volatile*)
-int pthread_spin_unlock(int volatile*)
+int pthread_spin_destroy(int*)
+int pthread_spin_init(int*, int)
+int pthread_spin_lock(int*)
+int pthread_spin_trylock(int*)
+int pthread_spin_unlock(int*)
@@ -951 +983 @@
-long ptrace(__ptrace_request, ...)
+long ptrace(int, ...)
@@ -963 +995 @@
-utmp* pututline(utmp const*)
+utmpx* pututline(utmpx const*)
@@ -989 +1021 @@
-int recvmmsg(int, mmsghdr*, unsigned int, int, timespec*)
+int recvmmsg(int, mmsghdr*, unsigned int, unsigned int, timespec*)
@@ -1014,0 +1047 @@
+char* rindex(char const*, int)
@@ -1063 +1096 @@
-int sendmmsg(int, mmsghdr*, unsigned int, int)
+int sendmmsg(int, mmsghdr*, unsigned int, unsigned int)
@@ -1178,0 +1212 @@
+char* strcasestr(char const*, char const*)
@@ -1179,0 +1214,2 @@
+char* strchr(char const*, int)
+char* strchrnul(char const*, int)
@@ -1188 +1224 @@
-char* strerror_r(int, char*, unsigned long)
+int strerror_r(int, char*, unsigned long)
@@ -1192,0 +1229,2 @@
+unsigned long strlcat(char*, char const*, unsigned long)
+unsigned long strlcpy(char*, char const*, unsigned long)
@@ -1200,0 +1239 @@
+char* strpbrk(char const*, char const*)
@@ -1201,0 +1241 @@
+char* strrchr(char const*, int)
@@ -1204,0 +1245 @@
+char* strstr(char const*, char const*)
@@ -1262,0 +1304,8 @@
+int thrd_create(unsigned long*, int (*)(void*), void*)
+unsigned long thrd_current()
+int thrd_detach(unsigned long)
+int thrd_equal(unsigned long, unsigned long)
+void thrd_exit(int)
+int thrd_join(unsigned long, int*)
+int thrd_sleep(timespec const*, timespec*)
+void thrd_yield()
@@ -1292,0 +1342,4 @@
+int tss_create(unsigned int*, void (*)(void*))
+void tss_delete(unsigned int)
+void* tss_get(unsigned int)
+int tss_set(unsigned int, void*)
@@ -1311 +1364 @@
-void updwtmp(char const*, utmp const*)
+void updwtmp(char const*, utmpx const*)
@@ -1345,3 +1398,3 @@
-int wait(void*)
-int wait3(void*, int, rusage*)
-int wait4(int, void*, int, rusage*)
+int wait(int*)
+int wait3(int*, int, rusage*)
+int wait4(int, int*, int, rusage*)
@@ -1357,0 +1411 @@
+wchar_t* wcschr(wchar_t const*, wchar_t)
@@ -1372,0 +1427,2 @@
+wchar_t* wcspbrk(wchar_t const*, wchar_t const*)
+wchar_t* wcsrchr(wchar_t const*, wchar_t)
@@ -1374,0 +1431 @@
+wchar_t* wcsstr(wchar_t const*, wchar_t const*)
@@ -1385,0 +1443 @@
+wchar_t* wcswcs(wchar_t const*, wchar_t const*)
@@ -1395,0 +1454 @@
+wchar_t* wmemchr(wchar_t const*, wchar_t, unsigned long)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-15 20:38       ` Szabolcs Nagy
@ 2016-04-16 17:09         ` Rich Felker
  2016-04-28  1:38           ` Bobby Bingham
  0 siblings, 1 reply; 14+ messages in thread
From: Rich Felker @ 2016-04-16 17:09 UTC (permalink / raw)
  To: musl

On Fri, Apr 15, 2016 at 10:38:33PM +0200, Szabolcs Nagy wrote:
> * Szabolcs Nagy <nsz@port70.net> [2016-04-14 15:42:13 +0200]:
> > * Bobby Bingham <koorogi@koorogi.info> [2016-04-14 03:01:38 -0500]:
> > > 
> > > How important is it to match glibc here?
> > > 
> > 
> > i think we don't care about abi compat
> > (but it might be interesting to check how much abi
> > difference there is between glibc and musl, i can
> > do this if i can build a musl+glibc toolchain)
> > 
> 
> attached some c++ abi comparisions

Thanks!

> (the comparision was not entirely clean, it involved
> various manual hacks, but most types and functions
> should be compared correctly glibc vs musl)
> 
> two interesting gcc warnings:
> 
> powerpc64 elf_vrreg_t (both musl and glibc):
> note: the ABI of passing aggregates with 16-byte alignment has changed in GCC 5

This could be mildly problematic, but it's in a junk interface that's
unlikely to be used cross-library anyway.

> x86_64 struct inotify_event (musl only):
> note: the ABI of passing struct with a flexible array member has changed in GCC 4.4

This looks irrelevant; passing the struct by value does not make sense.

> --- abi_type.powerpc64le.glibc	2016-04-15 21:00:27.432246225 +0100
> +++ abi_type.powerpc64le.musl	2016-04-15 20:57:39.000149371 +0100
> @@ -97 +96 @@
> -fexcept_t: unsigned int, unsigned int*, size (*) [4], align (*) [4]
> +fexcept_t: unsigned long, unsigned long*, size (*) [8], align (*) [8]

Is this right?

> @@ -100,2 +99,2 @@
> -fpos_t: _G_fpos_t, _G_fpos_t*, size (*) [16], align (*) [8]
> +fpos_t: _G_fpos64_t, _G_fpos64_t*, size (*) [16], align (*) [8]

You should probably be testing with -D_FILE_OFFSET_BITS=64. musl
implements that ABI, and it matters in a few places even on 64-bit
archs, like here.

> @@ -130 +130 @@
> -jmp_buf: __jmp_buf_tag*, __jmp_buf_tag (*) [1], size (*) [656], align (*) [16]
> +jmp_buf: __jmp_buf_tag*, __jmp_buf_tag (*) [1], size (*) [664], align (*) [8]

Let's fix at least alignment and hopefully size.

> @@ -141 +141 @@
> -mcontext_t: mcontext_t, mcontext_t*, size (*) [1272], align (*) [8]
> +mcontext_t: sigcontext, sigcontext*, size (*) [1528], align (*) [8]

IIRC on other archs we made an effort to make the tag here match ABI
(duplicating the struct def if needed). Not sure if it matters.

> @@ -183,2 +183,2 @@
> -pthread_rwlockattr_t: pthread_rwlockattr_t, pthread_rwlockattr_t*, size (*) [8], align (*) [8]
> +pthread_rwlockattr_t: pthread_rwlockattr_t, pthread_rwlockattr_t*, size (*) [8], align (*) [4]

Alignment difference was unintentional here but seems bad to try to
fix for existing archs and I don't want to make the pthread types
arch-specific; actually I want to move them to the shared
alltypes.h.in or new arch/generic* with just a dependency on 32/64
bit.

> -pthread_spinlock_t: int, int volatile*, size (*) [4], align (*) [4]
> +pthread_spinlock_t: int, int*, size (*) [4], align (*) [4]

Did glibc add volatile here? IIRC it was not there to begin with. If
so they broke their own C++ ABI. I'd like to change this too, and if
glibc did change it without anyone noticing/caring, we probably could
too.

> @@ -195 +195 @@
> -sem_t: sem_t, sem_t*, size (*) [32], align (*) [8]
> +sem_t: sem_t, sem_t*, size (*) [32], align (*) [4]

> @@ -229,2 +229,2 @@
> -cmsghdr: cmsghdr, cmsghdr*, size (*) [16], align (*) [8]
> +cmsghdr: cmsghdr, cmsghdr*, size (*) [16], align (*) [4]

This is likely going to hit the same issue we're trying to debug on
mips64.

> @@ -416 +417 @@
> -ucontext_t: ucontext, ucontext*, size (*) [1440], align (*) [8]
> +ucontext_t: ucontext, ucontext*, size (*) [1696], align (*) [8]

This may be a real problem. ucontext_t is ABI between kernel and
userspace and if it's wrong cancellation won't work right.

Rich


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-16 17:09         ` Rich Felker
@ 2016-04-28  1:38           ` Bobby Bingham
  2016-04-28  2:07             ` Rich Felker
  0 siblings, 1 reply; 14+ messages in thread
From: Bobby Bingham @ 2016-04-28  1:38 UTC (permalink / raw)
  To: musl

On Sat, Apr 16, 2016 at 01:09:34PM -0400, Rich Felker wrote:
> On Fri, Apr 15, 2016 at 10:38:33PM +0200, Szabolcs Nagy wrote:
> > * Szabolcs Nagy <nsz@port70.net> [2016-04-14 15:42:13 +0200]:
> > > * Bobby Bingham <koorogi@koorogi.info> [2016-04-14 03:01:38 -0500]:
> > > > 
> > > > How important is it to match glibc here?
> > > > 
> > > 
> > > i think we don't care about abi compat
> > > (but it might be interesting to check how much abi
> > > difference there is between glibc and musl, i can
> > > do this if i can build a musl+glibc toolchain)
> > > 
> > 
> > attached some c++ abi comparisions
> 
> Thanks!
> 
> > (the comparision was not entirely clean, it involved
> > various manual hacks, but most types and functions
> > should be compared correctly glibc vs musl)
> > 
> > two interesting gcc warnings:
> > 
> > powerpc64 elf_vrreg_t (both musl and glibc):
> > note: the ABI of passing aggregates with 16-byte alignment has changed in GCC 5
> 
> This could be mildly problematic, but it's in a junk interface that's
> unlikely to be used cross-library anyway.
> 
> > x86_64 struct inotify_event (musl only):
> > note: the ABI of passing struct with a flexible array member has changed in GCC 4.4
> 
> This looks irrelevant; passing the struct by value does not make sense.
> 
> > --- abi_type.powerpc64le.glibc	2016-04-15 21:00:27.432246225 +0100
> > +++ abi_type.powerpc64le.musl	2016-04-15 20:57:39.000149371 +0100
> > @@ -97 +96 @@
> > -fexcept_t: unsigned int, unsigned int*, size (*) [4], align (*) [4]
> > +fexcept_t: unsigned long, unsigned long*, size (*) [8], align (*) [8]
> 
> Is this right?

I've fixed this locally.  I'll submit a new patch soon.

> 
> > @@ -100,2 +99,2 @@
> > -fpos_t: _G_fpos_t, _G_fpos_t*, size (*) [16], align (*) [8]
> > +fpos_t: _G_fpos64_t, _G_fpos64_t*, size (*) [16], align (*) [8]
> 
> You should probably be testing with -D_FILE_OFFSET_BITS=64. musl
> implements that ABI, and it matters in a few places even on 64-bit
> archs, like here.
> 
> > @@ -130 +130 @@
> > -jmp_buf: __jmp_buf_tag*, __jmp_buf_tag (*) [1], size (*) [656], align (*) [16]
> > +jmp_buf: __jmp_buf_tag*, __jmp_buf_tag (*) [1], size (*) [664], align (*) [8]
> 
> Let's fix at least alignment and hopefully size.

Ok

> 
> > @@ -141 +141 @@
> > -mcontext_t: mcontext_t, mcontext_t*, size (*) [1272], align (*) [8]
> > +mcontext_t: sigcontext, sigcontext*, size (*) [1528], align (*) [8]
> 
> IIRC on other archs we made an effort to make the tag here match ABI
> (duplicating the struct def if needed). Not sure if it matters.

I can duplicate the structure if you want.  But it looks like glibc used
to do 'typedef struct sigcontext mcontext_t' as well:

https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h;h=a499a80ef9994e541b866202ee8440843b004fdd;hp=b75e25a3c84c852b22e1690ff530d3ddb8dff257;hb=5ef6ae4bdb;hpb=39b04aa39823faf1cc414e7f3eca4f43e01426e4

> 
> > @@ -183,2 +183,2 @@
> > -pthread_rwlockattr_t: pthread_rwlockattr_t, pthread_rwlockattr_t*, size (*) [8], align (*) [8]
> > +pthread_rwlockattr_t: pthread_rwlockattr_t, pthread_rwlockattr_t*, size (*) [8], align (*) [4]
> 
> Alignment difference was unintentional here but seems bad to try to
> fix for existing archs and I don't want to make the pthread types
> arch-specific; actually I want to move them to the shared
> alltypes.h.in or new arch/generic* with just a dependency on 32/64
> bit.
> 
> > -pthread_spinlock_t: int, int volatile*, size (*) [4], align (*) [4]
> > +pthread_spinlock_t: int, int*, size (*) [4], align (*) [4]
> 
> Did glibc add volatile here? IIRC it was not there to begin with. If
> so they broke their own C++ ABI. I'd like to change this too, and if
> glibc did change it without anyone noticing/caring, we probably could
> too.
> 
> > @@ -195 +195 @@
> > -sem_t: sem_t, sem_t*, size (*) [32], align (*) [8]
> > +sem_t: sem_t, sem_t*, size (*) [32], align (*) [4]
> 
> > @@ -229,2 +229,2 @@
> > -cmsghdr: cmsghdr, cmsghdr*, size (*) [16], align (*) [8]
> > +cmsghdr: cmsghdr, cmsghdr*, size (*) [16], align (*) [4]
> 
> This is likely going to hit the same issue we're trying to debug on
> mips64.

The mips64 issue ended up not being alignment related.  Do you still
want me to do something about this?  And if so, do you have a suggestion?

> 
> > @@ -416 +417 @@
> > -ucontext_t: ucontext, ucontext*, size (*) [1440], align (*) [8]
> > +ucontext_t: ucontext, ucontext*, size (*) [1696], align (*) [8]
> 
> This may be a real problem. ucontext_t is ABI between kernel and
> userspace and if it's wrong cancellation won't work right.

Kernel commit ce48b2100785 expanded the vmx_reserve member of mcontext_t
by 256 bytes.  The glibc headers haven't been updated for this expansion.

> 
> Rich


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-28  1:38           ` Bobby Bingham
@ 2016-04-28  2:07             ` Rich Felker
  2016-04-30 20:15               ` Bobby Bingham
  0 siblings, 1 reply; 14+ messages in thread
From: Rich Felker @ 2016-04-28  2:07 UTC (permalink / raw)
  To: musl

On Wed, Apr 27, 2016 at 08:38:19PM -0500, Bobby Bingham wrote:
> > > @@ -141 +141 @@
> > > -mcontext_t: mcontext_t, mcontext_t*, size (*) [1272], align (*) [8]
> > > +mcontext_t: sigcontext, sigcontext*, size (*) [1528], align (*) [8]
> > 
> > IIRC on other archs we made an effort to make the tag here match ABI
> > (duplicating the struct def if needed). Not sure if it matters.
> 
> I can duplicate the structure if you want.  But it looks like glibc used
> to do 'typedef struct sigcontext mcontext_t' as well:
> 
> https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h;h=a499a80ef9994e541b866202ee8440843b004fdd;hp=b75e25a3c84c852b22e1690ff530d3ddb8dff257;hb=5ef6ae4bdb;hpb=39b04aa39823faf1cc414e7f3eca4f43e01426e4

Wow, the glibc stuff is an utter mess and grossly non-conforming. It
doesn't even have a uc_mcontext member of type mcontext_t. At least it
looks like all modern kernels have the mcontext_t at the end where
it's extensible and doesn't break access to uc_sigmask if it changes.
We should probably check and make sure both the current 32-bit powerpc
ucontext_t and your proposed powerpc64 one have the mcontext_t members
(at least the program counter) accessible at the expected locations.
We should probably also let the kernel people know that mcontext_t
(and its location) are ABI whether they like it or not. This is
imposed by POSIX and the glibc hack of making it a pointer is
non-conforming.

> > > @@ -195 +195 @@
> > > -sem_t: sem_t, sem_t*, size (*) [32], align (*) [8]
> > > +sem_t: sem_t, sem_t*, size (*) [32], align (*) [4]
> > 
> > > @@ -229,2 +229,2 @@
> > > -cmsghdr: cmsghdr, cmsghdr*, size (*) [16], align (*) [8]
> > > +cmsghdr: cmsghdr, cmsghdr*, size (*) [16], align (*) [4]
> > 
> > This is likely going to hit the same issue we're trying to debug on
> > mips64.
> 
> The mips64 issue ended up not being alignment related.  Do you still
> want me to do something about this?  And if so, do you have a suggestion?

I'm not entirely sure, but I think you can leave it alone for now. If
it needs fixing here, then it already does on multiple existing archs,
and they should be handled together.

> > > @@ -416 +417 @@
> > > -ucontext_t: ucontext, ucontext*, size (*) [1440], align (*) [8]
> > > +ucontext_t: ucontext, ucontext*, size (*) [1696], align (*) [8]
> > 
> > This may be a real problem. ucontext_t is ABI between kernel and
> > userspace and if it's wrong cancellation won't work right.
> 
> Kernel commit ce48b2100785 expanded the vmx_reserve member of mcontext_t
> by 256 bytes.  The glibc headers haven't been updated for this expansion.

Ah. As noted above, uc_mcontext is at the end so it shouldn't break
anything.

Rich


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] add powerpc64 port
  2016-04-28  2:07             ` Rich Felker
@ 2016-04-30 20:15               ` Bobby Bingham
  0 siblings, 0 replies; 14+ messages in thread
From: Bobby Bingham @ 2016-04-30 20:15 UTC (permalink / raw)
  To: musl

On Wed, Apr 27, 2016 at 10:07:51PM -0400, Rich Felker wrote:
> On Wed, Apr 27, 2016 at 08:38:19PM -0500, Bobby Bingham wrote:
> > > > @@ -141 +141 @@
> > > > -mcontext_t: mcontext_t, mcontext_t*, size (*) [1272], align (*) [8]
> > > > +mcontext_t: sigcontext, sigcontext*, size (*) [1528], align (*) [8]
> > > 
> > > IIRC on other archs we made an effort to make the tag here match ABI
> > > (duplicating the struct def if needed). Not sure if it matters.
> > 
> > I can duplicate the structure if you want.  But it looks like glibc used
> > to do 'typedef struct sigcontext mcontext_t' as well:
> > 
> > https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h;h=a499a80ef9994e541b866202ee8440843b004fdd;hp=b75e25a3c84c852b22e1690ff530d3ddb8dff257;hb=5ef6ae4bdb;hpb=39b04aa39823faf1cc414e7f3eca4f43e01426e4
> 
> Wow, the glibc stuff is an utter mess and grossly non-conforming. It
> doesn't even have a uc_mcontext member of type mcontext_t. At least it

I went back and looked at some of the kernel history here.

For ppc32:
When this was added in 1998, struct ucontext didn't contain a uc_mcontext
member at all.  One was added in 2000, before the sigmask member, but it
difn't include registers directly, just a pointer to them.  The structure
was reworked in 2003 to the current layout, and hasn't changed since.

For ppc64:
When it was originally added in 2002, the uc_mcontext and uc_sigmask
members were swapped.  They were moved to their current positions in
2003, and haven't moved since.

> looks like all modern kernels have the mcontext_t at the end where
> it's extensible and doesn't break access to uc_sigmask if it changes.
> We should probably check and make sure both the current 32-bit powerpc
> ucontext_t and your proposed powerpc64 one have the mcontext_t members
> (at least the program counter) accessible at the expected locations.
> We should probably also let the kernel people know that mcontext_t
> (and its location) are ABI whether they like it or not. This is
> imposed by POSIX and the glibc hack of making it a pointer is
> non-conforming.

I don't think I got across the point I was trying to make, or got the
answer I was looking for.

The point was that until the commit linked above, glibc's mcontext_t
was a structure with tag 'sigcontext'.  That commit changed it.  I can
duplicate the structure definition if you want to match the tag with
current glibc, but since glibc changed the tag without worrying about
it, I'm not sure it really matters.

> 
> > > > @@ -195 +195 @@
> > > > -sem_t: sem_t, sem_t*, size (*) [32], align (*) [8]
> > > > +sem_t: sem_t, sem_t*, size (*) [32], align (*) [4]
> > > 
> > > > @@ -229,2 +229,2 @@
> > > > -cmsghdr: cmsghdr, cmsghdr*, size (*) [16], align (*) [8]
> > > > +cmsghdr: cmsghdr, cmsghdr*, size (*) [16], align (*) [4]
> > > 
> > > This is likely going to hit the same issue we're trying to debug on
> > > mips64.
> > 
> > The mips64 issue ended up not being alignment related.  Do you still
> > want me to do something about this?  And if so, do you have a suggestion?
> 
> I'm not entirely sure, but I think you can leave it alone for now. If
> it needs fixing here, then it already does on multiple existing archs,
> and they should be handled together.

Ok.

> 
> > > > @@ -416 +417 @@
> > > > -ucontext_t: ucontext, ucontext*, size (*) [1440], align (*) [8]
> > > > +ucontext_t: ucontext, ucontext*, size (*) [1696], align (*) [8]
> > > 
> > > This may be a real problem. ucontext_t is ABI between kernel and
> > > userspace and if it's wrong cancellation won't work right.
> > 
> > Kernel commit ce48b2100785 expanded the vmx_reserve member of mcontext_t
> > by 256 bytes.  The glibc headers haven't been updated for this expansion.
> 
> Ah. As noted above, uc_mcontext is at the end so it shouldn't break
> anything.

Right.  I was just explaining the size difference in this structure
between glibc and my patch.

> 
> Rich


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2016-04-30 20:15 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-04  5:26 [PATCH v2] add powerpc64 port Bobby Bingham
2016-04-13 23:05 ` Szabolcs Nagy
2016-04-13 23:13   ` Rich Felker
2016-04-14  0:58     ` Szabolcs Nagy
2016-04-14  8:01   ` Bobby Bingham
2016-04-14 13:42     ` Szabolcs Nagy
2016-04-15 20:38       ` Szabolcs Nagy
2016-04-16 17:09         ` Rich Felker
2016-04-28  1:38           ` Bobby Bingham
2016-04-28  2:07             ` Rich Felker
2016-04-30 20:15               ` Bobby Bingham
2016-04-14 19:14     ` Rich Felker
2016-04-15  0:55       ` Bobby Bingham
2016-04-15  2:08         ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).