0
|
1 ;; IA-64 machine description for vector operations.
|
|
2 ;; Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
|
|
3 ;;
|
|
4 ;; This file is part of GCC.
|
|
5 ;;
|
|
6 ;; GCC is free software; you can redistribute it and/or modify
|
|
7 ;; it under the terms of the GNU General Public License as published by
|
|
8 ;; the Free Software Foundation; either version 3, or (at your option)
|
|
9 ;; any later version.
|
|
10 ;;
|
|
11 ;; GCC is distributed in the hope that it will be useful,
|
|
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 ;; GNU General Public License for more details.
|
|
15 ;;
|
|
16 ;; You should have received a copy of the GNU General Public License
|
|
17 ;; along with GCC; see the file COPYING3. If not see
|
|
18 ;; <http://www.gnu.org/licenses/>.
|
|
19
|
|
20
|
|
21 ;; Integer vector operations
|
|
22
|
|
23 (define_mode_iterator VECINT [V8QI V4HI V2SI])
|
|
24 (define_mode_iterator VECINT12 [V8QI V4HI])
|
|
25 (define_mode_iterator VECINT24 [V4HI V2SI])
|
|
26 (define_mode_attr vecsize [(V8QI "1") (V4HI "2") (V2SI "4")])
|
|
27
|
|
28 (define_expand "mov<mode>"
|
|
29 [(set (match_operand:VECINT 0 "general_operand" "")
|
|
30 (match_operand:VECINT 1 "general_operand" ""))]
|
|
31 ""
|
|
32 {
|
|
33 rtx op1 = ia64_expand_move (operands[0], operands[1]);
|
|
34 if (!op1)
|
|
35 DONE;
|
|
36 operands[1] = op1;
|
|
37 })
|
|
38
|
|
39 (define_insn "*mov<mode>_internal"
|
|
40 [(set (match_operand:VECINT 0 "destination_operand"
|
|
41 "=r,r,r,r,m ,*f ,*f,Q ,r ,*f")
|
|
42 (match_operand:VECINT 1 "move_operand"
|
|
43 "rU,W,i,m,rU,U*f,Q ,*f,*f,r "))]
|
|
44 "ia64_move_ok (operands[0], operands[1])"
|
|
45 "@
|
|
46 mov %0 = %r1
|
|
47 addl %0 = %v1, r0
|
|
48 movl %0 = %v1
|
|
49 ld8%O1 %0 = %1%P1
|
|
50 st8%Q0 %0 = %r1%P0
|
|
51 mov %0 = %F1
|
|
52 ldf8 %0 = %1%P1
|
|
53 stf8 %0 = %1%P0
|
|
54 getf.sig %0 = %1
|
|
55 setf.sig %0 = %1"
|
|
56 [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,fmisc,fld,stf,frfr,tofr")])
|
|
57
|
|
58 (define_insn "one_cmpl<mode>2"
|
|
59 [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
|
|
60 (not:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")))]
|
|
61 ""
|
|
62 "andcm %0 = -1, %1"
|
|
63 [(set_attr "itanium_class" "ilog")])
|
|
64
|
|
65 (define_insn "and<mode>3"
|
|
66 [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
|
|
67 (and:VECINT
|
|
68 (match_operand:VECINT 1 "grfr_register_operand" "r,*f")
|
|
69 (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
|
|
70 ""
|
|
71 "@
|
|
72 and %0 = %2, %1
|
|
73 fand %0 = %2, %1"
|
|
74 [(set_attr "itanium_class" "ilog,fmisc")])
|
|
75
|
|
76 (define_insn "*andnot<mode>"
|
|
77 [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
|
|
78 (and:VECINT
|
|
79 (not:VECINT (match_operand:VECINT 1 "grfr_register_operand" "r,*f"))
|
|
80 (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
|
|
81 ""
|
|
82 "@
|
|
83 andcm %0 = %2, %1
|
|
84 fandcm %0 = %2, %1"
|
|
85 [(set_attr "itanium_class" "ilog,fmisc")])
|
|
86
|
|
87 (define_insn "ior<mode>3"
|
|
88 [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
|
|
89 (ior:VECINT
|
|
90 (match_operand:VECINT 1 "grfr_register_operand" "r,*f")
|
|
91 (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
|
|
92 ""
|
|
93 "@
|
|
94 or %0 = %2, %1
|
|
95 for %0 = %2, %1"
|
|
96 [(set_attr "itanium_class" "ilog,fmisc")])
|
|
97
|
|
98 (define_insn "xor<mode>3"
|
|
99 [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
|
|
100 (xor:VECINT
|
|
101 (match_operand:VECINT 1 "grfr_register_operand" "r,*f")
|
|
102 (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
|
|
103 ""
|
|
104 "@
|
|
105 xor %0 = %2, %1
|
|
106 fxor %0 = %2, %1"
|
|
107 [(set_attr "itanium_class" "ilog,fmisc")])
|
|
108
|
|
109 (define_insn "neg<mode>2"
|
|
110 [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
|
|
111 (neg:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")))]
|
|
112 ""
|
|
113 "psub<vecsize> %0 = r0, %1"
|
|
114 [(set_attr "itanium_class" "mmalua")])
|
|
115
|
|
116 (define_insn "add<mode>3"
|
|
117 [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
|
|
118 (plus:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")
|
|
119 (match_operand:VECINT 2 "gr_register_operand" "r")))]
|
|
120 ""
|
|
121 "padd<vecsize> %0 = %1, %2"
|
|
122 [(set_attr "itanium_class" "mmalua")])
|
|
123
|
|
124 (define_insn "*ssadd<mode>3"
|
|
125 [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
|
|
126 (ss_plus:VECINT12
|
|
127 (match_operand:VECINT12 1 "gr_register_operand" "r")
|
|
128 (match_operand:VECINT12 2 "gr_register_operand" "r")))]
|
|
129 ""
|
|
130 "padd<vecsize>.sss %0 = %1, %2"
|
|
131 [(set_attr "itanium_class" "mmalua")])
|
|
132
|
|
133 (define_insn "*usadd<mode>3"
|
|
134 [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
|
|
135 (us_plus:VECINT12
|
|
136 (match_operand:VECINT12 1 "gr_register_operand" "r")
|
|
137 (match_operand:VECINT12 2 "gr_register_operand" "r")))]
|
|
138 ""
|
|
139 "padd<vecsize>.uuu %0 = %1, %2"
|
|
140 [(set_attr "itanium_class" "mmalua")])
|
|
141
|
|
142 (define_insn "sub<mode>3"
|
|
143 [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
|
|
144 (minus:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")
|
|
145 (match_operand:VECINT 2 "gr_register_operand" "r")))]
|
|
146 ""
|
|
147 "psub<vecsize> %0 = %1, %2"
|
|
148 [(set_attr "itanium_class" "mmalua")])
|
|
149
|
|
150 (define_insn "*sssub<mode>3"
|
|
151 [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
|
|
152 (ss_minus:VECINT12
|
|
153 (match_operand:VECINT12 1 "gr_register_operand" "r")
|
|
154 (match_operand:VECINT12 2 "gr_register_operand" "r")))]
|
|
155 ""
|
|
156 "psub<vecsize>.sss %0 = %1, %2"
|
|
157 [(set_attr "itanium_class" "mmalua")])
|
|
158
|
|
159 (define_insn "*ussub<mode>3"
|
|
160 [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
|
|
161 (us_minus:VECINT12
|
|
162 (match_operand:VECINT12 1 "gr_register_operand" "r")
|
|
163 (match_operand:VECINT12 2 "gr_register_operand" "r")))]
|
|
164 ""
|
|
165 "psub<vecsize>.uuu %0 = %1, %2"
|
|
166 [(set_attr "itanium_class" "mmalua")])
|
|
167
|
|
168 (define_expand "mulv8qi3"
|
|
169 [(set (match_operand:V8QI 0 "gr_register_operand" "")
|
|
170 (mult:V8QI (match_operand:V8QI 1 "gr_register_operand" "r")
|
|
171 (match_operand:V8QI 2 "gr_register_operand" "r")))]
|
|
172 ""
|
|
173 {
|
|
174 rtx r1, l1, r2, l2, rm, lm;
|
|
175
|
|
176 r1 = gen_reg_rtx (V4HImode);
|
|
177 l1 = gen_reg_rtx (V4HImode);
|
|
178 r2 = gen_reg_rtx (V4HImode);
|
|
179 l2 = gen_reg_rtx (V4HImode);
|
|
180
|
|
181 /* Zero-extend the QImode elements into two words of HImode elements
|
|
182 by interleaving them with zero bytes. */
|
|
183 emit_insn (gen_mix1_r (gen_lowpart (V8QImode, r1),
|
|
184 operands[1], CONST0_RTX (V8QImode)));
|
|
185 emit_insn (gen_mix1_r (gen_lowpart (V8QImode, r2),
|
|
186 operands[2], CONST0_RTX (V8QImode)));
|
|
187 emit_insn (gen_mix1_l (gen_lowpart (V8QImode, l1),
|
|
188 operands[1], CONST0_RTX (V8QImode)));
|
|
189 emit_insn (gen_mix1_l (gen_lowpart (V8QImode, l2),
|
|
190 operands[2], CONST0_RTX (V8QImode)));
|
|
191
|
|
192 /* Multiply. */
|
|
193 rm = gen_reg_rtx (V4HImode);
|
|
194 lm = gen_reg_rtx (V4HImode);
|
|
195 emit_insn (gen_mulv4hi3 (rm, r1, r2));
|
|
196 emit_insn (gen_mulv4hi3 (lm, l1, l2));
|
|
197
|
|
198 /* Zap the high order bytes of the HImode elements by overwriting those
|
|
199 in one part with the low order bytes of the other. */
|
|
200 emit_insn (gen_mix1_r (operands[0],
|
|
201 gen_lowpart (V8QImode, rm),
|
|
202 gen_lowpart (V8QImode, lm)));
|
|
203 DONE;
|
|
204 })
|
|
205
|
|
206 (define_insn "mulv4hi3"
|
|
207 [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
|
|
208 (mult:V4HI (match_operand:V4HI 1 "gr_register_operand" "r")
|
|
209 (match_operand:V4HI 2 "gr_register_operand" "r")))]
|
|
210 ""
|
|
211 "pmpyshr2 %0 = %1, %2, 0"
|
|
212 [(set_attr "itanium_class" "mmmul")])
|
|
213
|
|
214 (define_insn "pmpy2_r"
|
|
215 [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
|
|
216 (mult:V2SI
|
|
217 (vec_select:V2SI
|
|
218 (sign_extend:V4SI
|
|
219 (match_operand:V4HI 1 "gr_register_operand" "r"))
|
|
220 (parallel [(const_int 0) (const_int 2)]))
|
|
221 (vec_select:V2SI
|
|
222 (sign_extend:V4SI
|
|
223 (match_operand:V4HI 2 "gr_register_operand" "r"))
|
|
224 (parallel [(const_int 0) (const_int 2)]))))]
|
|
225 ""
|
|
226 "pmpy2.r %0 = %1, %2"
|
|
227 [(set_attr "itanium_class" "mmshf")])
|
|
228
|
|
229 (define_insn "pmpy2_l"
|
|
230 [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
|
|
231 (mult:V2SI
|
|
232 (vec_select:V2SI
|
|
233 (sign_extend:V4SI
|
|
234 (match_operand:V4HI 1 "gr_register_operand" "r"))
|
|
235 (parallel [(const_int 1) (const_int 3)]))
|
|
236 (vec_select:V2SI
|
|
237 (sign_extend:V4SI
|
|
238 (match_operand:V4HI 2 "gr_register_operand" "r"))
|
|
239 (parallel [(const_int 1) (const_int 3)]))))]
|
|
240 ""
|
|
241 "pmpy2.l %0 = %1, %2"
|
|
242 [(set_attr "itanium_class" "mmshf")])
|
|
243
|
|
244 (define_expand "umax<mode>3"
|
|
245 [(set (match_operand:VECINT 0 "gr_register_operand" "")
|
|
246 (umax:VECINT (match_operand:VECINT 1 "gr_register_operand" "")
|
|
247 (match_operand:VECINT 2 "gr_register_operand" "")))]
|
|
248 ""
|
|
249 {
|
|
250 if (ia64_expand_vecint_minmax (UMAX, <MODE>mode, operands))
|
|
251 DONE;
|
|
252 })
|
|
253
|
|
254 (define_expand "smax<mode>3"
|
|
255 [(set (match_operand:VECINT 0 "gr_register_operand" "")
|
|
256 (smax:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
|
|
257 (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
|
|
258 ""
|
|
259 {
|
|
260 if (ia64_expand_vecint_minmax (SMAX, <MODE>mode, operands))
|
|
261 DONE;
|
|
262 })
|
|
263
|
|
264 (define_expand "umin<mode>3"
|
|
265 [(set (match_operand:VECINT 0 "gr_register_operand" "")
|
|
266 (umin:VECINT (match_operand:VECINT 1 "gr_register_operand" "")
|
|
267 (match_operand:VECINT 2 "gr_register_operand" "")))]
|
|
268 ""
|
|
269 {
|
|
270 if (ia64_expand_vecint_minmax (UMIN, <MODE>mode, operands))
|
|
271 DONE;
|
|
272 })
|
|
273
|
|
274 (define_expand "smin<mode>3"
|
|
275 [(set (match_operand:VECINT 0 "gr_register_operand" "")
|
|
276 (smin:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
|
|
277 (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
|
|
278 ""
|
|
279 {
|
|
280 if (ia64_expand_vecint_minmax (SMIN, <MODE>mode, operands))
|
|
281 DONE;
|
|
282 })
|
|
283
|
|
284 (define_insn "*umaxv8qi3"
|
|
285 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
286 (umax:V8QI (match_operand:V8QI 1 "gr_register_operand" "r")
|
|
287 (match_operand:V8QI 2 "gr_register_operand" "r")))]
|
|
288 ""
|
|
289 "pmax1.u %0 = %1, %2"
|
|
290 [(set_attr "itanium_class" "mmshf")])
|
|
291
|
|
292 (define_insn "*smaxv4hi3"
|
|
293 [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
|
|
294 (smax:V4HI (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
|
|
295 (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU")))]
|
|
296 ""
|
|
297 "pmax2 %0 = %r1, %r2"
|
|
298 [(set_attr "itanium_class" "mmshf")])
|
|
299
|
|
300 (define_insn "*uminv8qi3"
|
|
301 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
302 (umin:V8QI (match_operand:V8QI 1 "gr_register_operand" "r")
|
|
303 (match_operand:V8QI 2 "gr_register_operand" "r")))]
|
|
304 ""
|
|
305 "pmin1.u %0 = %1, %2"
|
|
306 [(set_attr "itanium_class" "mmshf")])
|
|
307
|
|
308 (define_insn "*sminv4hi3"
|
|
309 [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
|
|
310 (smin:V4HI (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
|
|
311 (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU")))]
|
|
312 ""
|
|
313 "pmin2 %0 = %r1, %r2"
|
|
314 [(set_attr "itanium_class" "mmshf")])
|
|
315
|
|
316 (define_insn "ashl<mode>3"
|
|
317 [(set (match_operand:VECINT24 0 "gr_register_operand" "=r")
|
|
318 (ashift:VECINT24
|
|
319 (match_operand:VECINT24 1 "gr_register_operand" "r")
|
|
320 (match_operand:DI 2 "gr_reg_or_5bit_operand" "rn")))]
|
|
321 ""
|
|
322 "pshl<vecsize> %0 = %1, %2"
|
|
323 [(set_attr "itanium_class" "mmshf")])
|
|
324
|
|
325 (define_insn "ashr<mode>3"
|
|
326 [(set (match_operand:VECINT24 0 "gr_register_operand" "=r")
|
|
327 (ashiftrt:VECINT24
|
|
328 (match_operand:VECINT24 1 "gr_register_operand" "r")
|
|
329 (match_operand:DI 2 "gr_reg_or_5bit_operand" "rn")))]
|
|
330 ""
|
|
331 "pshr<vecsize> %0 = %1, %2"
|
|
332 [(set_attr "itanium_class" "mmshf")])
|
|
333
|
|
334 (define_insn "lshr<mode>3"
|
|
335 [(set (match_operand:VECINT24 0 "gr_register_operand" "=r")
|
|
336 (lshiftrt:VECINT24
|
|
337 (match_operand:VECINT24 1 "gr_register_operand" "r")
|
|
338 (match_operand:DI 2 "gr_reg_or_5bit_operand" "rn")))]
|
|
339 ""
|
|
340 "pshr<vecsize>.u %0 = %1, %2"
|
|
341 [(set_attr "itanium_class" "mmshf")])
|
|
342
|
|
343 (define_expand "vec_shl_<mode>"
|
|
344 [(set (match_operand:VECINT 0 "gr_register_operand" "")
|
|
345 (ashift:DI (match_operand:VECINT 1 "gr_register_operand" "")
|
|
346 (match_operand:DI 2 "gr_reg_or_6bit_operand" "")))]
|
|
347 ""
|
|
348 {
|
|
349 operands[0] = gen_lowpart (DImode, operands[0]);
|
|
350 operands[1] = gen_lowpart (DImode, operands[1]);
|
|
351 })
|
|
352
|
|
353 (define_expand "vec_shr_<mode>"
|
|
354 [(set (match_operand:VECINT 0 "gr_register_operand" "")
|
|
355 (lshiftrt:DI (match_operand:VECINT 1 "gr_register_operand" "")
|
|
356 (match_operand:DI 2 "gr_reg_or_6bit_operand" "")))]
|
|
357 ""
|
|
358 {
|
|
359 operands[0] = gen_lowpart (DImode, operands[0]);
|
|
360 operands[1] = gen_lowpart (DImode, operands[1]);
|
|
361 })
|
|
362
|
|
363 (define_expand "widen_usumv8qi3"
|
|
364 [(match_operand:V4HI 0 "gr_register_operand" "")
|
|
365 (match_operand:V8QI 1 "gr_register_operand" "")
|
|
366 (match_operand:V4HI 2 "gr_register_operand" "")]
|
|
367 ""
|
|
368 {
|
|
369 ia64_expand_widen_sum (operands, true);
|
|
370 DONE;
|
|
371 })
|
|
372
|
|
373 (define_expand "widen_usumv4hi3"
|
|
374 [(match_operand:V2SI 0 "gr_register_operand" "")
|
|
375 (match_operand:V4HI 1 "gr_register_operand" "")
|
|
376 (match_operand:V2SI 2 "gr_register_operand" "")]
|
|
377 ""
|
|
378 {
|
|
379 ia64_expand_widen_sum (operands, true);
|
|
380 DONE;
|
|
381 })
|
|
382
|
|
383 (define_expand "widen_ssumv8qi3"
|
|
384 [(match_operand:V4HI 0 "gr_register_operand" "")
|
|
385 (match_operand:V8QI 1 "gr_register_operand" "")
|
|
386 (match_operand:V4HI 2 "gr_register_operand" "")]
|
|
387 ""
|
|
388 {
|
|
389 ia64_expand_widen_sum (operands, false);
|
|
390 DONE;
|
|
391 })
|
|
392
|
|
393 (define_expand "widen_ssumv4hi3"
|
|
394 [(match_operand:V2SI 0 "gr_register_operand" "")
|
|
395 (match_operand:V4HI 1 "gr_register_operand" "")
|
|
396 (match_operand:V2SI 2 "gr_register_operand" "")]
|
|
397 ""
|
|
398 {
|
|
399 ia64_expand_widen_sum (operands, false);
|
|
400 DONE;
|
|
401 })
|
|
402
|
|
403 (define_expand "udot_prodv8qi"
|
|
404 [(match_operand:V2SI 0 "gr_register_operand" "")
|
|
405 (match_operand:V8QI 1 "gr_register_operand" "")
|
|
406 (match_operand:V8QI 2 "gr_register_operand" "")
|
|
407 (match_operand:V2SI 3 "gr_register_operand" "")]
|
|
408 ""
|
|
409 {
|
|
410 ia64_expand_dot_prod_v8qi (operands, true);
|
|
411 DONE;
|
|
412 })
|
|
413
|
|
414 (define_expand "sdot_prodv8qi"
|
|
415 [(match_operand:V2SI 0 "gr_register_operand" "")
|
|
416 (match_operand:V8QI 1 "gr_register_operand" "")
|
|
417 (match_operand:V8QI 2 "gr_register_operand" "")
|
|
418 (match_operand:V2SI 3 "gr_register_operand" "")]
|
|
419 ""
|
|
420 {
|
|
421 ia64_expand_dot_prod_v8qi (operands, false);
|
|
422 DONE;
|
|
423 })
|
|
424
|
|
425 (define_expand "sdot_prodv4hi"
|
|
426 [(match_operand:V2SI 0 "gr_register_operand" "")
|
|
427 (match_operand:V4HI 1 "gr_register_operand" "")
|
|
428 (match_operand:V4HI 2 "gr_register_operand" "")
|
|
429 (match_operand:V2SI 3 "gr_register_operand" "")]
|
|
430 ""
|
|
431 {
|
|
432 rtx l, r, t;
|
|
433
|
|
434 r = gen_reg_rtx (V2SImode);
|
|
435 l = gen_reg_rtx (V2SImode);
|
|
436 t = gen_reg_rtx (V2SImode);
|
|
437
|
|
438 emit_insn (gen_pmpy2_r (r, operands[1], operands[2]));
|
|
439 emit_insn (gen_pmpy2_l (l, operands[1], operands[2]));
|
|
440 emit_insn (gen_addv2si3 (t, r, operands[3]));
|
|
441 emit_insn (gen_addv2si3 (operands[0], t, l));
|
|
442 DONE;
|
|
443 })
|
|
444
|
|
445 (define_expand "vcond<mode>"
|
|
446 [(set (match_operand:VECINT 0 "gr_register_operand" "")
|
|
447 (if_then_else:VECINT
|
|
448 (match_operator 3 ""
|
|
449 [(match_operand:VECINT 4 "gr_reg_or_0_operand" "")
|
|
450 (match_operand:VECINT 5 "gr_reg_or_0_operand" "")])
|
|
451 (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
|
|
452 (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
|
|
453 ""
|
|
454 {
|
|
455 ia64_expand_vecint_cmov (operands);
|
|
456 DONE;
|
|
457 })
|
|
458
|
|
459 (define_expand "vcondu<mode>"
|
|
460 [(set (match_operand:VECINT 0 "gr_register_operand" "")
|
|
461 (if_then_else:VECINT
|
|
462 (match_operator 3 ""
|
|
463 [(match_operand:VECINT 4 "gr_reg_or_0_operand" "")
|
|
464 (match_operand:VECINT 5 "gr_reg_or_0_operand" "")])
|
|
465 (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
|
|
466 (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
|
|
467 ""
|
|
468 {
|
|
469 ia64_expand_vecint_cmov (operands);
|
|
470 DONE;
|
|
471 })
|
|
472
|
|
473 (define_insn "*cmpeq_<mode>"
|
|
474 [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
|
|
475 (eq:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "rU")
|
|
476 (match_operand:VECINT 2 "gr_reg_or_0_operand" "rU")))]
|
|
477 ""
|
|
478 "pcmp<vecsize>.eq %0 = %r1, %r2"
|
|
479 [(set_attr "itanium_class" "mmalua")])
|
|
480
|
|
481 (define_insn "*cmpgt_<mode>"
|
|
482 [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
|
|
483 (gt:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "rU")
|
|
484 (match_operand:VECINT 2 "gr_reg_or_0_operand" "rU")))]
|
|
485 ""
|
|
486 "pcmp<vecsize>.gt %0 = %r1, %r2"
|
|
487 [(set_attr "itanium_class" "mmalua")])
|
|
488
|
|
489 (define_insn "pack2_sss"
|
|
490 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
491 (vec_concat:V8QI
|
|
492 (ss_truncate:V4QI
|
|
493 (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU"))
|
|
494 (ss_truncate:V4QI
|
|
495 (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))))]
|
|
496 ""
|
|
497 "pack2.sss %0 = %r1, %r2"
|
|
498 [(set_attr "itanium_class" "mmshf")])
|
|
499
|
|
500 (define_insn "*pack2_uss"
|
|
501 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
502 (vec_concat:V8QI
|
|
503 (us_truncate:V4QI
|
|
504 (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU"))
|
|
505 (us_truncate:V4QI
|
|
506 (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))))]
|
|
507 ""
|
|
508 "pack2.uss %0 = %r1, %r2"
|
|
509 [(set_attr "itanium_class" "mmshf")])
|
|
510
|
|
511 (define_insn "pack4_sss"
|
|
512 [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
|
|
513 (vec_concat:V4HI
|
|
514 (ss_truncate:V2HI
|
|
515 (match_operand:V2SI 1 "gr_reg_or_0_operand" "rU"))
|
|
516 (ss_truncate:V2HI
|
|
517 (match_operand:V2SI 2 "gr_reg_or_0_operand" "rU"))))]
|
|
518 ""
|
|
519 "pack4.sss %0 = %r1, %r2"
|
|
520 [(set_attr "itanium_class" "mmshf")])
|
|
521
|
|
522 (define_insn "unpack1_l"
|
|
523 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
524 (vec_select:V8QI
|
|
525 (vec_concat:V16QI
|
|
526 (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
|
|
527 (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
|
|
528 (parallel [(const_int 0)
|
|
529 (const_int 1)
|
|
530 (const_int 2)
|
|
531 (const_int 3)
|
|
532 (const_int 8)
|
|
533 (const_int 9)
|
|
534 (const_int 10)
|
|
535 (const_int 11)])))]
|
|
536 ""
|
|
537 "unpack1.l %0 = %r2, %r1"
|
|
538 [(set_attr "itanium_class" "mmshf")])
|
|
539
|
|
540 (define_insn "unpack1_h"
|
|
541 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
542 (vec_select:V8QI
|
|
543 (vec_concat:V16QI
|
|
544 (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
|
|
545 (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
|
|
546 (parallel [(const_int 4)
|
|
547 (const_int 5)
|
|
548 (const_int 6)
|
|
549 (const_int 7)
|
|
550 (const_int 12)
|
|
551 (const_int 13)
|
|
552 (const_int 14)
|
|
553 (const_int 15)])))]
|
|
554 ""
|
|
555 "unpack1.h %0 = %r2, %r1"
|
|
556 [(set_attr "itanium_class" "mmshf")])
|
|
557
|
|
558 (define_insn "mix1_r"
|
|
559 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
560 (vec_select:V8QI
|
|
561 (vec_concat:V16QI
|
|
562 (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
|
|
563 (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
|
|
564 (parallel [(const_int 0)
|
|
565 (const_int 8)
|
|
566 (const_int 2)
|
|
567 (const_int 10)
|
|
568 (const_int 4)
|
|
569 (const_int 12)
|
|
570 (const_int 6)
|
|
571 (const_int 14)])))]
|
|
572 ""
|
|
573 "mix1.r %0 = %r2, %r1"
|
|
574 [(set_attr "itanium_class" "mmshf")])
|
|
575
|
|
576 (define_insn "mix1_l"
|
|
577 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
578 (vec_select:V8QI
|
|
579 (vec_concat:V16QI
|
|
580 (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
|
|
581 (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
|
|
582 (parallel [(const_int 1)
|
|
583 (const_int 9)
|
|
584 (const_int 3)
|
|
585 (const_int 11)
|
|
586 (const_int 5)
|
|
587 (const_int 13)
|
|
588 (const_int 7)
|
|
589 (const_int 15)])))]
|
|
590 ""
|
|
591 "mix1.l %0 = %r2, %r1"
|
|
592 [(set_attr "itanium_class" "mmshf")])
|
|
593
|
|
594 (define_insn "*mux1_rev"
|
|
595 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
596 (vec_select:V8QI
|
|
597 (match_operand:V8QI 1 "gr_register_operand" "r")
|
|
598 (parallel [(const_int 7)
|
|
599 (const_int 6)
|
|
600 (const_int 5)
|
|
601 (const_int 4)
|
|
602 (const_int 3)
|
|
603 (const_int 2)
|
|
604 (const_int 1)
|
|
605 (const_int 0)])))]
|
|
606 ""
|
|
607 "mux1 %0 = %1, @rev"
|
|
608 [(set_attr "itanium_class" "mmshf")])
|
|
609
|
|
610 (define_insn "*mux1_mix"
|
|
611 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
612 (vec_select:V8QI
|
|
613 (match_operand:V8QI 1 "gr_register_operand" "r")
|
|
614 (parallel [(const_int 0)
|
|
615 (const_int 4)
|
|
616 (const_int 2)
|
|
617 (const_int 6)
|
|
618 (const_int 1)
|
|
619 (const_int 5)
|
|
620 (const_int 3)
|
|
621 (const_int 7)])))]
|
|
622 ""
|
|
623 "mux1 %0 = %1, @mix"
|
|
624 [(set_attr "itanium_class" "mmshf")])
|
|
625
|
|
626 (define_insn "*mux1_shuf"
|
|
627 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
628 (vec_select:V8QI
|
|
629 (match_operand:V8QI 1 "gr_register_operand" "r")
|
|
630 (parallel [(const_int 0)
|
|
631 (const_int 4)
|
|
632 (const_int 1)
|
|
633 (const_int 5)
|
|
634 (const_int 2)
|
|
635 (const_int 6)
|
|
636 (const_int 3)
|
|
637 (const_int 7)])))]
|
|
638 ""
|
|
639 "mux1 %0 = %1, @shuf"
|
|
640 [(set_attr "itanium_class" "mmshf")])
|
|
641
|
|
642 (define_insn "*mux1_alt"
|
|
643 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
644 (vec_select:V8QI
|
|
645 (match_operand:V8QI 1 "gr_register_operand" "r")
|
|
646 (parallel [(const_int 0)
|
|
647 (const_int 2)
|
|
648 (const_int 4)
|
|
649 (const_int 6)
|
|
650 (const_int 1)
|
|
651 (const_int 3)
|
|
652 (const_int 5)
|
|
653 (const_int 7)])))]
|
|
654 ""
|
|
655 "mux1 %0 = %1, @alt"
|
|
656 [(set_attr "itanium_class" "mmshf")])
|
|
657
|
|
658 (define_insn "*mux1_brcst_v8qi"
|
|
659 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
660 (vec_select:V8QI
|
|
661 (match_operand:V8QI 1 "gr_register_operand" "r")
|
|
662 (parallel [(const_int 0)
|
|
663 (const_int 0)
|
|
664 (const_int 0)
|
|
665 (const_int 0)
|
|
666 (const_int 0)
|
|
667 (const_int 0)
|
|
668 (const_int 0)
|
|
669 (const_int 0)])))]
|
|
670 ""
|
|
671 "mux1 %0 = %1, @brcst"
|
|
672 [(set_attr "itanium_class" "mmshf")])
|
|
673
|
|
674 (define_insn "*mux1_brcst_qi"
|
|
675 [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
|
|
676 (vec_duplicate:V8QI
|
|
677 (match_operand:QI 1 "gr_register_operand" "r")))]
|
|
678 ""
|
|
679 "mux1 %0 = %1, @brcst"
|
|
680 [(set_attr "itanium_class" "mmshf")])
|
|
681
|
|
682 (define_insn "unpack2_l"
|
|
683 [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
|
|
684 (vec_select:V4HI
|
|
685 (vec_concat:V8HI
|
|
686 (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
|
|
687 (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
|
|
688 (parallel [(const_int 0)
|
|
689 (const_int 4)
|
|
690 (const_int 1)
|
|
691 (const_int 5)])))]
|
|
692 ""
|
|
693 "unpack2.l %0 = %r2, %r1"
|
|
694 [(set_attr "itanium_class" "mmshf")])
|
|
695
|
|
696 (define_insn "unpack2_h"
|
|
697 [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
|
|
698 (vec_select:V4HI
|
|
699 (vec_concat:V8HI
|
|
700 (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
|
|
701 (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
|
|
702 (parallel [(const_int 2)
|
|
703 (const_int 6)
|
|
704 (const_int 3)
|
|
705 (const_int 7)])))]
|
|
706 ""
|
|
707 "unpack2.h %0 = %r2, %r1"
|
|
708 [(set_attr "itanium_class" "mmshf")])
|
|
709
|
|
710 (define_insn "*mix2_r"
|
|
711 [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
|
|
712 (vec_select:V4HI
|
|
713 (vec_concat:V8HI
|
|
714 (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
|
|
715 (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
|
|
716 (parallel [(const_int 0)
|
|
717 (const_int 4)
|
|
718 (const_int 2)
|
|
719 (const_int 6)])))]
|
|
720 ""
|
|
721 "mix2.r %0 = %r2, %r1"
|
|
722 [(set_attr "itanium_class" "mmshf")])
|
|
723
|
|
724 (define_insn "*mix2_l"
|
|
725 [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
|
|
726 (vec_select:V4HI
|
|
727 (vec_concat:V8HI
|
|
728 (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
|
|
729 (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
|
|
730 (parallel [(const_int 1)
|
|
731 (const_int 5)
|
|
732 (const_int 3)
|
|
733 (const_int 7)])))]
|
|
734 ""
|
|
735 "mix2.l %0 = %r2, %r1"
|
|
736 [(set_attr "itanium_class" "mmshf")])
|
|
737
|
|
738 (define_insn "*mux2"
|
|
739 [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
|
|
740 (vec_select:V4HI
|
|
741 (match_operand:V4HI 1 "gr_register_operand" "r")
|
|
742 (parallel [(match_operand 2 "const_int_2bit_operand" "")
|
|
743 (match_operand 3 "const_int_2bit_operand" "")
|
|
744 (match_operand 4 "const_int_2bit_operand" "")
|
|
745 (match_operand 5 "const_int_2bit_operand" "")])))]
|
|
746 ""
|
|
747 {
|
|
748 int mask;
|
|
749 mask = INTVAL (operands[2]);
|
|
750 mask |= INTVAL (operands[3]) << 2;
|
|
751 mask |= INTVAL (operands[4]) << 4;
|
|
752 mask |= INTVAL (operands[5]) << 6;
|
|
753 operands[2] = GEN_INT (mask);
|
|
754 return "%,mux2 %0 = %1, %2";
|
|
755 }
|
|
756 [(set_attr "itanium_class" "mmshf")])
|
|
757
|
|
758 (define_insn "*mux2_brcst_hi"
|
|
759 [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
|
|
760 (vec_duplicate:V4HI
|
|
761 (match_operand:HI 1 "gr_register_operand" "r")))]
|
|
762 ""
|
|
763 "mux2 %0 = %1, 0"
|
|
764 [(set_attr "itanium_class" "mmshf")])
|
|
765
|
|
766 ;; Note that mix4.r performs the exact same operation.
|
|
767 (define_insn "*unpack4_l"
|
|
768 [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
|
|
769 (vec_select:V2SI
|
|
770 (vec_concat:V4SI
|
|
771 (match_operand:V2SI 1 "gr_reg_or_0_operand" "rU")
|
|
772 (match_operand:V2SI 2 "gr_reg_or_0_operand" "rU"))
|
|
773 (parallel [(const_int 0)
|
|
774 (const_int 2)])))]
|
|
775 ""
|
|
776 "unpack4.l %0 = %r2, %r1"
|
|
777 [(set_attr "itanium_class" "mmshf")])
|
|
778
|
|
779 ;; Note that mix4.l performs the exact same operation.
|
|
780 (define_insn "*unpack4_h"
|
|
781 [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
|
|
782 (vec_select:V2SI
|
|
783 (vec_concat:V4SI
|
|
784 (match_operand:V2SI 1 "gr_reg_or_0_operand" "rU")
|
|
785 (match_operand:V2SI 2 "gr_reg_or_0_operand" "rU"))
|
|
786 (parallel [(const_int 1)
|
|
787 (const_int 3)])))]
|
|
788 ""
|
|
789 "unpack4.h %0 = %r2, %r1"
|
|
790 [(set_attr "itanium_class" "mmshf")])
|
|
791
|
|
792 (define_expand "vec_initv2si"
|
|
793 [(match_operand:V2SI 0 "gr_register_operand" "")
|
|
794 (match_operand 1 "" "")]
|
|
795 ""
|
|
796 {
|
|
797 rtx op1 = XVECEXP (operands[1], 0, 0);
|
|
798 rtx op2 = XVECEXP (operands[1], 0, 1);
|
|
799 rtx x;
|
|
800
|
|
801 if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
|
|
802 {
|
|
803 x = gen_rtx_CONST_VECTOR (V2SImode, XVEC (operands[1], 0));
|
|
804 emit_move_insn (operands[0], x);
|
|
805 DONE;
|
|
806 }
|
|
807
|
|
808 if (!gr_reg_or_0_operand (op1, SImode))
|
|
809 op1 = force_reg (SImode, op1);
|
|
810 if (!gr_reg_or_0_operand (op2, SImode))
|
|
811 op2 = force_reg (SImode, op2);
|
|
812
|
|
813 if (TARGET_BIG_ENDIAN)
|
|
814 x = gen_rtx_VEC_CONCAT (V2SImode, op2, op1);
|
|
815 else
|
|
816 x = gen_rtx_VEC_CONCAT (V2SImode, op1, op2);
|
|
817 emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
|
|
818 DONE;
|
|
819 })
|
|
820
|
|
821 (define_insn "*vecinit_v2si"
|
|
822 [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
|
|
823 (vec_concat:V2SI
|
|
824 (match_operand:SI 1 "gr_reg_or_0_operand" "rO")
|
|
825 (match_operand:SI 2 "gr_reg_or_0_operand" "rO")))]
|
|
826 ""
|
|
827 "unpack4.l %0 = %r2, %r1"
|
|
828 [(set_attr "itanium_class" "mmshf")])
|
|
829
|
|
830 ;; Missing operations
|
|
831 ;; padd.uus
|
|
832 ;; pavg
|
|
833 ;; pavgsub
|
|
834 ;; pmpyshr, general form
|
|
835 ;; psad
|
|
836 ;; pshladd
|
|
837 ;; pshradd
|
|
838 ;; psub.uus
|
|
839
|
|
840 ;; Floating point vector operations
|
|
841
|
|
842 (define_expand "movv2sf"
|
|
843 [(set (match_operand:V2SF 0 "general_operand" "")
|
|
844 (match_operand:V2SF 1 "general_operand" ""))]
|
|
845 ""
|
|
846 {
|
|
847 rtx op1 = ia64_expand_move (operands[0], operands[1]);
|
|
848 if (!op1)
|
|
849 DONE;
|
|
850 operands[1] = op1;
|
|
851 })
|
|
852
|
|
853 (define_insn "*movv2sf_internal"
|
|
854 [(set (match_operand:V2SF 0 "destination_operand"
|
|
855 "=f,f,f,Q,*r ,*r,*r,*r,m ,f ,*r")
|
|
856 (match_operand:V2SF 1 "move_operand"
|
|
857 "fU,Y,Q,f,U*r,W ,i ,m ,*r,*r,f "))]
|
|
858 "ia64_move_ok (operands[0], operands[1])"
|
|
859 {
|
|
860 static const char * const alt[] = {
|
|
861 "%,mov %0 = %F1",
|
|
862 "%,fpack %0 = %F2, %F1",
|
|
863 "%,ldf8 %0 = %1%P1",
|
|
864 "%,stf8 %0 = %1%P0",
|
|
865 "%,mov %0 = %r1",
|
|
866 "%,addl %0 = %v1, r0",
|
|
867 "%,movl %0 = %v1",
|
|
868 "%,ld8%O1 %0 = %1%P1",
|
|
869 "%,st8%Q0 %0 = %r1%P0",
|
|
870 "%,setf.sig %0 = %1",
|
|
871 "%,getf.sig %0 = %1"
|
|
872 };
|
|
873
|
|
874 if (which_alternative == 1)
|
|
875 {
|
|
876 operands[2] = XVECEXP (operands[1], 0, 1);
|
|
877 operands[1] = XVECEXP (operands[1], 0, 0);
|
|
878 }
|
|
879
|
|
880 return alt[which_alternative];
|
|
881 }
|
|
882 [(set_attr "itanium_class" "fmisc,fmisc,fld,stf,ialu,ialu,long_i,ld,st,tofr,frfr")])
|
|
883
|
|
884 (define_insn "absv2sf2"
|
|
885 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
886 (abs:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")))]
|
|
887 ""
|
|
888 "fpabs %0 = %1"
|
|
889 [(set_attr "itanium_class" "fmisc")])
|
|
890
|
|
891 (define_insn "negv2sf2"
|
|
892 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
893 (neg:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")))]
|
|
894 ""
|
|
895 "fpneg %0 = %1"
|
|
896 [(set_attr "itanium_class" "fmisc")])
|
|
897
|
|
898 (define_insn "*negabsv2sf2"
|
|
899 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
900 (neg:V2SF
|
|
901 (abs:V2SF (match_operand:V2SF 1 "fr_register_operand" "f"))))]
|
|
902 ""
|
|
903 "fpnegabs %0 = %1"
|
|
904 [(set_attr "itanium_class" "fmisc")])
|
|
905
|
|
906 ;; In order to convince combine to merge plus and mult to a useful fpma,
|
|
907 ;; we need a couple of extra patterns.
|
|
908 (define_expand "addv2sf3"
|
|
909 [(parallel
|
|
910 [(set (match_operand:V2SF 0 "fr_register_operand" "")
|
|
911 (plus:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
|
|
912 (match_operand:V2SF 2 "fr_register_operand" "")))
|
|
913 (use (match_dup 3))])]
|
|
914 ""
|
|
915 {
|
|
916 rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
|
|
917 operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
|
|
918 })
|
|
919
|
|
920 ;; The split condition here could be combine_completed, if we had such.
|
|
921 (define_insn_and_split "*addv2sf3_1"
|
|
922 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
923 (plus:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
|
|
924 (match_operand:V2SF 2 "fr_register_operand" "f")))
|
|
925 (use (match_operand:V2SF 3 "fr_register_operand" "f"))]
|
|
926 ""
|
|
927 "#"
|
|
928 "reload_completed"
|
|
929 [(set (match_dup 0)
|
|
930 (plus:V2SF
|
|
931 (mult:V2SF (match_dup 1) (match_dup 3))
|
|
932 (match_dup 2)))]
|
|
933 "")
|
|
934
|
|
935 (define_insn_and_split "*addv2sf3_2"
|
|
936 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
937 (plus:V2SF
|
|
938 (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
|
|
939 (match_operand:V2SF 2 "fr_register_operand" "f"))
|
|
940 (match_operand:V2SF 3 "fr_register_operand" "f")))
|
|
941 (use (match_operand:V2SF 4 "" "X"))]
|
|
942 ""
|
|
943 "#"
|
|
944 ""
|
|
945 [(set (match_dup 0)
|
|
946 (plus:V2SF
|
|
947 (mult:V2SF (match_dup 1) (match_dup 2))
|
|
948 (match_dup 3)))]
|
|
949 "")
|
|
950
|
|
951 ;; In order to convince combine to merge minus and mult to a useful fpms,
|
|
952 ;; we need a couple of extra patterns.
|
|
953 (define_expand "subv2sf3"
|
|
954 [(parallel
|
|
955 [(set (match_operand:V2SF 0 "fr_register_operand" "")
|
|
956 (minus:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
|
|
957 (match_operand:V2SF 2 "fr_register_operand" "")))
|
|
958 (use (match_dup 3))])]
|
|
959 ""
|
|
960 {
|
|
961 rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
|
|
962 operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
|
|
963 })
|
|
964
|
|
965 ;; The split condition here could be combine_completed, if we had such.
|
|
966 (define_insn_and_split "*subv2sf3_1"
|
|
967 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
968 (minus:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
|
|
969 (match_operand:V2SF 2 "fr_register_operand" "f")))
|
|
970 (use (match_operand:V2SF 3 "fr_register_operand" "f"))]
|
|
971 ""
|
|
972 "#"
|
|
973 "reload_completed"
|
|
974 [(set (match_dup 0)
|
|
975 (minus:V2SF
|
|
976 (mult:V2SF (match_dup 1) (match_dup 3))
|
|
977 (match_dup 2)))]
|
|
978 "")
|
|
979
|
|
980 (define_insn_and_split "*subv2sf3_2"
|
|
981 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
982 (minus:V2SF
|
|
983 (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
|
|
984 (match_operand:V2SF 2 "fr_register_operand" "f"))
|
|
985 (match_operand:V2SF 3 "fr_register_operand" "f")))
|
|
986 (use (match_operand:V2SF 4 "" "X"))]
|
|
987 ""
|
|
988 "#"
|
|
989 ""
|
|
990 [(set (match_dup 0)
|
|
991 (minus:V2SF
|
|
992 (mult:V2SF (match_dup 1) (match_dup 2))
|
|
993 (match_dup 3)))]
|
|
994 "")
|
|
995
|
|
996 (define_insn "mulv2sf3"
|
|
997 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
998 (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
|
|
999 (match_operand:V2SF 2 "fr_register_operand" "f")))]
|
|
1000 ""
|
|
1001 "fpmpy %0 = %1, %2"
|
|
1002 [(set_attr "itanium_class" "fmac")])
|
|
1003
|
|
1004 (define_insn "*fpma"
|
|
1005 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1006 (plus:V2SF
|
|
1007 (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
|
|
1008 (match_operand:V2SF 2 "fr_register_operand" "f"))
|
|
1009 (match_operand:V2SF 3 "fr_register_operand" "f")))]
|
|
1010 ""
|
|
1011 "fpma %0 = %1, %2, %3"
|
|
1012 [(set_attr "itanium_class" "fmac")])
|
|
1013
|
|
1014 (define_insn "*fpms"
|
|
1015 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1016 (minus:V2SF
|
|
1017 (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
|
|
1018 (match_operand:V2SF 2 "fr_register_operand" "f"))
|
|
1019 (match_operand:V2SF 3 "fr_register_operand" "f")))]
|
|
1020 ""
|
|
1021 "fpms %0 = %1, %2, %3"
|
|
1022 [(set_attr "itanium_class" "fmac")])
|
|
1023
|
|
1024 (define_insn "*fpnmpy"
|
|
1025 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1026 (neg:V2SF
|
|
1027 (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
|
|
1028 (match_operand:V2SF 2 "fr_register_operand" "f"))))]
|
|
1029 ""
|
|
1030 "fpnmpy %0 = %1, %2"
|
|
1031 [(set_attr "itanium_class" "fmac")])
|
|
1032
|
|
1033 (define_insn "*fpnma"
|
|
1034 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1035 (plus:V2SF
|
|
1036 (neg:V2SF
|
|
1037 (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
|
|
1038 (match_operand:V2SF 2 "fr_register_operand" "f")))
|
|
1039 (match_operand:V2SF 3 "fr_register_operand" "f")))]
|
|
1040 ""
|
|
1041 "fpnma %0 = %1, %2, %3"
|
|
1042 [(set_attr "itanium_class" "fmac")])
|
|
1043
|
|
1044 (define_insn "smaxv2sf3"
|
|
1045 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1046 (smax:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
|
|
1047 (match_operand:V2SF 2 "fr_register_operand" "f")))]
|
|
1048 ""
|
|
1049 "fpmax %0 = %1, %2"
|
|
1050 [(set_attr "itanium_class" "fmisc")])
|
|
1051
|
|
1052 (define_insn "sminv2sf3"
|
|
1053 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1054 (smin:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
|
|
1055 (match_operand:V2SF 2 "fr_register_operand" "f")))]
|
|
1056 ""
|
|
1057 "fpmin %0 = %1, %2"
|
|
1058 [(set_attr "itanium_class" "fmisc")])
|
|
1059
|
|
1060 (define_expand "reduc_splus_v2sf"
|
|
1061 [(match_operand:V2SF 0 "fr_register_operand" "")
|
|
1062 (match_operand:V2SF 1 "fr_register_operand" "")]
|
|
1063 ""
|
|
1064 {
|
|
1065 rtx tmp = gen_reg_rtx (V2SFmode);
|
|
1066 emit_insn (gen_fswap (tmp, operands[1], CONST0_RTX (V2SFmode)));
|
|
1067 emit_insn (gen_addv2sf3 (operands[0], operands[1], tmp));
|
|
1068 DONE;
|
|
1069 })
|
|
1070
|
|
1071 (define_expand "reduc_smax_v2sf"
|
|
1072 [(match_operand:V2SF 0 "fr_register_operand" "")
|
|
1073 (match_operand:V2SF 1 "fr_register_operand" "")]
|
|
1074 ""
|
|
1075 {
|
|
1076 rtx tmp = gen_reg_rtx (V2SFmode);
|
|
1077 emit_insn (gen_fswap (tmp, operands[1], CONST0_RTX (V2SFmode)));
|
|
1078 emit_insn (gen_smaxv2sf3 (operands[0], operands[1], tmp));
|
|
1079 DONE;
|
|
1080 })
|
|
1081
|
|
1082 (define_expand "reduc_smin_v2sf"
|
|
1083 [(match_operand:V2SF 0 "fr_register_operand" "")
|
|
1084 (match_operand:V2SF 1 "fr_register_operand" "")]
|
|
1085 ""
|
|
1086 {
|
|
1087 rtx tmp = gen_reg_rtx (V2SFmode);
|
|
1088 emit_insn (gen_fswap (tmp, operands[1], CONST0_RTX (V2SFmode)));
|
|
1089 emit_insn (gen_sminv2sf3 (operands[0], operands[1], tmp));
|
|
1090 DONE;
|
|
1091 })
|
|
1092
|
|
1093 (define_expand "vcondv2sf"
|
|
1094 [(set (match_operand:V2SF 0 "fr_register_operand" "")
|
|
1095 (if_then_else:V2SF
|
|
1096 (match_operator 3 ""
|
|
1097 [(match_operand:V2SF 4 "fr_reg_or_0_operand" "")
|
|
1098 (match_operand:V2SF 5 "fr_reg_or_0_operand" "")])
|
|
1099 (match_operand:V2SF 1 "fr_reg_or_0_operand" "")
|
|
1100 (match_operand:V2SF 2 "fr_reg_or_0_operand" "")))]
|
|
1101 ""
|
|
1102 {
|
|
1103 rtx x, cmp;
|
|
1104
|
|
1105 cmp = gen_reg_rtx (V2SFmode);
|
|
1106 PUT_MODE (operands[3], V2SFmode);
|
|
1107 emit_insn (gen_rtx_SET (VOIDmode, cmp, operands[3]));
|
|
1108
|
|
1109 x = gen_rtx_IF_THEN_ELSE (V2SFmode, cmp, operands[1], operands[2]);
|
|
1110 emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
|
|
1111 DONE;
|
|
1112 })
|
|
1113
|
|
1114 (define_insn "*fpcmp"
|
|
1115 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1116 (match_operator:V2SF 3 "comparison_operator"
|
|
1117 [(match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
|
|
1118 (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU")]))]
|
|
1119 ""
|
|
1120 "fpcmp.%D3 %0 = %F1, %F2"
|
|
1121 [(set_attr "itanium_class" "fmisc")])
|
|
1122
|
|
1123 (define_insn "*fselect"
|
|
1124 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1125 (if_then_else:V2SF
|
|
1126 (match_operand:V2SF 1 "fr_register_operand" "f")
|
|
1127 (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU")
|
|
1128 (match_operand:V2SF 3 "fr_reg_or_0_operand" "fU")))]
|
|
1129 ""
|
|
1130 "fselect %0 = %F2, %F3, %1"
|
|
1131 [(set_attr "itanium_class" "fmisc")])
|
|
1132
|
|
1133 (define_expand "vec_initv2sf"
|
|
1134 [(match_operand:V2SF 0 "fr_register_operand" "")
|
|
1135 (match_operand 1 "" "")]
|
|
1136 ""
|
|
1137 {
|
|
1138 rtx op1 = XVECEXP (operands[1], 0, 0);
|
|
1139 rtx op2 = XVECEXP (operands[1], 0, 1);
|
|
1140 rtx x;
|
|
1141
|
|
1142 if (GET_CODE (op1) == CONST_DOUBLE && GET_CODE (op2) == CONST_DOUBLE)
|
|
1143 {
|
|
1144 x = gen_rtx_CONST_VECTOR (V2SFmode, XVEC (operands[1], 0));
|
|
1145 emit_move_insn (operands[0], x);
|
|
1146 DONE;
|
|
1147 }
|
|
1148
|
|
1149 if (!fr_reg_or_fp01_operand (op1, SFmode))
|
|
1150 op1 = force_reg (SFmode, op1);
|
|
1151 if (!fr_reg_or_fp01_operand (op2, SFmode))
|
|
1152 op2 = force_reg (SFmode, op2);
|
|
1153
|
|
1154 if (TARGET_BIG_ENDIAN)
|
|
1155 emit_insn (gen_fpack (operands[0], op2, op1));
|
|
1156 else
|
|
1157 emit_insn (gen_fpack (operands[0], op1, op2));
|
|
1158 DONE;
|
|
1159 })
|
|
1160
|
|
1161 (define_insn "fpack"
|
|
1162 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1163 (vec_concat:V2SF
|
|
1164 (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
|
|
1165 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
|
|
1166 ""
|
|
1167 "fpack %0 = %F2, %F1"
|
|
1168 [(set_attr "itanium_class" "fmisc")])
|
|
1169
|
|
1170 (define_insn "fswap"
|
|
1171 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1172 (vec_select:V2SF
|
|
1173 (vec_concat:V4SF
|
|
1174 (match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
|
|
1175 (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU"))
|
|
1176 (parallel [(const_int 1) (const_int 2)])))]
|
|
1177 ""
|
|
1178 "fswap %0 = %F1, %F2"
|
|
1179 [(set_attr "itanium_class" "fmisc")])
|
|
1180
|
|
1181 (define_insn "*fmix_l"
|
|
1182 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1183 (vec_select:V2SF
|
|
1184 (vec_concat:V4SF
|
|
1185 (match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
|
|
1186 (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU"))
|
|
1187 (parallel [(const_int 1) (const_int 3)])))]
|
|
1188 ""
|
|
1189 "fmix.l %0 = %F2, %F1"
|
|
1190 [(set_attr "itanium_class" "fmisc")])
|
|
1191
|
|
1192 (define_insn "fmix_r"
|
|
1193 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1194 (vec_select:V2SF
|
|
1195 (vec_concat:V4SF
|
|
1196 (match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
|
|
1197 (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU"))
|
|
1198 (parallel [(const_int 0) (const_int 2)])))]
|
|
1199 ""
|
|
1200 "fmix.r %0 = %F2, %F1"
|
|
1201 [(set_attr "itanium_class" "fmisc")])
|
|
1202
|
|
1203 (define_insn "fmix_lr"
|
|
1204 [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
|
|
1205 (vec_select:V2SF
|
|
1206 (vec_concat:V4SF
|
|
1207 (match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
|
|
1208 (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU"))
|
|
1209 (parallel [(const_int 0) (const_int 3)])))]
|
|
1210 ""
|
|
1211 "fmix.lr %0 = %F2, %F1"
|
|
1212 [(set_attr "itanium_class" "fmisc")])
|
|
1213
|
|
1214 (define_expand "vec_setv2sf"
|
|
1215 [(match_operand:V2SF 0 "fr_register_operand" "")
|
|
1216 (match_operand:SF 1 "fr_register_operand" "")
|
|
1217 (match_operand 2 "const_int_operand" "")]
|
|
1218 ""
|
|
1219 {
|
|
1220 rtx tmp = gen_reg_rtx (V2SFmode);
|
|
1221 emit_insn (gen_fpack (tmp, operands[1], CONST0_RTX (SFmode)));
|
|
1222
|
|
1223 switch (INTVAL (operands[2]))
|
|
1224 {
|
|
1225 case 0:
|
|
1226 emit_insn (gen_fmix_lr (operands[0], tmp, operands[0]));
|
|
1227 break;
|
|
1228 case 1:
|
|
1229 emit_insn (gen_fmix_r (operands[0], operands[0], tmp));
|
|
1230 break;
|
|
1231 default:
|
|
1232 gcc_unreachable ();
|
|
1233 }
|
|
1234 DONE;
|
|
1235 })
|
|
1236
|
|
1237 (define_insn_and_split "*vec_extractv2sf_0_le"
|
|
1238 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,f,m")
|
|
1239 (unspec:SF [(match_operand:V2SF 1 "nonimmediate_operand" "rfm,rm,r")
|
|
1240 (const_int 0)]
|
|
1241 UNSPEC_VECT_EXTR))]
|
|
1242 "!TARGET_BIG_ENDIAN"
|
|
1243 "#"
|
|
1244 "reload_completed"
|
|
1245 [(set (match_dup 0) (match_dup 1))]
|
|
1246 {
|
|
1247 if (REG_P (operands[1]) && FR_REGNO_P (REGNO (operands[1])))
|
|
1248 operands[0] = gen_rtx_REG (V2SFmode, REGNO (operands[0]));
|
|
1249 else if (MEM_P (operands[1]))
|
|
1250 operands[1] = adjust_address (operands[1], SFmode, 0);
|
|
1251 else
|
|
1252 operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));
|
|
1253 })
|
|
1254
|
|
1255 (define_insn_and_split "*vec_extractv2sf_0_be"
|
|
1256 [(set (match_operand:SF 0 "register_operand" "=r,f")
|
|
1257 (unspec:SF [(match_operand:V2SF 1 "register_operand" "rf,r")
|
|
1258 (const_int 0)]
|
|
1259 UNSPEC_VECT_EXTR))]
|
|
1260 "TARGET_BIG_ENDIAN"
|
|
1261 "#"
|
|
1262 "reload_completed"
|
|
1263 [(set (match_dup 0) (match_dup 1))]
|
|
1264 {
|
|
1265 if (REG_P (operands[1]) && FR_REGNO_P (REGNO (operands[1])))
|
|
1266 operands[0] = gen_rtx_REG (V2SFmode, REGNO (operands[0]));
|
|
1267 else
|
|
1268 operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));
|
|
1269 })
|
|
1270
|
|
1271 (define_insn_and_split "*vec_extractv2sf_1"
|
|
1272 [(set (match_operand:SF 0 "register_operand" "=r")
|
|
1273 (unspec:SF [(match_operand:V2SF 1 "register_operand" "r")
|
|
1274 (const_int 1)]
|
|
1275 UNSPEC_VECT_EXTR))]
|
|
1276 ""
|
|
1277 "#"
|
|
1278 "reload_completed"
|
|
1279 [(const_int 0)]
|
|
1280 {
|
|
1281 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
|
1282 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
|
|
1283 if (TARGET_BIG_ENDIAN)
|
|
1284 emit_move_insn (operands[0], operands[1]);
|
|
1285 else
|
|
1286 emit_insn (gen_lshrdi3 (operands[0], operands[1], GEN_INT (32)));
|
|
1287 DONE;
|
|
1288 })
|
|
1289
|
|
1290 (define_expand "vec_extractv2sf"
|
|
1291 [(set (match_operand:SF 0 "register_operand" "")
|
|
1292 (unspec:SF [(match_operand:V2SF 1 "register_operand" "")
|
|
1293 (match_operand:DI 2 "const_int_operand" "")]
|
|
1294 UNSPEC_VECT_EXTR))]
|
|
1295 ""
|
|
1296 "")
|
|
1297
|
|
1298 ;; Missing operations
|
|
1299 ;; fprcpa
|
|
1300 ;; fpsqrta
|