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 }