162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Compiler-dependent intrinsics. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2002-2003 Hewlett-Packard Co 662306a36Sopenharmony_ci * David Mosberger-Tang <davidm@hpl.hp.com> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci#ifndef _UAPI_ASM_IA64_INTRINSICS_H 962306a36Sopenharmony_ci#define _UAPI_ASM_IA64_INTRINSICS_H 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/types.h> 1562306a36Sopenharmony_ci/* include compiler specific intrinsics */ 1662306a36Sopenharmony_ci#include <asm/ia64regs.h> 1762306a36Sopenharmony_ci#include <asm/gcc_intrin.h> 1862306a36Sopenharmony_ci#include <asm/cmpxchg.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#define ia64_set_rr0_to_rr4(val0, val1, val2, val3, val4) \ 2162306a36Sopenharmony_cido { \ 2262306a36Sopenharmony_ci ia64_set_rr(0x0000000000000000UL, (val0)); \ 2362306a36Sopenharmony_ci ia64_set_rr(0x2000000000000000UL, (val1)); \ 2462306a36Sopenharmony_ci ia64_set_rr(0x4000000000000000UL, (val2)); \ 2562306a36Sopenharmony_ci ia64_set_rr(0x6000000000000000UL, (val3)); \ 2662306a36Sopenharmony_ci ia64_set_rr(0x8000000000000000UL, (val4)); \ 2762306a36Sopenharmony_ci} while (0) 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* 3062306a36Sopenharmony_ci * Force an unresolved reference if someone tries to use 3162306a36Sopenharmony_ci * ia64_fetch_and_add() with a bad value. 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_ciextern unsigned long __bad_size_for_ia64_fetch_and_add (void); 3462306a36Sopenharmony_ciextern unsigned long __bad_increment_for_ia64_fetch_and_add (void); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#define IA64_FETCHADD(tmp,v,n,sz,sem) \ 3762306a36Sopenharmony_ci({ \ 3862306a36Sopenharmony_ci switch (sz) { \ 3962306a36Sopenharmony_ci case 4: \ 4062306a36Sopenharmony_ci tmp = ia64_fetchadd4_##sem((unsigned int *) v, n); \ 4162306a36Sopenharmony_ci break; \ 4262306a36Sopenharmony_ci \ 4362306a36Sopenharmony_ci case 8: \ 4462306a36Sopenharmony_ci tmp = ia64_fetchadd8_##sem((unsigned long *) v, n); \ 4562306a36Sopenharmony_ci break; \ 4662306a36Sopenharmony_ci \ 4762306a36Sopenharmony_ci default: \ 4862306a36Sopenharmony_ci __bad_size_for_ia64_fetch_and_add(); \ 4962306a36Sopenharmony_ci } \ 5062306a36Sopenharmony_ci}) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#define ia64_fetchadd(i,v,sem) \ 5362306a36Sopenharmony_ci({ \ 5462306a36Sopenharmony_ci __u64 _tmp; \ 5562306a36Sopenharmony_ci volatile __typeof__(*(v)) *_v = (v); \ 5662306a36Sopenharmony_ci /* Can't use a switch () here: gcc isn't always smart enough for that... */ \ 5762306a36Sopenharmony_ci if ((i) == -16) \ 5862306a36Sopenharmony_ci IA64_FETCHADD(_tmp, _v, -16, sizeof(*(v)), sem); \ 5962306a36Sopenharmony_ci else if ((i) == -8) \ 6062306a36Sopenharmony_ci IA64_FETCHADD(_tmp, _v, -8, sizeof(*(v)), sem); \ 6162306a36Sopenharmony_ci else if ((i) == -4) \ 6262306a36Sopenharmony_ci IA64_FETCHADD(_tmp, _v, -4, sizeof(*(v)), sem); \ 6362306a36Sopenharmony_ci else if ((i) == -1) \ 6462306a36Sopenharmony_ci IA64_FETCHADD(_tmp, _v, -1, sizeof(*(v)), sem); \ 6562306a36Sopenharmony_ci else if ((i) == 1) \ 6662306a36Sopenharmony_ci IA64_FETCHADD(_tmp, _v, 1, sizeof(*(v)), sem); \ 6762306a36Sopenharmony_ci else if ((i) == 4) \ 6862306a36Sopenharmony_ci IA64_FETCHADD(_tmp, _v, 4, sizeof(*(v)), sem); \ 6962306a36Sopenharmony_ci else if ((i) == 8) \ 7062306a36Sopenharmony_ci IA64_FETCHADD(_tmp, _v, 8, sizeof(*(v)), sem); \ 7162306a36Sopenharmony_ci else if ((i) == 16) \ 7262306a36Sopenharmony_ci IA64_FETCHADD(_tmp, _v, 16, sizeof(*(v)), sem); \ 7362306a36Sopenharmony_ci else \ 7462306a36Sopenharmony_ci _tmp = __bad_increment_for_ia64_fetch_and_add(); \ 7562306a36Sopenharmony_ci (__typeof__(*(v))) (_tmp); /* return old value */ \ 7662306a36Sopenharmony_ci}) 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci#define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, rel) + (i)) /* return new value */ 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci#endif 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci#endif /* _UAPI_ASM_IA64_INTRINSICS_H */ 83