26#ifndef KJK_INTRIN_ARM64_H_
27#define KJK_INTRIN_ARM64_H_
29#if !defined(__GNUC__) && !defined(__clang__)
30#error Unsupported compiler
35# define HAS_BUILTIN(x) __has_builtin(x)
37# define HAS_BUILTIN(x) 0
44#ifndef __INTRIN_INLINE
45# define __INTRIN_INLINE extern __inline__ __attribute__((__always_inline__, __gnu_inline__))
48#define _ReturnAddress() (__builtin_return_address(0))
50#define _AddressOfReturnAddress() ((void *)((unsigned char *)__builtin_frame_address(0) + 8))
52#if !HAS_BUILTIN(__break)
59#if !HAS_BUILTIN(_ReadWriteBarrier)
62 __asm__ __volatile__(
"" : : :
"memory");
66#define _ReadBarrier _ReadWriteBarrier
67#define _WriteBarrier _ReadWriteBarrier
69#if !HAS_BUILTIN(_byteswap_ushort)
72 return __builtin_bswap16(
value);
76#if !HAS_BUILTIN(_byteswap_ulong)
79 return __builtin_bswap32(
value);
83#if !HAS_BUILTIN(_byteswap_uint64)
86 return __builtin_bswap64(
value);
90#if !HAS_BUILTIN(_BitScanForward)
101#if !HAS_BUILTIN(_BitScanReverse)
112#if !HAS_BUILTIN(_BitScanForward64)
123#if !HAS_BUILTIN(_BitScanReverse64)
134#if !HAS_BUILTIN(_InterlockedCompareExchange)
137 return __sync_val_compare_and_swap(
Destination, Comparand, Exchange);
141#if !HAS_BUILTIN(_InterlockedCompareExchange16)
144 return __sync_val_compare_and_swap(
Destination, Comparand, Exchange);
148#if !HAS_BUILTIN(_InterlockedCompareExchange8)
151 return __sync_val_compare_and_swap(
Destination, Comparand, Exchange);
155#if !HAS_BUILTIN(_InterlockedCompareExchange64)
158 return __sync_val_compare_and_swap(
Destination, Comparand, Exchange);
162#if !HAS_BUILTIN(_InterlockedCompareExchangePointer)
165 return __sync_val_compare_and_swap(
Destination, Comparand, Exchange);
169#if !HAS_BUILTIN(_InterlockedExchange)
173 return __atomic_exchange_n(
Target,
Value, __ATOMIC_SEQ_CST);
177#if !HAS_BUILTIN(_InterlockedExchange16)
180 return __atomic_exchange_n(
Target,
Value, __ATOMIC_SEQ_CST);
184#if !HAS_BUILTIN(_InterlockedExchange8)
187 return __atomic_exchange_n(
Target,
Value, __ATOMIC_SEQ_CST);
191#if !HAS_BUILTIN(_InterlockedExchange64)
194 return __atomic_exchange_n(
Target,
Value, __ATOMIC_SEQ_CST);
198#if !HAS_BUILTIN(_InterlockedExchangePointer)
201 return __atomic_exchange_n(
Target,
Value, __ATOMIC_SEQ_CST);
205#if !HAS_BUILTIN(_InterlockedExchangeAdd)
212#if !HAS_BUILTIN(_InterlockedExchangeAdd16)
219#if !HAS_BUILTIN(_InterlockedExchangeAdd8)
226#if !HAS_BUILTIN(_InterlockedExchangeAdd64)
233#if !HAS_BUILTIN(_InterlockedAnd)
236 return __sync_fetch_and_and(
Value,
Mask);
240#if !HAS_BUILTIN(_InterlockedAnd16)
243 return __sync_fetch_and_and(
Value,
Mask);
247#if !HAS_BUILTIN(_InterlockedAnd8)
250 return __sync_fetch_and_and(
Value,
Mask);
254#if !HAS_BUILTIN(_InterlockedAnd64)
257 return __sync_fetch_and_and(
Value,
Mask);
261#if !HAS_BUILTIN(_InterlockedOr)
268#if !HAS_BUILTIN(_InterlockedOr16)
275#if !HAS_BUILTIN(_InterlockedOr8)
282#if !HAS_BUILTIN(_InterlockedOr64)
289#if !HAS_BUILTIN(_InterlockedXor)
292 return __sync_fetch_and_xor(
Value,
Mask);
296#if !HAS_BUILTIN(_InterlockedXor16)
299 return __sync_fetch_and_xor(
Value,
Mask);
303#if !HAS_BUILTIN(_InterlockedXor8)
306 return __sync_fetch_and_xor(
Value,
Mask);
310#if !HAS_BUILTIN(_InterlockedXor64)
313 return __sync_fetch_and_xor(
Value,
Mask);
317#if !HAS_BUILTIN(_InterlockedIncrement)
320 return __sync_add_and_fetch(
Addend, 1);
324#if !HAS_BUILTIN(_InterlockedIncrement16)
327 return __sync_add_and_fetch(
Addend, 1);
331#if !HAS_BUILTIN(_InterlockedIncrement64)
334 return __sync_add_and_fetch(
Addend, 1);
338#if !HAS_BUILTIN(_InterlockedDecrement)
341 return __sync_sub_and_fetch(
Addend, 1);
345#if !HAS_BUILTIN(_InterlockedDecrement16)
348 return __sync_sub_and_fetch(
Addend, 1);
352#if !HAS_BUILTIN(_InterlockedDecrement64)
355 return __sync_sub_and_fetch(
Addend, 1);
359#if !HAS_BUILTIN(_InterlockedCompareExchange128)
369 unsigned __int64 old_lo, old_hi;
372 "1: ldaxp %[ol], %[oh], %[mem] \n"
373 " cmp %[ol], %[cl] \n"
374 " ccmp %[oh], %[ch], #0, eq \n"
376 " stlxp %w[st], %[xl], %[xh], %[mem] \n"
377 " cbnz %w[st], 1b \n"
383 : [ol]
"=&r"(old_lo), [oh]
"=&r"(old_hi),
386 : [cl]
"r"(cmp_lo), [
ch]
"r"(cmp_hi),
387 [xl]
"r"((
unsigned __int64)ExchangeLow),
388 [xh]
"r"((
unsigned __int64)ExchangeHigh)
390 __asm__ __volatile__(
"dmb ish" :::
"memory");
393 ComparandResult[0] = (
__int64)old_lo;
394 ComparandResult[1] = (
__int64)old_hi;
399#if !HAS_BUILTIN(__nop)
407#if !HAS_BUILTIN(_bittest)
410 return (
a[
b / 32] >> (
b % 32)) & 1;
414#if !HAS_BUILTIN(_bittestandset)
417 long bit = 1L << (
b % 32);
418 long *
ptr = &
a[
b / 32];
419 unsigned char retval = (*
ptr >> (
b % 32)) & 1;
425#if !HAS_BUILTIN(_bittestandreset)
428 long bit = 1L << (
b % 32);
429 long *
ptr = &
a[
b / 32];
430 unsigned char retval = (*
ptr >> (
b % 32)) & 1;
436#if !HAS_BUILTIN(_bittestandcomplement)
439 long bit = 1L << (
b % 32);
440 long *
ptr = &
a[
b / 32];
441 unsigned char retval = (*
ptr >> (
b % 32)) & 1;
447#if !HAS_BUILTIN(_bittest64)
450 return (
a[
b / 64] >> (
b % 64)) & 1;
454#if !HAS_BUILTIN(_bittestandset64)
457 long long bit = 1LL << (
b % 64);
458 long long *
ptr = &
a[
b / 64];
459 unsigned char retval = (*
ptr >> (
b % 64)) & 1;
465#if !HAS_BUILTIN(_bittestandreset64)
468 long long bit = 1LL << (
b % 64);
469 long long *
ptr = &
a[
b / 64];
470 unsigned char retval = (*
ptr >> (
b % 64)) & 1;
476#if !HAS_BUILTIN(_bittestandcomplement64)
479 long long bit = 1LL << (
b % 64);
480 long long *
ptr = &
a[
b / 64];
481 unsigned char retval = (*
ptr >> (
b % 64)) & 1;
488#if !HAS_BUILTIN(_interlockedbittestandreset)
491 unsigned int bit =
b & 31;
492 long mask = 1L << bit;
493 long old = __sync_fetch_and_and(
a, ~
mask);
494 return (
unsigned char)((old >> bit) & 1);
498#if !HAS_BUILTIN(_interlockedbittestandset)
501 unsigned int bit =
b & 31;
502 long mask = 1L << bit;
503 long old = __sync_fetch_and_or(
a,
mask);
504 return (
unsigned char)((old >> bit) & 1);
508#if !HAS_BUILTIN(_interlockedbittestandreset64)
511 unsigned int bit =
b & 63;
512 long long mask = 1LL << bit;
513 long long old = __sync_fetch_and_and(
a, ~
mask);
514 return (
unsigned char)((old >> bit) & 1);
518#if !HAS_BUILTIN(_interlockedbittestandset64)
521 unsigned int bit =
b & 63;
522 long long mask = 1LL << bit;
523 long long old = __sync_fetch_and_or(
a,
mask);
524 return (
unsigned char)((old >> bit) & 1);
529#if !HAS_BUILTIN(_rotl8)
539#if !HAS_BUILTIN(_rotl16)
549#if !HAS_BUILTIN(_rotl)
559#if !HAS_BUILTIN(_rotl64)
569#if !HAS_BUILTIN(_rotr8)
579#if !HAS_BUILTIN(_rotr16)
589#if !HAS_BUILTIN(_rotr)
599#if !HAS_BUILTIN(_rotr64)
609#if !HAS_BUILTIN(_lrotl)
619#if !HAS_BUILTIN(_lrotr)
630#if !HAS_BUILTIN(_CountLeadingZeros)
634 return sizeof(
value) * 8;
635 return __builtin_clzl(
value);
639#if !HAS_BUILTIN(_CountLeadingZeros64)
644 return __builtin_clzll(
value);
648#if !HAS_BUILTIN(_CountOneBits)
651 return __builtin_popcountl(
value);
655#if !HAS_BUILTIN(_CountOneBits64)
658 return __builtin_popcountll(
value);
663#if !HAS_BUILTIN(__mulh)
666 return ((__int128)
a * (__int128)
b) >> 64;
670#if !HAS_BUILTIN(__umulh)
673 return ((
unsigned __int128)
a * (
unsigned __int128)
b) >> 64;
677#if !HAS_BUILTIN(_abs64)
685#if !HAS_BUILTIN(__yield)
693#if !HAS_BUILTIN(__dmb)
701 case 1:
__asm__ __volatile__(
"dmb oshld" :::
"memory");
break;
702 case 2:
__asm__ __volatile__(
"dmb oshst" :::
"memory");
break;
703 case 3:
__asm__ __volatile__(
"dmb osh" :::
"memory");
break;
704 case 5:
__asm__ __volatile__(
"dmb nshld" :::
"memory");
break;
705 case 6:
__asm__ __volatile__(
"dmb nshst" :::
"memory");
break;
706 case 7:
__asm__ __volatile__(
"dmb nsh" :::
"memory");
break;
707 case 9:
__asm__ __volatile__(
"dmb ishld" :::
"memory");
break;
708 case 10:
__asm__ __volatile__(
"dmb ishst" :::
"memory");
break;
709 case 11:
__asm__ __volatile__(
"dmb ish" :::
"memory");
break;
710 case 13:
__asm__ __volatile__(
"dmb ld" :::
"memory");
break;
711 case 14:
__asm__ __volatile__(
"dmb st" :::
"memory");
break;
712 default:
__asm__ __volatile__(
"dmb sy" :::
"memory");
break;
717#if !HAS_BUILTIN(__dsb)
722 case 1:
__asm__ __volatile__(
"dsb oshld" :::
"memory");
break;
723 case 2:
__asm__ __volatile__(
"dsb oshst" :::
"memory");
break;
724 case 3:
__asm__ __volatile__(
"dsb osh" :::
"memory");
break;
725 case 5:
__asm__ __volatile__(
"dsb nshld" :::
"memory");
break;
726 case 6:
__asm__ __volatile__(
"dsb nshst" :::
"memory");
break;
727 case 7:
__asm__ __volatile__(
"dsb nsh" :::
"memory");
break;
728 case 9:
__asm__ __volatile__(
"dsb ishld" :::
"memory");
break;
729 case 10:
__asm__ __volatile__(
"dsb ishst" :::
"memory");
break;
730 case 11:
__asm__ __volatile__(
"dsb ish" :::
"memory");
break;
731 case 13:
__asm__ __volatile__(
"dsb ld" :::
"memory");
break;
732 case 14:
__asm__ __volatile__(
"dsb st" :::
"memory");
break;
733 default:
__asm__ __volatile__(
"dsb sy" :::
"memory");
break;
738#if !HAS_BUILTIN(__isb)
744 __asm__ __volatile__(
"isb" :::
"memory");
752#if !HAS_BUILTIN(__getReg)
753#define __getReg(reg) \
755 _Static_assert((unsigned long long)(reg) <= 31ULL, \
756 "__getReg: register index out of range"); \
757 unsigned __int64 _value; \
758 __asm__ __volatile__("mov %0, x%c1" : "=r"(_value) : "i"(reg)); \
764#if !HAS_BUILTIN(_InterlockedAdd)
767 return __atomic_add_fetch(
Addend,
Value, __ATOMIC_SEQ_CST);
771#if !HAS_BUILTIN(_InterlockedAdd64)
774 return __atomic_add_fetch(
Addend,
Value, __ATOMIC_SEQ_CST);
781#if !HAS_BUILTIN(__readx18byte)
785 __asm__ __volatile__(
"ldrb %w0, [x18, %1]" :
"=r"(
value) :
"r"((
unsigned long long)
offset));
790#if !HAS_BUILTIN(__readx18word)
793 unsigned short value;
794 __asm__ __volatile__(
"ldrh %w0, [x18, %1]" :
"=r"(
value) :
"r"((
unsigned long long)
offset));
799#if !HAS_BUILTIN(__readx18dword)
803 __asm__ __volatile__(
"ldr %w0, [x18, %1]" :
"=r"(
value) :
"r"((
unsigned long long)
offset));
808#if !HAS_BUILTIN(__readx18qword)
812 __asm__ __volatile__(
"ldr %0, [x18, %1]" :
"=r"(
value) :
"r"((
unsigned long long)
offset));
817#if !HAS_BUILTIN(__writex18byte)
820 __asm__ __volatile__(
"strb %w1, [x18, %0]" : :
"r"((
unsigned long long)
offset),
"r"(
value) :
"memory");
824#if !HAS_BUILTIN(__writex18word)
827 __asm__ __volatile__(
"strh %w1, [x18, %0]" : :
"r"((
unsigned long long)
offset),
"r"(
value) :
"memory");
831#if !HAS_BUILTIN(__writex18dword)
834 __asm__ __volatile__(
"str %w1, [x18, %0]" : :
"r"((
unsigned long long)
offset),
"r"(
value) :
"memory");
838#if !HAS_BUILTIN(__writex18qword)
841 __asm__ __volatile__(
"str %1, [x18, %0]" : :
"r"((
unsigned long long)
offset),
"r"(
value) :
"memory");
GLuint GLuint GLsizei GLenum type
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
__int128 __attribute__((may_alias)) __ms_int128_t
__INTRIN_INLINE unsigned char _interlockedbittestandset(volatile long *a, long b)
__INTRIN_INLINE unsigned long long __umulh(unsigned long long a, unsigned long long b)
__INTRIN_INLINE void __writex18qword(unsigned long offset, unsigned __int64 value)
__INTRIN_INLINE unsigned short __cdecl _rotl16(unsigned short value, unsigned char shift)
__INTRIN_INLINE long long _InterlockedXor64(volatile long long *Value, long long Mask)
__INTRIN_INLINE unsigned char _interlockedbittestandset64(volatile long long *a, long long b)
__INTRIN_INLINE long _InterlockedAdd(volatile long *Addend, long Value)
__INTRIN_INLINE unsigned char _BitScanForward(unsigned long *Index, unsigned long Mask)
__INTRIN_INLINE void _ReadWriteBarrier(void)
__INTRIN_INLINE short _InterlockedAnd16(volatile short *Value, short Mask)
__INTRIN_INLINE void __dsb(unsigned int type)
__INTRIN_INLINE unsigned char __readx18byte(unsigned long offset)
__INTRIN_INLINE unsigned __int64 __readx18qword(unsigned long offset)
__INTRIN_INLINE long long _InterlockedAnd64(volatile long long *Value, long long Mask)
__INTRIN_INLINE long _InterlockedIncrement(volatile long *Addend)
__INTRIN_INLINE short _InterlockedDecrement16(volatile short *Addend)
__INTRIN_INLINE unsigned int _CountOneBits(unsigned long value)
__INTRIN_INLINE void __yield(void)
__INTRIN_INLINE long long __cdecl _abs64(long long value)
__INTRIN_INLINE unsigned int __cdecl _rotl(unsigned int value, int shift)
__INTRIN_INLINE unsigned char _bittestandcomplement64(long long *a, long long b)
__INTRIN_INLINE long long _InterlockedExchange64(volatile long long *Target, long long Value)
__INTRIN_INLINE long long __mulh(long long a, long long b)
__INTRIN_INLINE unsigned short _byteswap_ushort(unsigned short value)
__INTRIN_INLINE unsigned int _CountLeadingZeros(unsigned long value)
__INTRIN_INLINE unsigned long long _rotr64(unsigned long long value, int shift)
__INTRIN_INLINE long long _InterlockedOr64(volatile long long *Value, long long Mask)
__INTRIN_INLINE void __dmb(unsigned int type)
__INTRIN_INLINE unsigned short __readx18word(unsigned long offset)
__INTRIN_INLINE unsigned char _interlockedbittestandreset(volatile long *a, long b)
__INTRIN_INLINE long long _InterlockedIncrement64(volatile long long *Addend)
__INTRIN_INLINE unsigned char __cdecl _rotl8(unsigned char value, unsigned char shift)
__INTRIN_INLINE unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 value)
__INTRIN_INLINE void __nop(void)
__INTRIN_INLINE long long _InterlockedExchangeAdd64(volatile long long *Addend, long long Value)
__INTRIN_INLINE unsigned char _bittestandreset64(long long *a, long long b)
__INTRIN_INLINE char _InterlockedOr8(volatile char *Value, char Mask)
__INTRIN_INLINE short _InterlockedCompareExchange16(volatile short *Destination, short Exchange, short Comparand)
__INTRIN_INLINE void __writex18word(unsigned long offset, unsigned short value)
__INTRIN_INLINE unsigned char _BitScanReverse(unsigned long *Index, unsigned long Mask)
__INTRIN_INLINE void __writex18dword(unsigned long offset, unsigned long value)
__INTRIN_INLINE long long _InterlockedCompareExchange64(volatile long long *Destination, long long Exchange, long long Comparand)
__INTRIN_INLINE long _InterlockedOr(volatile long *Value, long Mask)
__INTRIN_INLINE unsigned char _BitScanReverse64(unsigned long *Index, unsigned long long Mask)
__INTRIN_INLINE unsigned char _bittestandset64(long long *a, long long b)
__INTRIN_INLINE long long _InterlockedAdd64(volatile long long *Addend, long long Value)
__INTRIN_INLINE short _InterlockedExchangeAdd16(volatile short *Addend, short Value)
__INTRIN_INLINE void __isb(unsigned int type)
__INTRIN_INLINE void * _InterlockedExchangePointer(void *volatile *Target, void *Value)
__INTRIN_INLINE unsigned long __cdecl _lrotr(unsigned long value, int shift)
__INTRIN_INLINE void __writex18byte(unsigned long offset, unsigned char value)
__INTRIN_INLINE char _InterlockedExchangeAdd8(volatile char *Addend, char Value)
__INTRIN_INLINE unsigned int _CountOneBits64(unsigned __int64 value)
__INTRIN_INLINE unsigned char _bittestandset(long *a, long b)
__INTRIN_INLINE short _InterlockedExchange16(volatile short *Target, short Value)
__INTRIN_INLINE unsigned char _bittestandreset(long *a, long b)
__INTRIN_INLINE long _InterlockedExchangeAdd(volatile long *Addend, long Value)
__INTRIN_INLINE unsigned short __cdecl _rotr16(unsigned short value, unsigned char shift)
__INTRIN_INLINE unsigned char __cdecl _rotr8(unsigned char value, unsigned char shift)
__INTRIN_INLINE unsigned long __cdecl _byteswap_ulong(unsigned long value)
__INTRIN_INLINE short _InterlockedIncrement16(volatile short *Addend)
__INTRIN_INLINE short _InterlockedXor16(volatile short *Value, short Mask)
__INTRIN_INLINE long _InterlockedExchange(volatile long *Target, long Value)
__INTRIN_INLINE long _InterlockedDecrement(volatile long *Addend)
__INTRIN_INLINE unsigned long long _rotl64(unsigned long long value, int shift)
__INTRIN_INLINE unsigned int __cdecl _rotr(unsigned int value, int shift)
__INTRIN_INLINE long long _InterlockedDecrement64(volatile long long *Addend)
__INTRIN_INLINE char _InterlockedCompareExchange8(volatile char *Destination, char Exchange, char Comparand)
__INTRIN_INLINE unsigned int _CountLeadingZeros64(unsigned __int64 value)
__INTRIN_INLINE void __break(int value)
__INTRIN_INLINE unsigned char _bittest(const long *a, long b)
__INTRIN_INLINE unsigned long __cdecl _lrotl(unsigned long value, int shift)
__INTRIN_INLINE unsigned char _bittestandcomplement(long *a, long b)
__INTRIN_INLINE long _InterlockedCompareExchange(volatile long *Destination, long Exchange, long Comparand)
__INTRIN_INLINE unsigned char _bittest64(const long long *a, long long b)
__INTRIN_INLINE unsigned char _interlockedbittestandreset64(volatile long long *a, long long b)
__INTRIN_INLINE unsigned long __readx18dword(unsigned long offset)
__INTRIN_INLINE void * _InterlockedCompareExchangePointer(void *volatile *Destination, void *Exchange, void *Comparand)
__INTRIN_INLINE unsigned char _BitScanForward64(unsigned long *Index, unsigned long long Mask)
__INTRIN_INLINE char _InterlockedExchange8(volatile char *Target, char Value)
__INTRIN_INLINE unsigned char _InterlockedCompareExchange128(volatile __int64 *Destination, __int64 ExchangeHigh, __int64 ExchangeLow, __int64 *ComparandResult)
volatile char *const const char modify volatile long *const const long modify _InterlockedOr16
volatile char *const const char modify volatile long *const const long modify volatile short *const const short modify volatile char *const const char modify _InterlockedXor
volatile char *const const char modify _InterlockedAnd
volatile char *const const char modify volatile long *const const long modify volatile short *const const short modify _InterlockedXor8
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tsub %rbp, %rax\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tpush %rbx\n" "\t.seh_pushreg %rbx\n" "\tpush %rdi\n" "\t.seh_pushreg %rdi\n" "\tpush %rsi\n" "\t.seh_pushreg %rsi\n" "\tpush %r12\n" "\t.seh_pushreg %r12\n" "\tpush %r13\n" "\t.seh_pushreg %r13\n" "\tpush %r14\n" "\t.seh_pushreg %r14\n" "\tpush %r15\n" "\t.seh_pushreg %r15\n" "\tsub $40, %rsp\n" "\t.seh_stackalloc 40\n" "\t.seh_endprologue\n" "\tsub %rax, %rdx\n" "\tmov %rdx, %rbp\n" "\tjmp *%r8\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $40, %rsp\n" "\tpop %r15\n" "\tpop %r14\n" "\tpop %r13\n" "\tpop %r12\n" "\tpop %rsi\n" "\tpop %rdi\n" "\tpop %rbx\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value