aboutsummaryrefslogtreecommitdiff
path: root/test cases/common/139 simd/simd_mmx.c
blob: dd78dd6e980e5d64e276933a3fc48898c79fac65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include<simdconfig.h>
#include<simdfuncs.h>

#include<stdint.h>

#ifdef _MSC_VER
#include<intrin.h>
int mmx_available() {
  return 1;
}

/* Contrary to MSDN documentation, MMX intrinsics
 * just plain don't work.
 */
void increment_mmx(float arr[4]) {
  arr[0]++;
  arr[1]++;
  arr[2]++;
  arr[3]++;
}

#else
#include<mmintrin.h>
#include<cpuid.h>
int mmx_available() {
    return __builtin_cpu_supports("mmx");
}

void increment_mmx(float arr[4]) {
    /* Super ugly but we know that values in arr are always small
     * enough to fit in int16;
     */
    __m64 packed = _mm_set_pi16(arr[3], arr[2], arr[1], arr[0]);
    __m64 incr = _mm_set1_pi16(1);
    __m64 result = _mm_add_pi16(packed, incr);
    int64_t unpacker = _m_to_int64(result);
    _mm_empty();
    for(int i=0; i<4; i++) {
      arr[i] = (float)(unpacker & ((1<<16)-1));
        unpacker >>= 16;
    }
}

#endif