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