Patchwork [v8,06/12] C-SKY: Linux ABI

login
register
mail settings
Submitter Han Mao
Date Dec. 20, 2018, 3:02 a.m.
Message ID <c6be61a7b9b77fd79fe827f7dc18e38ea7eeebc7.1545194586.git.han_mao@c-sky.com>
Download mbox | patch
Permalink /patch/30778/
State New
Headers show

Comments

Han Mao - Dec. 20, 2018, 3:02 a.m.
Linux-specific code that is required for maintaining ABI compatibility.
This doesn't contain the actual system call interface.

	* sysdeps/unix/sysv/linux/csky/Versions: New file.
	* sysdeps/unix/sysv/linux/csky/bits/mman.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/bits/procfs.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/bits/shmlba.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/c++-types.data: Likewise.
	* sysdeps/unix/sysv/linux/csky/abiv2/ucontext_i.sym: Likewise.
	* sysdeps/unix/sysv/linux/csky/ipc_priv.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/jmp_buf-macros.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/kernel-features.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/localplt.data: Likewise.
	* sysdeps/unix/sysv/linux/csky/makecontext.c: Likewise.
	* sysdeps/unix/sysv/linux/csky/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/register-dump.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/shlib-versions: Likewise.
	* sysdeps/unix/sysv/linux/csky/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/sys/cachectl.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/sys/ucontext.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/sys/user.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/sysdep.h: Likewise.
---
 sysdeps/unix/sysv/linux/csky/Versions             |   5 +
 sysdeps/unix/sysv/linux/csky/abiv2/ucontext_i.sym |  32 ++
 sysdeps/unix/sysv/linux/csky/bits/procfs.h        |  34 ++
 sysdeps/unix/sysv/linux/csky/bits/shmlba.h        |  29 ++
 sysdeps/unix/sysv/linux/csky/c++-types.data       |  67 +++
 sysdeps/unix/sysv/linux/csky/ipc_priv.h           |  21 +
 sysdeps/unix/sysv/linux/csky/jmp_buf-macros.h     |   6 +
 sysdeps/unix/sysv/linux/csky/kernel-features.h    |  29 ++
 sysdeps/unix/sysv/linux/csky/localplt.data        |  19 +
 sysdeps/unix/sysv/linux/csky/makecontext.c        |  74 +++
 sysdeps/unix/sysv/linux/csky/profil-counter.h     |  31 ++
 sysdeps/unix/sysv/linux/csky/register-dump.h      | 193 ++++++++
 sysdeps/unix/sysv/linux/csky/shlib-versions       |   9 +
 sysdeps/unix/sysv/linux/csky/sigcontextinfo.h     |  32 ++
 sysdeps/unix/sysv/linux/csky/sys/cachectl.h       |  36 ++
 sysdeps/unix/sysv/linux/csky/sys/ucontext.h       |  90 ++++
 sysdeps/unix/sysv/linux/csky/sys/user.h           |  60 +++
 sysdeps/unix/sysv/linux/csky/sysdep.h             | 534 ++++++++++++++++++++++
 18 files changed, 1301 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/csky/Versions
 create mode 100644 sysdeps/unix/sysv/linux/csky/abiv2/ucontext_i.sym
 create mode 100644 sysdeps/unix/sysv/linux/csky/bits/procfs.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/bits/shmlba.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/c++-types.data
 create mode 100644 sysdeps/unix/sysv/linux/csky/ipc_priv.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/jmp_buf-macros.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/kernel-features.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/localplt.data
 create mode 100644 sysdeps/unix/sysv/linux/csky/makecontext.c
 create mode 100644 sysdeps/unix/sysv/linux/csky/profil-counter.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/register-dump.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/shlib-versions
 create mode 100644 sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/sys/cachectl.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/sys/ucontext.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/sys/user.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/sysdep.h

Patch

diff --git a/sysdeps/unix/sysv/linux/csky/Versions b/sysdeps/unix/sysv/linux/csky/Versions
new file mode 100644
index 0000000..b61b3b2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/Versions
@@ -0,0 +1,5 @@ 
+libc {
+  GLIBC_2.29 {
+    cacheflush;
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/csky/abiv2/ucontext_i.sym b/sysdeps/unix/sysv/linux/csky/abiv2/ucontext_i.sym
new file mode 100644
index 0000000..4581b65
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/abiv2/ucontext_i.sym
@@ -0,0 +1,32 @@ 
+#include <inttypes.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+SIG_BLOCK
+SIG_SETMASK
+
+-- Offsets of the fields in the ucontext_t structure.
+#define ucontext(member)	offsetof (ucontext_t, member)
+#define mcontext(member)	ucontext (uc_mcontext.member)
+#define greg(member)		mcontext (__gregs.member)
+#define fpreg(member)		mcontext (__fpregs.member)
+
+UCONTEXT_FLAGS			ucontext (__uc_flags)
+UCONTEXT_LINK			ucontext (uc_link)
+UCONTEXT_STACK			ucontext (uc_stack)
+UCONTEXT_MCONTEXT		ucontext (uc_mcontext)
+UCONTEXT_SIGMASK		ucontext (uc_sigmask)
+
+MCONTEXT_CSKY_PC		greg (__pc)
+MCONTEXT_CSKY_SP		greg (__usp)
+MCONTEXT_CSKY_LR		greg (__lr)
+MCONTEXT_CSKY_A0		greg (__a0)
+MCONTEXT_CSKY_R8		greg (__regs[2])
+MCONTEXT_CSKY_R16		greg (__exregs[0])
+MCONTEXT_CSKY_HI		greg (__rhi)
+MCONTEXT_CSKY_LO		greg (__rlo)
+MCONTEXT_CSKY_R4		greg (__regs[0])
+MCONTEXT_CSKY_FESR		fpreg (__fesr)
+MCONTEXT_CSKY_FCR		fpreg (__fcr)
+MCONTEXT_CSKY_FR0		fpreg (__vr[0])
diff --git a/sysdeps/unix/sysv/linux/csky/bits/procfs.h b/sysdeps/unix/sysv/linux/csky/bits/procfs.h
new file mode 100644
index 0000000..83e37b0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/bits/procfs.h
@@ -0,0 +1,34 @@ 
+/* Types for registers for sys/procfs.h.  C-SKY version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_PROCFS_H
+# error "Never include <bits/procfs.h> directly; use <sys/procfs.h> instead."
+#endif
+
+/* Type for a general-purpose register.  */
+typedef unsigned long elf_greg_t;
+
+/* And the whole bunch of them.  We could have used `struct
+   user_regs' directly in the typedef, but tradition says that
+   the register set is an array, which does have some peculiar
+   semantics, so leave it that way.  */
+#define ELF_NGREG (sizeof (struct user_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* Register set for the floating-point registers.  */
+typedef struct user_fpregs elf_fpregset_t;
diff --git a/sysdeps/unix/sysv/linux/csky/bits/shmlba.h b/sysdeps/unix/sysv/linux/csky/bits/shmlba.h
new file mode 100644
index 0000000..3eb6c27
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/bits/shmlba.h
@@ -0,0 +1,29 @@ 
+/* Define SHMLBA.  C-SKY version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SHM_H
+# error "Never use <bits/shmlba.h> directly; include <sys/shm.h> instead."
+#endif
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple.  */
+#define SHMLBA		(__getpagesize () << 2)
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+__END_DECLS
diff --git a/sysdeps/unix/sysv/linux/csky/c++-types.data b/sysdeps/unix/sysv/linux/csky/c++-types.data
new file mode 100644
index 0000000..303f457
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/c++-types.data
@@ -0,0 +1,67 @@ 
+blkcnt64_t:x
+blkcnt_t:l
+blksize_t:i
+caddr_t:Pc
+clockid_t:i
+clock_t:l
+daddr_t:i
+dev_t:y
+fd_mask:l
+fsblkcnt64_t:y
+fsblkcnt_t:m
+fsfilcnt64_t:y
+fsfilcnt_t:m
+fsid_t:8__fsid_t
+gid_t:j
+id_t:j
+ino64_t:y
+ino_t:m
+int16_t:s
+int32_t:i
+int64_t:x
+int8_t:a
+intptr_t:i
+key_t:i
+loff_t:x
+mode_t:j
+nlink_t:j
+off64_t:x
+off_t:l
+pid_t:i
+pthread_attr_t:14pthread_attr_t
+pthread_barrier_t:17pthread_barrier_t
+pthread_barrierattr_t:21pthread_barrierattr_t
+pthread_cond_t:14pthread_cond_t
+pthread_condattr_t:18pthread_condattr_t
+pthread_key_t:j
+pthread_mutex_t:15pthread_mutex_t
+pthread_mutexattr_t:19pthread_mutexattr_t
+pthread_once_t:i
+pthread_rwlock_t:16pthread_rwlock_t
+pthread_rwlockattr_t:20pthread_rwlockattr_t
+pthread_spinlock_t:i
+pthread_t:m
+quad_t:x
+register_t:i
+rlim64_t:y
+rlim_t:m
+sigset_t:10__sigset_t
+size_t:j
+socklen_t:j
+ssize_t:i
+suseconds_t:l
+time_t:l
+u_char:h
+uid_t:j
+uint:j
+u_int:j
+u_int16_t:t
+u_int32_t:j
+u_int64_t:y
+u_int8_t:h
+ulong:m
+u_long:m
+u_quad_t:y
+useconds_t:j
+ushort:t
+u_short:t
diff --git a/sysdeps/unix/sysv/linux/csky/ipc_priv.h b/sysdeps/unix/sysv/linux/csky/ipc_priv.h
new file mode 100644
index 0000000..56ded89
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/ipc_priv.h
@@ -0,0 +1,21 @@ 
+/* Old SysV permission definition for Linux.  C-SKY version.
+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/ipc.h>  /* For __key_t  */
+
+#define __IPC_64	0x0
diff --git a/sysdeps/unix/sysv/linux/csky/jmp_buf-macros.h b/sysdeps/unix/sysv/linux/csky/jmp_buf-macros.h
new file mode 100644
index 0000000..5a390c7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/jmp_buf-macros.h
@@ -0,0 +1,6 @@ 
+#define JMP_BUF_SIZE 268
+#define SIGJMP_BUF_SIZE 268
+#define JMP_BUF_ALIGN 4
+#define SIGJMP_BUF_ALIGN 4
+#define MASK_WAS_SAVED_OFFSET 136
+#define SAVED_MASK_OFFSET 140
diff --git a/sysdeps/unix/sysv/linux/csky/kernel-features.h b/sysdeps/unix/sysv/linux/csky/kernel-features.h
new file mode 100644
index 0000000..f1fbc71
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/kernel-features.h
@@ -0,0 +1,29 @@ 
+/* Set flags signalling availability of kernel features based on given
+   kernel version number.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include_next <kernel-features.h>
+
+/* fadvise64_64 reorganize the syscall arguments.  */
+#define __ASSUME_FADVISE64_64_6ARG	1
+
+/* Define this if your 32-bit syscall API requires 64-bit register
+   pairs to start with an even-number register.  */
+#ifdef __CSKYABIV1__
+# define __ASSUME_ALIGNED_REGISTER_PAIRS	1
+#endif
diff --git a/sysdeps/unix/sysv/linux/csky/localplt.data b/sysdeps/unix/sysv/linux/csky/localplt.data
new file mode 100644
index 0000000..14c02cb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/localplt.data
@@ -0,0 +1,19 @@ 
+# See scripts/check-localplt.awk for how this file is processed.
+# PLT use is required for the malloc family and for matherr because
+# users can define their own functions and have library internals call them.
+libc.so: calloc
+libc.so: free
+libc.so: malloc
+libc.so: memalign
+libc.so: realloc
+# The main malloc is interposed into the dynamic linker, for
+# allocations after the initial link (when dlopen is used).
+ld.so: malloc
+ld.so: calloc
+ld.so: realloc
+ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
+ld.so: _dl_signal_exception
+ld.so: _dl_catch_exception
diff --git a/sysdeps/unix/sysv/linux/csky/makecontext.c b/sysdeps/unix/sysv/linux/csky/makecontext.c
new file mode 100644
index 0000000..c0d7d1e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/makecontext.c
@@ -0,0 +1,74 @@ 
+/* Create new context.  C-SKY version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdarg.h>
+#include <ucontext.h>
+
+/* Number of arguments that go in registers.  */
+#define NREG_ARGS  4
+
+/* Take a context previously prepared via getcontext() and set to
+   call func() with the given int only args.  */
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+  extern void __startcontext (void);
+  unsigned long *funcstack;
+  va_list vl;
+  unsigned long *regptr;
+  unsigned int reg;
+  int misaligned;
+
+  /* Start at the top of stack.  */
+  funcstack = (unsigned long *) (ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
+
+  /* Ensure the stack stays eight byte aligned.  */
+  misaligned = ((unsigned long) funcstack & 4) != 0;
+
+  if ((argc > NREG_ARGS) && (argc & 1) != 0)
+    misaligned = !misaligned;
+
+  if (misaligned)
+    funcstack -= 1;
+
+  va_start (vl, argc);
+
+  /* Reserve space for the on-stack arguments.  */
+  if (argc > NREG_ARGS)
+    funcstack -= (argc - NREG_ARGS);
+
+  ucp->uc_mcontext.__gregs.__usp = (unsigned long) funcstack;
+  ucp->uc_mcontext.__gregs.__pc = (unsigned long) func;
+
+  /* Exit to startcontext() with the next context in R9.  */
+  ucp->uc_mcontext.__gregs.__regs[5] = (unsigned long) ucp->uc_link;
+  ucp->uc_mcontext.__gregs.__lr = (unsigned long) __startcontext;
+
+  /* The first four arguments go into registers.  */
+  regptr = &(ucp->uc_mcontext.__gregs.__a0);
+
+  for (reg = 0; (reg < argc) && (reg < NREG_ARGS); reg++)
+    *regptr++ = va_arg (vl, unsigned long);
+
+  /* And the remainder on the stack.  */
+  for (; reg < argc; reg++)
+    *funcstack++ = va_arg (vl, unsigned long);
+
+  va_end (vl);
+}
+weak_alias (__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/csky/profil-counter.h b/sysdeps/unix/sysv/linux/csky/profil-counter.h
new file mode 100644
index 0000000..1f7ec7a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/profil-counter.h
@@ -0,0 +1,31 @@ 
+/* Low-level statistical profiling support function.  Linux/C-SKY version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <signal.h>
+#include <sigcontextinfo.h>
+
+void
+__profil_counter (int signo, const SIGCONTEXT scp)
+{
+  profil_count ((void *) GET_PC (scp));
+
+  /* This is a hack to prevent the compiler from implementing the
+     above function call as a sibcall.  The sibcall would overwrite
+     the signal context.  */
+  asm volatile ("");
+}
diff --git a/sysdeps/unix/sysv/linux/csky/register-dump.h b/sysdeps/unix/sysv/linux/csky/register-dump.h
new file mode 100644
index 0000000..9abe87a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/register-dump.h
@@ -0,0 +1,193 @@ 
+/* Dump registers.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/uio.h>
+#include <_itoa.h>
+#include <bits/sigcontext.h>
+#include <sys/ucontext.h>
+
+/* abiv1 register dump in this format:
+
+ PSR: XXXXXXXX  PC: XXXXXXXX   SP: XXXXXXXX   LR: XXXXXXXX
+ MASK: XXXXXXXX
+
+ A0: XXXXXXXX   A1: XXXXXXXX   A2: XXXXXXXX   A3: XXXXXXXX
+ R6: XXXXXXXX   R7: XXXXXXXX   R8: XXXXXXXX   R9: XXXXXXXX
+ R10: XXXXXXXX  R11: XXXXXXXX  R12: XXXXXXXX  R13: XXXXXXXX
+ R14: XXXXXXXX  R1: XXXXXXXX
+
+ abiv2 register dump in this format:
+
+ PSR: XXXXXXXX  PC: XXXXXXXX   SP: XXXXXXXX   LR: XXXXXXXX
+ MASK: XXXXXXXX
+
+ A0: XXXXXXXX   A1: XXXXXXXX   A2: XXXXXXXX   A3: XXXXXXXX
+ R4: XXXXXXXX   R5: XXXXXXXX   R6: XXXXXXXX   R7: XXXXXXXX
+ R8: XXXXXXXX   R9: XXXXXXXX   R10: XXXXXXXX  R11: XXXXXXXX
+ R12: XXXXXXXX  R13: XXXXXXXX  R14: XXXXXXXX  R15: XXXXXXXX
+ R16: XXXXXXXX  R17: XXXXXXXX  R18: XXXXXXXX  R19: XXXXXXXX
+ R20: XXXXXXXX  R21: XXXXXXXX  R22: XXXXXXXX  R23: XXXXXXXX
+ R24: XXXXXXXX  R25: XXXXXXXX  R26: XXXXXXXX  R27: XXXXXXXX
+ R28: XXXXXXXX  R29: XXXXXXXX  R30: XXXXXXXX  R31: XXXXXXXX
+
+ */
+
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
+{
+  char *cp = _itoa_word (value, buf + len, 16, 0);
+  while (cp > buf)
+    *--cp = '0';
+}
+
+static void
+register_dump (int fd, const struct ucontext_t *ctx)
+{
+  char regs[35][8];
+  struct iovec iov[97];
+  size_t nr = 0;
+
+#define ADD_STRING(str) \
+  iov[nr].iov_base = (char *) str;					      \
+  iov[nr].iov_len = strlen (str);					      \
+  ++nr
+#define ADD_MEM(str, len) \
+  iov[nr].iov_base = str;						      \
+  iov[nr].iov_len = len;						      \
+  ++nr
+
+  /* Generate strings of register contents.  */
+  hexvalue (ctx->uc_mcontext.__gregs.__sr, regs[0], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__pc, regs[1], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__usp, regs[2], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__lr, regs[3], 8);
+  hexvalue (ctx->uc_mcontext.__mask, regs[4], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__a0, regs[5], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__a1, regs[6], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__a2, regs[7], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__a3, regs[8], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[0], regs[9], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[1], regs[10], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[2], regs[11], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[3], regs[12], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[4], regs[13], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[5], regs[14], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[6], regs[15], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[7], regs[16], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[8], regs[17], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[9], regs[18], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[0], regs[19], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[1], regs[20], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[2], regs[21], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[3], regs[22], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[4], regs[23], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[5], regs[24], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[6], regs[25], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[7], regs[26], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[8], regs[27], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[9], regs[28], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[10], regs[29], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[11], regs[30], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[12], regs[31], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[13], regs[32], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[14], regs[33], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__tls, regs[34], 8);
+
+  /* Generate the output.  */
+  ADD_STRING ("Register dump:\n\n PSR: ");
+  ADD_MEM (regs[0], 8);
+  ADD_STRING ("  PC: ");
+  ADD_MEM (regs[1], 8);
+  ADD_STRING ("   SP: ");
+  ADD_MEM (regs[2], 8);
+  ADD_STRING ("   LR: ");
+  ADD_MEM (regs[3], 8);
+  ADD_STRING ("\n MASK: ");
+  ADD_MEM (regs[4], 8);
+  ADD_STRING ("\n\n A0: ");
+  ADD_MEM (regs[5], 8);
+  ADD_STRING ("   A1: ");
+  ADD_MEM (regs[6], 8);
+  ADD_STRING ("   A2: ");
+  ADD_MEM (regs[7], 8);
+  ADD_STRING ("   A3: ");
+  ADD_MEM (regs[8], 8);
+  ADD_STRING ("\n R4: ");
+  ADD_MEM (regs[9], 8);
+  ADD_STRING ("   r5: ");
+  ADD_MEM (regs[10], 8);
+  ADD_STRING ("   r6: ");
+  ADD_MEM (regs[11], 8);
+  ADD_STRING ("   r7: ");
+  ADD_MEM (regs[12], 8);
+  ADD_STRING ("\n R8: ");
+  ADD_MEM (regs[13], 8);
+  ADD_STRING ("   R9: ");
+  ADD_MEM (regs[14], 8);
+  ADD_STRING ("   R10: ");
+  ADD_MEM (regs[15], 8);
+  ADD_STRING ("  R11: ");
+  ADD_MEM (regs[16], 8);
+  ADD_STRING ("\n R12: ");
+  ADD_MEM (regs[17], 8);
+  ADD_STRING ("  R13: ");
+  ADD_MEM (regs[18], 8);
+  ADD_STRING ("  R14: ");
+  ADD_MEM (regs[19], 8);
+  ADD_STRING ("  R15: ");
+  ADD_MEM (regs[20], 8);
+  ADD_STRING ("\n R16: ");
+  ADD_MEM (regs[21], 8);
+  ADD_STRING ("  R17: ");
+  ADD_MEM (regs[22], 8);
+  ADD_STRING ("  R18: ");
+  ADD_MEM (regs[23], 8);
+  ADD_STRING ("  R19: ");
+  ADD_MEM (regs[24], 8);
+  ADD_STRING ("\n R20: ");
+  ADD_MEM (regs[25], 8);
+  ADD_STRING ("  R21: ");
+  ADD_MEM (regs[26], 8);
+  ADD_STRING ("  R22: ");
+  ADD_MEM (regs[27], 8);
+  ADD_STRING ("  R23: ");
+  ADD_MEM (regs[28], 8);
+  ADD_STRING ("\n R24: ");
+  ADD_MEM (regs[29], 8);
+  ADD_STRING ("  R25: ");
+  ADD_MEM (regs[30], 8);
+  ADD_STRING ("  R26: ");
+  ADD_MEM (regs[31], 8);
+  ADD_STRING ("  R27: ");
+  ADD_MEM (regs[32], 8);
+  ADD_STRING ("\n R28: ");
+  ADD_MEM (regs[33], 8);
+  ADD_STRING ("  R29: ");
+  ADD_MEM (regs[34], 8);
+  ADD_STRING ("  R30: ");
+  ADD_MEM (regs[33], 8);
+  ADD_STRING ("  TP: ");
+  ADD_MEM (regs[34], 8);
+
+  ADD_STRING ("\n");
+
+  /* Write the stuff out.  */
+  writev (fd, iov, nr);
+}
+
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/sysdeps/unix/sysv/linux/csky/shlib-versions b/sysdeps/unix/sysv/linux/csky/shlib-versions
new file mode 100644
index 0000000..8c02635
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/shlib-versions
@@ -0,0 +1,9 @@ 
+DEFAULT			GLIBC_2.29
+
+%if CSKYABI == 2 && CSKY_HARD_FLOAT == 1
+ld=ld-linux-cskyv2-hf.so.1
+%elif CSKYABI == 2 && CSKY_HARD_FLOAT == 0
+ld=ld-linux-cskyv2.so.1
+%else
+%error cannot determine ABI
+%endif
diff --git a/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h b/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
new file mode 100644
index 0000000..b9054d3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
@@ -0,0 +1,32 @@ 
+/* C-SKY definitions for signal handling calling conventions.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define SIGCONTEXT siginfo_t *_si, struct ucontext_t *
+#define GET_PC(ctx)     ((void *) (ctx)->uc_mcontext.__gregs.__pc)
+
+/* There is no reliable way to get the sigcontext unless we use a
+   three-argument signal handler.  */
+#define __sigaction(sig, act, oact) ({ \
+  (act)->sa_flags |= SA_SIGINFO; \
+  (__sigaction) (sig, act, oact); \
+})
+
+#define sigaction(sig, act, oact) ({ \
+  (act)->sa_flags |= SA_SIGINFO; \
+  (sigaction) (sig, act, oact); \
+})
diff --git a/sysdeps/unix/sysv/linux/csky/sys/cachectl.h b/sysdeps/unix/sysv/linux/csky/sys/cachectl.h
new file mode 100644
index 0000000..5d4decf
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/sys/cachectl.h
@@ -0,0 +1,36 @@ 
+/* C-SKY cache flushing interface.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_CACHECTL_H
+#define _SYS_CACHECTL_H 1
+
+#include <features.h>
+
+/* Get the kernel definition for the op bits.  */
+#include <asm/cachectl.h>
+
+__BEGIN_DECLS
+
+#ifdef __USE_MISC
+extern int cacheflush (void *__addr, const int __nbytes,
+		       const int __op) __THROW;
+#endif
+
+__END_DECLS
+
+#endif /* sys/cachectl.h */
diff --git a/sysdeps/unix/sysv/linux/csky/sys/ucontext.h b/sysdeps/unix/sysv/linux/csky/sys/ucontext.h
new file mode 100644
index 0000000..7ecb3ff
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/sys/ucontext.h
@@ -0,0 +1,90 @@ 
+/* struct ucontext definition, C-SKY version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H	1
+
+#include <features.h>
+
+#include <bits/types/sigset_t.h>
+#include <bits/types/stack_t.h>
+
+typedef struct
+  {
+    unsigned long __tls;
+    unsigned long __lr;
+    unsigned long __pc;
+    unsigned long __sr;
+    unsigned long __usp;
+
+    /*
+     * a0, a1, a2, a3:
+     * abiv1: r2, r3, r4, r5
+     * abiv2: r0, r1, r2, r3
+     */
+
+    unsigned long __orig_a0;
+    unsigned long __a0;
+    unsigned long __a1;
+    unsigned long __a2;
+    unsigned long __a3;
+
+    /*
+     * ABIV2: r4 ~ r13
+     */
+    unsigned long __regs[10];
+
+    /* r16 ~ r30 */
+    unsigned long __exregs[15];
+
+    unsigned long __rhi;
+    unsigned long __rlo;
+    unsigned long __glibc_reserved;
+  } gregset_t;
+
+typedef struct
+  {
+    unsigned long __vr[64];
+    unsigned long __fcr;
+    unsigned long __fesr;
+    unsigned long __fid;
+    unsigned long __glibc_reserved;
+  } fpregset_t;
+
+/* Context to describe whole processor state.  */
+typedef struct
+  {
+    unsigned long __mask;
+    gregset_t __gregs;
+    fpregset_t __fpregs;
+  } mcontext_t;
+
+/* Userlevel context.  */
+typedef struct ucontext_t
+  {
+    unsigned long int __uc_flags;
+    struct ucontext_t *uc_link;
+    stack_t uc_stack;
+    mcontext_t uc_mcontext;
+    sigset_t uc_sigmask;
+  } ucontext_t;
+
+#undef __ctx
+
+
+#endif /* sys/ucontext.h */
diff --git a/sysdeps/unix/sysv/linux/csky/sys/user.h b/sysdeps/unix/sysv/linux/csky/sys/user.h
new file mode 100644
index 0000000..9714277
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/sys/user.h
@@ -0,0 +1,60 @@ 
+/* ptrace register data format definitions.  C-SKY version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H  1
+
+struct user_fpregs {
+  unsigned long fsr;		/* FPU status reg.  */
+  unsigned long fesr;		/* FPU exception status reg.  */
+  unsigned long fp[32];		/* FPU general regs.  */
+};
+
+struct user_regs {
+  unsigned long int uregs[34];	/* CSKY V2 has 32 general rgister.  */
+};
+
+/* When the kernel dumps core, it starts by dumping the user struct -
+   this will be used by gdb to figure out where the data and stack segments
+   are within the file, and what virtual addresses to use.  */
+struct user{
+/* We start with the registers, to mimic the way that "memory" is returned
+   from the ptrace(3,...) function.  */
+  struct user_regs    regs;        /* The registers are actually stored.  */
+  int                 u_fpvalid;   /* True if math co-processor being used.  */
+
+/* The rest of this junk is to help gdb figure out what goes where.  */
+  unsigned long int   u_tsize;     /* Text segment size (pages).  */
+  unsigned long int   u_dsize;     /* Data segment size (pages).  */
+  unsigned long int   u_ssize;     /* Stack segment size (pages).  */
+  unsigned long       start_code;  /* Starting virtual address of text.  */
+  unsigned long       start_stack; /* Starting virtual address of stack area.
+				      This is actually the bottom of the stack
+				      the top of the stack is always found in
+				      the esp register.  */
+  long int            signal;      /* Signal that caused the core dump.  */
+  int                 reserved;    /* No longer used.  */
+  struct user_regs *  u_ar0;       /* Used by gdb to help find the values
+				      for the registers.  */
+  unsigned long       magic;       /* To uniquely identify a core file.  */
+  char                u_comm[32];  /* User command that was responsible.  */
+  struct user_fpregs  u_fp;
+  struct user_fpregs* u_fpstate;   /* Math Co-processor pointer.  */
+};
+
+#endif /* _SYS_USER_H */
diff --git a/sysdeps/unix/sysv/linux/csky/sysdep.h b/sysdeps/unix/sysv/linux/csky/sysdep.h
new file mode 100644
index 0000000..cec6f95
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/sysdep.h
@@ -0,0 +1,534 @@ 
+/* Assembly macros for C-SKY.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LINUX_CSKY_SYSDEP_H
+#define _LINUX_CSKY_SYSDEP_H 1
+
+/* There is some commonality.  */
+#include <sysdeps/unix/sysv/linux/generic/sysdep.h>
+#include <sysdeps/unix/sysv/linux/sysdep.h>
+#include <sysdeps/csky/sysdep.h>
+
+/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO.  */
+#include <dl-sysdep.h>
+
+#include <tls.h>
+
+/* In order to get __set_errno() definition in INLINE_SYSCALL.  */
+#ifndef __ASSEMBLER__
+# include <errno.h>
+#endif
+
+#undef SYS_ify
+#define SYS_ify(syscall_name)  (__NR_##syscall_name)
+
+#ifdef __ASSEMBLER__
+/* Linux uses a negative return value to indicate syscall errors,
+   unlike most Unices, which use the condition codes' carry flag.
+
+   Since version 2.1 the return value of a system call might be
+   negative even if the call succeeded.  E.g., the `lseek' system call
+   might return a large offset.  Therefore we must not anymore test
+   for < 0, but test for a real error by making sure the value in R0
+   is a real error number.  Linus said he will make sure the no syscall
+   returns a value in -1 .. -4095 as a valid result so we can safely
+   test with -4095.  */
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)	\
+  .text;					\
+  ENTRY (name);					\
+  DO_CALL (syscall_name, args);
+
+# define GETGB				\
+	grs	t0, .Lgetpc;		\
+.Lgetpc:				\
+	lrw	gb, .Lgetpc@GOTPC;	\
+	addu	gb, t0;
+
+# if IS_IN (libc)
+#  ifdef __PIC__
+#   define PSEUDO_RET			\
+	btsti	a0, 31;			\
+	bf	1f;			\
+	subi	sp, 8;			\
+	st.w	lr, (sp);		\
+	st.w	gb, (sp, 4);		\
+	GETGB;				\
+	lrw	a2, SYSCALL_ERROR@PLT;	\
+	add	a2, gb;			\
+	ld.w	a2, (a2);		\
+	jsr	a2;			\
+	ld.w	lr, (sp);		\
+	ld.w	gb, (sp, 4);		\
+	addi	sp, 8;			\
+1:					\
+	rts
+#  else
+#   define PSEUDO_RET			\
+	btsti	a0, 31;			\
+	bf	1f;			\
+	jmpi	SYSCALL_ERROR;		\
+1:					\
+	rts
+#  endif
+# else
+#  ifdef __PIC__
+#   define PSEUDO_RET			\
+	btsti	a0, 31;			\
+	bf	1f;			\
+	subi	sp, 8;			\
+	st.w	lr, (sp);		\
+	st.w	gb, (sp, 4);		\
+	GETGB;				\
+	bsr	SYSCALL_ERROR;		\
+	ld.w	lr, (sp);		\
+	ld.w	gb, (sp, 4);		\
+	addi	sp, 8;			\
+1:					\
+	rts
+#  else
+#   define PSEUDO_RET			\
+	btsti	a0, 31;			\
+	bt	SYSCALL_ERROR;		\
+	rts
+#  endif
+# endif
+
+# undef ret
+# define ret PSEUDO_RET
+
+# undef PSEUDO_END
+# define PSEUDO_END(name)		\
+  .align 4;				\
+  SYSCALL_ERROR_HANDLER;		\
+  END (name)
+
+# undef PSEUDO_NOERRNO
+# define PSEUDO_NOERRNO(name, syscall_name, args)	\
+  .text;						\
+  ENTRY (name);						\
+  DO_CALL (syscall_name, args)
+
+# define PSEUDO_RET_NOERRNO rts
+
+# undef ret_NOERRNO
+# define ret_NOERRNO PSEUDO_RET_NOERRNO
+
+# undef PSEUDO_END_NOERRNO
+# define PSEUDO_END_NOERRNO(name) END (name)
+
+/* The function has to return the error code.  */
+# undef PSEUDO_ERRVAL
+# define PSEUDO_ERRVAL(name, syscall_name, args)	\
+  .text;						\
+  ENTRY (name)						\
+  DO_CALL (syscall_name, args);				\
+  not	a0;						\
+  addi	a0, 1
+
+# undef PSEUDO_END_ERRVAL
+# define PSEUDO_END_ERRVAL(name) END (name)
+
+# define ret_ERRVAL rts
+
+# if !IS_IN (libc)
+#  define SYSCALL_ERROR __local_syscall_error
+#  if RTLD_PRIVATE_ERRNO
+#   ifdef __PIC__
+#    define SYSCALL_ERROR_HANDLER	\
+__local_syscall_error:			\
+	lrw	a1, rtld_errno@PLT; 	\
+	addu	a1, gb;			\
+	ldw	a1, (a1);		\
+	rsubi	a0, 0;			\
+	stw	a0, (a1);		\
+	bmaski	a0, 0;			\
+	rts
+#   else /* __PIC__ */
+#    define SYSCALL_ERROR_HANDLER	\
+__local_syscall_error:			\
+	lrw	a1, rtld_errno;		\
+	rsubi	a0, 0;			\
+	stw	a0, (a1);		\
+	bmaski	a0, 0;			\
+	rts
+#   endif /* __PIC__ */
+#  else /* !RTLD_PRIVATE_ERRNO */
+#   ifdef __PIC__
+#    define SYSCALL_ERROR_HANDLER		\
+__local_syscall_error:				\
+	subi	sp, 8;				\
+	stw	a0, (sp, 0);			\
+	stw	r15, (sp, 4);			\
+	lrw	a1, __errno_location@PLT;	\
+	add	a1, gb;				\
+	ldw	a1, (a1);			\
+	jsr	a1;				\
+	ldw	a1, (sp, 0); /* load errno*/	\
+	ldw	r15, (sp, 4);			\
+	addi	sp, 8;				\
+	movi	a2, 0;				\
+	rsub	a1, a1, a2;			\
+	stw	a1, (a0);			\
+	bmaski	a0, 0;				\
+	rts
+#    else
+#     define SYSCALL_ERROR_HANDLER 		\
+__local_syscall_error:				\
+	subi	sp, 8;				\
+	stw	a0, (sp, 0);			\
+	stw	r15, (sp, 4);			\
+	lrw	a1, __errno_location;		\
+	jsr	a1;				\
+	ldw	a1, (sp, 0); /* load errno */	\
+	ldw	r15, (sp, 4);			\
+	addi	sp, 8;				\
+	movi	a2, 0;				\
+	rsub	a1, a1, a2;			\
+	stw	a1, (a0);			\
+	bmaski	a0, 0;				\
+	rts
+#   endif /* __PIC__ */
+#  endif/* RTLD_PRIVATE_ERROR */
+# else
+#  define SYSCALL_ERROR_HANDLER  /* Nothing here; code in sysdep.S is used.  */
+#  define SYSCALL_ERROR __syscall_error
+# endif/* IS_IN (libc) */
+
+/* define DO_CALL */
+# undef DO_CALL
+# define DO_CALL(syscall_name, args)	\
+  DOARGS_##args;			\
+  lrw	r7, SYS_ify(syscall_name);	\
+  trap	0;				\
+  UNDOARGS_##args
+
+# undef  DOARGS_0
+# define DOARGS_0			\
+	subi	sp, 8;			\
+	cfi_adjust_cfa_offset (8);	\
+	stw	r7, (sp, 0);		\
+	cfi_rel_offset (r7, 0);
+
+# undef  DOARGS_1
+# define DOARGS_1 DOARGS_0
+# undef  DOARGS_2
+# define DOARGS_2 DOARGS_0
+# undef  DOARGS_3
+# define DOARGS_3 DOARGS_0
+# undef  DOARGS_4
+# define DOARGS_4 DOARGS_0
+# undef  DOARGS_5
+# define DOARGS_5			\
+	subi	sp, 8;			\
+	cfi_adjust_cfa_offset (8);	\
+	stw	r7, (sp, 0);		\
+	cfi_rel_offset (7, 0);		\
+	stw	r4, (sp, 4);		\
+	cfi_rel_offset (4, 4);		\
+	ldw	r4, (sp, 8)
+# undef  DOARGS_6
+# define DOARGS_6			\
+	subi	sp, 16;			\
+	cfi_adjust_cfa_offset (16);	\
+	stw	r7, (sp, 0);		\
+	cfi_rel_offset (7, 0);		\
+	stw	r4, (sp, 4);		\
+	cfi_rel_offset (4, 4);		\
+	stw	r5, (sp, 8);		\
+	cfi_rel_offset (5, 8);		\
+	ldw	r4, (sp, 16);		\
+	ldw	r5, (sp, 20)
+
+# undef  UNDOARGS_0
+# define UNDOARGS_0 \
+  ldw  r7, (sp, 0); \
+  cfi_restore (r7); \
+  addi sp, 8;   \
+  cfi_adjust_cfa_offset (-8);
+
+# undef  UNDOARGS_1
+# define UNDOARGS_1 UNDOARGS_0
+# undef  UNDOARGS_2
+# define UNDOARGS_2 UNDOARGS_0
+# undef  UNDOARGS_3
+# define UNDOARGS_3 UNDOARGS_0
+# undef  UNDOARGS_4
+# define UNDOARGS_4 UNDOARGS_0
+# undef  UNDOARGS_5
+# define UNDOARGS_5			\
+	ldw	r7, (sp, 0);		\
+	cfi_restore (r4);		\
+	ldw	r4, (sp, 4);		\
+	cfi_restore (r4);		\
+	addi	sp, 8;			\
+	cfi_adjust_cfa_offset (-8);
+
+# undef  UNDOARGS_6
+# define UNDOARGS_6			\
+	ldw	r7, (sp, 0);		\
+	cfi_restore (r7);		\
+	ldw	r4, (sp, 4);		\
+	cfi_restore (r4);		\
+	ldw	r5, (sp, 8);		\
+	cfi_restore (r5);		\
+	addi	sp, 16;			\
+	cfi_adjust_cfa_offset (-16);
+
+#else /* not __ASSEMBLER__ */
+
+/* Define a macro which expands into the inline wrapper code for a system
+   call.  */
+# undef INLINE_SYSCALL
+# define INLINE_SYSCALL(name, nr, args...)				\
+  ({ unsigned int _sys_result = INTERNAL_SYSCALL (name, , nr, args);	\
+     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_sys_result,), 0))	\
+       {								\
+	 __set_errno (INTERNAL_SYSCALL_ERRNO (_sys_result, ));		\
+	 _sys_result = (unsigned int) -1;				\
+       }								\
+     (int) _sys_result; })
+
+# undef INTERNAL_SYSCALL_DECL
+# define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+# undef INTERNAL_SYSCALL_ERROR_P
+# define INTERNAL_SYSCALL_ERROR_P(val, err) \
+  ((unsigned int) (val) >= 0xffffff01u)
+
+# undef INTERNAL_SYSCALL_ERRNO
+# define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+
+# undef INTERNAL_SYSCALL_RAW
+#  define INTERNAL_SYSCALL_RAW0(name, err, dummy...)			\
+  ({unsigned int __sys_result;						\
+     {									\
+       register int _a1 __asm__ ("a0"), _nr __asm__ ("r7");		\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr)				\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW1(name, err, arg1)			\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1);				\
+     {									\
+       register int _a1 __asm__ ("a0"), _nr __asm__ ("r7");		\
+       _a1 = _tmp_arg1;							\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1)			\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW2(name, err, arg1, arg2)			\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\
+     {									\
+       register int _nr __asm__ ("r7");					\
+       register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\
+       _a1 = _tmp_arg1, _a2 = _tmp_arg2;				\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1), "r" (_a2)		\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW3(name, err, arg1, arg2, arg3)		\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\
+    register int _tmp_arg3 = (int)(arg3);				\
+     {									\
+       register int _nr __asm__ ("r7");					\
+       register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\
+       register int _a3 __asm__ ("a2");					\
+       _a1 = _tmp_arg1;							\
+       _a2 = _tmp_arg2;							\
+       _a3 = _tmp_arg3;							\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1), "r" (_a2),		\
+			       "r" (_a3)				\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW4(name, err, arg1, arg2, arg3, arg4)	\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\
+    register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4);	\
+     {									\
+       register int _nr __asm__ ("r7");					\
+       register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\
+       register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3");		\
+       _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3;		\
+       _a4 = _tmp_arg4;							\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1), "r" (_a2),		\
+			       "r" (_a3), "r" (_a4)			\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW5(name, err, arg1, arg2, arg3, arg4,	\
+			      arg5)					\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\
+    register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4);	\
+    register int _tmp_arg5 = (int)(arg5);				\
+     {									\
+       register int _nr __asm__ ("r7");					\
+       register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\
+       register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3");		\
+       register int _a5 __asm__ ("r4");					\
+       _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3;		\
+       _a4 = _tmp_arg4, _a5 = _tmp_arg5;				\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1), "r" (_a2),		\
+			       "r" (_a3), "r" (_a4), "r" (_a5)		\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW6(name, err, arg1, arg2, arg3, arg4,	\
+			      arg5, arg6)				\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\
+    register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4);	\
+    register int _tmp_arg5 = (int)(arg5), _tmp_arg6 = (int)(arg6);	\
+     {									\
+       register int _nr __asm__ ("r7");					\
+       register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\
+       register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3");		\
+       register int _a5 __asm__ ("r4"), _a6 __asm__ ("r5");		\
+       _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3;		\
+       _a4 = _tmp_arg4, _a5 = _tmp_arg5, _a6 = _tmp_arg6;		\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1), "r" (_a2),		\
+			       "r" (_a3), "r" (_a4), "r" (_a5),		\
+			       "r" (_a6)				\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW7(name, err, arg1, arg2, arg3, arg4,	\
+			      arg5, arg6, arg7)				\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\
+    register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4);	\
+    register int _tmp_arg5 = (int)(arg5), _tmp_arg6 = (int)(arg6);	\
+    register int _tmp_arg7 = (int)(arg7);				\
+     {									\
+       register int _nr __asm__ ("r7");					\
+       register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\
+       register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3");		\
+       register int _a5 __asm__ ("r4"), _a6 __asm__ ("r5");		\
+       register int _a7 __asm__ ("r6");					\
+       _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3;		\
+       _a4 = _tmp_arg4, _a5 = _tmp_arg5, _a6 = _tmp_arg6;		\
+       _a7 = _tmp_arg7;							\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1), "r" (_a2),		\
+			       "r" (_a3), "r" (_a4), "r" (_a5),		\
+			       "r" (_a6), "r" (_a7)			\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+# undef INTERNAL_SYSCALL
+# define INTERNAL_SYSCALL(name, err, nr, args...)		\
+  INTERNAL_SYSCALL_RAW##nr(SYS_ify(name), err, args)
+
+# undef INTERNAL_SYSCALL_NCS
+# define INTERNAL_SYSCALL_NCS(number, err, nr, args...)		\
+  INTERNAL_SYSCALL_RAW##nr (number, err, args)
+
+#endif /* __ASSEMBLER__ */
+
+/* Pointer mangling support.  */
+#if (IS_IN (rtld) || \
+     (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
+# ifdef __ASSEMBLER__
+#  define PTR_MANGLE(dst, src, guard)			\
+	grs	t0, 1f;					\
+1:							\
+	lrw	guard, 1b@GOTPC;			\
+	addu	t0, guard;				\
+	lrw	guard, __pointer_chk_guard_local@GOT;	\
+	ldr.w	guard, (t0, guard << 0);		\
+	ldw	guard, (guard, 0);			\
+	xor	dst, src, guard;
+#  define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard)
+#  define PTR_MANGLE2(dst, src, guard) \
+	xor	dst, src, guard
+#  define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard)
+# else
+extern uintptr_t __pointer_chk_guard_local;
+#  define PTR_MANGLE(var) \
+  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
+#  define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#else
+# ifdef __ASSEMBLER__
+#  define PTR_MANGLE(dst, src, guard)		\
+	grs	t0, 1f;				\
+1:						\
+	lrw	guard, 1b@GOTPC;		\
+	addu	t0, guard;			\
+	lrw	guard, __pointer_chk_guard@GOT;	\
+	ldr.w	guard, (t0, guard << 0);	\
+	ldw	guard, (guard, 0);		\
+	xor	dst, src, guard;
+#  define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard)
+#  define PTR_MANGLE2(dst, src, guard) \
+	xor	dst, src, guard
+#  define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard)
+# else
+extern uintptr_t __pointer_chk_guard;
+#  define PTR_MANGLE(var) \
+  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
+#  define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#endif
+
+#endif /* linux/csky/sysdep.h */