1 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 /* 3 * Compiler-dependent intrinsics. 4 * 5 * Copyright (C) 2002-2003 Hewlett-Packard Co 6 * David Mosberger-Tang <davidm@hpl.hp.com> 7 */ 8 #ifndef _UAPI_ASM_IA64_INTRINSICS_H 9 #define _UAPI_ASM_IA64_INTRINSICS_H 10 11 12 #ifndef __ASSEMBLY__ 13 14 #include <linux/types.h> 15 /* include compiler specific intrinsics */ 16 #include <asm/ia64regs.h> 17 #include <asm/gcc_intrin.h> 18 #include <asm/cmpxchg.h> 19 20 #define ia64_set_rr0_to_rr4(val0, val1, val2, val3, val4) \ 21 do { \ 22 ia64_set_rr(0x0000000000000000UL, (val0)); \ 23 ia64_set_rr(0x2000000000000000UL, (val1)); \ 24 ia64_set_rr(0x4000000000000000UL, (val2)); \ 25 ia64_set_rr(0x6000000000000000UL, (val3)); \ 26 ia64_set_rr(0x8000000000000000UL, (val4)); \ 27 } while (0) 28 29 /* 30 * Force an unresolved reference if someone tries to use 31 * ia64_fetch_and_add() with a bad value. 32 */ 33 extern unsigned long __bad_size_for_ia64_fetch_and_add (void); 34 extern unsigned long __bad_increment_for_ia64_fetch_and_add (void); 35 36 #define IA64_FETCHADD(tmp,v,n,sz,sem) \ 37 ({ \ 38 switch (sz) { \ 39 case 4: \ 40 tmp = ia64_fetchadd4_##sem((unsigned int *) v, n); \ 41 break; \ 42 \ 43 case 8: \ 44 tmp = ia64_fetchadd8_##sem((unsigned long *) v, n); \ 45 break; \ 46 \ 47 default: \ 48 __bad_size_for_ia64_fetch_and_add(); \ 49 } \ 50 }) 51 52 #define ia64_fetchadd(i,v,sem) \ 53 ({ \ 54 __u64 _tmp; \ 55 volatile __typeof__(*(v)) *_v = (v); \ 56 /* Can't use a switch () here: gcc isn't always smart enough for that... */ \ 57 if ((i) == -16) \ 58 IA64_FETCHADD(_tmp, _v, -16, sizeof(*(v)), sem); \ 59 else if ((i) == -8) \ 60 IA64_FETCHADD(_tmp, _v, -8, sizeof(*(v)), sem); \ 61 else if ((i) == -4) \ 62 IA64_FETCHADD(_tmp, _v, -4, sizeof(*(v)), sem); \ 63 else if ((i) == -1) \ 64 IA64_FETCHADD(_tmp, _v, -1, sizeof(*(v)), sem); \ 65 else if ((i) == 1) \ 66 IA64_FETCHADD(_tmp, _v, 1, sizeof(*(v)), sem); \ 67 else if ((i) == 4) \ 68 IA64_FETCHADD(_tmp, _v, 4, sizeof(*(v)), sem); \ 69 else if ((i) == 8) \ 70 IA64_FETCHADD(_tmp, _v, 8, sizeof(*(v)), sem); \ 71 else if ((i) == 16) \ 72 IA64_FETCHADD(_tmp, _v, 16, sizeof(*(v)), sem); \ 73 else \ 74 _tmp = __bad_increment_for_ia64_fetch_and_add(); \ 75 (__typeof__(*(v))) (_tmp); /* return old value */ \ 76 }) 77 78 #define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, rel) + (i)) /* return new value */ 79 80 #endif 81 82 #endif /* _UAPI_ASM_IA64_INTRINSICS_H */ 83