1 /** 2 * tmmintrin.h style functions 3 * 4 * Copyright: 5 * (C) 2014-2015 Etienne Cimon 6 * 7 * License: 8 * Released under the MIT license 9 */ 10 module botan.utils.simd.tmmintrin; 11 12 import botan.constants; 13 static if (BOTAN_HAS_AES_SSSE3 && BOTAN_HAS_SIMD_SSE2): 14 15 public import botan.utils.simd.emmintrin; 16 17 version(GDC) { 18 @inline: 19 // _mm_shuffle_epi8 20 __m128i _mm_shuffle_epi8()(auto ref __m128i a, auto const ref __m128i b) { 21 return cast(__m128i) __builtin_ia32_pshufb128(a, b); 22 } 23 24 // _mm_alignr_epi8 25 __m128i _mm_alignr_epi8(int n)(auto ref __m128i a, auto ref __m128i b) { 26 return cast(__m128i) __builtin_ia32_palignr128(cast(long2) a, cast(long2) b, n*8); 27 } 28 } 29 30 version(none) { 31 // _mm_shuffle_epi8 32 __m128i _mm_shuffle_epi8()(auto ref __m128i a, auto const ref __m128i b) { 33 return cast(__m128i) __builtin_ia32_pshufb128(a, b); 34 } 35 36 __m128i _mm_alignr_epi8(int n)(auto ref __m128i a, auto ref __m128i b) { 37 return cast(__m128i) __builtin_ia32_palignr128(cast(long2) a, cast(long2) b, n*8); 38 } 39 } 40 41 version(D_InlineAsm_X86_64) { 42 // _mm_min_epi8 ; PSHUFB 43 __m128i _mm_shuffle_epi8()(auto const ref __m128i a, auto const ref __m128i b) { 44 45 const(__m128i)* _a = &a; 46 const(__m128i)* _b = &b; 47 __m128i c; 48 __m128i* _c = &c; 49 50 asm pure nothrow { 51 mov RAX, _a; 52 mov RBX, _b; 53 mov RCX, _c; 54 movdqu XMM1, [RAX]; 55 movdqu XMM2, [RBX]; 56 pshufb XMM1, XMM2; 57 movdqu [RCX], XMM1; 58 } 59 return c; 60 } 61 62 // _mm_alignr_epi8 ; palignr 63 __m128i _mm_alignr_epi8(int n)(auto const ref __m128i a, auto const ref __m128i b) { 64 const(__m128i)* _a = &a; 65 const(__m128i)* _b = &b; 66 __m128i c; 67 __m128i* _c = &c; 68 69 mixin(` 70 asm pure nothrow { 71 mov RAX, _a; 72 mov RBX, _b; 73 mov RCX, _c; 74 movdqu XMM1, [RAX]; 75 movdqu XMM2, [RBX]; 76 palignr XMM1, XMM2, ` ~ n.stringof ~ `; 77 movdqu [RCX], XMM1; 78 } 79 `); 80 81 return c; 82 } 83 }