1 ;; PowerPC paired single and double hummer description
2 ;; Copyright (C) 2007, 2009
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by David Edelsohn <edelsohn@gnu.org> and Revital Eres
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with this program; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
24 [(UNSPEC_INTERHI_V2SF 330)
25 (UNSPEC_INTERLO_V2SF 331)
26 (UNSPEC_EXTEVEN_V2SF 332)
27 (UNSPEC_EXTODD_V2SF 333)
30 (define_insn "negv2sf2"
31 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
32 (neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))]
35 [(set_attr "type" "fp")])
37 (define_insn "sqrtv2sf2"
38 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
39 (sqrt:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))]
42 [(set_attr "type" "fp")])
44 (define_insn "absv2sf2"
45 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
46 (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))]
49 [(set_attr "type" "fp")])
51 (define_insn "nabsv2sf2"
52 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
53 (neg:V2SF (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f"))))]
56 [(set_attr "type" "fp")])
58 (define_insn "addv2sf3"
59 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
60 (plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f")
61 (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
64 [(set_attr "type" "fp")])
66 (define_insn "subv2sf3"
67 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
68 (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
69 (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
72 [(set_attr "type" "fp")])
74 (define_insn "mulv2sf3"
75 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
76 (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f")
77 (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
80 [(set_attr "type" "fp")])
82 (define_insn "resv2sf2"
83 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
84 (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
85 "TARGET_PAIRED_FLOAT && flag_finite_math_only"
87 [(set_attr "type" "fp")])
89 (define_insn "divv2sf3"
90 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
91 (div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
92 (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
95 [(set_attr "type" "sdiv")])
97 (define_insn "paired_madds0"
98 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
100 (plus:SF (mult:SF (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
101 (parallel [(const_int 0)]))
102 (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
103 (parallel [(const_int 0)])))
104 (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f")
105 (parallel [(const_int 0)])))
106 (plus:SF (mult:SF (vec_select:SF (match_dup 1)
107 (parallel [(const_int 1)]))
108 (vec_select:SF (match_dup 2)
109 (parallel [(const_int 0)])))
110 (vec_select:SF (match_dup 3)
111 (parallel [(const_int 1)])))))]
112 "TARGET_PAIRED_FLOAT && TARGET_FUSED_MADD"
113 "ps_madds0 %0,%1,%2,%3"
114 [(set_attr "type" "fp")])
116 (define_insn "paired_madds1"
117 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
119 (plus:SF (mult:SF (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
120 (parallel [(const_int 0)]))
121 (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
122 (parallel [(const_int 1)])))
123 (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f")
124 (parallel [(const_int 0)])))
125 (plus:SF (mult:SF (vec_select:SF (match_dup 1)
126 (parallel [(const_int 1)]))
127 (vec_select:SF (match_dup 2)
128 (parallel [(const_int 1)])))
129 (vec_select:SF (match_dup 3)
130 (parallel [(const_int 1)])))))]
131 "TARGET_PAIRED_FLOAT && TARGET_FUSED_MADD"
132 "ps_madds1 %0,%1,%2,%3"
133 [(set_attr "type" "fp")])
135 (define_insn "paired_madd"
136 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
137 (plus:V2SF (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f")
138 (match_operand:V2SF 2 "gpc_reg_operand" "f"))
139 (match_operand:V2SF 3 "gpc_reg_operand" "f")))]
140 "TARGET_PAIRED_FLOAT && TARGET_FUSED_MADD"
141 "ps_madd %0,%1,%2,%3"
142 [(set_attr "type" "fp")])
144 (define_insn "paired_msub"
145 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
146 (minus:V2SF (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f")
147 (match_operand:V2SF 2 "gpc_reg_operand" "f"))
148 (match_operand:V2SF 3 "gpc_reg_operand" "f")))]
149 "TARGET_PAIRED_FLOAT && TARGET_FUSED_MADD"
150 "ps_msub %0,%1,%2,%3"
151 [(set_attr "type" "fp")])
153 (define_insn "paired_nmadd"
154 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
155 (neg:V2SF (plus:V2SF (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f")
156 (match_operand:V2SF 2 "gpc_reg_operand" "f"))
157 (match_operand:V2SF 3 "gpc_reg_operand" "f"))))]
158 "TARGET_PAIRED_FLOAT && TARGET_FUSED_MADD
159 && HONOR_SIGNED_ZEROS (SFmode)"
160 "ps_nmadd %0,%1,%2,%3"
161 [(set_attr "type" "fp")])
163 (define_insn "paired_nmsub"
164 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
165 (neg:V2SF (minus:V2SF (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f")
166 (match_operand:V2SF 2 "gpc_reg_operand" "f"))
167 (match_operand:V2SF 3 "gpc_reg_operand" "f"))))]
168 "TARGET_PAIRED_FLOAT && TARGET_FUSED_MADD
169 && HONOR_SIGNED_ZEROS (DFmode)"
170 "ps_nmsub %0,%1,%2,%3"
171 [(set_attr "type" "dmul")])
173 (define_insn "selv2sf4"
174 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
176 (if_then_else:SF (ge (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
177 (parallel [(const_int 0)]))
178 (match_operand:SF 4 "zero_fp_constant" "F"))
179 (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
180 (parallel [(const_int 0)]))
181 (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f")
182 (parallel [(const_int 0)])))
183 (if_then_else:SF (ge (vec_select:SF (match_dup 1)
184 (parallel [(const_int 1)]))
186 (vec_select:SF (match_dup 2)
187 (parallel [(const_int 1)]))
188 (vec_select:SF (match_dup 3)
189 (parallel [(const_int 1)])))))]
191 "TARGET_PAIRED_FLOAT"
193 [(set_attr "type" "fp")])
195 (define_insn "*movv2sf_paired"
196 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=Z,f,f,o,r,r,f")
197 (match_operand:V2SF 1 "input_operand" "f,Z,f,r,o,r,W"))]
199 && (register_operand (operands[0], V2SFmode)
200 || register_operand (operands[1], V2SFmode))"
202 switch (which_alternative)
204 case 0: return "psq_stx %1,%y0,0,0";
205 case 1: return "psq_lx %0,%y1,0,0";
206 case 2: return "ps_mr %0,%1";
211 default: gcc_unreachable ();
214 [(set_attr "type" "fpstore,fpload,fp,*,*,*,*")])
216 (define_insn "paired_stx"
217 [(set (match_operand:V2SF 0 "memory_operand" "=Z")
218 (match_operand:V2SF 1 "gpc_reg_operand" "f"))]
219 "TARGET_PAIRED_FLOAT"
221 [(set_attr "type" "fpstore")])
223 (define_insn "paired_lx"
224 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
225 (match_operand:V2SF 1 "memory_operand" "Z"))]
226 "TARGET_PAIRED_FLOAT"
228 [(set_attr "type" "fpload")])
232 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
233 (match_operand:V2SF 1 "input_operand" ""))]
234 "TARGET_PAIRED_FLOAT && reload_completed
235 && gpr_or_gpr_p (operands[0], operands[1])"
238 rs6000_split_multireg_move (operands[0], operands[1]); DONE;
241 (define_insn "paired_cmpu0"
242 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
243 (compare:CCFP (vec_select:SF
244 (match_operand:V2SF 1 "gpc_reg_operand" "f")
245 (parallel [(const_int 0)]))
247 (match_operand:V2SF 2 "gpc_reg_operand" "f")
248 (parallel [(const_int 0)]))))]
249 "TARGET_PAIRED_FLOAT"
251 [(set_attr "type" "fpcompare")])
253 (define_insn "paired_cmpu1"
254 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
255 (compare:CCFP (vec_select:SF
256 (match_operand:V2SF 1 "gpc_reg_operand" "f")
257 (parallel [(const_int 1)]))
259 (match_operand:V2SF 2 "gpc_reg_operand" "f")
260 (parallel [(const_int 1)]))))]
261 "TARGET_PAIRED_FLOAT"
263 [(set_attr "type" "fpcompare")])
265 (define_insn "paired_merge00"
266 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
268 (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
269 (parallel [(const_int 0)]))
270 (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
271 (parallel [(const_int 0)]))))]
272 "TARGET_PAIRED_FLOAT"
273 "ps_merge00 %0, %1, %2"
274 [(set_attr "type" "fp")])
276 (define_insn "paired_merge01"
277 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
279 (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
280 (parallel [(const_int 0)]))
281 (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
282 (parallel [(const_int 1)]))))]
283 "TARGET_PAIRED_FLOAT"
284 "ps_merge01 %0, %1, %2"
285 [(set_attr "type" "fp")])
287 (define_insn "paired_merge10"
288 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
290 (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
291 (parallel [(const_int 1)]))
292 (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
293 (parallel [(const_int 0)]))))]
294 "TARGET_PAIRED_FLOAT"
295 "ps_merge10 %0, %1, %2"
296 [(set_attr "type" "fp")])
298 (define_insn "paired_merge11"
299 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
301 (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
302 (parallel [(const_int 1)]))
303 (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
304 (parallel [(const_int 1)]))))]
305 "TARGET_PAIRED_FLOAT"
306 "ps_merge11 %0, %1, %2"
307 [(set_attr "type" "fp")])
309 (define_insn "paired_sum0"
310 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
311 (vec_concat:V2SF (plus:SF (vec_select:SF
312 (match_operand:V2SF 1 "gpc_reg_operand" "f")
313 (parallel [(const_int 0)]))
315 (match_operand:V2SF 2 "gpc_reg_operand" "f")
316 (parallel [(const_int 1)])))
318 (match_operand:V2SF 3 "gpc_reg_operand" "f")
319 (parallel [(const_int 1)]))))]
320 "TARGET_PAIRED_FLOAT"
321 "ps_sum0 %0,%1,%2,%3"
322 [(set_attr "type" "fp")])
324 (define_insn "paired_sum1"
325 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
326 (vec_concat:V2SF (vec_select:SF
327 (match_operand:V2SF 2 "gpc_reg_operand" "f")
328 (parallel [(const_int 1)]))
329 (plus:SF (vec_select:SF
330 (match_operand:V2SF 1 "gpc_reg_operand" "f")
331 (parallel [(const_int 0)]))
333 (match_operand:V2SF 3 "gpc_reg_operand" "f")
334 (parallel [(const_int 1)])))))]
335 "TARGET_PAIRED_FLOAT"
336 "ps_sum1 %0,%1,%2,%3"
337 [(set_attr "type" "fp")])
339 (define_insn "paired_muls0"
340 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
341 (mult:V2SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
343 (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
344 (parallel [(const_int 0)])))))]
345 "TARGET_PAIRED_FLOAT"
346 "ps_muls0 %0, %1, %2"
347 [(set_attr "type" "fp")])
350 (define_insn "paired_muls1"
351 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
352 (mult:V2SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
354 (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
355 (parallel [(const_int 1)])))))]
356 "TARGET_PAIRED_FLOAT"
357 "ps_muls1 %0, %1, %2"
358 [(set_attr "type" "fp")])
360 (define_expand "vec_initv2sf"
361 [(match_operand:V2SF 0 "gpc_reg_operand" "=f")
362 (match_operand 1 "" "")]
363 "TARGET_PAIRED_FLOAT"
365 paired_expand_vector_init (operands[0], operands[1]);
369 (define_insn "*vconcatsf"
370 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
372 (match_operand:SF 1 "gpc_reg_operand" "f")
373 (match_operand:SF 2 "gpc_reg_operand" "f")))]
374 "TARGET_PAIRED_FLOAT"
375 "ps_merge00 %0, %1, %2"
376 [(set_attr "type" "fp")])
378 (define_expand "sminv2sf3"
379 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
380 (smin:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
381 (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
382 "TARGET_PAIRED_FLOAT"
384 rtx tmp = gen_reg_rtx (V2SFmode);
386 emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2]));
387 emit_insn (gen_selv2sf4 (operands[0], tmp, operands[2], operands[1], CONST0_RTX (SFmode)));
391 (define_expand "smaxv2sf3"
392 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
393 (smax:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
394 (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
395 "TARGET_PAIRED_FLOAT"
397 rtx tmp = gen_reg_rtx (V2SFmode);
399 emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2]));
400 emit_insn (gen_selv2sf4 (operands[0], tmp, operands[1], operands[2], CONST0_RTX (SFmode)));
404 (define_expand "reduc_smax_v2sf"
405 [(match_operand:V2SF 0 "gpc_reg_operand" "=f")
406 (match_operand:V2SF 1 "gpc_reg_operand" "f")]
407 "TARGET_PAIRED_FLOAT"
409 rtx tmp_swap = gen_reg_rtx (V2SFmode);
410 rtx tmp = gen_reg_rtx (V2SFmode);
412 emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1]));
413 emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap));
414 emit_insn (gen_selv2sf4 (operands[0], tmp, operands[1], tmp_swap, CONST0_RTX (SFmode)));
419 (define_expand "reduc_smin_v2sf"
420 [(match_operand:V2SF 0 "gpc_reg_operand" "=f")
421 (match_operand:V2SF 1 "gpc_reg_operand" "f")]
422 "TARGET_PAIRED_FLOAT"
424 rtx tmp_swap = gen_reg_rtx (V2SFmode);
425 rtx tmp = gen_reg_rtx (V2SFmode);
427 emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1]));
428 emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap));
429 emit_insn (gen_selv2sf4 (operands[0], tmp, tmp_swap, operands[1], CONST0_RTX (SFmode)));
434 (define_expand "vec_interleave_highv2sf"
435 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
436 (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")
437 (match_operand:V2SF 2 "gpc_reg_operand" "f")]
438 UNSPEC_INTERHI_V2SF))]
439 "TARGET_PAIRED_FLOAT"
442 emit_insn (gen_paired_merge00 (operands[0], operands[1], operands[2]));
446 (define_expand "vec_interleave_lowv2sf"
447 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
448 (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")
449 (match_operand:V2SF 2 "gpc_reg_operand" "f")]
450 UNSPEC_INTERLO_V2SF))]
451 "TARGET_PAIRED_FLOAT"
454 emit_insn (gen_paired_merge11 (operands[0], operands[1], operands[2]));
458 (define_expand "vec_extract_evenv2sf"
459 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
460 (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")
461 (match_operand:V2SF 2 "gpc_reg_operand" "f")]
462 UNSPEC_EXTEVEN_V2SF))]
463 "TARGET_PAIRED_FLOAT"
466 emit_insn (gen_paired_merge00 (operands[0], operands[1], operands[2]));
470 (define_expand "vec_extract_oddv2sf"
471 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
472 (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")
473 (match_operand:V2SF 2 "gpc_reg_operand" "f")]
474 UNSPEC_EXTODD_V2SF))]
475 "TARGET_PAIRED_FLOAT"
478 emit_insn (gen_paired_merge11 (operands[0], operands[1], operands[2]));
483 (define_expand "reduc_splus_v2sf"
484 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
485 (match_operand:V2SF 1 "gpc_reg_operand" "f"))]
486 "TARGET_PAIRED_FLOAT"
489 emit_insn (gen_paired_sum1 (operands[0], operands[1], operands[1], operands[1]));
493 (define_expand "movmisalignv2sf"
494 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
495 (match_operand:V2SF 1 "gpc_reg_operand" "f"))]
496 "TARGET_PAIRED_FLOAT"
498 paired_expand_vector_move (operands);
502 (define_expand "vcondv2sf"
503 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
505 (match_operator 3 "gpc_reg_operand"
506 [(match_operand:V2SF 4 "gpc_reg_operand" "f")
507 (match_operand:V2SF 5 "gpc_reg_operand" "f")])
508 (match_operand:V2SF 1 "gpc_reg_operand" "f")
509 (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
510 "TARGET_PAIRED_FLOAT && flag_unsafe_math_optimizations"
513 if (paired_emit_vector_cond_expr (operands[0], operands[1], operands[2],
514 operands[3], operands[4], operands[5]))