1;; PowerPC paired single and double hummer description
2;; Copyright (C) 2007-2014 Free Software Foundation, Inc.
3;; Contributed by David Edelsohn <edelsohn@gnu.org> and Revital Eres
4;; <eres@il.ibm.com>
5
6;; This file is part of GCC.
7
8;; GCC is free software; you can redistribute it and/or modify it
9;; under the terms of the GNU General Public License as published
10;; by the Free Software Foundation; either version 3, or (at your
11;; option) any later version.
12
13;; GCC is distributed in the hope that it will be useful, but WITHOUT
14;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16;; License for more details.
17;;
18;; You should have received a copy of the GNU General Public License
19;; along with this program; see the file COPYING3.  If not see
20;; <http://www.gnu.org/licenses/>.
21
22(define_c_enum "unspec"
23  [UNSPEC_INTERHI_V2SF
24   UNSPEC_INTERLO_V2SF
25   UNSPEC_EXTEVEN_V2SF
26   UNSPEC_EXTODD_V2SF
27  ])
28
29(define_insn "paired_negv2sf2"
30  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
31	(neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))]
32  "TARGET_PAIRED_FLOAT"
33  "ps_neg %0,%1"
34  [(set_attr "type" "fp")])
35
36(define_insn "sqrtv2sf2"
37  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
38	(sqrt:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))]
39  "TARGET_PAIRED_FLOAT"
40  "ps_rsqrte %0,%1"
41  [(set_attr "type" "fp")])
42
43(define_insn "paired_absv2sf2"
44  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
45	(abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))]
46  "TARGET_PAIRED_FLOAT"
47  "ps_abs %0,%1"
48  [(set_attr "type" "fp")])
49
50(define_insn "nabsv2sf2"
51  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
52	(neg:V2SF (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f"))))]
53  "TARGET_PAIRED_FLOAT"
54  "ps_nabs %0,%1"
55  [(set_attr "type" "fp")])
56
57(define_insn "paired_addv2sf3"
58  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
59	(plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f")
60		   (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
61  "TARGET_PAIRED_FLOAT"
62  "ps_add %0,%1,%2"
63  [(set_attr "type" "fp")])
64
65(define_insn "paired_subv2sf3"
66  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
67        (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
68                    (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
69  "TARGET_PAIRED_FLOAT"
70  "ps_sub %0,%1,%2"
71  [(set_attr "type" "fp")])
72
73(define_insn "paired_mulv2sf3"
74  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
75	(mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f")
76		   (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
77  "TARGET_PAIRED_FLOAT"
78  "ps_mul %0,%1,%2"
79  [(set_attr "type" "fp")])
80
81(define_insn "resv2sf2"
82  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
83	(unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
84  "TARGET_PAIRED_FLOAT && flag_finite_math_only"
85  "ps_res %0,%1"
86  [(set_attr "type" "fp")])
87
88(define_insn "paired_divv2sf3"
89  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
90	(div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
91		  (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
92  "TARGET_PAIRED_FLOAT"
93  "ps_div %0,%1,%2"
94  [(set_attr "type" "sdiv")])
95
96(define_insn "paired_madds0"
97 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
98       (vec_concat:V2SF
99	 (fma:SF
100           (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	 (fma:SF
107	   (vec_select:SF (match_dup 1)
108                          (parallel [(const_int 1)]))
109	   (vec_select:SF (match_dup 2)
110                          (parallel [(const_int 0)]))
111	   (vec_select:SF (match_dup 3)
112                          (parallel [(const_int 1)])))))]
113  "TARGET_PAIRED_FLOAT"
114  "ps_madds0 %0,%1,%2,%3"
115  [(set_attr "type" "fp")])
116
117(define_insn "paired_madds1"
118 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
119       (vec_concat:V2SF
120         (fma:SF
121	   (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
122                          (parallel [(const_int 0)]))
123           (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
124                          (parallel [(const_int 1)]))
125           (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f")
126                          (parallel [(const_int 0)])))
127	 (fma:SF
128	   (vec_select:SF (match_dup 1)
129                          (parallel [(const_int 1)]))
130           (vec_select:SF (match_dup 2)
131                          (parallel [(const_int 1)]))
132           (vec_select:SF (match_dup 3)
133                          (parallel [(const_int 1)])))))]
134  "TARGET_PAIRED_FLOAT"
135  "ps_madds1 %0,%1,%2,%3"
136  [(set_attr "type" "fp")])
137
138(define_insn "*paired_madd"
139  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
140	(fma:V2SF
141	  (match_operand:V2SF 1 "gpc_reg_operand" "f")
142	  (match_operand:V2SF 2 "gpc_reg_operand" "f")
143	  (match_operand:V2SF 3 "gpc_reg_operand" "f")))]
144  "TARGET_PAIRED_FLOAT"
145  "ps_madd %0,%1,%2,%3"
146  [(set_attr "type" "fp")])
147
148(define_insn "*paired_msub"
149  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
150	(fma:V2SF
151	  (match_operand:V2SF 1 "gpc_reg_operand" "f")
152	  (match_operand:V2SF 2 "gpc_reg_operand" "f")
153	  (neg:V2SF (match_operand:V2SF 3 "gpc_reg_operand" "f"))))]
154  "TARGET_PAIRED_FLOAT"
155  "ps_msub %0,%1,%2,%3"
156  [(set_attr "type" "fp")])
157
158(define_insn "*paired_nmadd"
159  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
160	(neg:V2SF
161	  (fma:V2SF
162	    (match_operand:V2SF 1 "gpc_reg_operand" "f")
163	    (match_operand:V2SF 2 "gpc_reg_operand" "f")
164	    (match_operand:V2SF 3 "gpc_reg_operand" "f"))))]
165  "TARGET_PAIRED_FLOAT"
166  "ps_nmadd %0,%1,%2,%3"
167  [(set_attr "type" "fp")])
168
169(define_insn "*paired_nmsub"
170  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
171	(neg:V2SF
172	  (fma:V2SF
173	    (match_operand:V2SF 1 "gpc_reg_operand" "f")
174	    (match_operand:V2SF 2 "gpc_reg_operand" "f")
175	    (neg:V2SF (match_operand:V2SF 3 "gpc_reg_operand" "f")))))]
176  "TARGET_PAIRED_FLOAT"
177  "ps_nmsub %0,%1,%2,%3"
178  [(set_attr "type" "dmul")])
179
180(define_insn "selv2sf4"
181  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
182	(vec_concat:V2SF
183	 (if_then_else:SF (ge (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
184					     (parallel [(const_int 0)]))
185			      (match_operand:SF 4 "zero_fp_constant" "F"))
186			  (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
187					 (parallel [(const_int 0)]))
188			  (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f")
189					 (parallel [(const_int 0)])))
190	 (if_then_else:SF (ge (vec_select:SF (match_dup 1)
191					     (parallel [(const_int 1)]))
192			      (match_dup 4))
193			  (vec_select:SF (match_dup 2)
194					 (parallel [(const_int 1)]))
195			  (vec_select:SF (match_dup 3)
196					 (parallel [(const_int 1)])))))]
197
198  "TARGET_PAIRED_FLOAT"
199  "ps_sel %0,%1,%2,%3"
200  [(set_attr "type" "fp")])
201
202(define_insn "*movv2sf_paired"
203  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=Z,f,f,Y,r,r,f")
204		 (match_operand:V2SF 1 "input_operand" "f,Z,f,r,Y,r,W"))]
205  "TARGET_PAIRED_FLOAT
206   && (register_operand (operands[0], V2SFmode)
207       || register_operand (operands[1], V2SFmode))"
208{
209  switch (which_alternative)
210    {
211    case 0: return "psq_stx %1,%y0,0,0";
212    case 1: return "psq_lx %0,%y1,0,0";
213    case 2: return "ps_mr %0,%1";
214    case 3: return "#";
215    case 4: return "#";
216    case 5: return "#";
217    case 6: return "#";
218    default: gcc_unreachable ();
219    }
220}
221  [(set_attr "type" "fpstore,fpload,fp,*,*,*,*")])
222
223(define_insn "paired_stx"
224  [(set (match_operand:V2SF 0 "memory_operand" "=Z")
225        (match_operand:V2SF 1 "gpc_reg_operand" "f"))]
226  "TARGET_PAIRED_FLOAT"
227  "psq_stx %1,%y0,0,0"
228  [(set_attr "type" "fpstore")])
229
230(define_insn "paired_lx"
231  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
232        (match_operand:V2SF 1 "memory_operand" "Z"))]
233  "TARGET_PAIRED_FLOAT"
234  "psq_lx %0,%y1,0,0"
235  [(set_attr "type" "fpload")])
236
237
238(define_split
239  [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
240        (match_operand:V2SF 1 "input_operand" ""))]
241  "TARGET_PAIRED_FLOAT && reload_completed
242   && gpr_or_gpr_p (operands[0], operands[1])"
243  [(pc)]
244  {
245  rs6000_split_multireg_move (operands[0], operands[1]); DONE;
246  })
247
248(define_insn "paired_cmpu0"
249  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
250	(compare:CCFP (vec_select:SF
251		       (match_operand:V2SF 1 "gpc_reg_operand" "f")
252		       (parallel [(const_int 0)]))
253		      (vec_select:SF
254		       (match_operand:V2SF 2 "gpc_reg_operand" "f")
255		       (parallel [(const_int 0)]))))]
256  "TARGET_PAIRED_FLOAT"
257  "ps_cmpu0 %0,%1,%2"
258  [(set_attr "type" "fpcompare")])
259
260(define_insn "paired_cmpu1"
261  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
262	(compare:CCFP (vec_select:SF
263		       (match_operand:V2SF 1 "gpc_reg_operand" "f")
264		       (parallel [(const_int 1)]))
265		      (vec_select:SF
266		       (match_operand:V2SF 2 "gpc_reg_operand" "f")
267		       (parallel [(const_int 1)]))))]
268  "TARGET_PAIRED_FLOAT"
269  "ps_cmpu1 %0,%1,%2"
270  [(set_attr "type" "fpcompare")])
271
272(define_insn "paired_merge00"
273  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
274	(vec_select:V2SF
275	  (vec_concat:V4SF
276	    (match_operand:V2SF 1 "gpc_reg_operand" "f")
277	    (match_operand:V2SF 2 "gpc_reg_operand" "f"))
278	  (parallel [(const_int 0) (const_int 2)])))]
279  "TARGET_PAIRED_FLOAT"
280  "ps_merge00 %0, %1, %2"
281  [(set_attr "type" "fp")])
282
283(define_insn "paired_merge01"
284  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
285	(vec_select:V2SF
286	  (vec_concat:V4SF
287	    (match_operand:V2SF 1 "gpc_reg_operand" "f")
288	    (match_operand:V2SF 2 "gpc_reg_operand" "f"))
289	  (parallel [(const_int 0) (const_int 3)])))]
290  "TARGET_PAIRED_FLOAT"
291  "ps_merge01 %0, %1, %2"
292  [(set_attr "type" "fp")])
293
294(define_insn "paired_merge10"
295  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
296	(vec_select:V2SF
297	  (vec_concat:V4SF
298	    (match_operand:V2SF 1 "gpc_reg_operand" "f")
299	    (match_operand:V2SF 2 "gpc_reg_operand" "f"))
300	  (parallel [(const_int 1) (const_int 2)])))]
301  "TARGET_PAIRED_FLOAT"
302  "ps_merge10 %0, %1, %2"
303  [(set_attr "type" "fp")])
304
305(define_insn "paired_merge11"
306  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
307	(vec_select:V2SF
308	  (vec_concat:V4SF
309	    (match_operand:V2SF 1 "gpc_reg_operand" "f")
310	    (match_operand:V2SF 2 "gpc_reg_operand" "f"))
311	  (parallel [(const_int 1) (const_int 3)])))]
312  "TARGET_PAIRED_FLOAT"
313  "ps_merge11 %0, %1, %2"
314  [(set_attr "type" "fp")])
315
316(define_expand "vec_perm_constv2sf"
317  [(match_operand:V2SF 0 "gpc_reg_operand" "")
318   (match_operand:V2SF 1 "gpc_reg_operand" "")
319   (match_operand:V2SF 2 "gpc_reg_operand" "")
320   (match_operand:V2SI 3 "" "")]
321  "TARGET_PAIRED_FLOAT"
322{
323  if (rs6000_expand_vec_perm_const (operands))
324    DONE;
325  else
326    FAIL;
327})
328
329(define_insn "paired_sum0"
330  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
331	(vec_concat:V2SF (plus:SF (vec_select:SF
332				   (match_operand:V2SF 1 "gpc_reg_operand" "f")
333				   (parallel [(const_int 0)]))
334				  (vec_select:SF
335				   (match_operand:V2SF 2 "gpc_reg_operand" "f")
336				   (parallel [(const_int 1)])))
337			 (vec_select:SF
338			  (match_operand:V2SF 3 "gpc_reg_operand" "f")
339			  (parallel [(const_int 1)]))))]
340  "TARGET_PAIRED_FLOAT"
341  "ps_sum0 %0,%1,%2,%3"
342  [(set_attr "type" "fp")])
343
344(define_insn "paired_sum1"
345  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
346	(vec_concat:V2SF (vec_select:SF
347			  (match_operand:V2SF 2 "gpc_reg_operand" "f")
348			  (parallel [(const_int 1)]))
349			 (plus:SF (vec_select:SF
350				   (match_operand:V2SF 1 "gpc_reg_operand" "f")
351				   (parallel [(const_int 0)]))
352				  (vec_select:SF
353				   (match_operand:V2SF 3 "gpc_reg_operand" "f")
354				   (parallel [(const_int 1)])))))]
355  "TARGET_PAIRED_FLOAT"
356  "ps_sum1 %0,%1,%2,%3"
357  [(set_attr "type" "fp")])
358
359(define_insn "paired_muls0"
360  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
361	(mult:V2SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
362		   (vec_duplicate:V2SF
363		    (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
364				   (parallel [(const_int 0)])))))]
365  "TARGET_PAIRED_FLOAT"
366  "ps_muls0 %0, %1, %2"
367  [(set_attr "type" "fp")])
368
369
370(define_insn "paired_muls1"
371  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
372	(mult:V2SF (match_operand:V2SF 2 "gpc_reg_operand" "f")
373		   (vec_duplicate:V2SF
374		    (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
375				   (parallel [(const_int 1)])))))]
376  "TARGET_PAIRED_FLOAT"
377  "ps_muls1 %0, %1, %2"
378  [(set_attr "type" "fp")])
379
380(define_expand "vec_initv2sf"
381  [(match_operand:V2SF 0 "gpc_reg_operand" "=f")
382   (match_operand 1 "" "")]
383  "TARGET_PAIRED_FLOAT"
384{
385  paired_expand_vector_init (operands[0], operands[1]);
386  DONE;
387})
388
389(define_insn "*vconcatsf"
390  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
391        (vec_concat:V2SF
392         (match_operand:SF 1 "gpc_reg_operand" "f")
393         (match_operand:SF 2 "gpc_reg_operand" "f")))]
394  "TARGET_PAIRED_FLOAT"
395  "ps_merge00 %0, %1, %2"
396  [(set_attr "type" "fp")])
397
398(define_expand "sminv2sf3"
399  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
400        (smin:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
401                   (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
402  "TARGET_PAIRED_FLOAT"
403{
404  rtx tmp = gen_reg_rtx (V2SFmode);
405
406  emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2]));
407  emit_insn (gen_selv2sf4 (operands[0], tmp, operands[2], operands[1], CONST0_RTX (SFmode)));
408  DONE;
409})
410
411(define_expand "smaxv2sf3"
412  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
413        (smax:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
414                   (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
415  "TARGET_PAIRED_FLOAT"
416{
417  rtx tmp = gen_reg_rtx (V2SFmode);
418
419  emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2]));
420  emit_insn (gen_selv2sf4 (operands[0], tmp, operands[1], operands[2], CONST0_RTX (SFmode)));
421  DONE;
422})
423
424(define_expand "reduc_smax_v2sf"
425  [(match_operand:V2SF 0 "gpc_reg_operand" "=f")
426   (match_operand:V2SF 1 "gpc_reg_operand" "f")]
427  "TARGET_PAIRED_FLOAT"
428{
429  rtx tmp_swap = gen_reg_rtx (V2SFmode);
430  rtx tmp = gen_reg_rtx (V2SFmode);
431
432  emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1]));
433  emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap));
434  emit_insn (gen_selv2sf4 (operands[0], tmp, operands[1], tmp_swap, CONST0_RTX (SFmode)));
435
436  DONE;
437})
438
439(define_expand "reduc_smin_v2sf"
440  [(match_operand:V2SF 0 "gpc_reg_operand" "=f")
441   (match_operand:V2SF 1 "gpc_reg_operand" "f")]
442  "TARGET_PAIRED_FLOAT"
443{
444  rtx tmp_swap = gen_reg_rtx (V2SFmode);
445  rtx tmp = gen_reg_rtx (V2SFmode);
446
447  emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1]));
448  emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap));
449  emit_insn (gen_selv2sf4 (operands[0], tmp, tmp_swap, operands[1], CONST0_RTX (SFmode)));
450
451  DONE;
452})
453
454(define_expand "reduc_splus_v2sf"
455  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
456        (match_operand:V2SF 1 "gpc_reg_operand" "f"))]
457  "TARGET_PAIRED_FLOAT"
458  "
459{
460  emit_insn (gen_paired_sum1 (operands[0], operands[1], operands[1], operands[1]));
461  DONE;
462}")
463
464(define_expand "movmisalignv2sf"
465  [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
466        (match_operand:V2SF 1 "any_operand" ""))]
467  "TARGET_PAIRED_FLOAT"
468{
469  paired_expand_vector_move (operands);
470  DONE;
471})
472
473(define_expand "vcondv2sfv2sf"
474  [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
475        (if_then_else:V2SF
476         (match_operator 3 "gpc_reg_operand"
477                         [(match_operand:V2SF 4 "gpc_reg_operand" "f")
478                          (match_operand:V2SF 5 "gpc_reg_operand" "f")])
479         (match_operand:V2SF 1 "gpc_reg_operand" "f")
480         (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
481  "TARGET_PAIRED_FLOAT && flag_unsafe_math_optimizations"
482{
483  if (paired_emit_vector_cond_expr (operands[0], operands[1], operands[2],
484                                    operands[3], operands[4], operands[5]))
485    DONE;
486  else
487    FAIL;
488})
489