summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/xtensa/bits
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/xtensa/bits')
-rw-r--r--libc/sysdeps/linux/xtensa/bits/atomic.h177
-rw-r--r--libc/sysdeps/linux/xtensa/bits/fcntl.h7
-rw-r--r--libc/sysdeps/linux/xtensa/bits/ipc.h4
-rw-r--r--libc/sysdeps/linux/xtensa/bits/kernel_stat.h6
-rw-r--r--libc/sysdeps/linux/xtensa/bits/msq.h16
-rw-r--r--libc/sysdeps/linux/xtensa/bits/shm.h24
-rw-r--r--libc/sysdeps/linux/xtensa/bits/stat.h8
-rw-r--r--libc/sysdeps/linux/xtensa/bits/xtensa-config.h6
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 */