1 /**
2 * altivec 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.altivec;
11  
12 import botan.constants;
13 static if (BOTAN_HAS_SIMD_ALTIVEC):
14 
15 import core.simd;
16 
17 pure:
18 nothrow:
19 @trusted:
20 
21 alias vector_uint = uint4;
22 alias vector_byte = byte16;
23 
24 // todo: LDC & DMD
25 // warning: untested
26 version(GDC) {
27     // GDC <--> immintrin => gcc/gcc/config/i386/immintrin.h
28     static import gcc.attribute;
29     import gcc.builtins;
30     enum inline = gcc.attribute.attribute("forceinline");
31     enum altivec = gcc.attribute.attribute("target", "powerpc_altivec_ok");
32     
33     @inline @altivec
34     vector_uint vec_ld(int a1, in uint* a2) {
35         return cast(vector_uint) __builtin_altivec_lvx(a1, cast(void*) a2);
36     }
37 
38     @inline @altivec
39     vector_byte vec_lvsl(int a1, in uint* a2) {
40         if (!a2) {
41             vector_uint a2_;
42             return cast(vector_byte) __builtin_altivec_lvsl(a1, cast(void *) &a2_);
43         }
44         return cast(vector_byte) __builtin_altivec_lvsl(a1, cast(void *) a2);
45     }
46 
47     @inline @altivec
48     vector_byte vec_xor(vector_byte a1, in ubyte16 a2) {
49         return cast(vector_byte) __builtin_altivec_vxor(cast(int4) a1, cast(int4) a2);
50     }
51 
52     @inline @altivec
53     vector_uint vec_perm(vector_uint a1, vector_uint a2, ubyte16 a3) {
54         return cast(vector_uint) __builtin_altivec_vperm_4si(cast(int4) a1, cast(int4) a2, cast(vector_byte) a3);
55     }
56 
57     @inline @altivec
58     ubyte16 vec_splat_u8(in int a1) {
59         return cast(ubyte16) __builtin_altivec_vspltisb(a1);
60     }
61 
62     @inline @altivec
63     vector_uint vec_rl(vector_uint a1, vector_uint a2) {
64         return cast(vector_uint) __builtin_altivec_vrlw(cast(int4) a1, cast(int4) a2);
65     }
66 
67     @inline @altivec
68     vector_uint vec_add(vector_uint a1, vector_uint a2) {
69         return cast(vector_uint) __builtin_altivec_vadduwm(cast(int4) a1, cast(int4) a2);
70     }
71 
72     @inline @altivec
73     vector_uint vec_sub(vector_uint a1, vector_uint a2) {
74         return cast(vector_uint) __builtin_altivec_vsubuwm(cast(int4) a1, cast(int4) a2);
75     }
76 
77     @inline @altivec
78     vector_uint vec_or(vector_uint a1, vector_uint a2) {
79         return cast(vector_uint) __builtin_altivec_vor(cast(int4) a1, cast(int4) a2);
80     }
81 
82     @inline @altivec
83     vector_uint vec_and(vector_uint a1, vector_uint a2) {
84         return cast(vector_uint) __builtin_altivec_vand(cast(int4) a1, cast(int4) a2);
85     }
86 
87     @inline @altivec
88     vector_uint vec_sl(vector_uint a1, vector_uint a2) {
89         return cast(vector_uint) __builtin_altivec_vslw(cast(int4) a1, cast(int4) a2);
90     }
91 
92     @inline @altivec
93     vector_uint vec_sr(vector_uint a1, vector_uint a2) {
94         return cast(vector_uint) __builtin_altivec_vsrw(cast(int4) a1, cast(int4) a2);
95     }
96     
97     @inline @altivec
98     vector_uint vec_nor(vector_uint a1, vector_uint a2) {
99         return cast(vector_uint) __builtin_altivec_vnor(cast(int4) a1, cast(int4) a2);
100     }
101 
102     @inline @altivec
103     vector_uint vec_andc(vector_uint a1, vector_uint a2) {
104         return cast(vector_uint) __builtin_altivec_vandc(cast(int4) a1, cast(int4) a2);
105     }
106 
107     @inline @altivec
108     vector_uint vec_mergeh(vector_uint a1, vector_uint a2) {
109         return cast(vector_uint) __builtin_altivec_vmrghw(cast(int4) a1, cast(int4) a2);
110     }
111 
112     @inline @altivec
113     vector_uint vec_mergel(vector_uint a1, vector_uint a2) {
114         return cast(vector_uint) __builtin_altivec_vmrglw(cast(int4) a1, cast(int4) a2);
115     }
116 }