summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/metag/bits
diff options
context:
space:
mode:
authorMarkos Chandras <markos.chandras@imgtec.com>2010-11-18 14:58:01 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2013-03-14 22:47:08 +0100
commitdaecc9a410a6f23d80daf8ce3afd280fea329e63 (patch)
tree8d603dd538809431cc01b9e656c827d1f0709052 /libc/sysdeps/linux/metag/bits
parent20221281b3d67880439cd1d16c151f4528d034fb (diff)
metag: Add NPTL support
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com> Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Diffstat (limited to 'libc/sysdeps/linux/metag/bits')
-rw-r--r--libc/sysdeps/linux/metag/bits/atomic.h66
-rw-r--r--libc/sysdeps/linux/metag/bits/syscalls.h73
2 files changed, 113 insertions, 26 deletions
diff --git a/libc/sysdeps/linux/metag/bits/atomic.h b/libc/sysdeps/linux/metag/bits/atomic.h
new file mode 100644
index 000000000..64aa50bc4
--- /dev/null
+++ b/libc/sysdeps/linux/metag/bits/atomic.h
@@ -0,0 +1,66 @@
+/*
+ * Copyrith (C) 2013 Imagination Technologies Ltd.
+ *
+ * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+ *
+ */
+
+#include <stdint.h>
+#include <sysdep.h>
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+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 intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+void __metag_link_error (void);
+
+#define atomic_full_barrier() \
+ __asm__ __volatile__("": : :"memory")
+
+/* Atomic compare and exchange. This sequence relies on the kernel to
+ provide a compare and exchange operation which is atomic. */
+
+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+ ({ __metag_link_error (); oldval; })
+
+#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+ ({ __metag_link_error (); oldval; })
+
+/* This code uses the kernel helper to do cmpxchg. It relies on the fact
+ the helper code only clobbers D0Re0. */
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ ({ register __typeof (oldval) a_current __asm__ ("D1Ar1"); \
+ register __typeof (oldval) a_newval __asm__ ("D0Ar2") = (newval); \
+ register __typeof (mem) a_ptr __asm__ ("D1Ar3") = (mem); \
+ register __typeof (oldval) a_oldval __asm__ ("D0Ar4") = (oldval); \
+ __asm__ __volatile__ \
+ ("0:\n\t" \
+ "GETD %[cur], [%[ptr]]\n\t" \
+ "CMP %[cur], %[old]\n\t" \
+ "BNE 1f\n\t" \
+ "MOVT D1RtP, #0x6fff\n\t" \
+ "ADD D1RtP, D1RtP, #0xf040\n\t" \
+ "SWAP D1RtP, PC\n\t" \
+ "MOV %[cur], %[old]\n\t" \
+ "CMP D0Re0, #0\n\t" \
+ "BNE 0b\n\t" \
+ "1:" \
+ : [cur] "=&r" (a_current) \
+ : [new] "r" (a_newval), [ptr] "r" (a_ptr), \
+ [old] "r" (a_oldval) \
+ : "D0Re0", "D1RtP", "cc", "memory"); \
+ a_current; })
+
+#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ __metag_link_error (); oldval; })
diff --git a/libc/sysdeps/linux/metag/bits/syscalls.h b/libc/sysdeps/linux/metag/bits/syscalls.h
index b5c8fc58c..7ea09c2c3 100644
--- a/libc/sysdeps/linux/metag/bits/syscalls.h
+++ b/libc/sysdeps/linux/metag/bits/syscalls.h
@@ -49,8 +49,9 @@
(__extension__ \
({unsigned int __sys_result; \
{ \
+ PREP_ARGS_##nr (args); \
register int _result __asm__ ("D0Re0"), _nr __asm__ ("D1Re0"); \
- LOAD_ARGS_##nr (args); \
+ LOAD_ARGS_##nr; \
_nr = (name); \
__asm__ volatile ("SWITCH #0x440001 ! syscall " #name \
: "=r" (_result) \
@@ -68,32 +69,52 @@
#undef INTERNAL_SYSCALL_ERRNO
#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
-#define LOAD_ARGS_0()
+#define PREP_ARGS_0()
+#define PREP_ARGS_1(a1) \
+ int _t1 = (int) (a1); \
+ PREP_ARGS_0 ()
+#define PREP_ARGS_2(a1, a2) \
+ int _t2 = (int) (a2); \
+ PREP_ARGS_1 (a1)
+#define PREP_ARGS_3(a1, a2, a3) \
+ int _t3 = (int) (a3); \
+ PREP_ARGS_2 (a1, a2)
+#define PREP_ARGS_4(a1, a2, a3, a4) \
+ int _t4 = (int) (a4); \
+ PREP_ARGS_3 (a1, a2, a3)
+#define PREP_ARGS_5(a1, a2, a3, a4, a5) \
+ int _t5 = (int) (a5); \
+ PREP_ARGS_4 (a1, a2, a3, a4)
+#define PREP_ARGS_6(a1, a2, a3, a4, a5, a6) \
+ int _t6 = (int) (a6); \
+ PREP_ARGS_5 (a1, a2, a3, a4, a5)
+
+#define LOAD_ARGS_0
#define ASM_ARGS_0
-#define LOAD_ARGS_1(a1) \
- register int _a1 __asm__ ("D1Ar1") = (int) (a1); \
- LOAD_ARGS_0 ()
-#define ASM_ARGS_1 ASM_ARGS_0, "d" (_a1)
-#define LOAD_ARGS_2(a1, a2) \
- register int _a2 __asm__ ("D0Ar2") = (int) (a2); \
- LOAD_ARGS_1 (a1)
-#define ASM_ARGS_2 ASM_ARGS_1, "d" (_a2)
-#define LOAD_ARGS_3(a1, a2, a3) \
- register int _a3 __asm__ ("D1Ar3") = (int) (a3); \
- LOAD_ARGS_2 (a1, a2)
-#define ASM_ARGS_3 ASM_ARGS_2, "d" (_a3)
-#define LOAD_ARGS_4(a1, a2, a3, a4) \
- register int _a4 __asm__ ("D0Ar4") = (int) (a4); \
- LOAD_ARGS_3 (a1, a2, a3)
-#define ASM_ARGS_4 ASM_ARGS_3, "d" (_a4)
-#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
- register int _a5 __asm__ ("D1Ar5") = (int) (a5); \
- LOAD_ARGS_4 (a1, a2, a3, a4)
-#define ASM_ARGS_5 ASM_ARGS_4, "d" (_a5)
-#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
- register int _a6 __asm__ ("D0Ar6") = (int) (a6); \
- LOAD_ARGS_5 (a1, a2, a3, a4, a5)
-#define ASM_ARGS_6 ASM_ARGS_5, "d" (_a6)
+#define LOAD_ARGS_1 \
+ register int _a1 __asm__ ("D1Ar1") = (int) (_t1); \
+ LOAD_ARGS_0
+#define ASM_ARGS_1 ASM_ARGS_0, "d" (_a1)
+#define LOAD_ARGS_2 \
+ register int _a2 __asm__ ("D0Ar2") = (int) (_t2); \
+ LOAD_ARGS_1
+#define ASM_ARGS_2 ASM_ARGS_1, "d" (_a2)
+#define LOAD_ARGS_3 \
+ register int _a3 __asm__ ("D1Ar3") = (int) (_t3); \
+ LOAD_ARGS_2
+#define ASM_ARGS_3 ASM_ARGS_2, "d" (_a3)
+#define LOAD_ARGS_4 \
+ register int _a4 __asm__ ("D0Ar4") = (int) (_t4); \
+ LOAD_ARGS_3
+#define ASM_ARGS_4 ASM_ARGS_3, "d" (_a4)
+#define LOAD_ARGS_5 \
+ register int _a5 __asm__ ("D1Ar5") = (int) (_t5); \
+ LOAD_ARGS_4
+#define ASM_ARGS_5 ASM_ARGS_4, "d" (_a5)
+#define LOAD_ARGS_6 \
+ register int _a6 __asm__ ("D0Ar6") = (int) (_t6); \
+ LOAD_ARGS_5
+#define ASM_ARGS_6 ASM_ARGS_5, "d" (_a6)
#endif /* __ASSEMBLER__ */
#endif /* _BITS_SYSCALLS_H */