OSDN Git Service

2007-04-24 Hui-May Chang <hm.chang@apple.com>
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.target / i386 / reload-1.c
1 /* { dg-do compile { target i?86-*-* } } */
2 /* { dg-options "-O3 -msse2 -fdump-rtl-csa" } */
3 /* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
4 /* { dg-final { scan-file-not reload-1.c.167r.csa "deleted 1 dead insns" } }*/
5 #include <emmintrin.h>
6 typedef __SIZE_TYPE__ size_t;
7 typedef float vFloat __attribute__ ((__vector_size__ (16)));
8 typedef double vDouble __attribute__ ((__vector_size__ (16)));
9 typedef struct buf
10 {
11   void *data;
12   unsigned long h;
13   unsigned long  w;
14   size_t bytes;
15 } buf;
16
17 typedef struct job
18 {
19   struct Job *next;
20   void * info;
21   long (*func)(struct Job *job);
22   long error;
23 } job;
24
25 typedef struct fj
26 {
27     job hd;
28     buf src;
29     buf dest;
30     float g;
31     unsigned int flags;
32 } fj;
33
34 static const double r[256], t[256];
35
36 long bar (const buf *src, const buf *dest, float g, unsigned int flags)
37 {
38   float *d0 = (float*) src->data;
39   float *d1 = (float*) dest->data;
40   uintptr_t w = dest->w;
41   uintptr_t idx;
42   vFloat p0;
43   static const vFloat m0;
44   static const vDouble p[3], m, b;
45   float *sr = d0;
46   float *dr = d1;
47   for( idx = 0; idx + 8 <= w; idx += 8 )
48   {
49     vFloat f0 = _mm_loadu_ps (sr);
50     vFloat f1 = _mm_loadu_ps (sr + 4);
51     sr += 8;
52     vFloat fa0 = _mm_andnot_ps (m0, f0);
53     vFloat fa1 = _mm_andnot_ps (m0, f1);
54     vDouble v0 = _mm_cvtps_pd (fa0);
55     vDouble v1 = _mm_cvtps_pd (_mm_movehl_ps (fa0, fa0));
56     vDouble v2 = _mm_cvtps_pd (fa1);
57     vDouble v3 = _mm_cvtps_pd (_mm_movehl_ps (fa1, fa1));
58     vDouble  vi0, vi1, vi2, vi3;
59     __m128i b0, b1, b2, b3;
60     b0 = _mm_packs_epi32 (_mm_packs_epi32 (b0, b1), _mm_packs_epi32 (b2, b3));
61     b1 = _mm_srli_epi64 (b0, 32);
62     unsigned int i0 = _mm_cvtsi128_si32 (b0); 
63     unsigned int i2 = _mm_cvtsi128_si32 (b1);
64     v0 -= _mm_loadh_pd (_mm_load_sd (r + (i0 & 0xff)), r + (i0 >> 16));
65     v1 -= _mm_loadh_pd (_mm_load_sd (r + (i2 & 0xff)), r + (i2 >> 16));
66     b0 = _mm_unpackhi_epi64 (b0, b0);
67     b1 = _mm_unpackhi_epi64 (b1, b1);
68     unsigned int i4 = _mm_cvtsi128_si32 (b0);
69     unsigned int i6 = _mm_cvtsi128_si32 (b1);
70     v2 -= _mm_loadh_pd (_mm_load_sd (r + (i4 & 0xff)), r + (i4 >> 16));
71     v3 -= _mm_loadh_pd (_mm_load_sd (r + (i6 & 0xff)), r + (i6 >> 16));
72     v0 = p[0] + (p[1] + p[2] * v0) * v0;
73     v1 = p[0] + (p[1] + p[2] * v1) * v1;
74     v2 = p[0] + (p[1] + p[2] * v2) * v2;
75     v3 = p[0] + (p[1] + p[2] * v3) * v3;
76     vi0 = (vDouble) _mm_slli_epi64 ((__m128i)((vi0 + b) + m), 52);
77     vi1 = (vDouble) _mm_slli_epi64 ((__m128i)((vi1 + b) + m), 52);
78     vi2 = (vDouble) _mm_slli_epi64 ((__m128i)((vi2 + b) + m), 52);
79     vi3 = (vDouble) _mm_slli_epi64 ((__m128i)((vi3 + b) + m), 52);
80     vi0 *= _mm_loadh_pd (_mm_load_sd (t + (i0 & 0xff)), t + (i0 >> 16));
81     vi1 *= _mm_loadh_pd (_mm_load_sd (t + (i2 & 0xff)), t + (i2 >> 16));
82     vi2 *= _mm_loadh_pd (_mm_load_sd (t + (i4 & 0xff)), t + (i4 >> 16));
83     vi3 *= _mm_loadh_pd (_mm_load_sd (t + (i6 & 0xff)), t + (i6 >> 16));
84     v0 *= vi0;
85     v1 *= vi1;
86     v2 *= vi2;
87     v3 *= vi3;
88     vFloat r0 = _mm_movelh_ps (_mm_cvtpd_ps( v0 ), _mm_cvtpd_ps (v1));
89     vFloat r1 = _mm_movelh_ps (_mm_cvtpd_ps( v2 ), _mm_cvtpd_ps (v3));
90     vFloat z0 = _mm_cmpeq_ps (f0, _mm_setzero_ps());
91     vFloat z1 = _mm_cmpeq_ps (f1, _mm_setzero_ps());
92     r0 = _mm_andnot_ps (z0, r0);
93     r1 = _mm_andnot_ps (z1, r1);
94     z0 = _mm_and_ps (z0, p0);
95     z1 = _mm_and_ps (z1, p0);
96     r0 = _mm_or_ps (r0, z0);
97     r1 = _mm_or_ps (r1, z1);
98     _mm_storeu_ps (dr, r0);
99     _mm_storeu_ps (dr + 4, r1);
100     dr += 8;
101   }
102   return 0;
103 }
104
105 long foo (job *j )
106 {
107   fj *jd = (fj*) j;
108   return bar (&jd->src, &jd->dest, jd->g, jd->flags);
109 }