1#include <smmintrin.h> 2#include <math.h> 3 4#define NUM 64 5 6static void 7init_round (FP_T *src) 8{ 9 int i, sign = 1; 10 FP_T f = rand (); 11 12 for (i = 0; i < NUM; i++) 13 { 14 src[i] = (i + 1)* f * M_PI * sign; 15 if (i < (NUM / 2)) 16 { 17 if ((i % 6) == 0) 18 f = f * src[i]; 19 } 20 else if (i == (NUM / 2)) 21 f = rand (); 22 else if ((i % 6) == 0) 23 f = 1 / (f * (i + 1) * src[i] * M_PI *sign); 24 sign = -sign; 25 } 26} 27 28static FP_T 29do_round (FP_T f, int type) 30{ 31 short saved_cw, new_cw, clr_mask; 32 FP_T ret; 33 34 if ((type & 4)) 35 { 36 type = 0; 37 clr_mask = 0xFFFF; 38 } 39 else 40 { 41 type = 0x003F | ((type & 3) << 10); 42 clr_mask = ~0x0C3F; 43 } 44 45 __asm__ ("fld" ASM_SUFFIX " %0" : : "m" (*&f)); 46 47 __asm__ ("fstcw %0" : "=m" (*&saved_cw)); 48 new_cw = saved_cw & clr_mask; 49 new_cw |= type; 50 __asm__ ("fldcw %0" : : "m" (*&new_cw)); 51 52 __asm__ ("frndint\n" 53 "fstp" ASM_SUFFIX " %0\n" : "=m" (*&ret)); 54 __asm__ ("fldcw %0" : : "m" (*&saved_cw)); 55 return ret; 56} 57 58static void 59sse4_1_test (void) 60{ 61 int i; 62 FP_T f; 63 union 64 { 65 VEC_T x[NUM / LOOP_INCREMENT]; 66 FP_T f[NUM]; 67 } dst, src; 68 69 init_round (src.f); 70 71 for (i = 0; i < NUM / LOOP_INCREMENT; i++) 72 dst.x[i] = ROUND_INTRIN (src.x[i], ROUND_MODE); 73 74 for (i = 0; i < NUM; i += CHECK_LOOP_INCREMENT) 75 { 76 f = do_round (src.f[i], CHECK_ROUND_MODE); 77 if (f != dst.f[i]) 78 abort (); 79 } 80 81 if (_MM_FROUND_TO_NEAREST_INT != 0x00 82 || _MM_FROUND_TO_NEG_INF != 0x01 83 || _MM_FROUND_TO_POS_INF != 0x02 84 || _MM_FROUND_TO_ZERO != 0x03 85 || _MM_FROUND_CUR_DIRECTION != 0x04 86 || _MM_FROUND_RAISE_EXC != 0x00 87 || _MM_FROUND_NO_EXC != 0x08 88 || _MM_FROUND_NINT != 0x00 89 || _MM_FROUND_FLOOR != 0x01 90 || _MM_FROUND_CEIL != 0x02 91 || _MM_FROUND_TRUNC != 0x03 92 || _MM_FROUND_RINT != 0x04 93 || _MM_FROUND_NEARBYINT != 0x0C) 94 abort (); 95} 96