diff options
author | Markos Chandras <markos.chandras@imgtec.com> | 2010-11-18 14:58:01 +0000 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2013-03-14 22:47:08 +0100 |
commit | daecc9a410a6f23d80daf8ce3afd280fea329e63 (patch) | |
tree | 8d603dd538809431cc01b9e656c827d1f0709052 /libc/sysdeps/linux/metag/bits | |
parent | 20221281b3d67880439cd1d16c151f4528d034fb (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.h | 66 | ||||
-rw-r--r-- | libc/sysdeps/linux/metag/bits/syscalls.h | 73 |
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 */ |