diff options
Diffstat (limited to 'libc/sysdeps/linux/xtensa')
44 files changed, 886 insertions, 874 deletions
diff --git a/libc/sysdeps/linux/xtensa/Makefile.arch b/libc/sysdeps/linux/xtensa/Makefile.arch index f54886444..b9b6b87d5 100644 --- a/libc/sysdeps/linux/xtensa/Makefile.arch +++ b/libc/sysdeps/linux/xtensa/Makefile.arch @@ -5,10 +5,10 @@ # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -CSRC := brk.c fork.c posix_fadvise.c posix_fadvise64.c pread_write.c \ - sigaction.c __syscall_error.c +CSRC-y := brk.c sigaction.c __syscall_error.c -SSRC := bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S \ +SSRC-y := bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S \ sigrestorer.S syscall.S mmap.S windowspill.S __longjmp.S vfork.S -include $(top_srcdir)libc/sysdeps/linux/Makefile.commonarch +CSRC-$(if $(UCLIBC_HAS_THREADS_NATIVE),,y) += fork.c +SSRC-$(if $(UCLIBC_HAS_THREADS_NATIVE),,y) += clone.S diff --git a/libc/sysdeps/linux/xtensa/__longjmp.S b/libc/sysdeps/linux/xtensa/__longjmp.S index 0fa939095..acc0b4ff2 100644 --- a/libc/sysdeps/linux/xtensa/__longjmp.S +++ b/libc/sysdeps/linux/xtensa/__longjmp.S @@ -14,9 +14,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ /* This implementation relies heavily on the Xtensa register window mechanism. Setjmp flushes all the windows except its own to the @@ -49,6 +48,7 @@ ENTRY (__longjmp) +#if defined(__XTENSA_WINDOWED_ABI__) /* Invalidate all but the current window. Reading and writing special registers WINDOWBASE and WINDOWSTART are privileged operations, so user processes must call the @@ -84,7 +84,7 @@ ENTRY (__longjmp) slli a4, a7, 4 sub a6, a8, a4 addi a5, a2, 16 - addi a8, a8, -16 // a8 = end of register overflow area + addi a8, a8, -16 /* a8 = end of register overflow area */ .Lljloop: l32i a7, a5, 0 l32i a4, a5, 4 @@ -105,8 +105,8 @@ ENTRY (__longjmp) case the contents were moved by an alloca after calling setjmp. This is a bit paranoid but it doesn't cost much. */ - l32i a7, a2, 4 // load the target stack pointer - addi a7, a7, -16 // find the destination save area + l32i a7, a2, 4 /* load the target stack pointer */ + addi a7, a7, -16 /* find the destination save area */ l32i a4, a2, 48 l32i a5, a2, 52 s32i a4, a7, 0 @@ -121,6 +121,22 @@ ENTRY (__longjmp) movnez a2, a3, a3 retw +#elif defined(__XTENSA_CALL0_ABI__) + l32i a0, a2, 0 + l32i a1, a2, 4 + l32i a12, a2, 8 + l32i a13, a2, 12 + l32i a14, a2, 16 + l32i a15, a2, 20 + + /* Return v ? v : 1. */ + movi a2, 1 + movnez a2, a3, a3 + + ret +#else +#error Unsupported Xtensa ABI +#endif END (__longjmp) libc_hidden_def (__longjmp) diff --git a/libc/sysdeps/linux/xtensa/bits/atomic.h b/libc/sysdeps/linux/xtensa/bits/atomic.h new file mode 100644 index 000000000..b2be547f0 --- /dev/null +++ b/libc/sysdeps/linux/xtensa/bits/atomic.h @@ -0,0 +1,232 @@ +/* Copyright (C) 2012 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 _BITS_ATOMIC_H +#define _BITS_ATOMIC_H 1 + +#include <inttypes.h> + +typedef int32_t atomic32_t; +typedef uint32_t uatomic32_t; +typedef int_fast32_t atomic_fast32_t; +typedef uint_fast32_t uatomic_fast32_t; + +typedef int64_t atomic64_t; +typedef uint64_t uatomic64_t; +typedef int_fast64_t atomic_fast64_t; +typedef uint_fast64_t uatomic_fast64_t; + +typedef intptr_t atomicptr_t; +typedef uintptr_t uatomicptr_t; +typedef intmax_t atomic_max_t; +typedef uintmax_t uatomic_max_t; + + +/* Xtensa has only a 32-bit form of a store-conditional instruction. */ + +#define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \ + (abort (), 0) + +#define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval) \ + (abort (), 0) + +#define __arch_compare_and_exchange_bool_8_rel(mem, newval, oldval) \ + (abort (), 0) + +#define __arch_compare_and_exchange_bool_16_rel(mem, newval, oldval) \ + (abort (), 0) + +/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL. + Return the old *MEM value. */ + +#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + "1: l32i %1, %2, 0 \n" \ + " bne %1, %4, 2f \n" \ + " wsr %1, SCOMPARE1 \n" \ + " mov %0, %1 \n" \ + " mov %1, %3 \n" \ + " s32c1i %1, %2, 0 \n" \ + " bne %0, %1, 1b \n" \ + "2: \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (newval), "a" (oldval) \ + : "memory" ); \ + __tmp; \ + }) + +/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL. + Return zero if *MEM was changed or non-zero if no exchange happened. */ + +#define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + "1: l32i %0, %2, 0 \n" \ + " sub %1, %4, %0 \n" \ + " bnez %1, 2f \n" \ + " wsr %0, SCOMPARE1 \n" \ + " mov %1, %3 \n" \ + " s32c1i %1, %2, 0 \n" \ + " bne %0, %1, 1b \n" \ + " movi %1, 0 \n" \ + "2: \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (newval), "a" (oldval) \ + : "memory" ); \ + __tmp != 0; \ + }) + +/* Store NEWVALUE in *MEM and return the old value. */ + +#define __arch_exchange_32_acq(mem, newval) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + "1: l32i %0, %2, 0 \n" \ + " wsr %0, SCOMPARE1 \n" \ + " mov %1, %3 \n" \ + " s32c1i %1, %2, 0 \n" \ + " bne %0, %1, 1b \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (newval) \ + : "memory" ); \ + __tmp; \ + }) + +/* Add VALUE to *MEM and return the old value of *MEM. */ + +#define __arch_atomic_exchange_and_add_32(mem, value) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + "1: l32i %0, %2, 0 \n" \ + " wsr %0, SCOMPARE1 \n" \ + " add %1, %0, %3 \n" \ + " s32c1i %1, %2, 0 \n" \ + " bne %0, %1, 1b \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (value) \ + : "memory" ); \ + __tmp; \ + }) + +/* Subtract VALUE from *MEM and return the old value of *MEM. */ + +#define __arch_atomic_exchange_and_sub_32(mem, value) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + "1: l32i %0, %2, 0 \n" \ + " wsr %0, SCOMPARE1 \n" \ + " sub %1, %0, %3 \n" \ + " s32c1i %1, %2, 0 \n" \ + " bne %0, %1, 1b \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (value) \ + : "memory" ); \ + __tmp; \ + }) + +/* Decrement *MEM if it is > 0, and return the old value. */ + +#define __arch_atomic_decrement_if_positive_32(mem) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + "1: l32i %0, %2, 0 \n" \ + " blti %0, 1, 2f \n" \ + " wsr %0, SCOMPARE1 \n" \ + " addi %1, %0, -1 \n" \ + " s32c1i %1, %2, 0 \n" \ + " bne %0, %1, 1b \n" \ + "2: \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem) \ + : "memory" ); \ + __value; \ + }) + + +/* These are the preferred public interfaces: */ + +#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ + ({ \ + if (sizeof (*mem) != 4) \ + abort(); \ + __arch_compare_and_exchange_val_32_acq(mem, newval, oldval); \ + }) + +#define atomic_exchange_acq(mem, newval) \ + ({ \ + if (sizeof(*(mem)) != 4) \ + abort(); \ + __arch_exchange_32_acq(mem, newval); \ + }) + +#define atomic_exchange_and_add(mem, newval) \ + ({ \ + if (sizeof(*(mem)) != 4) \ + abort(); \ + __arch_atomic_exchange_and_add_32(mem, newval); \ + }) + +#define atomic_exchange_and_sub(mem, newval) \ + ({ \ + if (sizeof(*(mem)) != 4) \ + abort(); \ + __arch_atomic_exchange_and_sub_32(mem, newval); \ + }) + +#define atomic_decrement_if_positive(mem) \ + ({ \ + if (sizeof(*(mem)) != 4) \ + abort(); \ + __arch_atomic_decrement_if_positive_32(mem); \ + }) + + +# define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \ + (abort (), 0) + +# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ + (abort (), (__typeof (*mem)) 0) + +# define __arch_compare_and_exchange_bool_64_rel(mem, newval, oldval) \ + (abort (), 0) + +# define __arch_compare_and_exchange_val_64_rel(mem, newval, oldval) \ + (abort (), (__typeof (*mem)) 0) + +# define __arch_atomic_exchange_64_acq(mem, value) \ + ({ abort (); (*mem) = (value); }) + +# define __arch_atomic_exchange_64_rel(mem, value) \ + ({ abort (); (*mem) = (value); }) + +# define __arch_atomic_exchange_and_add_64(mem, value) \ + ({ abort (); (*mem) = (value); }) + +# define __arch_atomic_increment_val_64(mem) \ + ({ abort (); (*mem)++; }) + +# define __arch_atomic_decrement_val_64(mem) \ + ({ abort (); (*mem)--; }) + +# define __arch_atomic_decrement_if_positive_64(mem) \ + ({ abort (); (*mem)--; }) + + + +#endif /* _BITS_ATOMIC_H */ + diff --git a/libc/sysdeps/linux/xtensa/bits/fcntl.h b/libc/sysdeps/linux/xtensa/bits/fcntl.h index 23de96c02..d21c4e03c 100644 --- a/libc/sysdeps/linux/xtensa/bits/fcntl.h +++ b/libc/sysdeps/linux/xtensa/bits/fcntl.h @@ -14,9 +14,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _FCNTL_H # error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead." @@ -50,6 +49,8 @@ # define O_DIRECTORY 0200000 /* Must be a directory. */ # define O_NOFOLLOW 0400000 /* Do not follow links. */ # define O_NOATIME 01000000 /* Do not set atime. */ +# define O_CLOEXEC 02000000 /* set close_on_exec */ +# define O_PATH 010000000 /* Resolve pathname but do not open file. */ #endif /* For now Linux has synchronisity options for data and read operations. @@ -99,6 +100,8 @@ # define F_NOTIFY 1026 /* Request notfications on a directory. */ # define F_DUPFD_CLOEXEC 1030 /* Duplicate file descriptor with close-on-exit set on new fd. */ +# define F_SETPIPE_SZ 1031 /* Set pipe page size array. */ +# define F_GETPIPE_SZ 1032 /* Get pipe page size array. */ #endif /* For F_[GET|SET]FD. */ @@ -186,7 +189,7 @@ struct flock64 #endif -#ifdef __USE_GNU +#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__ /* Flags for SYNC_FILE_RANGE. */ # define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages in the range before performing the @@ -209,7 +212,7 @@ struct flock64 __BEGIN_DECLS -#ifdef __USE_GNU +#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__ /* Provide kernel hint to read ahead. */ extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count) diff --git a/libc/sysdeps/linux/xtensa/bits/ipc.h b/libc/sysdeps/linux/xtensa/bits/ipc.h index 481bdcc52..2ad5fc0a2 100644 --- a/libc/sysdeps/linux/xtensa/bits/ipc.h +++ b/libc/sysdeps/linux/xtensa/bits/ipc.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _SYS_IPC_H # error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." diff --git a/libc/sysdeps/linux/xtensa/bits/kernel_stat.h b/libc/sysdeps/linux/xtensa/bits/kernel_stat.h index 26da9281b..5e4f5c4e5 100644 --- a/libc/sysdeps/linux/xtensa/bits/kernel_stat.h +++ b/libc/sysdeps/linux/xtensa/bits/kernel_stat.h @@ -1,16 +1,10 @@ #ifndef _BITS_STAT_STRUCT_H #define _BITS_STAT_STRUCT_H -#ifndef _LIBC -#error bits/kernel_stat.h is for internal uClibc use only! -#endif - /* This file provides whatever this particular arch's kernel thinks * struct kernel_stat should look like... It turns out each arch has a * different opinion on the subject... */ -#define STAT_HAVE_NSEC 1 - struct kernel_stat { unsigned long st_dev; unsigned long st_ino; @@ -22,12 +16,9 @@ struct kernel_stat { long st_size; unsigned long st_blksize; unsigned long st_blocks; - unsigned long st_atime; - unsigned long st_atime_nsec; - unsigned long st_mtime; - unsigned long st_mtime_nsec; - unsigned long st_ctime; - unsigned long st_ctime_nsec; + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; unsigned long __unused4; unsigned long __unused5; }; @@ -44,12 +35,9 @@ struct kernel_stat64 { unsigned long st_blksize; /* Optimal block size for I/O. */ unsigned long __unused2; unsigned long long st_blocks; /* Number 512-byte blocks allocated. */ - unsigned long st_atime; /* Time of last access. */ - unsigned long st_atime_nsec; - unsigned long st_mtime; /* Time of last modification. */ - unsigned long st_mtime_nsec; - unsigned long st_ctime; /* Time of last status change. */ - unsigned long st_ctime_nsec; + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ unsigned long __unused4; unsigned long __unused5; }; diff --git a/libc/sysdeps/linux/xtensa/bits/kernel_types.h b/libc/sysdeps/linux/xtensa/bits/kernel_types.h index 44f1075f7..ed38f2e18 100644 --- a/libc/sysdeps/linux/xtensa/bits/kernel_types.h +++ b/libc/sysdeps/linux/xtensa/bits/kernel_types.h @@ -33,6 +33,8 @@ typedef unsigned int __kernel_gid32_t; typedef unsigned short __kernel_old_uid_t; typedef unsigned short __kernel_old_gid_t; typedef unsigned short __kernel_old_dev_t; +typedef long __kernel_long_t; +typedef unsigned long __kernel_ulong_t; typedef long long __kernel_loff_t; /* Beginning in 2.6 kernels, which is the first version that includes the diff --git a/libc/sysdeps/linux/xtensa/bits/mathdef.h b/libc/sysdeps/linux/xtensa/bits/mathdef.h index 0177fa9fc..1c73cb255 100644 --- a/libc/sysdeps/linux/xtensa/bits/mathdef.h +++ b/libc/sysdeps/linux/xtensa/bits/mathdef.h @@ -13,9 +13,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #if !defined _MATH_H && !defined _COMPLEX_H # error "Never use <bits/mathdef.h> directly; include <math.h> instead" diff --git a/libc/sysdeps/linux/xtensa/bits/mman.h b/libc/sysdeps/linux/xtensa/bits/mman.h index d3beae6aa..a42e92663 100644 --- a/libc/sysdeps/linux/xtensa/bits/mman.h +++ b/libc/sysdeps/linux/xtensa/bits/mman.h @@ -13,9 +13,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _SYS_MMAN_H # error "Never use <bits/mman.h> directly; include <sys/mman.h> instead." @@ -64,6 +63,8 @@ # define MAP_NORESERVE 0x0400 /* Don't check for reservations. */ # define MAP_POPULATE 0x10000 /* Populate (prefault) pagetables. */ # define MAP_NONBLOCK 0x20000 /* Do not block on IO. */ +# define MAP_UNINITIALIZED 0x4000000 /* For anonymous mmap, memory could + be uninitialized. */ #endif /* Flags to `msync'. */ diff --git a/libc/sysdeps/linux/xtensa/bits/msq.h b/libc/sysdeps/linux/xtensa/bits/msq.h index 2eca21e6c..e4f3fa317 100644 --- a/libc/sysdeps/linux/xtensa/bits/msq.h +++ b/libc/sysdeps/linux/xtensa/bits/msq.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _SYS_MSG_H # error "Never use <bits/msq.h> directly; include <sys/msg.h> instead." diff --git a/libc/sysdeps/linux/xtensa/bits/setjmp.h b/libc/sysdeps/linux/xtensa/bits/setjmp.h index 1bc4896c8..5d3e5509e 100644 --- a/libc/sysdeps/linux/xtensa/bits/setjmp.h +++ b/libc/sysdeps/linux/xtensa/bits/setjmp.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ /* Define the machine-dependent type `jmp_buf'. Xtensa version. */ #ifndef _BITS_SETJMP_H @@ -24,23 +23,21 @@ # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead." #endif +#if defined(__XTENSA_WINDOWED_ABI__) /* The jmp_buf structure for Xtensa holds the following (where "proc" is the procedure that calls setjmp): 4-12 registers from the window of proc, the 4 words from the save area at proc's $sp (in case a subsequent alloca in proc moves $sp), and the return address within proc. Everything else is saved on the stack in the normal save areas. */ -#ifndef _ASM typedef int __jmp_buf[17]; -#endif - -#define JB_SP 1 -#define JB_PC 16 +#elif defined(__XTENSA_CALL0_ABI__) +/* The jmp_buf structure for Xtensa Call0 ABI holds the return address, + the stack pointer and callee-saved registers (a12 - a15). */ -/* Test if longjmp to JMPBUF would unwind the frame containing a local - variable at ADDRESS. */ - -#define _JMPBUF_UNWINDS(jmpbuf, address) \ - ((void *) (address) < (void *) (jmpbuf)[JB_SP]) +typedef int __jmp_buf[6]; +#else +#error Unsupported Xtensa ABI +#endif #endif /* bits/setjmp.h */ diff --git a/libc/sysdeps/linux/xtensa/bits/shm.h b/libc/sysdeps/linux/xtensa/bits/shm.h index de41d0d99..d288a1cca 100644 --- a/libc/sysdeps/linux/xtensa/bits/shm.h +++ b/libc/sysdeps/linux/xtensa/bits/shm.h @@ -13,9 +13,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _SYS_SHM_H # error "Never include <bits/shm.h> directly; use <sys/shm.h> instead." diff --git a/libc/sysdeps/linux/xtensa/bits/sigcontext.h b/libc/sysdeps/linux/xtensa/bits/sigcontext.h new file mode 100644 index 000000000..c0af295f9 --- /dev/null +++ b/libc/sysdeps/linux/xtensa/bits/sigcontext.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2012 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/>. */ + +#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H +# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead." +#endif + +#ifndef _BITS_SIGCONTEXT_H +#define _BITS_SIGCONTEXT_H 1 + +struct sigcontext +{ + unsigned long sc_pc; + unsigned long sc_ps; + unsigned long sc_lbeg; + unsigned long sc_lend; + unsigned long sc_lcount; + unsigned long sc_sar; + unsigned long sc_acclo; + unsigned long sc_acchi; + unsigned long sc_a[16]; + void *sc_xtregs; +}; + +#endif /* _BITS_SIGCONTEXT_H */ + diff --git a/libc/sysdeps/linux/xtensa/bits/sigcontextinfo.h b/libc/sysdeps/linux/xtensa/bits/sigcontextinfo.h index 8f3301c9a..39ad5f689 100644 --- a/libc/sysdeps/linux/xtensa/bits/sigcontextinfo.h +++ b/libc/sysdeps/linux/xtensa/bits/sigcontextinfo.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ /* Also see register-dump.h, where we spill live registers to the stack so that we can trace the stack backward. */ diff --git a/libc/sysdeps/linux/xtensa/bits/stackinfo.h b/libc/sysdeps/linux/xtensa/bits/stackinfo.h index 50ddf2514..6ecdd69ba 100644 --- a/libc/sysdeps/linux/xtensa/bits/stackinfo.h +++ b/libc/sysdeps/linux/xtensa/bits/stackinfo.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ /* This file contains a bit of information about the stack allocation of the processor. */ diff --git a/libc/sysdeps/linux/xtensa/bits/stat.h b/libc/sysdeps/linux/xtensa/bits/stat.h index c6debc894..c61b188b7 100644 --- a/libc/sysdeps/linux/xtensa/bits/stat.h +++ b/libc/sysdeps/linux/xtensa/bits/stat.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _SYS_STAT_H # error "Never include <bits/stat.h> directly; use <sys/stat.h> instead." @@ -55,7 +54,7 @@ struct stat unsigned long __pad2; __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ #endif -#if 0 /*def __USE_MISC*/ +#ifdef __USE_MISC /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -95,7 +94,7 @@ struct stat64 unsigned long __pad2; __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ -#if 0 /*def __USE_MISC*/ +#ifdef __USE_MISC /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -151,3 +150,8 @@ struct stat64 #define __S_IREAD 0400 /* Read by owner. */ #define __S_IWRITE 0200 /* Write by owner. */ #define __S_IEXEC 0100 /* Execute by owner. */ + +#ifdef __USE_ATFILE +# define UTIME_NOW ((1l << 30) - 1l) +# define UTIME_OMIT ((1l << 30) - 2l) +#endif diff --git a/libc/sysdeps/linux/xtensa/bits/syscalls.h b/libc/sysdeps/linux/xtensa/bits/syscalls.h index a59a8052a..7e900c590 100644 --- a/libc/sysdeps/linux/xtensa/bits/syscalls.h +++ b/libc/sysdeps/linux/xtensa/bits/syscalls.h @@ -9,8 +9,6 @@ glibc .../sysdeps/unix/sysv/linux/xtensa/sysdep.h */ -#define SYS_ify(syscall_name) __NR_##syscall_name - #ifdef __ASSEMBLER__ /* The register layout upon entering the function is: @@ -74,67 +72,16 @@ /* Define a macro which expands into the inline wrapper code for a system call. */ -#undef INLINE_SYSCALL -#define INLINE_SYSCALL(name, nr, args...) \ - ({ unsigned long resultvar = INTERNAL_SYSCALL (name, , nr, args); \ - if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0)) \ - { \ - __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, )); \ - resultvar = (unsigned long) -1; \ - } \ - (long) resultvar; }) - -#undef INTERNAL_SYSCALL_DECL -#define INTERNAL_SYSCALL_DECL(err) do { } while (0) - #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ +(__extension__ \ ({ LD_ARG(2, name); \ LD_ARGS_##nr(args); \ __asm__ __volatile__ ("syscall\n" \ : "=a" (_a2) \ : ASM_ARGS_##nr \ : "memory"); \ - (long) _a2; }) - -#undef INTERNAL_SYSCALL -#define INTERNAL_SYSCALL(name, err, nr, args...) \ - INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args) - -#undef INTERNAL_SYSCALL_ERROR_P -#define INTERNAL_SYSCALL_ERROR_P(val, err) \ - ((unsigned long) (val) >= -4095L) - -#undef INTERNAL_SYSCALL_ERRNO -#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) - -#define _syscall0(args...) SYSCALL_FUNC (0, args) -#define _syscall1(args...) SYSCALL_FUNC (1, args) -#define _syscall2(args...) SYSCALL_FUNC (2, args) -#define _syscall3(args...) SYSCALL_FUNC (3, args) -#define _syscall4(args...) SYSCALL_FUNC (4, args) -#define _syscall5(args...) SYSCALL_FUNC (5, args) -#define _syscall6(args...) SYSCALL_FUNC (6, args) - -#define C_DECL_ARGS_0() void -#define C_DECL_ARGS_1(t, v) t v -#define C_DECL_ARGS_2(t, v, args...) t v, C_DECL_ARGS_1(args) -#define C_DECL_ARGS_3(t, v, args...) t v, C_DECL_ARGS_2(args) -#define C_DECL_ARGS_4(t, v, args...) t v, C_DECL_ARGS_3(args) -#define C_DECL_ARGS_5(t, v, args...) t v, C_DECL_ARGS_4(args) -#define C_DECL_ARGS_6(t, v, args...) t v, C_DECL_ARGS_5(args) - -#define C_ARGS_0() -#define C_ARGS_1(t, v) v -#define C_ARGS_2(t, v, args...) v, C_ARGS_1 (args) -#define C_ARGS_3(t, v, args...) v, C_ARGS_2 (args) -#define C_ARGS_4(t, v, args...) v, C_ARGS_3 (args) -#define C_ARGS_5(t, v, args...) v, C_ARGS_4 (args) -#define C_ARGS_6(t, v, args...) v, C_ARGS_5 (args) - -#define SYSCALL_FUNC(nargs, type, name, args...) \ -type name (C_DECL_ARGS_##nargs (args)) { \ - return (type) INLINE_SYSCALL (name, nargs, C_ARGS_##nargs (args)); \ -} - + (long) _a2; \ + }) \ +) #endif /* not __ASSEMBLER__ */ #endif /* _BITS_SYSCALLS_H */ diff --git a/libc/sysdeps/linux/xtensa/bits/uClibc_arch_features.h b/libc/sysdeps/linux/xtensa/bits/uClibc_arch_features.h index d6a99b4d2..a15744c2f 100644 --- a/libc/sysdeps/linux/xtensa/bits/uClibc_arch_features.h +++ b/libc/sysdeps/linux/xtensa/bits/uClibc_arch_features.h @@ -11,8 +11,8 @@ /* can your target use syscall6() for mmap ? */ #define __UCLIBC_MMAP_HAS_6_ARGS__ -/* does your target use syscall4() for truncate64 ? (32bit arches only) */ -#define __UCLIBC_TRUNCATE64_HAS_4_ARGS__ +/* does your target align 64bit values in register pairs ? (32bit arches only) */ +#define __UCLIBC_SYSCALL_ALIGN_64BIT__ /* does your target have a broken create_module() ? */ #undef __UCLIBC_BROKEN_CREATE_MODULE__ @@ -23,19 +23,19 @@ /* does your target have an asm .set ? */ #define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__ -/* define if target doesn't like .global */ -#undef __UCLIBC_ASM_GLOBAL_DIRECTIVE__ - /* define if target supports .weak */ #define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__ /* define if target supports .weakext */ #undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__ -/* needed probably only for ppc64 */ -#undef __UCLIBC_HAVE_ASM_GLOBAL_DOT_NAME__ +/* define if target supports CFI pseudo ops */ +#undef __UCLIBC_HAVE_ASM_CFI_DIRECTIVES__ /* define if target supports IEEE signed zero floats */ #define __UCLIBC_HAVE_SIGNED_ZERO__ +/* only weird assemblers generally need this */ +#undef __UCLIBC_ASM_LINE_SEP__ + #endif /* _BITS_UCLIBC_ARCH_FEATURES_H */ diff --git a/libc/sysdeps/linux/xtensa/bits/uClibc_page.h b/libc/sysdeps/linux/xtensa/bits/uClibc_page.h deleted file mode 100644 index 74a9f60ba..000000000 --- a/libc/sysdeps/linux/xtensa/bits/uClibc_page.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2004 Erik Andersen - * - * This 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, write to the Free - * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA. - */ - -/* Supply an architecture specific value for PAGE_SIZE and friends. */ - -#ifndef _UCLIBC_PAGE_H -#define _UCLIBC_PAGE_H - -#include <bits/xtensa-config.h> - -/* PAGE_SHIFT determines the page size -- in this case 4096 */ -#define PAGE_SHIFT XCHAL_MMU_MIN_PTE_PAGE_SIZE -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) - -#endif /* _UCLIBC_PAGE_H */ diff --git a/libc/sysdeps/linux/xtensa/bits/wordsize.h b/libc/sysdeps/linux/xtensa/bits/wordsize.h index ba643b60a..ca82fd7d4 100644 --- a/libc/sysdeps/linux/xtensa/bits/wordsize.h +++ b/libc/sysdeps/linux/xtensa/bits/wordsize.h @@ -12,8 +12,7 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #define __WORDSIZE 32 diff --git a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h index 34cf28c0a..2e60af936 100644 --- a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h +++ b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h @@ -14,9 +14,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef XTENSA_CONFIG_H #define XTENSA_CONFIG_H @@ -44,10 +43,4 @@ #undef XCHAL_NUM_AREGS #define XCHAL_NUM_AREGS 64 -/* Set a default page size. This is currently needed when bootstrapping - the runtime linker. See comments in dl-machine.h where this is used. */ - -#undef XCHAL_MMU_MIN_PTE_PAGE_SIZE -#define XCHAL_MMU_MIN_PTE_PAGE_SIZE 12 - #endif /* !XTENSA_CONFIG_H */ diff --git a/libc/sysdeps/linux/xtensa/brk.c b/libc/sysdeps/linux/xtensa/brk.c index 51f610b70..512810409 100644 --- a/libc/sysdeps/linux/xtensa/brk.c +++ b/libc/sysdeps/linux/xtensa/brk.c @@ -13,9 +13,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include <errno.h> #include <unistd.h> @@ -24,7 +23,6 @@ /* This must be initialized data because commons can't have aliases. */ void *__curbrk attribute_hidden = 0; -libc_hidden_proto(brk) int brk (void *addr) { diff --git a/libc/sysdeps/linux/xtensa/clone.S b/libc/sysdeps/linux/xtensa/clone.S index 31921ea47..88cd6c1c3 100644 --- a/libc/sysdeps/linux/xtensa/clone.S +++ b/libc/sysdeps/linux/xtensa/clone.S @@ -1,35 +1,38 @@ -/* Copyright (C) 2001, 2005, 2007 Free Software Foundation, Inc. +/* Copyright (C) 2001, 2005 Free Software Foundation, Inc. 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. + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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. + Library 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ /* clone is even more special than fork as it mucks with stacks - and invokes a function in the right context after it's all over. */ + and invokes a function in the right context after its all over. */ -#include "sysdep.h" -#include <sys/syscall.h> +#include <features.h> +#include <sysdep.h> #define _ERRNO_H 1 #include <bits/errno.h> +#ifdef RESET_PID +#include <tls.h> +#endif +#define __ASSEMBLY__ +#include <linux/sched.h> -/* int clone (a2 = int (*fn)(void *arg), - a3 = void *child_stack, - a4 = int flags, - a5 = void *arg, - a6 = pid_t *ptid, - a7 = struct user_desc *tls, - 16(sp) = pid_t *ctid) */ +/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, + a2 a3 a4 a5 + pid_t *ptid, struct user_desc *tls, pid_t *ctid) + a6 a7 16(sp) +*/ .text ENTRY (__clone) @@ -40,7 +43,7 @@ ENTRY (__clone) /* a2 and a3 are candidates for destruction by system-call return parameters. We don't need the stack pointer after the system - call. We trust that the kernel will preserve a7, a9, and a6. */ + call. We trust that the kernel will preserve a6, a7 and a9. */ mov a9, a5 /* save function argument */ mov a5, a7 @@ -48,55 +51,69 @@ ENTRY (__clone) mov a8, a6 /* use a8 as a temp */ mov a6, a4 mov a4, a8 - l32i a8, a1, 16 /* child_tid */ - movi a2, SYS_ify (clone) - - /* syscall (a2 = NR_clone, - a6 = clone_flags, - a3 = usp, - a4 = parent_tid, - a5 = child_tls, - a8 = child_tid) */ + l32i a8, a1, FRAMESIZE /* child_tid */ + movi a2, SYS_ify(clone) + + /* syscall(NR_clone,clone_flags, usp, parent_tid, child_tls, child_tid) + a2 a6 a3 a4 a5 a8 + */ + syscall bltz a2, SYSCALL_ERROR_LABEL beqz a2, .Lthread_start - /* Fall through for parent. */ + /* fall through for parent */ + .Lpseudo_end: - retw + abi_ret .Leinval: movi a2, -EINVAL j SYSCALL_ERROR_LABEL .Lthread_start: - /* Start child thread. */ - movi a0, 0 /* terminate the stack frame */ + +#if CLONE_THREAD != 0x00010000 || CLONE_VM != 0x00000100 +# error invalid values for CLONE_THREAD or CLONE_VM +#endif #ifdef RESET_PID - /* Check and see if we need to reset the PID. */ - bbsi.l a6, 16, 1f /* CLONE_THREAD = 0x00010000 */ + bbsi.l a6, 16, .Lskip_restore_pid /* CLONE_THREAD = 0x00010000 */ movi a2, -1 - bbsi.l a6, 8, 2f /* CLONE_VM = 0x00000100 */ - movi a2, SYS_ify (getpid) + bbsi a6, 8, .Lgotpid /* CLONE_VM = 0x00000100 */ + movi a2, SYS_ify(getpid) syscall -2: rur a3, THREADPTR - movi a4, PID_OFFSET - add a4, a4, a3 - s32i a2, a4, 0 - movi a4, TID_OFFSET - add a4, a4, a3 - s32i a2, a3, 0 -1: -#endif /* RESET_PID */ +.Lgotpid: + rur a3, threadptr + movi a0, TLS_PRE_TCB_SIZE + sub a3, a3, a0 + s32i a2, a3, PID + s32i a2, a3, TID +.Lskip_restore_pid: +#endif + + /* start child thread */ + movi a0, 0 /* terminate the stack frame */ +#if defined(__XTENSA_WINDOWED_ABI__) mov a6, a9 /* load up the 'arg' parameter */ callx4 a7 /* call the user's function */ /* Call _exit. Note that any return parameter from the user's - function in a6 is seen as inputs to _exit. */ + function in a6 is seen as inputs to _exit. */ movi a2, JUMPTARGET(_exit) callx4 a2 +#elif defined(__XTENSA_CALL0_ABI__) + mov a2, a9 /* load up the 'arg' parameter */ + callx0 a7 /* call the user's function */ + + /* Call _exit. Note that any return parameter from the user's + function in a2 is seen as inputs to _exit. */ + movi a0, JUMPTARGET(_exit) + callx0 a0 +#else +#error Unsupported Xtensa ABI +#endif PSEUDO_END (__clone) diff --git a/libc/sysdeps/linux/xtensa/crt1.S b/libc/sysdeps/linux/xtensa/crt1.S index 63fbadc15..efbe264c0 100644 --- a/libc/sysdeps/linux/xtensa/crt1.S +++ b/libc/sysdeps/linux/xtensa/crt1.S @@ -30,9 +30,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include <features.h> @@ -77,6 +76,7 @@ .global _start .type _start, @function _start: +#if defined(__XTENSA_WINDOWED_ABI__) /* Clear a0 to obviously mark the outermost frame. */ movi a0, 0 @@ -105,6 +105,35 @@ _start: But let the libc call main. */ movi a4, __uClibc_main callx4 a4 +#elif defined(__XTENSA_CALL0_ABI__) + /* Setup the shared library termination function. */ + mov a7, a2 + + /* Load up the user's main function. */ + movi a2, main + + /* Extract the arguments as encoded on the stack and set up + the arguments for `main': argc, argv. envp will be determined + later in __uClibc_main. */ + l32i a3, a1, 0 /* Load the argument count. */ + addi a4, a1, 4 /* Compute the argv pointer. */ + + /* Push address of our own entry points to .fini and .init. */ + movi a5, _init + movi a6, _fini + + /* Provide the highest stack address to the user code (for stacks + which grow downwards). Note that we destroy the stack version + of argc here. */ + s32i a1, a1, 0 + + /* Call the user's main function, and exit with its value. + But let the libc call main. */ + movi a0, __uClibc_main + callx0 a0 +#else +#error Unsupported Xtensa ABI +#endif /* Crash if somehow `exit' does return. */ ill diff --git a/libc/sysdeps/linux/xtensa/crti.S b/libc/sysdeps/linux/xtensa/crti.S index a01c02c9f..ba804eb45 100644 --- a/libc/sysdeps/linux/xtensa/crti.S +++ b/libc/sysdeps/linux/xtensa/crti.S @@ -5,12 +5,25 @@ .global _init .type _init, @function _init: +#if defined(__XTENSA_WINDOWED_ABI__) entry sp, 48 - +#elif defined(__XTENSA_CALL0_ABI__) + addi sp, sp, -16 + s32i a0, sp, 0 +#else +#error Unsupported Xtensa ABI +#endif .section .fini .align 4 .global _fini .type _fini, @function _fini: +#if defined(__XTENSA_WINDOWED_ABI__) entry sp, 48 +#elif defined(__XTENSA_CALL0_ABI__) + addi sp, sp, -16 + s32i a0, sp, 0 +#else +#error Unsupported Xtensa ABI +#endif diff --git a/libc/sysdeps/linux/xtensa/crtn.S b/libc/sysdeps/linux/xtensa/crtn.S index ab1a489c5..a3598da1a 100644 --- a/libc/sysdeps/linux/xtensa/crtn.S +++ b/libc/sysdeps/linux/xtensa/crtn.S @@ -1,8 +1,23 @@ /* glibc's sysdeps/xtensa/elf/initfini.c used for reference [EPILOG] */ .section .init +#if defined(__XTENSA_WINDOWED_ABI__) retw - +#elif defined(__XTENSA_CALL0_ABI__) + l32i a0, sp, 0 + addi sp, sp, 16 + ret +#else +#error Unsupported Xtensa ABI +#endif .section .fini +#if defined(__XTENSA_WINDOWED_ABI__) retw +#elif defined(__XTENSA_CALL0_ABI__) + l32i a0, sp, 0 + addi sp, sp, 16 + ret +#else +#error Unsupported Xtensa ABI +#endif diff --git a/libc/sysdeps/linux/xtensa/fork.c b/libc/sysdeps/linux/xtensa/fork.c index b06d934fb..4e4f937a0 100644 --- a/libc/sysdeps/linux/xtensa/fork.c +++ b/libc/sysdeps/linux/xtensa/fork.c @@ -7,19 +7,23 @@ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -#include <unistd.h> -#include <sys/syscall.h> -#define _SIGNAL_H -#include <bits/signum.h> /* Xtensa doesn't provide a 'fork' system call, so we use 'clone'. */ +#include <sys/syscall.h> -extern __typeof(fork) __libc_fork; +#if defined __NR_clone && defined __ARCH_USE_MMU__ +# include <unistd.h> +# include <signal.h> +# include <cancel.h> -libc_hidden_proto (fork) -pid_t __libc_fork (void) +pid_t fork(void) { - return (pid_t) INLINE_SYSCALL (clone, 2, SIGCHLD, 0); + return (pid_t) INLINE_SYSCALL(clone, 2, SIGCHLD, 0); } -weak_alias (__libc_fork, fork) -libc_hidden_weak (fork) +# ifdef __UCLIBC_HAS_THREADS__ +strong_alias(fork,__libc_fork) +libc_hidden_weak(fork) +# else +libc_hidden_def(fork) +# endif +#endif diff --git a/libc/sysdeps/linux/xtensa/jmpbuf-offsets.h b/libc/sysdeps/linux/xtensa/jmpbuf-offsets.h new file mode 100644 index 000000000..4078dff55 --- /dev/null +++ b/libc/sysdeps/linux/xtensa/jmpbuf-offsets.h @@ -0,0 +1,20 @@ +/* Private macros for accessing __jmp_buf contents. Xtensa version. + Copyright (C) 2006 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 JB_SP 1 +#define JB_PC 16 diff --git a/libc/sysdeps/linux/xtensa/jmpbuf-unwind.h b/libc/sysdeps/linux/xtensa/jmpbuf-unwind.h new file mode 100644 index 000000000..4516d9398 --- /dev/null +++ b/libc/sysdeps/linux/xtensa/jmpbuf-unwind.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ +#include <setjmp.h> +#include <jmpbuf-offsets.h> + +/* Test if longjmp to JMPBUF would unwind the frame + containing a local variable at ADDRESS. */ +#define _JMPBUF_UNWINDS(jmpbuf, address) \ + ((void *) (address) < (void *) (jmpbuf)[JB_SP]) + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <stdint.h> +#include <unwind.h> + +#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ + _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) + +#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ + ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_SP] - (_adj)) +#endif diff --git a/libc/sysdeps/linux/xtensa/mmap.S b/libc/sysdeps/linux/xtensa/mmap.S index c991e7d27..b4dd7c53b 100644 --- a/libc/sysdeps/linux/xtensa/mmap.S +++ b/libc/sysdeps/linux/xtensa/mmap.S @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "sysdep.h" #include <sys/syscall.h> @@ -49,7 +48,7 @@ ENTRY (__mmap) bltz a2, SYSCALL_ERROR_LABEL .Lpseudo_end: - retw + abi_ret PSEUDO_END (__mmap) diff --git a/libc/sysdeps/linux/xtensa/posix_fadvise.c b/libc/sysdeps/linux/xtensa/posix_fadvise.c deleted file mode 100644 index 0fe13a1e9..000000000 --- a/libc/sysdeps/linux/xtensa/posix_fadvise.c +++ /dev/null @@ -1,29 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * posix_fadvise() for Xtensa uClibc - * - * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> - * Copyright (C) 2007 Tensilica Inc. - * - * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - */ - -#include <sys/syscall.h> -#include <fcntl.h> - -int posix_fadvise (int fd, off_t offset, off_t len, int advice) -{ -#ifdef __NR_fadvise64_64 - INTERNAL_SYSCALL_DECL (err); - int ret = INTERNAL_SYSCALL (fadvise64_64, err, 6, fd, advice, - __LONG_LONG_PAIR ((long) (offset >> 31), - (long) offset), - __LONG_LONG_PAIR ((long) (len >> 31), - (long) len)); - if (!INTERNAL_SYSCALL_ERROR_P (ret, err)) - return 0; - return INTERNAL_SYSCALL_ERRNO (ret, err); -#else - return ENOSYS; -#endif -} diff --git a/libc/sysdeps/linux/xtensa/posix_fadvise64.c b/libc/sysdeps/linux/xtensa/posix_fadvise64.c deleted file mode 100644 index 1fdeeba79..000000000 --- a/libc/sysdeps/linux/xtensa/posix_fadvise64.c +++ /dev/null @@ -1,39 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * posix_fadvise64() for Xtensa uClibc - * - * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> - * Copyright (C) 2007 Tensilica Inc. - * - * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - */ - -#include <features.h> -#include <unistd.h> -#include <errno.h> -#include <endian.h> -#include <stdint.h> -#include <sys/types.h> -#include <sys/syscall.h> -#include <fcntl.h> - -#ifdef __UCLIBC_HAS_LFS__ - -int posix_fadvise64 (int fd, __off64_t offset, __off64_t len, int advice) -{ -#ifdef __NR_fadvise64_64 - INTERNAL_SYSCALL_DECL (err); - int ret = INTERNAL_SYSCALL (fadvise64_64, err, 6, fd, advice, - __LONG_LONG_PAIR ((long) (offset >> 32), - (long) offset), - __LONG_LONG_PAIR ((long) (len >> 32), - (long) len)); - if (!INTERNAL_SYSCALL_ERROR_P (ret, err)) - return 0; - return INTERNAL_SYSCALL_ERRNO (ret, err); -#else - return ENOSYS; -#endif -} - -#endif /* __UCLIBC_HAS_LFS__ */ diff --git a/libc/sysdeps/linux/xtensa/pread_write.c b/libc/sysdeps/linux/xtensa/pread_write.c deleted file mode 100644 index 40d0f0324..000000000 --- a/libc/sysdeps/linux/xtensa/pread_write.c +++ /dev/null @@ -1,193 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> - * - * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - */ -/* - * Based in part on the files - * ./sysdeps/unix/sysv/linux/pwrite.c, - * ./sysdeps/unix/sysv/linux/pread.c, - * sysdeps/posix/pread.c - * sysdeps/posix/pwrite.c - * from GNU libc 2.2.5, but reworked considerably... - */ - -#include <sys/syscall.h> -#include <unistd.h> -#include <stdint.h> -#include <endian.h> - -extern __typeof(pread) __libc_pread; -extern __typeof(pwrite) __libc_pwrite; -#ifdef __UCLIBC_HAS_LFS__ -extern __typeof(pread64) __libc_pread64; -extern __typeof(pwrite64) __libc_pwrite64; -#endif - -#include <bits/kernel_types.h> - -#ifdef __NR_pread - -# define __NR___syscall_pread __NR_pread -/* On Xtensa, 64-bit values are aligned in even/odd register pairs. */ -static __inline__ _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf, - size_t, count, int, pad, off_t, offset_hi, off_t, offset_lo); - -ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset) -{ - return __syscall_pread(fd, buf, count, 0, __LONG_LONG_PAIR(offset >> 31, offset)); -} -weak_alias(__libc_pread,pread) - -# ifdef __UCLIBC_HAS_LFS__ -ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset) -{ - uint32_t low = offset & 0xffffffff; - uint32_t high = offset >> 32; - return __syscall_pread(fd, buf, count, 0, __LONG_LONG_PAIR(high, low)); -} -weak_alias(__libc_pread64,pread64) -# endif /* __UCLIBC_HAS_LFS__ */ - -#endif /* __NR_pread */ - -#ifdef __NR_pwrite - -# define __NR___syscall_pwrite __NR_pwrite -/* On Xtensa, 64-bit values are aligned in even/odd register pairs. */ -static __inline__ _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf, - size_t, count, int, pad, off_t, offset_hi, off_t, offset_lo); - -ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset) -{ - return __syscall_pwrite(fd, buf, count, 0, __LONG_LONG_PAIR(offset >> 31, offset)); -} -weak_alias(__libc_pwrite,pwrite) - -# ifdef __UCLIBC_HAS_LFS__ -ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset) -{ - uint32_t low = offset & 0xffffffff; - uint32_t high = offset >> 32; - return __syscall_pwrite(fd, buf, count, 0, __LONG_LONG_PAIR(high, low)); -} -weak_alias(__libc_pwrite64,pwrite64) -# endif /* __UCLIBC_HAS_LFS__ */ -#endif /* __NR_pwrite */ - -#if ! defined __NR_pread || ! defined __NR_pwrite -libc_hidden_proto(read) -libc_hidden_proto(write) -libc_hidden_proto(lseek) - -static ssize_t __fake_pread_write(int fd, void *buf, - size_t count, off_t offset, int do_pwrite) -{ - int save_errno; - ssize_t result; - off_t old_offset; - - /* Since we must not change the file pointer preserve the - * value so that we can restore it later. */ - if ((old_offset=lseek(fd, 0, SEEK_CUR)) == (off_t) -1) - return -1; - - /* Set to wanted position. */ - if (lseek(fd, offset, SEEK_SET) == (off_t) -1) - return -1; - - if (do_pwrite == 1) { - /* Write the data. */ - result = write(fd, buf, count); - } else { - /* Read the data. */ - result = read(fd, buf, count); - } - - /* Now we have to restore the position. If this fails we - * have to return this as an error. */ - save_errno = errno; - if (lseek(fd, old_offset, SEEK_SET) == (off_t) -1) - { - if (result == -1) - __set_errno(save_errno); - return -1; - } - __set_errno(save_errno); - return(result); -} - -# ifdef __UCLIBC_HAS_LFS__ -libc_hidden_proto(lseek64) - -static ssize_t __fake_pread_write64(int fd, void *buf, - size_t count, off64_t offset, int do_pwrite) -{ - int save_errno; - ssize_t result; - off64_t old_offset; - - /* Since we must not change the file pointer preserve the - * value so that we can restore it later. */ - if ((old_offset=lseek64(fd, 0, SEEK_CUR)) == (off64_t) -1) - return -1; - - /* Set to wanted position. */ - if (lseek64(fd, offset, SEEK_SET) == (off64_t) -1) - return -1; - - if (do_pwrite == 1) { - /* Write the data. */ - result = write(fd, buf, count); - } else { - /* Read the data. */ - result = read(fd, buf, count); - } - - /* Now we have to restore the position. */ - save_errno = errno; - if (lseek64(fd, old_offset, SEEK_SET) == (off64_t) -1) { - if (result == -1) - __set_errno (save_errno); - return -1; - } - __set_errno (save_errno); - return result; -} -# endif /* __UCLIBC_HAS_LFS__ */ -#endif /* ! defined __NR_pread || ! defined __NR_pwrite */ - -#ifndef __NR_pread -ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset) -{ - return __fake_pread_write(fd, buf, count, offset, 0); -} -weak_alias(__libc_pread,pread) - -# ifdef __UCLIBC_HAS_LFS__ -ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset) -{ - return __fake_pread_write64(fd, buf, count, offset, 0); -} -weak_alias(__libc_pread64,pread64) -# endif /* __UCLIBC_HAS_LFS__ */ -#endif /* ! __NR_pread */ - -#ifndef __NR_pwrite -ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset) -{ - /* we won't actually be modifying the buffer, - *just cast it to get rid of warnings */ - return __fake_pread_write(fd, (void*)buf, count, offset, 1); -} -weak_alias(__libc_pwrite,pwrite) - -# ifdef __UCLIBC_HAS_LFS__ -ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset) -{ - return __fake_pread_write64(fd, (void*)buf, count, offset, 1); -} -weak_alias(__libc_pwrite64,pwrite64) -# endif /* __UCLIBC_HAS_LFS__ */ -#endif /* ! __NR_pwrite */ diff --git a/libc/sysdeps/linux/xtensa/setjmp.S b/libc/sysdeps/linux/xtensa/setjmp.S index 5e81460c7..862bf6729 100644 --- a/libc/sysdeps/linux/xtensa/setjmp.S +++ b/libc/sysdeps/linux/xtensa/setjmp.S @@ -13,9 +13,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ /* This implementation relies heavily on the Xtensa register window mechanism. Setjmp flushes all the windows except its own to the @@ -25,24 +24,52 @@ then sets things up so that it will return to the right place, using a window underflow to automatically restore the registers. - Note that it would probably be sufficient to only copy the - registers from setjmp's caller into jmp_buf. However, we also copy - the save area located at the stack pointer of setjmp's caller. - This save area will typically remain intact until the longjmp call. - The one exception is when there is an intervening alloca in - setjmp's caller. This is certainly an unusual situation and is - likely to cause problems in any case (the storage allocated on the - stack cannot be safely accessed following the longjmp). As bad as - it is, on most systems this situation would not necessarily lead to - a catastrophic failure. If we did not preserve the extra save area - on Xtensa, however, it would. When setjmp's caller returns after a - longjmp, there will be a window underflow; an invalid return - address or stack pointer in the save area will almost certainly - lead to a crash. Keeping a copy of the extra save area in the - jmp_buf avoids this with only a small additional cost. If setjmp - and longjmp are ever time-critical, this could be removed. */ + Note that we also save the area located just below the stack pointer + of the caller. This save area could get overwritten by alloca + following the call to setjmp. The alloca moves the stack pointer + to allocate memory on the stack. This newly allocated memory + includes(!) the original save area (alloca copies the save area + before it moves that stack pointer). + + + previous caller SP -> |------------------------------| <-----+ + | caller-2 registers a0-a3 | | p + |------------------------------| | o + | caller registers a4-a8/a12 | | i + |------------------------------| | n + | caller local stack | | t + caller SP -> |------------------------------| <-+ | s + | caller-1 registers a0-a3 | -:---+ + callee (setjmp) SP -> |==============================| | + | caller registers a0-a3 | --+ + |------------------------------| + + In case of an alloca, registers a0-a3 of the previous caller (caller-1) + are copied (*), and the original location get likely overwritten. + + previous caller SP -> |------------------------------| <-----+ + | caller-2 registers a0-a3 | | p + |------------------------------| | o + | caller registers a4-a8/a12 | | i + |------------------------------| | n + | caller local stack | | t + caller SP before alloca-> |------------------------------| | s + | alloca area (overwrites old | | + | copy of caller-1 registers) | | + caller SP after alloca -> |------------------------------| <-+ | + | caller-1 registers a0-a3 (*) | -:---+ + callee (setjmp) SP -> |==============================| | + | caller registers a0-a3 | --+ + |------------------------------| + + So, when longcall returns to the original caller SP, it also needs + to restore the save area below the SP. + + */ #include "sysdep.h" + +/* NOTE: The ENTRY macro must allocate exactly 16 bytes (entry a1, 16) */ /* int setjmp (a2 = jmp_buf env) */ @@ -57,74 +84,85 @@ ENTRY (setjmp) j 1f END (setjmp) -/* int __sigsetjmp (a2 = jmp_buf env, - a3 = int savemask) */ +/* int __sigsetjmp (a2 = jmp_buf env, a3 = int savemask) */ ENTRY (__sigsetjmp) -1: +1: +#if defined(__XTENSA_WINDOWED_ABI__) /* Flush registers. */ movi a4, __window_spill callx4 a4 - /* Preserve the second argument (savemask) in a15. The selection - of a15 is arbitrary, except it's otherwise unused. There is no - risk of triggering a window overflow since we just returned - from __window_spill(). */ - mov a15, a3 - - /* Copy the register save area at (sp - 16). */ - addi a5, a1, -16 - l32i a3, a5, 0 - l32i a4, a5, 4 - s32i a3, a2, 0 - s32i a4, a2, 4 - l32i a3, a5, 8 - l32i a4, a5, 12 - s32i a3, a2, 8 - s32i a4, a2, 12 - - /* Copy 0-8 words from the register overflow area. */ - extui a3, a0, 30, 2 - blti a3, 2, .Lendsj - l32i a7, a1, 4 - slli a4, a3, 4 - sub a5, a7, a4 - addi a6, a2, 16 - addi a7, a7, -16 // a7 = end of register overflow area + /* Copy the caller register a0-a3 at (sp - 16) to jmpbuf. */ + addi a7, a1, -16 + l32i a4, a7, 0 + l32i a5, a7, 4 + s32i a4, a2, 0 + s32i a5, a2, 4 + l32i a4, a7, 8 + l32i a5, a7, 12 + s32i a4, a2, 8 + s32i a5, a2, 12 + + /* Copy the caller registers a4-a8/a12 from the overflow area. */ + /* Note that entry moved the SP by 16B, so SP of caller-1 is at 4(sp) */ + extui a7, a0, 30, 2 + blti a7, 2, .Lendsj + l32i a8, a1, 4 /* a8: SP of 'caller-1' */ + slli a4, a7, 4 + sub a6, a8, a4 + addi a5, a2, 16 + addi a8, a8, -16 /* a8: end of register overflow area */ .Lsjloop: - l32i a3, a5, 0 - l32i a4, a5, 4 - s32i a3, a6, 0 - s32i a4, a6, 4 - l32i a3, a5, 8 - l32i a4, a5, 12 - s32i a3, a6, 8 - s32i a4, a6, 12 - addi a5, a5, 16 + l32i a7, a6, 0 + l32i a4, a6, 4 + s32i a7, a5, 0 + s32i a4, a5, 4 + l32i a7, a6, 8 + l32i a4, a6, 12 + s32i a7, a5, 8 + s32i a4, a5, 12 + addi a5, a6, 16 addi a6, a6, 16 - blt a5, a7, .Lsjloop + blt a6, a8, .Lsjloop .Lendsj: - /* Copy the register save area at sp. */ - l32i a3, a1, 0 - l32i a4, a1, 4 - s32i a3, a2, 48 - s32i a4, a2, 52 - l32i a3, a1, 8 - l32i a4, a1, 12 - s32i a3, a2, 56 - s32i a4, a2, 60 + /* Copy previous caller registers (this is assuming 'entry a1,16') */ + l32i a4, a1, 0 + l32i a5, a1, 4 + s32i a4, a2, 48 + s32i a5, a2, 52 + l32i a4, a1, 8 + l32i a5, a1, 12 + s32i a4, a2, 56 + s32i a5, a2, 60 /* Save the return address, including the window size bits. */ s32i a0, a2, 64 - /* a2 still addresses jmp_buf. a15 contains savemask. */ + /* a2 still points to jmp_buf. a3 contains savemask. */ mov a6, a2 - mov a7, a15 + mov a7, a3 movi a3, __sigjmp_save callx4 a3 mov a2, a6 retw +#elif defined(__XTENSA_CALL0_ABI__) + s32i a0, a2, 0 + s32i a1, a2, 4 + s32i a12, a2, 8 + s32i a13, a2, 12 + s32i a14, a2, 16 + s32i a15, a2, 20 + mov a12, a2 + movi a0, __sigjmp_save + callx0 a0 + l32i a0, a12, 0 + l32i a12, a12, 8 + ret +#else +#error Unsupported Xtensa ABI +#endif END(__sigsetjmp) weak_extern(_setjmp) diff --git a/libc/sysdeps/linux/xtensa/sigaction.c b/libc/sysdeps/linux/xtensa/sigaction.c index 790a8f21f..2a20c6859 100644 --- a/libc/sysdeps/linux/xtensa/sigaction.c +++ b/libc/sysdeps/linux/xtensa/sigaction.c @@ -15,45 +15,30 @@ #define SA_RESTORER 0x04000000 -extern void __default_sa_restorer (void); +extern void __default_sa_restorer(void); -/* Experimentally off - libc_hidden_proto(memcpy) */ - -int __libc_sigaction (int signum, const struct sigaction *act, - struct sigaction *oldact) +int __libc_sigaction(int sig, const struct sigaction *act, + struct sigaction *oact) { - struct kernel_sigaction kact, koldact; - int result; - - if (act) { - kact.k_sa_handler = act->sa_handler; - memcpy(&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask)); - kact.sa_flags = act->sa_flags; - - if (kact.sa_flags & SA_RESTORER) { - kact.sa_restorer = act->sa_restorer; - } else { - kact.sa_restorer = __default_sa_restorer; - kact.sa_flags |= SA_RESTORER; - } - } - - result = __syscall_rt_sigaction(signum, act ? __ptrvalue (&kact) : NULL, - oldact ? __ptrvalue (&koldact) : NULL, - _NSIG / 8); + struct sigaction kact; - if (oldact && result >= 0) { - oldact->sa_handler = koldact.k_sa_handler; - memcpy(&oldact->sa_mask, &koldact.sa_mask, sizeof(oldact->sa_mask)); - oldact->sa_flags = koldact.sa_flags; - oldact->sa_restorer = koldact.sa_restorer; + if (act && !(act->sa_flags & SA_RESTORER)) { + memcpy(&kact, act, sizeof(kact)); + kact.sa_restorer = __default_sa_restorer; + kact.sa_flags |= SA_RESTORER; + act = &kact; } - - return result; + /* NB: kernel (as of 2.6.25) will return EINVAL + * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */ + return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask)); } #ifndef LIBC_SIGACTION -libc_hidden_proto (sigaction) -weak_alias (__libc_sigaction, sigaction) -libc_hidden_weak (sigaction) +# ifndef __UCLIBC_HAS_THREADS__ +strong_alias(__libc_sigaction,sigaction) +libc_hidden_def(sigaction) +# else +weak_alias(__libc_sigaction,sigaction) +libc_hidden_weak(sigaction) +# endif #endif diff --git a/libc/sysdeps/linux/xtensa/sigrestorer.S b/libc/sysdeps/linux/xtensa/sigrestorer.S index 474a89319..697f54e1d 100644 --- a/libc/sysdeps/linux/xtensa/sigrestorer.S +++ b/libc/sysdeps/linux/xtensa/sigrestorer.S @@ -11,6 +11,12 @@ #endif .text + /* This space separates __default_sa_restorer from the previous + * function, so that its corresponding FDE is not mistakenly found + * by the libgcc stack unwinder. This is important for correct signal + * stack unwinding. + */ + .space 1 .align 4 .global __default_sa_restorer .type __default_sa_restorer, @function diff --git a/libc/sysdeps/linux/xtensa/sys/procfs.h b/libc/sysdeps/linux/xtensa/sys/procfs.h index f6f8752bc..484460449 100644 --- a/libc/sysdeps/linux/xtensa/sys/procfs.h +++ b/libc/sysdeps/linux/xtensa/sys/procfs.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _SYS_PROCFS_H #define _SYS_PROCFS_H 1 diff --git a/libc/sysdeps/linux/xtensa/sys/ptrace.h b/libc/sysdeps/linux/xtensa/sys/ptrace.h deleted file mode 100644 index 7aad929bb..000000000 --- a/libc/sysdeps/linux/xtensa/sys/ptrace.h +++ /dev/null @@ -1,156 +0,0 @@ -/* `ptrace' debugger support interface. Linux version. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 - 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ - -#ifndef _SYS_PTRACE_H -#define _SYS_PTRACE_H 1 - -#include <features.h> - -/* Kludge away careless namespace pollution from the kernel. */ - -#undef PTRACE_GETREGS -#undef PTRACE_SETREGS -#undef PTRACE_GETFPREGS -#undef PTRACE_SETFPREGS -#undef PTRACE_GETFPREGSIZE - - -__BEGIN_DECLS - -/* Type of the REQUEST argument to `ptrace.' */ -enum __ptrace_request -{ - /* Indicate that the process making this request should be traced. - All signals received by this process can be intercepted by its - parent, and its parent can use the other `ptrace' requests. */ - PTRACE_TRACEME = 0, -#define PT_TRACE_ME PTRACE_TRACEME - - /* Return the word in the process's text space at address ADDR. */ - PTRACE_PEEKTEXT = 1, -#define PT_READ_I PTRACE_PEEKTEXT - - /* Return the word in the process's data space at address ADDR. */ - PTRACE_PEEKDATA = 2, -#define PT_READ_D PTRACE_PEEKDATA - - /* Return the word in the process's user area at offset ADDR. */ - PTRACE_PEEKUSER = 3, -#define PT_READ_U PTRACE_PEEKUSER - - /* Write the word DATA into the process's text space at address ADDR. */ - PTRACE_POKETEXT = 4, -#define PT_WRITE_I PTRACE_POKETEXT - - /* Write the word DATA into the process's data space at address ADDR. */ - PTRACE_POKEDATA = 5, -#define PT_WRITE_D PTRACE_POKEDATA - - /* Write the word DATA into the process's user area at offset ADDR. */ - PTRACE_POKEUSER = 6, -#define PT_WRITE_U PTRACE_POKEUSER - - /* Continue the process. */ - PTRACE_CONT = 7, -#define PT_CONTINUE PTRACE_CONT - - /* Kill the process. */ - PTRACE_KILL = 8, -#define PT_KILL PTRACE_KILL - - /* Single step the process. - This is not supported on all machines. */ - PTRACE_SINGLESTEP = 9, -#define PT_STEP PTRACE_SINGLESTEP - - /* Get all general purpose registers used by a processes. - This is not supported on all machines. */ - PTRACE_GETREGS = 12, -#define PT_GETREGS PTRACE_GETREGS - - /* Set all general purpose registers used by a processes. - This is not supported on all machines. */ - PTRACE_SETREGS = 13, -#define PT_SETREGS PTRACE_SETREGS - - /* Get all floating point registers used by a processes. - This is not supported on all machines. */ - PTRACE_GETFPREGS = 14, -#define PT_GETFPREGS PTRACE_GETFPREGS - - /* Set all floating point registers used by a processes. - This is not supported on all machines. */ - PTRACE_SETFPREGS = 15, -#define PT_SETFPREGS PTRACE_SETFPREGS - - /* Attach to a process that is already running. */ - PTRACE_ATTACH = 16, -#define PT_ATTACH PTRACE_ATTACH - - /* Detach from a process attached to with PTRACE_ATTACH. */ - PTRACE_DETACH = 17, -#define PT_DETACH PTRACE_DETACH - - /* Get size required for the buffer holding the floating point registers. - This is not supported on all machines. */ - PTRACE_GETFPREGSIZE = 18, -#define PT_GETFPREGSIZE PTRACE_GETFPREGSIZE - - /* Continue and stop at the next (return from) syscall. */ - PTRACE_SYSCALL = 24 -#define PT_SYSCALL PTRACE_SYSCALL -}; - -/* Options set using PTRACE_SETOPTIONS. */ -enum __ptrace_setoptions { - PTRACE_O_TRACESYSGOOD = 0x00000001, - PTRACE_O_TRACEFORK = 0x00000002, - PTRACE_O_TRACEVFORK = 0x00000004, - PTRACE_O_TRACECLONE = 0x00000008, - PTRACE_O_TRACEEXEC = 0x00000010, - PTRACE_O_TRACEVFORKDONE = 0x00000020, - PTRACE_O_TRACEEXIT = 0x00000040, - PTRACE_O_MASK = 0x0000007f -}; - -/* Wait extended result codes for the above trace options. */ -enum __ptrace_eventcodes { - PTRACE_EVENT_FORK = 1, - PTRACE_EVENT_VFORK = 2, - PTRACE_EVENT_CLONE = 3, - PTRACE_EVENT_EXEC = 4, - PTRACE_EVENT_VFORK_DONE = 5, - PTRACE_EVENT_EXIT = 6 -}; - -/* Perform process tracing functions. REQUEST is one of the values - above, and determines the action to be taken. - For all requests except PTRACE_TRACEME, PID specifies the process to be - traced. - - PID and the other arguments described above for the various requests should - appear (those that are used for the particular request) as: - pid_t PID, void *ADDR, int DATA, void *ADDR2 - after REQUEST. */ -extern long int ptrace (enum __ptrace_request __request, ...) __THROW; - -__END_DECLS - -#endif /* _SYS_PTRACE_H */ diff --git a/libc/sysdeps/linux/xtensa/sys/ucontext.h b/libc/sysdeps/linux/xtensa/sys/ucontext.h index 4c37201ea..da75d988f 100644 --- a/libc/sysdeps/linux/xtensa/sys/ucontext.h +++ b/libc/sysdeps/linux/xtensa/sys/ucontext.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _SYS_UCONTEXT_H #define _SYS_UCONTEXT_H 1 diff --git a/libc/sysdeps/linux/xtensa/sys/user.h b/libc/sysdeps/linux/xtensa/sys/user.h new file mode 100644 index 000000000..f97f93edb --- /dev/null +++ b/libc/sysdeps/linux/xtensa/sys/user.h @@ -0,0 +1,20 @@ +/* + * include/asm-xtensa/user.h + * + * Xtensa Processor version. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001 - 2005 Tensilica Inc. + */ + +#ifndef _XTENSA_USER_H +#define _XTENSA_USER_H + +/* This file usually defines a 'struct user' structure. However, it it only + * used for a.out file, which are not supported on Xtensa. + */ + +#endif /* _XTENSA_USER_H */ diff --git a/libc/sysdeps/linux/xtensa/syscall.S b/libc/sysdeps/linux/xtensa/syscall.S index 955e889cf..790a8d018 100644 --- a/libc/sysdeps/linux/xtensa/syscall.S +++ b/libc/sysdeps/linux/xtensa/syscall.S @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "sysdep.h" @@ -27,7 +26,7 @@ */ ENTRY (syscall) - l32i a9, a1, 16 /* load extra argument from stack */ + l32i a9, a1, FRAMESIZE/* load extra argument from stack */ mov a8, a7 mov a7, a3 /* preserve a3 in a7 */ mov a3, a4 @@ -38,5 +37,5 @@ ENTRY (syscall) movi a4, -4095 bgeu a2, a4, SYSCALL_ERROR_LABEL .Lpseudo_end: - retw + abi_ret PSEUDO_END (syscall) diff --git a/libc/sysdeps/linux/xtensa/sysdep.h b/libc/sysdeps/linux/xtensa/sysdep.h index 5708a8114..f5a40eb3a 100644 --- a/libc/sysdeps/linux/xtensa/sysdep.h +++ b/libc/sysdeps/linux/xtensa/sysdep.h @@ -13,9 +13,14 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _LINUX_XTENSA_SYSDEP_H +#define _LINUX_XTENSA_SYSDEP_H 1 + +#include <common/sysdep.h> +#include <sys/syscall.h> #ifdef __ASSEMBLER__ @@ -23,29 +28,53 @@ #define ASM_TYPE_DIRECTIVE(name, typearg) .type name, typearg #define ASM_SIZE_DIRECTIVE(name) .size name, . - name -#ifdef __STDC__ -#define C_LABEL(name) name : +#if defined(__XTENSA_WINDOWED_ABI__) +#define abi_entry(reg, frame_size) entry reg, frame_size +#define abi_ret retw +#elif defined(__XTENSA_CALL0_ABI__) +#define abi_entry(reg, frame_size) +#define abi_ret ret #else -#define C_LABEL(name) name/**/: +#error Unsupported Xtensa ABI #endif + #define ENTRY(name) \ - ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ + .globl C_SYMBOL_NAME(name); \ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), @function); \ .align ALIGNARG(2); \ LITERAL_POSITION; \ C_LABEL(name) \ - entry sp, FRAMESIZE; \ + abi_entry(sp, FRAMESIZE); \ + CALL_MCOUNT + +#define HIDDEN_ENTRY(name) \ + .globl C_SYMBOL_NAME(name); \ + .hidden C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), @function); \ + .align ALIGNARG(2); \ + LITERAL_POSITION; \ + C_LABEL(name) \ + abi_entry(sp, FRAMESIZE); \ CALL_MCOUNT #undef END #define END(name) ASM_SIZE_DIRECTIVE(name) +/* Local label name for asm code. */ +#ifndef L +# ifdef HAVE_ELF +# define L(name) .L##name +# else +# define L(name) name +# endif +#endif + /* Define a macro for this directive so it can be removed in a few places. */ #define LITERAL_POSITION .literal_position #undef JUMPTARGET -#ifdef PIC +#ifdef __PIC__ /* The "@PLT" suffix is currently a no-op for non-shared linking, but it doesn't hurt to use it conditionally for PIC code in case that changes someday. */ @@ -54,7 +83,15 @@ #define JUMPTARGET(name) name #endif +#ifndef FRAMESIZE +#if defined(__XTENSA_WINDOWED_ABI__) #define FRAMESIZE 16 +#elif defined(__XTENSA_CALL0_ABI__) +#define FRAMESIZE 0 +#else +#error Unsupported Xtensa ABI +#endif +#endif #define CALL_MCOUNT /* Do nothing. */ @@ -98,7 +135,7 @@ END (name) #undef ret_NOERRNO -#define ret_NOERRNO retw +#define ret_NOERRNO abi_ret /* The function has to return the error code. */ #undef PSEUDO_ERRVAL @@ -112,19 +149,11 @@ #define PSEUDO_END_ERRVAL(name) \ END (name) -#define ret_ERRVAL retw - -#if RTLD_PRIVATE_ERRNO -# define SYSCALL_ERROR_HANDLER \ -0: movi a4, rtld_errno; \ - neg a2, a2; \ - s32i a2, a4, 0; \ - movi a2, -1; \ - j .Lpseudo_end; +#undef ret_ERRVAL +#define ret_ERRVAL abi_ret -#elif defined _LIBC_REENTRANT - -# if USE___THREAD +#if defined _LIBC_REENTRANT +# if defined USE___THREAD # ifndef NOT_IN_libc # define SYSCALL_ERROR_ERRNO __libc_errno # else @@ -139,6 +168,8 @@ movi a2, -1; \ j .Lpseudo_end; # else /* !USE___THREAD */ + +#if defined(__XTENSA_WINDOWED_ABI__) # define SYSCALL_ERROR_HANDLER \ 0: neg a2, a2; \ mov a6, a2; \ @@ -147,6 +178,24 @@ s32i a2, a6, 0; \ movi a2, -1; \ j .Lpseudo_end; +#elif defined(__XTENSA_CALL0_ABI__) +# define SYSCALL_ERROR_HANDLER \ +0: neg a2, a2; \ + addi a1, a1, -16; \ + s32i a0, a1, 0; \ + s32i a2, a1, 4; \ + movi a0, __errno_location@PLT; \ + callx0 a0; \ + l32i a0, a1, 0; \ + l32i a3, a1, 4; \ + addi a1, a1, 16; \ + s32i a3, a2, 0; \ + movi a2, -1; \ + j .Lpseudo_end; +#else +#error Unsupported Xtensa ABI +#endif + # endif /* !USE___THREAD */ #else /* !_LIBC_REENTRANT */ #define SYSCALL_ERROR_HANDLER \ @@ -158,3 +207,9 @@ #endif /* _LIBC_REENTRANT */ #endif /* __ASSEMBLER__ */ + +/* Pointer mangling is not yet supported for Xtensa. */ +#define PTR_MANGLE(var) (void) (var) +#define PTR_DEMANGLE(var) (void) (var) + +#endif /* _LINUX_XTENSA_SYSDEP_H */ diff --git a/libc/sysdeps/linux/xtensa/vfork.S b/libc/sysdeps/linux/xtensa/vfork.S index 830a0cd4d..8058fb057 100644 --- a/libc/sysdeps/linux/xtensa/vfork.S +++ b/libc/sysdeps/linux/xtensa/vfork.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2005, 2007 Free Software Foundation, Inc. +/* Copyright (C) 2005-2013 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 @@ -12,80 +12,78 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "sysdep.h" #include <sys/syscall.h> #define _SIGNAL_H #include <bits/signum.h> +#define __ASSEMBLY__ +#include <linux/sched.h> -/* Clone the calling process, but without copying the whole address space. +/* + Clone the calling process, but without copying the whole address space. The calling process is suspended until the new process exits or is replaced by a call to `execve'. Return -1 for errors, 0 to the new process, and the process ID of the new process to the old process. Note that it is important that we don't create a new stack frame for the - caller. */ + caller. - -/* The following are defined in linux/sched.h, which unfortunately - is not safe for inclusion in an assembly file. */ -#define CLONE_VM 0x00000100 /* set if VM shared between processes */ -#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to - wake it up on mm_release */ +*/ #ifndef SAVE_PID -#define SAVE_PID +#define SAVE_PID(a,b,c,d) #endif - #ifndef RESTORE_PID -#define RESTORE_PID +#define RESTORE_PID(a,b,c) +#endif +#ifndef RESTORE_PID12 +#define RESTORE_PID12(a,b,c) #endif +/* + pid_t vfork(void); + Implemented as __clone_syscall(CLONE_VFORK | CLONE_VM | SIGCHLD, 0) + */ -/* pid_t vfork(void); - Implemented as __clone_syscall(CLONE_VFORK | CLONE_VM | SIGCHLD, 0) */ -ENTRY (__vfork) +HIDDEN_ENTRY (__vfork) - movi a6, .Ljumptable - extui a2, a0, 30, 2 // call-size: call4/8/12 = 1/2/3 - addx4 a4, a2, a6 // find return address in jumptable - l32i a4, a4, 0 - add a4, a4, a6 +#if defined(__XTENSA_WINDOWED_ABI__) + .literal .Ljumptable, 0, .L4, .L8, .L12 + mov a3, a0 # move return address out of the way + movi a0, .Ljumptable + extui a2, a3, 30, 2 # call-size: call4/8/12 = 1/2/3 + addx4 a0, a2, a0 # find return address in jumptable + l32i a0, a0, 0 + # exchange top 2 bits of a0 and a3: + xor a2, a0, a3 + extui a2, a2, 30, 2 slli a2, a2, 30 - xor a3, a0, a2 // remove call-size from return address - extui a5, a4, 30, 2 // get high bits of jump target - slli a5, a5, 30 - or a3, a3, a5 // stuff them into the return address - xor a4, a4, a5 // clear high bits of jump target - or a0, a4, a2 // create temporary return address - retw // "return" to .L4, .L8, or .L12 - - .align 4 -.Ljumptable: - .word 0 - .word .L4 - .Ljumptable - .word .L8 - .Ljumptable - .word .L12 - .Ljumptable + xor a0, a0, a2 + xor a3, a3, a2 + retw /* a7: return address */ + .L4: mov a12, a2 mov a13, a3 - SAVE_PID + SAVE_PID(a5,a15,a2,a3) - /* Use syscall 'clone'. Set new stack pointer to the same address. */ - movi a2, SYS_ify (clone) - movi a3, 0 + /* use syscall 'clone' and set new stack pointer to the same address */ + + movi a2, SYS_ify(clone) + movi a3, 0 movi a6, CLONE_VM | CLONE_VFORK | SIGCHLD + syscall - RESTORE_PID + RESTORE_PID(a5,a15,a2) movi a5, -4096 @@ -95,22 +93,24 @@ ENTRY (__vfork) bgeu a6, a5, 1f jx a7 -1: call4 .Lerr // returns to original caller +1: call4 .Lerr /* a11: return address */ + .L8: mov a12, a2 mov a13, a3 mov a14, a6 - SAVE_PID + SAVE_PID(a9,a15,a2,a3) - movi a2, SYS_ify (clone) + movi a2, SYS_ify(clone) movi a3, 0 movi a6, CLONE_VM | CLONE_VFORK | SIGCHLD + syscall - RESTORE_PID + RESTORE_PID(a9,a15,a2) movi a9, -4096 @@ -121,22 +121,25 @@ ENTRY (__vfork) bgeu a10, a9, 1f jx a11 -1: call8 .Lerr // returns to original caller + +1: call8 .Lerr /* a15: return address */ + .L12: mov a12, a2 mov a13, a3 mov a14, a6 - SAVE_PID + SAVE_PID (a2,a3,a2,a6) - movi a2, SYS_ify (clone) + movi a2, SYS_ify(clone) movi a3, 0 movi a6, CLONE_VM | CLONE_VFORK | SIGCHLD + syscall - RESTORE_PID + RESTORE_PID12(a3,a6,a15) mov a3, a13 movi a13, -4096 @@ -148,23 +151,43 @@ ENTRY (__vfork) bgeu a14, a13, 1f jx a15 -1: call12 .Lerr // returns to original caller +1: call12 .Lerr .align 4 + .Lerr: entry a1, 16 - /* Restore the return address. */ - extui a4, a0, 30, 2 // get the call-size bits + /* Restore return address */ + + extui a4, a0, 30, 2 slli a4, a4, 30 - slli a3, a3, 2 // clear high bits of target address - srli a3, a3, 2 - or a0, a3, a4 // combine them + or a0, a3, a4 PSEUDO_END (__vfork) .Lpseudo_end: retw +#elif defined(__XTENSA_CALL0_ABI__) + SAVE_PID(a5, a8, a3, a4) + + /* Use syscall 'clone'. Set new stack pointer to the same address. */ + movi a2, SYS_ify (clone) + movi a3, 0 + movi a6, CLONE_VM | CLONE_VFORK | SIGCHLD + syscall + + RESTORE_PID(a5, a8, a2) -libc_hidden_def (__vfork) + movi a3, -4096 + bgeu a2, a3, 1f + ret +1: + PSEUDO_END (__vfork) +.Lpseudo_end: + ret +#else +#error Unsupported Xtensa ABI +#endif weak_alias (__vfork, vfork) +libc_hidden_def(vfork) diff --git a/libc/sysdeps/linux/xtensa/windowspill.S b/libc/sysdeps/linux/xtensa/windowspill.S index a63771756..013025648 100644 --- a/libc/sysdeps/linux/xtensa/windowspill.S +++ b/libc/sysdeps/linux/xtensa/windowspill.S @@ -13,12 +13,12 @@ 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, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include <bits/xtensa-config.h> +#ifdef __XTENSA_WINDOWED_ABI__ .text .align 4 .literal_position @@ -26,8 +26,8 @@ .type __window_spill, @function __window_spill: entry a1, 48 - bbci.l a0, 31, .L4 // branch if called with call4 - bbsi.l a0, 30, .L12 // branch if called with call12 + bbci.l a0, 31, .L4 /* branch if called with call4 */ + bbsi.l a0, 30, .L12 /* branch if called with call12 */ /* Called with call8: touch register NUM_REGS-12 (4/20/52) */ .L8: @@ -36,18 +36,18 @@ __window_spill: retw .align 4 -1: _entry a1, 48 // touch NUM_REGS-24 (x/8/40) +1: _entry a1, 48 /* touch NUM_REGS-24 (x/8/40) */ #if XCHAL_NUM_AREGS == 32 mov a8, a0 retw #else mov a12, a0 - _entry a1, 48 // touch NUM_REGS-36 (x/x/28) + _entry a1, 48 /* touch NUM_REGS-36 (x/x/28) */ mov a12, a0 - _entry a1, 48 // touch NUM_REGS-48 (x/x/16) + _entry a1, 48 /* touch NUM_REGS-48 (x/x/16) */ mov a12, a0 - _entry a1, 16 // touch NUM_REGS-60 (x/x/4) + _entry a1, 16 /* touch NUM_REGS-60 (x/x/4) */ #endif #endif mov a4, a0 @@ -62,14 +62,14 @@ __window_spill: retw .align 4 -1: _entry a1, 48 // touch NUM_REGS-20 (x/12/44) +1: _entry a1, 48 /* touch NUM_REGS-20 (x/12/44) */ mov a12, a0 #if XCHAL_NUM_AREGS > 32 - _entry a1, 48 // touch NUM_REGS-32 (x/x/32) + _entry a1, 48 /* touch NUM_REGS-32 (x/x/32) */ mov a12, a0 - _entry a1, 48 // touch NUM_REGS-44 (x/x/20) + _entry a1, 48 /* touch NUM_REGS-44 (x/x/20) */ mov a12, a0 - _entry a1, 48 // touch NUM_REGS-56 (x/x/8) + _entry a1, 48 /* touch NUM_REGS-56 (x/x/8) */ mov a8, a0 #endif #endif @@ -82,15 +82,17 @@ __window_spill: retw .align 4 -1: _entry a1, 48 // touch NUM_REGS-28 (x/4/36) +1: _entry a1, 48 /* touch NUM_REGS-28 (x/4/36) */ #if XCHAL_NUM_AREGS == 32 mov a4, a0 #else mov a12, a0 - _entry a1, 48 // touch NUM_REGS-40 (x/x/24) + _entry a1, 48 /* touch NUM_REGS-40 (x/x/24) */ mov a12, a0 - _entry a1, 48 // touch NUM_REGS-52 (x/x/12) + _entry a1, 48 /* touch NUM_REGS-52 (x/x/12) */ mov a12, a0 #endif #endif retw + +#endif |
