[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / libclc / generic / lib / integer / rotate.inc
blob33bb0a85241d20be989c3b9145dd21b60ff3b44c
1 /**
2  * Not necessarily optimal... but it produces correct results (at least for int)
3  * If we're lucky, LLVM will recognize the pattern and produce rotate
4  * instructions:
5  * http://llvm.1065342.n5.nabble.com/rotate-td47679.html
6  * 
7  * Eventually, someone should feel free to implement an llvm-specific version
8  */
10 _CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE rotate(__CLC_GENTYPE x, __CLC_GENTYPE n){
11     //Try to avoid extra work if someone's spinning the value through multiple
12     //full rotations
13     n = n % (__CLC_GENTYPE)__CLC_GENSIZE;
15 #ifdef __CLC_SCALAR
16     if (n > 0){
17         return (x << n) | (((__CLC_U_GENTYPE)x) >> (__CLC_GENSIZE - n));
18     } else if (n == 0){
19         return x;
20     } else {
21         return ( (((__CLC_U_GENTYPE)x) >> -n) | (x << (__CLC_GENSIZE + n)) );
22     }
23 #else
24     //XXX: There's a lot of __builtin_astype calls to cast everything to
25     //     unsigned ... This should be improved so that if __CLC_GENTYPE==__CLC_U_GENTYPE, no
26     //     casts are required.
27     
28     __CLC_U_GENTYPE x_1 = __builtin_astype(x, __CLC_U_GENTYPE);
30     //XXX: Is (__CLC_U_GENTYPE >> S__CLC_GENTYPE) | (__CLC_U_GENTYPE << S__CLC_GENTYPE) legal?
31     //     If so, then combine the amt and shifts into a single set of statements
32     
33     __CLC_U_GENTYPE amt;
34     amt = (n < (__CLC_GENTYPE)0 ? __builtin_astype((__CLC_GENTYPE)0-n, __CLC_U_GENTYPE) : (__CLC_U_GENTYPE)0);
35     x_1 = (x_1 >> amt) | (x_1 << ((__CLC_U_GENTYPE)__CLC_GENSIZE - amt));
37     amt = (n < (__CLC_GENTYPE)0 ? (__CLC_U_GENTYPE)0 : __builtin_astype(n, __CLC_U_GENTYPE));
38     x_1 = (x_1 << amt) | (x_1 >> ((__CLC_U_GENTYPE)__CLC_GENSIZE - amt));
40     return __builtin_astype(x_1, __CLC_GENTYPE);
41 #endif