#ifndef COSMOPOLITAN_LIBC_INTRIN_MACROS_H_ #define COSMOPOLITAN_LIBC_INTRIN_MACROS_H_ #include "libc/dce.h" #include "libc/nexgen32e/x86feature.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) #define INTRIN_COMMUTATIVE "%" #define INTRIN_NONCOMMUTATIVE #if defined(__x86_64__) && !defined(__STRICT_ANSI__) typedef char __intrin_xmm_t _Vector_size(16) forcealign(16) mayalias; #define INTRIN_SSEVEX_X_X_X_(PURE, ISA, OP, FLAGS, A, B, C) \ do { \ if (!IsModeDbg() && X86_HAVE(ISA)) { \ __intrin_xmm_t *Xmm0 = (void *)(A); \ const __intrin_xmm_t *Xmm1 = (const __intrin_xmm_t *)(B); \ const __intrin_xmm_t *Xmm2 = (const __intrin_xmm_t *)(C); \ if (!X86_NEED(AVX)) { \ asm(OP "\t%1,%0" : "=x"(*Xmm0) : FLAGS "x"(*Xmm2), "0"(*Xmm1)); \ } else { \ asm("v" OP "\t%2,%1,%0" : "=x"(*Xmm0) : FLAGS "x"(*Xmm1), "x"(*Xmm2)); \ } \ } else { \ PURE(A, B, C); \ } \ } while (0) #define INTRIN_SSEVEX_X_X_I_(PURE, ISA, OP, A, B, I) \ do { \ if (!IsModeDbg() && X86_HAVE(ISA)) { \ __intrin_xmm_t *Xmm0 = (void *)(A); \ const __intrin_xmm_t *Xmm1 = (const __intrin_xmm_t *)(B); \ if (!X86_NEED(AVX)) { \ asm(OP "\t%2,%1,%0" : "=x"(*Xmm0) : "x"(*Xmm1), "i"(I)); \ } else { \ asm("v" OP "\t%2,%1,%0" : "=x"(*Xmm0) : "x"(*Xmm1), "i"(I)); \ } \ } else { \ PURE(A, B, I); \ } \ } while (0) #define INTRIN_SSEVEX_X_X_(PURE, ISA, OP, A, B) \ do { \ if (!IsModeDbg() && X86_HAVE(ISA)) { \ __intrin_xmm_t *Xmm0 = (void *)(A); \ const __intrin_xmm_t *Xmm1 = (const __intrin_xmm_t *)(B); \ if (!X86_NEED(AVX)) { \ asm(OP "\t%1,%0" : "=x"(*Xmm0) : "0"(*Xmm1)); \ } else { \ asm("v" OP "\t%1,%0" : "=x"(*Xmm0) : "x"(*Xmm1)); \ } \ } else { \ PURE(A, B); \ } \ } while (0) #define INTRIN_SSEVEX_X_I_(PURE, ISA, OP, A, B, I) \ do { \ if (!IsModeDbg() && X86_HAVE(ISA)) { \ __intrin_xmm_t *Xmm0 = (void *)(A); \ const __intrin_xmm_t *Xmm1 = (const __intrin_xmm_t *)(B); \ if (!X86_NEED(AVX)) { \ asm(OP "\t%1,%0" : "=x"(*Xmm0) : "i"(I), "0"(*Xmm1)); \ } else { \ asm("v" OP "\t%2,%1,%0" : "=x"(*Xmm0) : "x"(*Xmm1), "i"(I)); \ } \ } else { \ PURE(A, B, I); \ } \ } while (0) #else #define INTRIN_SSEVEX_X_X_X_(PURE, ISA, OP, FLAGS, A, B, C) PURE(A, B, C) #define INTRIN_SSEVEX_X_X_I_(PURE, ISA, OP, A, B, I) PURE(A, B, I) #define INTRIN_SSEVEX_X_I_(PURE, ISA, OP, A, B, I) PURE(A, B, I) #endif /* X86 && !ANSI */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_INTRIN_MACROS_H_ */