diff options
Diffstat (limited to 'libc/sysdeps/linux/xtensa/bits')
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/atomic.h | 177 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/fcntl.h | 7 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/ipc.h | 4 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/kernel_stat.h | 6 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/msq.h | 16 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/shm.h | 24 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/stat.h | 8 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/xtensa-config.h | 6 |
8 files changed, 192 insertions, 56 deletions
diff --git a/libc/sysdeps/linux/xtensa/bits/atomic.h b/libc/sysdeps/linux/xtensa/bits/atomic.h index b2be547f0..18b809998 100644 --- a/libc/sysdeps/linux/xtensa/bits/atomic.h +++ b/libc/sysdeps/linux/xtensa/bits/atomic.h @@ -18,6 +18,7 @@ #ifndef _BITS_ATOMIC_H #define _BITS_ATOMIC_H 1 +#include <bits/xtensa-config.h> #include <inttypes.h> typedef int32_t atomic32_t; @@ -50,22 +51,144 @@ typedef uintmax_t uatomic_max_t; #define __arch_compare_and_exchange_bool_16_rel(mem, newval, oldval) \ (abort (), 0) +#if XCHAL_HAVE_EXCLUSIVE + +/* 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__( \ + " memw \n" \ + "1: l32ex %0, %2 \n" \ + " bne %0, %4, 2f \n" \ + " mov %1, %3 \n" \ + " s32ex %1, %2 \n" \ + " getex %1 \n" \ + " beqz %1, 1b \n" \ + " memw \n" \ + "2: \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (newval), "a" (oldval) \ + : "memory" ); \ + __value; \ + }) + +/* 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__( \ + " memw \n" \ + "1: l32ex %0, %2 \n" \ + " sub %0, %4, %0 \n" \ + " bnez %0, 2f \n" \ + " mov %1, %3 \n" \ + " s32ex %1, %2 \n" \ + " getex %1 \n" \ + " beqz %1, 1b \n" \ + " movi %0, 0 \n" \ + " memw \n" \ + "2: \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (newval), "a" (oldval) \ + : "memory" ); \ + __value != 0; \ + }) + +/* Store NEWVALUE in *MEM and return the old value. */ + +#define __arch_exchange_32_acq(mem, newval) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + " memw \n" \ + "1: l32ex %0, %2 \n" \ + " mov %1, %3 \n" \ + " s32ex %1, %2 \n" \ + " getex %1 \n" \ + " beqz %1, 1b \n" \ + " memw \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (newval) \ + : "memory" ); \ + __value; \ + }) + +/* 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__( \ + " memw \n" \ + "1: l32ex %0, %2 \n" \ + " add %1, %0, %3 \n" \ + " s32ex %1, %2 \n" \ + " getex %1 \n" \ + " beqz %1, 1b \n" \ + " memw \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (value) \ + : "memory" ); \ + __value; \ + }) + +/* 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__( \ + " memw \n" \ + "1: l32ex %0, %2 \n" \ + " sub %1, %0, %3 \n" \ + " s32ex %1, %2 \n" \ + " getex %1 \n" \ + " beqz %1, 1b \n" \ + " memw \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__( \ + " memw \n" \ + "1: l32ex %0, %2 \n" \ + " blti %0, 1, 2f \n" \ + " addi %1, %0, -1 \n" \ + " s32ex %1, %2 \n" \ + " getex %1 \n" \ + " beqz %1, 1b \n" \ + " memw \n" \ + "2: \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem) \ + : "memory" ); \ + __value; \ + }) + +#elif XCHAL_HAVE_S32C1I + /* 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" \ + "1: l32i %1, %2 \n" \ " bne %1, %4, 2f \n" \ " wsr %1, SCOMPARE1 \n" \ " mov %0, %1 \n" \ " mov %1, %3 \n" \ - " s32c1i %1, %2, 0 \n" \ + " s32c1i %1, %2 \n" \ " bne %0, %1, 1b \n" \ "2: \n" \ - : "=&a" (__value), "=&a" (__tmp) \ - : "a" (mem), "a" (newval), "a" (oldval) \ + : "=&a" (__value), "=&a" (__tmp), "+m" (*(mem)) \ + : "a" (newval), "a" (oldval) \ : "memory" ); \ __tmp; \ }) @@ -76,17 +199,17 @@ typedef uintmax_t uatomic_max_t; #define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \ ({__typeof__(*(mem)) __tmp, __value; \ __asm__ __volatile__( \ - "1: l32i %0, %2, 0 \n" \ + "1: l32i %0, %2 \n" \ " sub %1, %4, %0 \n" \ " bnez %1, 2f \n" \ " wsr %0, SCOMPARE1 \n" \ " mov %1, %3 \n" \ - " s32c1i %1, %2, 0 \n" \ + " s32c1i %1, %2 \n" \ " bne %0, %1, 1b \n" \ " movi %1, 0 \n" \ "2: \n" \ - : "=&a" (__value), "=&a" (__tmp) \ - : "a" (mem), "a" (newval), "a" (oldval) \ + : "=&a" (__value), "=&a" (__tmp), "+m" (*(mem)) \ + : "a" (newval), "a" (oldval) \ : "memory" ); \ __tmp != 0; \ }) @@ -96,13 +219,13 @@ typedef uintmax_t uatomic_max_t; #define __arch_exchange_32_acq(mem, newval) \ ({__typeof__(*(mem)) __tmp, __value; \ __asm__ __volatile__( \ - "1: l32i %0, %2, 0 \n" \ + "1: l32i %0, %2 \n" \ " wsr %0, SCOMPARE1 \n" \ " mov %1, %3 \n" \ - " s32c1i %1, %2, 0 \n" \ + " s32c1i %1, %2 \n" \ " bne %0, %1, 1b \n" \ - : "=&a" (__value), "=&a" (__tmp) \ - : "a" (mem), "a" (newval) \ + : "=&a" (__value), "=&a" (__tmp), "+m" (*(mem)) \ + : "a" (newval) \ : "memory" ); \ __tmp; \ }) @@ -112,13 +235,13 @@ typedef uintmax_t uatomic_max_t; #define __arch_atomic_exchange_and_add_32(mem, value) \ ({__typeof__(*(mem)) __tmp, __value; \ __asm__ __volatile__( \ - "1: l32i %0, %2, 0 \n" \ + "1: l32i %0, %2 \n" \ " wsr %0, SCOMPARE1 \n" \ " add %1, %0, %3 \n" \ - " s32c1i %1, %2, 0 \n" \ + " s32c1i %1, %2 \n" \ " bne %0, %1, 1b \n" \ - : "=&a" (__value), "=&a" (__tmp) \ - : "a" (mem), "a" (value) \ + : "=&a" (__value), "=&a" (__tmp), "+m" (*(mem)) \ + : "a" (value) \ : "memory" ); \ __tmp; \ }) @@ -128,13 +251,13 @@ typedef uintmax_t uatomic_max_t; #define __arch_atomic_exchange_and_sub_32(mem, value) \ ({__typeof__(*(mem)) __tmp, __value; \ __asm__ __volatile__( \ - "1: l32i %0, %2, 0 \n" \ + "1: l32i %0, %2 \n" \ " wsr %0, SCOMPARE1 \n" \ " sub %1, %0, %3 \n" \ - " s32c1i %1, %2, 0 \n" \ + " s32c1i %1, %2 \n" \ " bne %0, %1, 1b \n" \ - : "=&a" (__value), "=&a" (__tmp) \ - : "a" (mem), "a" (value) \ + : "=&a" (__value), "=&a" (__tmp), "+m" (*(mem)) \ + : "a" (value) \ : "memory" ); \ __tmp; \ }) @@ -144,19 +267,23 @@ typedef uintmax_t uatomic_max_t; #define __arch_atomic_decrement_if_positive_32(mem) \ ({__typeof__(*(mem)) __tmp, __value; \ __asm__ __volatile__( \ - "1: l32i %0, %2, 0 \n" \ + "1: l32i %0, %2 \n" \ " blti %0, 1, 2f \n" \ " wsr %0, SCOMPARE1 \n" \ " addi %1, %0, -1 \n" \ - " s32c1i %1, %2, 0 \n" \ + " s32c1i %1, %2 \n" \ " bne %0, %1, 1b \n" \ "2: \n" \ - : "=&a" (__value), "=&a" (__tmp) \ - : "a" (mem) \ - : "memory" ); \ + : "=&a" (__value), "=&a" (__tmp), "+m" (*(mem)) \ + :: "memory" ); \ __value; \ }) +#else + +#error No hardware atomic operations + +#endif /* These are the preferred public interfaces: */ diff --git a/libc/sysdeps/linux/xtensa/bits/fcntl.h b/libc/sysdeps/linux/xtensa/bits/fcntl.h index f8ae40ca7..5af9d2124 100644 --- a/libc/sysdeps/linux/xtensa/bits/fcntl.h +++ b/libc/sysdeps/linux/xtensa/bits/fcntl.h @@ -54,6 +54,7 @@ # define O_DIRECT 040000 /* Direct disk access. */ # define O_NOATIME 01000000 /* Do not set atime. */ # define O_PATH 010000000 /* Resolve pathname but do not open file. */ +# define O_TMPFILE 020200000 /* Atomically create nameless file. */ #endif /* For now Linux has synchronisity options for data and read operations. @@ -101,11 +102,13 @@ # define F_SETLEASE 1024 /* Set a lease. */ # define F_GETLEASE 1025 /* Enquire what lease is active. */ # 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 +#if defined __USE_XOPEN2K8 || defined __USE_GNU +# define F_DUPFD_CLOEXEC 1030 /* Duplicate file descriptor with + close-on-exit set on new fd. */ +#endif /* For F_[GET|SET]FD. */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ diff --git a/libc/sysdeps/linux/xtensa/bits/ipc.h b/libc/sysdeps/linux/xtensa/bits/ipc.h index 2ad5fc0a2..f4222de8c 100644 --- a/libc/sysdeps/linux/xtensa/bits/ipc.h +++ b/libc/sysdeps/linux/xtensa/bits/ipc.h @@ -48,6 +48,6 @@ struct ipc_perm __gid_t cgid; /* Creator's group ID. */ unsigned int mode; /* Read/write permission. */ unsigned int __seq; /* Sequence number. */ - unsigned long int __unused1; - unsigned long int __unused2; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; }; diff --git a/libc/sysdeps/linux/xtensa/bits/kernel_stat.h b/libc/sysdeps/linux/xtensa/bits/kernel_stat.h index 5e4f5c4e5..d884344d3 100644 --- a/libc/sysdeps/linux/xtensa/bits/kernel_stat.h +++ b/libc/sysdeps/linux/xtensa/bits/kernel_stat.h @@ -33,13 +33,13 @@ struct kernel_stat64 { unsigned long long st_rdev; /* Device number, if device. */ long long st_size; /* Size of file, in bytes. */ unsigned long st_blksize; /* Optimal block size for I/O. */ - unsigned long __unused2; + unsigned long __uclibc_unused2; unsigned long long st_blocks; /* Number 512-byte blocks allocated. */ 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; + unsigned long __uclibc_unused4; + unsigned long __uclibc_unused5; }; #endif /* _BITS_STAT_STRUCT_H */ diff --git a/libc/sysdeps/linux/xtensa/bits/msq.h b/libc/sysdeps/linux/xtensa/bits/msq.h index e4f3fa317..0f65b4274 100644 --- a/libc/sysdeps/linux/xtensa/bits/msq.h +++ b/libc/sysdeps/linux/xtensa/bits/msq.h @@ -38,19 +38,19 @@ struct msqid_ds { struct ipc_perm msg_perm; /* structure describing operation permission */ #if defined (__XTENSA_EB__) - unsigned long int __unused1; + unsigned long int __uclibc_unused1; __time_t msg_stime; /* time of last msgsnd command */ - unsigned long int __unused2; + unsigned long int __uclibc_unused2; __time_t msg_rtime; /* time of last msgrcv command */ - unsigned long int __unused3; + unsigned long int __uclibc_unused3; __time_t msg_ctime; /* time of last change */ #elif defined (__XTENSA_EL__) __time_t msg_stime; /* time of last msgsnd command */ - unsigned long int __unused1; + unsigned long int __uclibc_unused1; __time_t msg_rtime; /* time of last msgrcv command */ - unsigned long int __unused2; + unsigned long int __uclibc_unused2; __time_t msg_ctime; /* time of last change */ - unsigned long int __unused3; + unsigned long int __uclibc_unused3; #else # error endian order not defined #endif @@ -59,8 +59,8 @@ struct msqid_ds msglen_t msg_qbytes; /* max number of bytes allowed on queue */ __pid_t msg_lspid; /* pid of last msgsnd() */ __pid_t msg_lrpid; /* pid of last msgrcv() */ - unsigned long int __unused4; - unsigned long int __unused5; + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; }; #ifdef __USE_MISC diff --git a/libc/sysdeps/linux/xtensa/bits/shm.h b/libc/sysdeps/linux/xtensa/bits/shm.h index d288a1cca..d1e13cb49 100644 --- a/libc/sysdeps/linux/xtensa/bits/shm.h +++ b/libc/sysdeps/linux/xtensa/bits/shm.h @@ -52,17 +52,17 @@ struct shmid_ds size_t shm_segsz; /* size of segment in bytes */ #if defined (__XTENSA_EL__) __time_t shm_atime; /* time of last shmat() */ - unsigned long int __unused1; + unsigned long int __uclibc_unused1; __time_t shm_dtime; /* time of last shmdt() */ - unsigned long int __unused2; + unsigned long int __uclibc_unused2; __time_t shm_ctime; /* time of last change by shmctl() */ - unsigned long int __unused3; + unsigned long int __uclibc_unused3; #elif defined (__XTENSA_EB__) - unsigned long int __unused1; + unsigned long int __uclibc_unused1; __time_t shm_atime; /* time of last shmat() */ - unsigned long int __unused2; + unsigned long int __uclibc_unused2; __time_t shm_dtime; /* time of last shmdt() */ - unsigned long int __unused3; + unsigned long int __uclibc_unused3; __time_t shm_ctime; /* time of last change by shmctl() */ #else # error endian order not defined @@ -70,8 +70,8 @@ struct shmid_ds __pid_t shm_cpid; /* pid of creator */ __pid_t shm_lpid; /* pid of last shmop */ shmatt_t shm_nattch; /* number of current attaches */ - unsigned long int __unused4; - unsigned long int __unused5; + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; }; #ifdef __USE_MISC @@ -93,10 +93,10 @@ struct shminfo unsigned long int shmmni; unsigned long int shmseg; unsigned long int shmall; - unsigned long int __unused1; - unsigned long int __unused2; - unsigned long int __unused3; - unsigned long int __unused4; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + unsigned long int __uclibc_unused3; + unsigned long int __uclibc_unused4; }; struct shm_info diff --git a/libc/sysdeps/linux/xtensa/bits/stat.h b/libc/sysdeps/linux/xtensa/bits/stat.h index c61b188b7..045a017fd 100644 --- a/libc/sysdeps/linux/xtensa/bits/stat.h +++ b/libc/sysdeps/linux/xtensa/bits/stat.h @@ -75,8 +75,8 @@ struct stat __time_t st_ctime; /* Time of last status change. */ unsigned long int st_ctimensec; /* Nsecs of last status change. */ #endif - unsigned long int __unused4; - unsigned long int __unused5; + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; }; #ifdef __USE_LARGEFILE64 @@ -112,8 +112,8 @@ struct stat64 __time_t st_ctime; /* Time of last status change. */ unsigned long int st_ctimensec; /* Nsecs of last status change. */ #endif - unsigned long __unused4; - unsigned long __unused5; + unsigned long __uclibc_unused4; + unsigned long __uclibc_unused5; }; #endif diff --git a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h index 2e60af936..b99928b1e 100644 --- a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h +++ b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h @@ -43,4 +43,10 @@ #undef XCHAL_NUM_AREGS #define XCHAL_NUM_AREGS 64 +#undef XCHAL_HAVE_S32C1I +#define XCHAL_HAVE_S32C1I 1 + +#undef XCHAL_HAVE_EXCLUSIVE +#define XCHAL_HAVE_EXCLUSIVE 0 + #endif /* !XTENSA_CONFIG_H */ |