4138e37f01de77151fad60f572515a4d2fc3f0f3
[gcc.git] / gcc / testsuite / c-c++-common / pr44832.c
1 /* PR debug/44832 */
2 /* { dg-do compile } */
3 /* { dg-options "-O2 -fcompare-debug" } */
4
5 struct rtx_def;
6 typedef struct rtx_def *rtx;
7 typedef const struct rtx_def *const_rtx;
8 struct rtvec_def;
9 typedef struct rtvec_def *rtvec;
10 extern int ix86_isa_flags;
11
12 enum machine_mode
13 {
14 VOIDmode,
15 V8HImode,
16 V16QImode,
17 V4SImode,
18 V2DImode,
19 V32QImode,
20 MAX_MACHINE_MODE,
21
22 NUM_MACHINE_MODES = MAX_MACHINE_MODE
23 };
24 extern unsigned char mode_size[NUM_MACHINE_MODES];
25 extern const unsigned char mode_inner[NUM_MACHINE_MODES];
26 extern const unsigned char mode_nunits[NUM_MACHINE_MODES];
27 enum rtx_code {
28
29 CONST_INT ,
30
31 CONST_FIXED ,
32
33 CONST_DOUBLE
34
35 };
36 union rtunion_def
37 {
38 rtvec rt_rtvec;
39 };
40 typedef union rtunion_def rtunion;
41 struct rtx_def {
42
43 __extension__ enum rtx_code code: 16;
44
45 __extension__ enum machine_mode mode : 8;
46
47 union u {
48 rtunion fld[1];
49 } u;
50 };
51 struct rtvec_def {
52 rtx elem[1];
53 };
54 extern int rtx_equal_p (const_rtx, const_rtx);
55 extern rtx gen_reg_rtx (enum machine_mode);
56
57 extern void
58 ix86_expand_vector_init_concat (enum machine_mode mode,
59 rtx target, rtx *ops, int n);
60
61 static void
62 ix86_expand_vector_init_general (unsigned char mmx_ok, enum machine_mode mode,
63 rtx target, rtx vals)
64 {
65 rtx ops[32], op0, op1;
66 enum machine_mode half_mode = VOIDmode;
67 int n, i;
68
69 switch (mode)
70 {
71 case V4SImode:
72 case V2DImode:
73 n = mode_nunits[mode];
74 ix86_expand_vector_init_concat (mode, target, ops, n);
75 return;
76
77 case V32QImode:
78 goto half;
79 half:
80 {
81 typedef int eger;
82 if (mode != V4SImode)
83 ops[0] = 0;
84 }
85 n = mode_nunits[mode];
86 for (i = 0; i < n; i++)
87 ops[i] = (((((vals)->u.fld[0]).rt_rtvec))->elem[i]);
88 op0 = gen_reg_rtx (VOIDmode);
89 return;
90
91 case V16QImode:
92 if (!((ix86_isa_flags & (1 << 19)) != 0))
93 break;
94
95 case V8HImode:
96 if (!((ix86_isa_flags & (1 << 17)) != 0))
97 break;
98
99 n = mode_nunits[mode];
100 for (i = 0; i < n; i++)
101 ops[i] = (((((vals)->u.fld[0]).rt_rtvec))->elem[i]);
102 return;
103
104 default:
105 ;
106 }
107
108 {
109 int n_words;
110
111 n_words = ((unsigned short) mode_size[mode]) / 4;
112
113 if (n_words == 4)
114 ix86_expand_vector_init_general (0, V4SImode, 0, 0);
115 }
116 }
117
118
119 void
120 ix86_expand_vector_init (unsigned char mmx_ok, rtx target, rtx vals)
121 {
122 enum machine_mode mode = ((enum machine_mode) (target)->mode);
123 enum machine_mode inner_mode = ((enum machine_mode) mode_inner[mode]);
124 int n_elts = mode_nunits[mode];
125 int n_var = 0, one_var = -1;
126 unsigned char all_same = 1, all_const_zero = 1;
127 int i;
128 rtx x;
129
130 for (i = 0; i < n_elts; ++i)
131 {
132 x = (((((vals)->u.fld[0]).rt_rtvec))->elem[i]);
133 if (!((((enum rtx_code) (x)->code) == CONST_INT)
134 || ((enum rtx_code) (x)->code) == CONST_DOUBLE
135 || ((enum rtx_code) (x)->code) == CONST_FIXED))
136 n_var++, one_var = i;
137 else
138 all_const_zero = 0;
139 if (i > 0 && !rtx_equal_p (x, (((((vals)->u.fld[0]).rt_rtvec))->elem[0])))
140 all_same = 0;
141 }
142
143
144 if (n_var == 0)
145 {
146 return;
147 }
148
149 if (all_same)
150 return;
151
152 if (n_var == 1)
153 {
154 if (all_const_zero)
155 return;
156
157 }
158
159 ix86_expand_vector_init_general (mmx_ok, mode, target, vals);
160 }