vector.md revision 1.1.1.2 1 ;;- Instruction patterns for the System z vector facility
2 ;; Copyright (C) 2015-2016 Free Software Foundation, Inc.
3 ;; Contributed by Andreas Krebbel (Andreas.Krebbel (a] de.ibm.com)
4
5 ;; This file is part of GCC.
6
7 ;; GCC is free software; you can redistribute it and/or modify it under
8 ;; the terms of the GNU General Public License as published by the Free
9 ;; Software Foundation; either version 3, or (at your option) any later
10 ;; version.
11
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 ;; for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 ; All vector modes supported in a vector register
22 (define_mode_iterator V
23 [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1SF
24 V2SF V4SF V1DF V2DF])
25 (define_mode_iterator VT
26 [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1SF
27 V2SF V4SF V1DF V2DF V1TF V1TI TI])
28
29 ; All vector modes directly supported by the hardware having full vector reg size
30 ; V_HW2 is duplicate of V_HW for having two iterators expanding
31 ; independently e.g. vcond
32 (define_mode_iterator V_HW [V16QI V8HI V4SI V2DI V2DF])
33 (define_mode_iterator V_HW2 [V16QI V8HI V4SI V2DI V2DF])
34 ; Including TI for instructions that support it (va, vn, ...)
35 (define_mode_iterator VT_HW [V16QI V8HI V4SI V2DI V2DF V1TI TI])
36
37 ; All full size integer vector modes supported in a vector register + TImode
38 (define_mode_iterator VIT_HW [V16QI V8HI V4SI V2DI V1TI TI])
39 (define_mode_iterator VI_HW [V16QI V8HI V4SI V2DI])
40 (define_mode_iterator VI_HW_QHS [V16QI V8HI V4SI])
41 (define_mode_iterator VI_HW_HS [V8HI V4SI])
42 (define_mode_iterator VI_HW_QH [V16QI V8HI])
43
44 ; All integer vector modes supported in a vector register + TImode
45 (define_mode_iterator VIT [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1TI TI])
46 (define_mode_iterator VI [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI])
47 (define_mode_iterator VI_QHS [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI])
48
49 (define_mode_iterator V_8 [V1QI])
50 (define_mode_iterator V_16 [V2QI V1HI])
51 (define_mode_iterator V_32 [V4QI V2HI V1SI V1SF])
52 (define_mode_iterator V_64 [V8QI V4HI V2SI V2SF V1DI V1DF])
53 (define_mode_iterator V_128 [V16QI V8HI V4SI V4SF V2DI V2DF V1TI V1TF])
54
55 ; A blank for vector modes and a * for TImode. This is used to hide
56 ; the TImode expander name in case it is defined already. See addti3
57 ; for an example.
58 (define_mode_attr ti* [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "")
59 (V1HI "") (V2HI "") (V4HI "") (V8HI "")
60 (V1SI "") (V2SI "") (V4SI "")
61 (V1DI "") (V2DI "")
62 (V1TI "*") (TI "*")])
63
64 ; The element type of the vector.
65 (define_mode_attr non_vec[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI")
66 (V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI")
67 (V1SI "SI") (V2SI "SI") (V4SI "SI")
68 (V1DI "DI") (V2DI "DI")
69 (V1TI "TI")
70 (V1SF "SF") (V2SF "SF") (V4SF "SF")
71 (V1DF "DF") (V2DF "DF")
72 (V1TF "TF")])
73
74 ; The instruction suffix
75 (define_mode_attr bhfgq[(V1QI "b") (V2QI "b") (V4QI "b") (V8QI "b") (V16QI "b")
76 (V1HI "h") (V2HI "h") (V4HI "h") (V8HI "h")
77 (V1SI "f") (V2SI "f") (V4SI "f")
78 (V1DI "g") (V2DI "g")
79 (V1TI "q") (TI "q")
80 (V1SF "f") (V2SF "f") (V4SF "f")
81 (V1DF "g") (V2DF "g")
82 (V1TF "q")])
83
84 ; This is for vmalhw. It gets an 'w' attached to avoid confusion with
85 ; multiply and add logical high vmalh.
86 (define_mode_attr w [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "")
87 (V1HI "w") (V2HI "w") (V4HI "w") (V8HI "w")
88 (V1SI "") (V2SI "") (V4SI "")
89 (V1DI "") (V2DI "")])
90
91 ; Resulting mode of a vector comparison. For floating point modes an
92 ; integer vector mode with the same element size is picked.
93 (define_mode_attr tointvec [(V1QI "V1QI") (V2QI "V2QI") (V4QI "V4QI") (V8QI "V8QI") (V16QI "V16QI")
94 (V1HI "V1HI") (V2HI "V2HI") (V4HI "V4HI") (V8HI "V8HI")
95 (V1SI "V1SI") (V2SI "V2SI") (V4SI "V4SI")
96 (V1DI "V1DI") (V2DI "V2DI")
97 (V1TI "V1TI")
98 (V1SF "V1SI") (V2SF "V2SI") (V4SF "V4SI")
99 (V1DF "V1DI") (V2DF "V2DI")
100 (V1TF "V1TI")])
101
102 ; Vector with doubled element size.
103 (define_mode_attr vec_double [(V1QI "V1HI") (V2QI "V1HI") (V4QI "V2HI") (V8QI "V4HI") (V16QI "V8HI")
104 (V1HI "V1SI") (V2HI "V1SI") (V4HI "V2SI") (V8HI "V4SI")
105 (V1SI "V1DI") (V2SI "V1DI") (V4SI "V2DI")
106 (V1DI "V1TI") (V2DI "V1TI")
107 (V1SF "V1DF") (V2SF "V1DF") (V4SF "V2DF")])
108
109 ; Vector with half the element size.
110 (define_mode_attr vec_half [(V1HI "V2QI") (V2HI "V4QI") (V4HI "V8QI") (V8HI "V16QI")
111 (V1SI "V2HI") (V2SI "V4HI") (V4SI "V8HI")
112 (V1DI "V2SI") (V2DI "V4SI")
113 (V1TI "V2DI")
114 (V1DF "V2SF") (V2DF "V4SF")
115 (V1TF "V1DF")])
116
117 ; The comparisons not setting CC iterate over the rtx code.
118 (define_code_iterator VFCMP_HW_OP [eq gt ge])
119 (define_code_attr asm_fcmp_op [(eq "e") (gt "h") (ge "he")])
120
121
122
123 ; Comparison operators on int and fp compares which are directly
124 ; supported by the HW.
125 (define_code_iterator VICMP_HW_OP [eq gt gtu])
126 ; For int insn_cmp_op can be used in the insn name as well as in the asm output.
127 (define_code_attr insn_cmp_op [(eq "eq") (gt "h") (gtu "hl") (ge "he")])
128
129 ; Flags for vector string instructions (vfae all 4, vfee only ZS and CS, vstrc all 4)
130 (define_constants
131 [(VSTRING_FLAG_IN 8) ; invert result
132 (VSTRING_FLAG_RT 4) ; result type
133 (VSTRING_FLAG_ZS 2) ; zero search
134 (VSTRING_FLAG_CS 1)]) ; condition code set
135
136 (include "vx-builtins.md")
137
138 ; Full HW vector size moves
139 (define_insn "mov<mode>"
140 [(set (match_operand:V_128 0 "nonimmediate_operand" "=v, v,QR, v, v, v, v, v,v,d")
141 (match_operand:V_128 1 "general_operand" " v,QR, v,j00,jm1,jyy,jxx,jKK,d,v"))]
142 "TARGET_VX"
143 "@
144 vlr\t%v0,%v1
145 vl\t%v0,%1
146 vst\t%v1,%0
147 vzero\t%v0
148 vone\t%v0
149 vgbm\t%v0,%t1
150 vgm<bhfgq>\t%v0,%s1,%e1
151 vrepi<bhfgq>\t%v0,%h1
152 vlvgp\t%v0,%1,%N1
153 #"
154 [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRI,VRI,VRI,VRI,VRR,*")])
155
156 (define_split
157 [(set (match_operand:V_128 0 "register_operand" "")
158 (match_operand:V_128 1 "register_operand" ""))]
159 "TARGET_VX && GENERAL_REG_P (operands[0]) && VECTOR_REG_P (operands[1])"
160 [(set (match_dup 2)
161 (unspec:DI [(subreg:V2DI (match_dup 1) 0)
162 (const_int 0)] UNSPEC_VEC_EXTRACT))
163 (set (match_dup 3)
164 (unspec:DI [(subreg:V2DI (match_dup 1) 0)
165 (const_int 1)] UNSPEC_VEC_EXTRACT))]
166 {
167 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
168 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
169 })
170
171 ; Moves for smaller vector modes.
172
173 ; In these patterns only the vlr, vone, and vzero instructions write
174 ; VR bytes outside the mode. This should be ok since we disallow
175 ; formerly bigger modes being accessed with smaller modes via
176 ; subreg. Note: The vone, vzero instructions could easily be replaced
177 ; with vlei which would only access the bytes belonging to the mode.
178 ; However, this would probably be slower.
179
180 (define_insn "mov<mode>"
181 [(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d, v,QR, v, v, v, v,d, Q, S, Q, S, d, d,d,d,d,R,T")
182 (match_operand:V_8 1 "general_operand" " v,d,v,QR, v,j00,jm1,jyy,jxx,d,j00,j00,jm1,jm1,j00,jm1,R,T,b,d,d"))]
183 ""
184 "@
185 vlr\t%v0,%v1
186 vlvgb\t%v0,%1,0
187 vlgvb\t%0,%v1,0
188 vleb\t%v0,%1,0
189 vsteb\t%v1,%0,0
190 vzero\t%v0
191 vone\t%v0
192 vgbm\t%v0,%t1
193 vgm\t%v0,%s1,%e1
194 lr\t%0,%1
195 mvi\t%0,0
196 mviy\t%0,0
197 mvi\t%0,-1
198 mviy\t%0,-1
199 lhi\t%0,0
200 lhi\t%0,-1
201 lh\t%0,%1
202 lhy\t%0,%1
203 lhrl\t%0,%1
204 stc\t%1,%0
205 stcy\t%1,%0"
206 [(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SI,SIY,SI,SIY,RI,RI,RX,RXY,RIL,RX,RXY")])
207
208 (define_insn "mov<mode>"
209 [(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d, v,QR, v, v, v, v,d, Q, Q, d, d,d,d,d,R,T,b")
210 (match_operand:V_16 1 "general_operand" " v,d,v,QR, v,j00,jm1,jyy,jxx,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
211 ""
212 "@
213 vlr\t%v0,%v1
214 vlvgh\t%v0,%1,0
215 vlgvh\t%0,%v1,0
216 vleh\t%v0,%1,0
217 vsteh\t%v1,%0,0
218 vzero\t%v0
219 vone\t%v0
220 vgbm\t%v0,%t1
221 vgm\t%v0,%s1,%e1
222 lr\t%0,%1
223 mvhhi\t%0,0
224 mvhhi\t%0,-1
225 lhi\t%0,0
226 lhi\t%0,-1
227 lh\t%0,%1
228 lhy\t%0,%1
229 lhrl\t%0,%1
230 sth\t%1,%0
231 sthy\t%1,%0
232 sthrl\t%1,%0"
233 [(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")])
234
235 (define_insn "mov<mode>"
236 [(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d, v,QR, f, v, v, v, v, Q, Q, d, d,d,d,d,d,R,T,b")
237 (match_operand:V_32 1 "general_operand" " f,R,T,f,f,v,d,v,QR, v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
238 "TARGET_VX"
239 "@
240 lder\t%v0,%v1
241 lde\t%0,%1
242 ley\t%0,%1
243 ste\t%1,%0
244 stey\t%1,%0
245 vlr\t%v0,%v1
246 vlvgf\t%v0,%1,0
247 vlgvf\t%0,%v1,0
248 vlef\t%v0,%1,0
249 vstef\t%1,%0,0
250 lzer\t%v0
251 vzero\t%v0
252 vone\t%v0
253 vgbm\t%v0,%t1
254 vgm\t%v0,%s1,%e1
255 mvhi\t%0,0
256 mvhi\t%0,-1
257 lhi\t%0,0
258 lhi\t%0,-1
259 lrl\t%0,%1
260 lr\t%0,%1
261 l\t%0,%1
262 ly\t%0,%1
263 st\t%1,%0
264 sty\t%1,%0
265 strl\t%1,%0"
266 [(set_attr "op_type" "RRE,RXE,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,SIL,SIL,RI,RI,
267 RIL,RR,RX,RXY,RX,RXY,RIL")])
268
269 (define_insn "mov<mode>"
270 [(set (match_operand:V_64 0 "nonimmediate_operand"
271 "=f,f,f,R,T,v,v,d, v,QR, f, v, v, v, v, Q, Q, d, d,f,d,d,d, d,RT,b")
272 (match_operand:V_64 1 "general_operand"
273 " f,R,T,f,f,v,d,v,QR, v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,d,f,b,d,RT, d,d"))]
274 "TARGET_ZARCH"
275 "@
276 ldr\t%0,%1
277 ld\t%0,%1
278 ldy\t%0,%1
279 std\t%1,%0
280 stdy\t%1,%0
281 vlr\t%v0,%v1
282 vlvgg\t%v0,%1,0
283 vlgvg\t%0,%v1,0
284 vleg\t%v0,%1,0
285 vsteg\t%v1,%0,0
286 lzdr\t%0
287 vzero\t%v0
288 vone\t%v0
289 vgbm\t%v0,%t1
290 vgm\t%v0,%s1,%e1
291 mvghi\t%0,0
292 mvghi\t%0,-1
293 lghi\t%0,0
294 lghi\t%0,-1
295 ldgr\t%0,%1
296 lgdr\t%0,%1
297 lgrl\t%0,%1
298 lgr\t%0,%1
299 lg\t%0,%1
300 stg\t%1,%0
301 stgrl\t%1,%0"
302 [(set_attr "op_type" "RRE,RX,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,
303 SIL,SIL,RI,RI,RRE,RRE,RIL,RR,RXY,RXY,RIL")])
304
305
306 ; vec_load_lanes?
307
308 ; vec_store_lanes?
309
310 ; vec_set is supposed to *modify* an existing vector so operand 0 is
311 ; duplicated as input operand.
312 (define_expand "vec_set<mode>"
313 [(set (match_operand:V 0 "register_operand" "")
314 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "")
315 (match_operand:SI 2 "nonmemory_operand" "")
316 (match_dup 0)]
317 UNSPEC_VEC_SET))]
318 "TARGET_VX")
319
320 ; FIXME: Support also vector mode operands for 1
321 ; FIXME: A target memory operand seems to be useful otherwise we end
322 ; up with vl vlvgg vst. Shouldn't the middle-end be able to handle
323 ; that itself?
324 (define_insn "*vec_set<mode>"
325 [(set (match_operand:V 0 "register_operand" "=v, v,v")
326 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,QR,K")
327 (match_operand:SI 2 "nonmemory_operand" "an, I,I")
328 (match_operand:V 3 "register_operand" "0, 0,0")]
329 UNSPEC_VEC_SET))]
330 "TARGET_VX
331 && (!CONST_INT_P (operands[2])
332 || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
333 "@
334 vlvg<bhfgq>\t%v0,%1,%Y2
335 vle<bhfgq>\t%v0,%1,%2
336 vlei<bhfgq>\t%v0,%1,%2"
337 [(set_attr "op_type" "VRS,VRX,VRI")])
338
339 (define_insn "*vec_set<mode>_plus"
340 [(set (match_operand:V 0 "register_operand" "=v")
341 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d")
342 (plus:SI (match_operand:SI 2 "register_operand" "a")
343 (match_operand:SI 4 "const_int_operand" "n"))
344 (match_operand:V 3 "register_operand" "0")]
345 UNSPEC_VEC_SET))]
346 "TARGET_VX"
347 "vlvg<bhfgq>\t%v0,%1,%Y4(%2)"
348 [(set_attr "op_type" "VRS")])
349
350
351 ; FIXME: Support also vector mode operands for 0
352 ; FIXME: This should be (vec_select ..) or something but it does only allow constant selectors :(
353 ; This is used via RTL standard name as well as for expanding the builtin
354 (define_expand "vec_extract<mode>"
355 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "")
356 (unspec:<non_vec> [(match_operand:V 1 "register_operand" "")
357 (match_operand:SI 2 "nonmemory_operand" "")]
358 UNSPEC_VEC_EXTRACT))]
359 "TARGET_VX")
360
361 (define_insn "*vec_extract<mode>"
362 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,QR")
363 (unspec:<non_vec> [(match_operand:V 1 "register_operand" "v, v")
364 (match_operand:SI 2 "nonmemory_operand" "an, I")]
365 UNSPEC_VEC_EXTRACT))]
366 "TARGET_VX
367 && (!CONST_INT_P (operands[2])
368 || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
369 "@
370 vlgv<bhfgq>\t%0,%v1,%Y2
371 vste<bhfgq>\t%v1,%0,%2"
372 [(set_attr "op_type" "VRS,VRX")])
373
374 (define_insn "*vec_extract<mode>_plus"
375 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d")
376 (unspec:<non_vec> [(match_operand:V 1 "register_operand" "v")
377 (plus:SI (match_operand:SI 2 "nonmemory_operand" "a")
378 (match_operand:SI 3 "const_int_operand" "n"))]
379 UNSPEC_VEC_EXTRACT))]
380 "TARGET_VX"
381 "vlgv<bhfgq>\t%0,%v1,%Y3(%2)"
382 [(set_attr "op_type" "VRS")])
383
384 (define_expand "vec_init<V_HW:mode>"
385 [(match_operand:V_HW 0 "register_operand" "")
386 (match_operand:V_HW 1 "nonmemory_operand" "")]
387 "TARGET_VX"
388 {
389 s390_expand_vec_init (operands[0], operands[1]);
390 DONE;
391 })
392
393 ; Replicate from vector element
394 (define_insn "*vec_splat<mode>"
395 [(set (match_operand:V_HW 0 "register_operand" "=v")
396 (vec_duplicate:V_HW
397 (vec_select:<non_vec>
398 (match_operand:V_HW 1 "register_operand" "v")
399 (parallel
400 [(match_operand:QI 2 "const_mask_operand" "C")]))))]
401 "TARGET_VX && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW:MODE>mode)"
402 "vrep<bhfgq>\t%v0,%v1,%2"
403 [(set_attr "op_type" "VRI")])
404
405 (define_insn "*vec_splats<mode>"
406 [(set (match_operand:V_HW 0 "register_operand" "=v,v,v,v")
407 (vec_duplicate:V_HW (match_operand:<non_vec> 1 "general_operand" "QR,K,v,d")))]
408 "TARGET_VX"
409 "@
410 vlrep<bhfgq>\t%v0,%1
411 vrepi<bhfgq>\t%v0,%h1
412 vrep<bhfgq>\t%v0,%v1,0
413 #"
414 [(set_attr "op_type" "VRX,VRI,VRI,*")])
415
416 ; vec_splats is supposed to replicate op1 into all elements of op0
417 ; This splitter first sets the rightmost element of op0 to op1 and
418 ; then does a vec_splat to replicate that element into all other
419 ; elements.
420 (define_split
421 [(set (match_operand:V_HW 0 "register_operand" "")
422 (vec_duplicate:V_HW (match_operand:<non_vec> 1 "register_operand" "")))]
423 "TARGET_VX && GENERAL_REG_P (operands[1])"
424 [(set (match_dup 0)
425 (unspec:V_HW [(match_dup 1) (match_dup 2) (match_dup 0)] UNSPEC_VEC_SET))
426 (set (match_dup 0)
427 (vec_duplicate:V_HW
428 (vec_select:<non_vec>
429 (match_dup 0) (parallel [(match_dup 2)]))))]
430 {
431 operands[2] = GEN_INT (GET_MODE_NUNITS (<MODE>mode) - 1);
432 })
433
434 (define_expand "vcond<V_HW:mode><V_HW2:mode>"
435 [(set (match_operand:V_HW 0 "register_operand" "")
436 (if_then_else:V_HW
437 (match_operator 3 "comparison_operator"
438 [(match_operand:V_HW2 4 "register_operand" "")
439 (match_operand:V_HW2 5 "nonmemory_operand" "")])
440 (match_operand:V_HW 1 "nonmemory_operand" "")
441 (match_operand:V_HW 2 "nonmemory_operand" "")))]
442 "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)"
443 {
444 s390_expand_vcond (operands[0], operands[1], operands[2],
445 GET_CODE (operands[3]), operands[4], operands[5]);
446 DONE;
447 })
448
449 (define_expand "vcondu<V_HW:mode><V_HW2:mode>"
450 [(set (match_operand:V_HW 0 "register_operand" "")
451 (if_then_else:V_HW
452 (match_operator 3 "comparison_operator"
453 [(match_operand:V_HW2 4 "register_operand" "")
454 (match_operand:V_HW2 5 "nonmemory_operand" "")])
455 (match_operand:V_HW 1 "nonmemory_operand" "")
456 (match_operand:V_HW 2 "nonmemory_operand" "")))]
457 "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)"
458 {
459 s390_expand_vcond (operands[0], operands[1], operands[2],
460 GET_CODE (operands[3]), operands[4], operands[5]);
461 DONE;
462 })
463
464 ; We only have HW support for byte vectors. The middle-end is
465 ; supposed to lower the mode if required.
466 (define_insn "vec_permv16qi"
467 [(set (match_operand:V16QI 0 "register_operand" "=v")
468 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
469 (match_operand:V16QI 2 "register_operand" "v")
470 (match_operand:V16QI 3 "register_operand" "v")]
471 UNSPEC_VEC_PERM))]
472 "TARGET_VX"
473 "vperm\t%v0,%v1,%v2,%v3"
474 [(set_attr "op_type" "VRR")])
475
476 ; vec_perm_const for V2DI using vpdi?
477
478 ;;
479 ;; Vector integer arithmetic instructions
480 ;;
481
482 ; vab, vah, vaf, vag, vaq
483
484 ; We use nonimmediate_operand instead of register_operand since it is
485 ; better to have the reloads into VRs instead of splitting the
486 ; operation into two DImode ADDs.
487 (define_insn "<ti*>add<mode>3"
488 [(set (match_operand:VIT 0 "nonimmediate_operand" "=v")
489 (plus:VIT (match_operand:VIT 1 "nonimmediate_operand" "%v")
490 (match_operand:VIT 2 "general_operand" "v")))]
491 "TARGET_VX"
492 "va<bhfgq>\t%v0,%v1,%v2"
493 [(set_attr "op_type" "VRR")])
494
495 ; vsb, vsh, vsf, vsg, vsq
496 (define_insn "<ti*>sub<mode>3"
497 [(set (match_operand:VIT 0 "nonimmediate_operand" "=v")
498 (minus:VIT (match_operand:VIT 1 "nonimmediate_operand" "v")
499 (match_operand:VIT 2 "general_operand" "v")))]
500 "TARGET_VX"
501 "vs<bhfgq>\t%v0,%v1,%v2"
502 [(set_attr "op_type" "VRR")])
503
504 ; vmlb, vmlhw, vmlf
505 (define_insn "mul<mode>3"
506 [(set (match_operand:VI_QHS 0 "register_operand" "=v")
507 (mult:VI_QHS (match_operand:VI_QHS 1 "register_operand" "%v")
508 (match_operand:VI_QHS 2 "register_operand" "v")))]
509 "TARGET_VX"
510 "vml<bhfgq><w>\t%v0,%v1,%v2"
511 [(set_attr "op_type" "VRR")])
512
513 ; vlcb, vlch, vlcf, vlcg
514 (define_insn "neg<mode>2"
515 [(set (match_operand:VI 0 "register_operand" "=v")
516 (neg:VI (match_operand:VI 1 "register_operand" "v")))]
517 "TARGET_VX"
518 "vlc<bhfgq>\t%v0,%v1"
519 [(set_attr "op_type" "VRR")])
520
521 ; vlpb, vlph, vlpf, vlpg
522 (define_insn "abs<mode>2"
523 [(set (match_operand:VI 0 "register_operand" "=v")
524 (abs:VI (match_operand:VI 1 "register_operand" "v")))]
525 "TARGET_VX"
526 "vlp<bhfgq>\t%v0,%v1"
527 [(set_attr "op_type" "VRR")])
528
529
530 ; Vector sum across
531
532 ; Sum across DImode parts of the 1st operand and add the rightmost
533 ; element of 2nd operand
534 ; vsumgh, vsumgf
535 (define_insn "*vec_sum2<mode>"
536 [(set (match_operand:V2DI 0 "register_operand" "=v")
537 (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "v")
538 (match_operand:VI_HW_HS 2 "register_operand" "v")]
539 UNSPEC_VEC_VSUMG))]
540 "TARGET_VX"
541 "vsumg<bhfgq>\t%v0,%v1,%v2"
542 [(set_attr "op_type" "VRR")])
543
544 ; vsumb, vsumh
545 (define_insn "*vec_sum4<mode>"
546 [(set (match_operand:V4SI 0 "register_operand" "=v")
547 (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "v")
548 (match_operand:VI_HW_QH 2 "register_operand" "v")]
549 UNSPEC_VEC_VSUM))]
550 "TARGET_VX"
551 "vsum<bhfgq>\t%v0,%v1,%v2"
552 [(set_attr "op_type" "VRR")])
553
554 ;;
555 ;; Vector bit instructions (int + fp)
556 ;;
557
558 ; Vector and
559
560 (define_insn "and<mode>3"
561 [(set (match_operand:VT 0 "register_operand" "=v")
562 (and:VT (match_operand:VT 1 "register_operand" "%v")
563 (match_operand:VT 2 "register_operand" "v")))]
564 "TARGET_VX"
565 "vn\t%v0,%v1,%v2"
566 [(set_attr "op_type" "VRR")])
567
568
569 ; Vector or
570
571 (define_insn "ior<mode>3"
572 [(set (match_operand:VT 0 "register_operand" "=v")
573 (ior:VT (match_operand:VT 1 "register_operand" "%v")
574 (match_operand:VT 2 "register_operand" "v")))]
575 "TARGET_VX"
576 "vo\t%v0,%v1,%v2"
577 [(set_attr "op_type" "VRR")])
578
579
580 ; Vector xor
581
582 (define_insn "xor<mode>3"
583 [(set (match_operand:VT 0 "register_operand" "=v")
584 (xor:VT (match_operand:VT 1 "register_operand" "%v")
585 (match_operand:VT 2 "register_operand" "v")))]
586 "TARGET_VX"
587 "vx\t%v0,%v1,%v2"
588 [(set_attr "op_type" "VRR")])
589
590
591 ; Bitwise inversion of a vector - used for vec_cmpne
592 (define_insn "*not<mode>"
593 [(set (match_operand:VT 0 "register_operand" "=v")
594 (not:VT (match_operand:VT 1 "register_operand" "v")))]
595 "TARGET_VX"
596 "vnot\t%v0,%v1"
597 [(set_attr "op_type" "VRR")])
598
599 ; Vector population count
600
601 (define_insn "popcountv16qi2"
602 [(set (match_operand:V16QI 0 "register_operand" "=v")
603 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
604 UNSPEC_POPCNT))]
605 "TARGET_VX"
606 "vpopct\t%v0,%v1,0"
607 [(set_attr "op_type" "VRR")])
608
609 ; vpopct only counts bits in byte elements. Bigger element sizes need
610 ; to be emulated. Word and doubleword elements can use the sum across
611 ; instructions. For halfword sized elements we do a shift of a copy
612 ; of the result, add it to the result and extend it to halfword
613 ; element size (unpack).
614
615 (define_expand "popcountv8hi2"
616 [(set (match_dup 2)
617 (unspec:V16QI [(subreg:V16QI (match_operand:V8HI 1 "register_operand" "v") 0)]
618 UNSPEC_POPCNT))
619 ; Make a copy of the result
620 (set (match_dup 3) (match_dup 2))
621 ; Generate the shift count operand in a VR (8->byte 7)
622 (set (match_dup 4) (match_dup 5))
623 (set (match_dup 4) (unspec:V16QI [(const_int 8)
624 (const_int 7)
625 (match_dup 4)] UNSPEC_VEC_SET))
626 ; Vector shift right logical by one byte
627 (set (match_dup 3)
628 (unspec:V16QI [(match_dup 3) (match_dup 4)] UNSPEC_VEC_SRLB))
629 ; Add the shifted and the original result
630 (set (match_dup 2)
631 (plus:V16QI (match_dup 2) (match_dup 3)))
632 ; Generate mask for the odd numbered byte elements
633 (set (match_dup 3)
634 (const_vector:V16QI [(const_int 0) (const_int 255)
635 (const_int 0) (const_int 255)
636 (const_int 0) (const_int 255)
637 (const_int 0) (const_int 255)
638 (const_int 0) (const_int 255)
639 (const_int 0) (const_int 255)
640 (const_int 0) (const_int 255)
641 (const_int 0) (const_int 255)]))
642 ; Zero out the even indexed bytes
643 (set (match_operand:V8HI 0 "register_operand" "=v")
644 (and:V8HI (subreg:V8HI (match_dup 2) 0)
645 (subreg:V8HI (match_dup 3) 0)))
646 ]
647 "TARGET_VX"
648 {
649 operands[2] = gen_reg_rtx (V16QImode);
650 operands[3] = gen_reg_rtx (V16QImode);
651 operands[4] = gen_reg_rtx (V16QImode);
652 operands[5] = CONST0_RTX (V16QImode);
653 })
654
655 (define_expand "popcountv4si2"
656 [(set (match_dup 2)
657 (unspec:V16QI [(subreg:V16QI (match_operand:V4SI 1 "register_operand" "v") 0)]
658 UNSPEC_POPCNT))
659 (set (match_operand:V4SI 0 "register_operand" "=v")
660 (unspec:V4SI [(match_dup 2) (match_dup 3)]
661 UNSPEC_VEC_VSUM))]
662 "TARGET_VX"
663 {
664 operands[2] = gen_reg_rtx (V16QImode);
665 operands[3] = force_reg (V16QImode, CONST0_RTX (V16QImode));
666 })
667
668 (define_expand "popcountv2di2"
669 [(set (match_dup 2)
670 (unspec:V16QI [(subreg:V16QI (match_operand:V2DI 1 "register_operand" "v") 0)]
671 UNSPEC_POPCNT))
672 (set (match_dup 3)
673 (unspec:V4SI [(match_dup 2) (match_dup 4)]
674 UNSPEC_VEC_VSUM))
675 (set (match_operand:V2DI 0 "register_operand" "=v")
676 (unspec:V2DI [(match_dup 3) (match_dup 5)]
677 UNSPEC_VEC_VSUMG))]
678 "TARGET_VX"
679 {
680 operands[2] = gen_reg_rtx (V16QImode);
681 operands[3] = gen_reg_rtx (V4SImode);
682 operands[4] = force_reg (V16QImode, CONST0_RTX (V16QImode));
683 operands[5] = force_reg (V4SImode, CONST0_RTX (V4SImode));
684 })
685
686 ; Count leading zeros
687 (define_insn "clz<mode>2"
688 [(set (match_operand:V 0 "register_operand" "=v")
689 (clz:V (match_operand:V 1 "register_operand" "v")))]
690 "TARGET_VX"
691 "vclz<bhfgq>\t%v0,%v1"
692 [(set_attr "op_type" "VRR")])
693
694 ; Count trailing zeros
695 (define_insn "ctz<mode>2"
696 [(set (match_operand:V 0 "register_operand" "=v")
697 (ctz:V (match_operand:V 1 "register_operand" "v")))]
698 "TARGET_VX"
699 "vctz<bhfgq>\t%v0,%v1"
700 [(set_attr "op_type" "VRR")])
701
702
703
704 ; Each vector element rotated by the corresponding vector element
705 ; verllvb, verllvh, verllvf, verllvg
706 (define_insn "vrotl<mode>3"
707 [(set (match_operand:VI 0 "register_operand" "=v")
708 (rotate:VI (match_operand:VI 1 "register_operand" "v")
709 (match_operand:VI 2 "register_operand" "v")))]
710 "TARGET_VX"
711 "verllv<bhfgq>\t%v0,%v1,%v2"
712 [(set_attr "op_type" "VRR")])
713
714
715 ; Vector rotate and shift by scalar instructions
716
717 (define_code_iterator VEC_SHIFTS [ashift ashiftrt lshiftrt rotate])
718 (define_code_attr vec_shifts_name [(ashift "ashl") (ashiftrt "ashr")
719 (lshiftrt "lshr") (rotate "rotl")])
720 (define_code_attr vec_shifts_mnem [(ashift "vesl") (ashiftrt "vesra")
721 (lshiftrt "vesrl") (rotate "verll")])
722
723 ; Each vector element rotated by a scalar
724 (define_expand "<vec_shifts_name><mode>3"
725 [(set (match_operand:VI 0 "register_operand" "")
726 (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "")
727 (match_operand:SI 2 "nonmemory_operand" "")))]
728 "TARGET_VX")
729
730 ; verllb, verllh, verllf, verllg
731 ; veslb, veslh, veslf, veslg
732 ; vesrab, vesrah, vesraf, vesrag
733 ; vesrlb, vesrlh, vesrlf, vesrlg
734 (define_insn "*<vec_shifts_name><mode>3<addr_style_op>"
735 [(set (match_operand:VI 0 "register_operand" "=v")
736 (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "v")
737 (match_operand:SI 2 "nonmemory_operand" "an")))]
738 "TARGET_VX"
739 "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2"
740 [(set_attr "op_type" "VRS")])
741
742 ; Shift each element by corresponding vector element
743
744 ; veslvb, veslvh, veslvf, veslvg
745 (define_insn "vashl<mode>3"
746 [(set (match_operand:VI 0 "register_operand" "=v")
747 (ashift:VI (match_operand:VI 1 "register_operand" "v")
748 (match_operand:VI 2 "register_operand" "v")))]
749 "TARGET_VX"
750 "veslv<bhfgq>\t%v0,%v1,%v2"
751 [(set_attr "op_type" "VRR")])
752
753 ; vesravb, vesravh, vesravf, vesravg
754 (define_insn "vashr<mode>3"
755 [(set (match_operand:VI 0 "register_operand" "=v")
756 (ashiftrt:VI (match_operand:VI 1 "register_operand" "v")
757 (match_operand:VI 2 "register_operand" "v")))]
758 "TARGET_VX"
759 "vesrav<bhfgq>\t%v0,%v1,%v2"
760 [(set_attr "op_type" "VRR")])
761
762 ; vesrlvb, vesrlvh, vesrlvf, vesrlvg
763 (define_insn "vlshr<mode>3"
764 [(set (match_operand:VI 0 "register_operand" "=v")
765 (lshiftrt:VI (match_operand:VI 1 "register_operand" "v")
766 (match_operand:VI 2 "register_operand" "v")))]
767 "TARGET_VX"
768 "vesrlv<bhfgq>\t%v0,%v1,%v2"
769 [(set_attr "op_type" "VRR")])
770
771 ; Vector shift right logical by byte
772
773 ; Pattern used by e.g. popcount
774 (define_insn "*vec_srb<mode>"
775 [(set (match_operand:V_HW 0 "register_operand" "=v")
776 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
777 (match_operand:<tointvec> 2 "register_operand" "v")]
778 UNSPEC_VEC_SRLB))]
779 "TARGET_VX"
780 "vsrlb\t%v0,%v1,%v2"
781 [(set_attr "op_type" "VRR")])
782
783
784 ; vmnb, vmnh, vmnf, vmng
785 (define_insn "smin<mode>3"
786 [(set (match_operand:VI 0 "register_operand" "=v")
787 (smin:VI (match_operand:VI 1 "register_operand" "%v")
788 (match_operand:VI 2 "register_operand" "v")))]
789 "TARGET_VX"
790 "vmn<bhfgq>\t%v0,%v1,%v2"
791 [(set_attr "op_type" "VRR")])
792
793 ; vmxb, vmxh, vmxf, vmxg
794 (define_insn "smax<mode>3"
795 [(set (match_operand:VI 0 "register_operand" "=v")
796 (smax:VI (match_operand:VI 1 "register_operand" "%v")
797 (match_operand:VI 2 "register_operand" "v")))]
798 "TARGET_VX"
799 "vmx<bhfgq>\t%v0,%v1,%v2"
800 [(set_attr "op_type" "VRR")])
801
802 ; vmnlb, vmnlh, vmnlf, vmnlg
803 (define_insn "umin<mode>3"
804 [(set (match_operand:VI 0 "register_operand" "=v")
805 (umin:VI (match_operand:VI 1 "register_operand" "%v")
806 (match_operand:VI 2 "register_operand" "v")))]
807 "TARGET_VX"
808 "vmnl<bhfgq>\t%v0,%v1,%v2"
809 [(set_attr "op_type" "VRR")])
810
811 ; vmxlb, vmxlh, vmxlf, vmxlg
812 (define_insn "umax<mode>3"
813 [(set (match_operand:VI 0 "register_operand" "=v")
814 (umax:VI (match_operand:VI 1 "register_operand" "%v")
815 (match_operand:VI 2 "register_operand" "v")))]
816 "TARGET_VX"
817 "vmxl<bhfgq>\t%v0,%v1,%v2"
818 [(set_attr "op_type" "VRR")])
819
820 ; vmeb, vmeh, vmef
821 (define_insn "vec_widen_smult_even_<mode>"
822 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
823 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
824 (match_operand:VI_QHS 2 "register_operand" "v")]
825 UNSPEC_VEC_SMULT_EVEN))]
826 "TARGET_VX"
827 "vme<bhfgq>\t%v0,%v1,%v2"
828 [(set_attr "op_type" "VRR")])
829
830 ; vmleb, vmleh, vmlef
831 (define_insn "vec_widen_umult_even_<mode>"
832 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
833 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
834 (match_operand:VI_QHS 2 "register_operand" "v")]
835 UNSPEC_VEC_UMULT_EVEN))]
836 "TARGET_VX"
837 "vmle<bhfgq>\t%v0,%v1,%v2"
838 [(set_attr "op_type" "VRR")])
839
840 ; vmob, vmoh, vmof
841 (define_insn "vec_widen_smult_odd_<mode>"
842 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
843 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
844 (match_operand:VI_QHS 2 "register_operand" "v")]
845 UNSPEC_VEC_SMULT_ODD))]
846 "TARGET_VX"
847 "vmo<bhfgq>\t%v0,%v1,%v2"
848 [(set_attr "op_type" "VRR")])
849
850 ; vmlob, vmloh, vmlof
851 (define_insn "vec_widen_umult_odd_<mode>"
852 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
853 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
854 (match_operand:VI_QHS 2 "register_operand" "v")]
855 UNSPEC_VEC_UMULT_ODD))]
856 "TARGET_VX"
857 "vmlo<bhfgq>\t%v0,%v1,%v2"
858 [(set_attr "op_type" "VRR")])
859
860 ; vec_widen_umult_hi
861 ; vec_widen_umult_lo
862 ; vec_widen_smult_hi
863 ; vec_widen_smult_lo
864
865 ; vec_widen_ushiftl_hi
866 ; vec_widen_ushiftl_lo
867 ; vec_widen_sshiftl_hi
868 ; vec_widen_sshiftl_lo
869
870 ;;
871 ;; Vector floating point arithmetic instructions
872 ;;
873
874 (define_insn "addv2df3"
875 [(set (match_operand:V2DF 0 "register_operand" "=v")
876 (plus:V2DF (match_operand:V2DF 1 "register_operand" "%v")
877 (match_operand:V2DF 2 "register_operand" "v")))]
878 "TARGET_VX"
879 "vfadb\t%v0,%v1,%v2"
880 [(set_attr "op_type" "VRR")])
881
882 (define_insn "subv2df3"
883 [(set (match_operand:V2DF 0 "register_operand" "=v")
884 (minus:V2DF (match_operand:V2DF 1 "register_operand" "%v")
885 (match_operand:V2DF 2 "register_operand" "v")))]
886 "TARGET_VX"
887 "vfsdb\t%v0,%v1,%v2"
888 [(set_attr "op_type" "VRR")])
889
890 (define_insn "mulv2df3"
891 [(set (match_operand:V2DF 0 "register_operand" "=v")
892 (mult:V2DF (match_operand:V2DF 1 "register_operand" "%v")
893 (match_operand:V2DF 2 "register_operand" "v")))]
894 "TARGET_VX"
895 "vfmdb\t%v0,%v1,%v2"
896 [(set_attr "op_type" "VRR")])
897
898 (define_insn "divv2df3"
899 [(set (match_operand:V2DF 0 "register_operand" "=v")
900 (div:V2DF (match_operand:V2DF 1 "register_operand" "v")
901 (match_operand:V2DF 2 "register_operand" "v")))]
902 "TARGET_VX"
903 "vfddb\t%v0,%v1,%v2"
904 [(set_attr "op_type" "VRR")])
905
906 (define_insn "sqrtv2df2"
907 [(set (match_operand:V2DF 0 "register_operand" "=v")
908 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "v")))]
909 "TARGET_VX"
910 "vfsqdb\t%v0,%v1"
911 [(set_attr "op_type" "VRR")])
912
913 (define_insn "fmav2df4"
914 [(set (match_operand:V2DF 0 "register_operand" "=v")
915 (fma:V2DF (match_operand:V2DF 1 "register_operand" "%v")
916 (match_operand:V2DF 2 "register_operand" "v")
917 (match_operand:V2DF 3 "register_operand" "v")))]
918 "TARGET_VX"
919 "vfmadb\t%v0,%v1,%v2,%v3"
920 [(set_attr "op_type" "VRR")])
921
922 (define_insn "fmsv2df4"
923 [(set (match_operand:V2DF 0 "register_operand" "=v")
924 (fma:V2DF (match_operand:V2DF 1 "register_operand" "%v")
925 (match_operand:V2DF 2 "register_operand" "v")
926 (neg:V2DF (match_operand:V2DF 3 "register_operand" "v"))))]
927 "TARGET_VX"
928 "vfmsdb\t%v0,%v1,%v2,%v3"
929 [(set_attr "op_type" "VRR")])
930
931 (define_insn "negv2df2"
932 [(set (match_operand:V2DF 0 "register_operand" "=v")
933 (neg:V2DF (match_operand:V2DF 1 "register_operand" "v")))]
934 "TARGET_VX"
935 "vflcdb\t%v0,%v1"
936 [(set_attr "op_type" "VRR")])
937
938 (define_insn "absv2df2"
939 [(set (match_operand:V2DF 0 "register_operand" "=v")
940 (abs:V2DF (match_operand:V2DF 1 "register_operand" "v")))]
941 "TARGET_VX"
942 "vflpdb\t%v0,%v1"
943 [(set_attr "op_type" "VRR")])
944
945 (define_insn "*negabsv2df2"
946 [(set (match_operand:V2DF 0 "register_operand" "=v")
947 (neg:V2DF (abs:V2DF (match_operand:V2DF 1 "register_operand" "v"))))]
948 "TARGET_VX"
949 "vflndb\t%v0,%v1"
950 [(set_attr "op_type" "VRR")])
951
952 ; Emulate with compare + select
953 (define_insn_and_split "smaxv2df3"
954 [(set (match_operand:V2DF 0 "register_operand" "=v")
955 (smax:V2DF (match_operand:V2DF 1 "register_operand" "%v")
956 (match_operand:V2DF 2 "register_operand" "v")))]
957 "TARGET_VX"
958 "#"
959 ""
960 [(set (match_dup 3)
961 (gt:V2DI (match_dup 1) (match_dup 2)))
962 (set (match_dup 0)
963 (if_then_else:V2DF
964 (eq (match_dup 3) (match_dup 4))
965 (match_dup 2)
966 (match_dup 1)))]
967 {
968 operands[3] = gen_reg_rtx (V2DImode);
969 operands[4] = CONST0_RTX (V2DImode);
970 })
971
972 ; Emulate with compare + select
973 (define_insn_and_split "sminv2df3"
974 [(set (match_operand:V2DF 0 "register_operand" "=v")
975 (smin:V2DF (match_operand:V2DF 1 "register_operand" "%v")
976 (match_operand:V2DF 2 "register_operand" "v")))]
977 "TARGET_VX"
978 "#"
979 ""
980 [(set (match_dup 3)
981 (gt:V2DI (match_dup 1) (match_dup 2)))
982 (set (match_dup 0)
983 (if_then_else:V2DF
984 (eq (match_dup 3) (match_dup 4))
985 (match_dup 1)
986 (match_dup 2)))]
987 {
988 operands[3] = gen_reg_rtx (V2DImode);
989 operands[4] = CONST0_RTX (V2DImode);
990 })
991
992
993 ;;
994 ;; Integer compares
995 ;;
996
997 (define_insn "*vec_cmp<VICMP_HW_OP:code><VI:mode>_nocc"
998 [(set (match_operand:VI 2 "register_operand" "=v")
999 (VICMP_HW_OP:VI (match_operand:VI 0 "register_operand" "v")
1000 (match_operand:VI 1 "register_operand" "v")))]
1001 "TARGET_VX"
1002 "vc<VICMP_HW_OP:insn_cmp_op><VI:bhfgq>\t%v2,%v0,%v1"
1003 [(set_attr "op_type" "VRR")])
1004
1005
1006 ;;
1007 ;; Floating point compares
1008 ;;
1009
1010 ; EQ, GT, GE
1011 (define_insn "*vec_cmp<VFCMP_HW_OP:code>v2df_nocc"
1012 [(set (match_operand:V2DI 0 "register_operand" "=v")
1013 (VFCMP_HW_OP:V2DI (match_operand:V2DF 1 "register_operand" "v")
1014 (match_operand:V2DF 2 "register_operand" "v")))]
1015 "TARGET_VX"
1016 "vfc<VFCMP_HW_OP:asm_fcmp_op>db\t%v0,%v1,%v2"
1017 [(set_attr "op_type" "VRR")])
1018
1019 ; Expanders for not directly supported comparisons
1020
1021 ; UNEQ a u== b -> !(a > b | b > a)
1022 (define_expand "vec_cmpuneqv2df"
1023 [(set (match_operand:V2DI 0 "register_operand" "=v")
1024 (gt:V2DI (match_operand:V2DF 1 "register_operand" "v")
1025 (match_operand:V2DF 2 "register_operand" "v")))
1026 (set (match_dup 3)
1027 (gt:V2DI (match_dup 2) (match_dup 1)))
1028 (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))
1029 (set (match_dup 0) (not:V2DI (match_dup 0)))]
1030 "TARGET_VX"
1031 {
1032 operands[3] = gen_reg_rtx (V2DImode);
1033 })
1034
1035 ; LTGT a <> b -> a > b | b > a
1036 (define_expand "vec_cmpltgtv2df"
1037 [(set (match_operand:V2DI 0 "register_operand" "=v")
1038 (gt:V2DI (match_operand:V2DF 1 "register_operand" "v")
1039 (match_operand:V2DF 2 "register_operand" "v")))
1040 (set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
1041 (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))]
1042 "TARGET_VX"
1043 {
1044 operands[3] = gen_reg_rtx (V2DImode);
1045 })
1046
1047 ; ORDERED (a, b): a >= b | b > a
1048 (define_expand "vec_orderedv2df"
1049 [(set (match_operand:V2DI 0 "register_operand" "=v")
1050 (ge:V2DI (match_operand:V2DF 1 "register_operand" "v")
1051 (match_operand:V2DF 2 "register_operand" "v")))
1052 (set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
1053 (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))]
1054 "TARGET_VX"
1055 {
1056 operands[3] = gen_reg_rtx (V2DImode);
1057 })
1058
1059 ; UNORDERED (a, b): !ORDERED (a, b)
1060 (define_expand "vec_unorderedv2df"
1061 [(set (match_operand:V2DI 0 "register_operand" "=v")
1062 (ge:V2DI (match_operand:V2DF 1 "register_operand" "v")
1063 (match_operand:V2DF 2 "register_operand" "v")))
1064 (set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
1065 (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))
1066 (set (match_dup 0) (not:V2DI (match_dup 0)))]
1067 "TARGET_VX"
1068 {
1069 operands[3] = gen_reg_rtx (V2DImode);
1070 })
1071
1072 (define_insn "*vec_load_pairv2di"
1073 [(set (match_operand:V2DI 0 "register_operand" "=v")
1074 (vec_concat:V2DI (match_operand:DI 1 "register_operand" "d")
1075 (match_operand:DI 2 "register_operand" "d")))]
1076 "TARGET_VX"
1077 "vlvgp\t%v0,%1,%2"
1078 [(set_attr "op_type" "VRR")])
1079
1080 (define_insn "vllv16qi"
1081 [(set (match_operand:V16QI 0 "register_operand" "=v")
1082 (unspec:V16QI [(match_operand:SI 1 "register_operand" "d")
1083 (match_operand:BLK 2 "memory_operand" "Q")]
1084 UNSPEC_VEC_LOAD_LEN))]
1085 "TARGET_VX"
1086 "vll\t%v0,%1,%2"
1087 [(set_attr "op_type" "VRS")])
1088
1089 ; vfenebs, vfenehs, vfenefs
1090 ; vfenezbs, vfenezhs, vfenezfs
1091 (define_insn "vec_vfenes<mode>"
1092 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1093 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1094 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1095 (match_operand:QI 3 "const_mask_operand" "C")]
1096 UNSPEC_VEC_VFENE))
1097 (set (reg:CCRAW CC_REGNUM)
1098 (unspec:CCRAW [(match_dup 1)
1099 (match_dup 2)
1100 (match_dup 3)]
1101 UNSPEC_VEC_VFENECC))]
1102 "TARGET_VX"
1103 {
1104 unsigned HOST_WIDE_INT flags = INTVAL (operands[3]);
1105
1106 gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
1107 flags &= ~VSTRING_FLAG_CS;
1108
1109 if (flags == VSTRING_FLAG_ZS)
1110 return "vfenez<bhfgq>s\t%v0,%v1,%v2";
1111 return "vfene<bhfgq>s\t%v0,%v1,%v2";
1112 }
1113 [(set_attr "op_type" "VRR")])
1114
1115
1116 ; Vector select
1117
1118 ; The following splitters simplify vec_sel for constant 0 or -1
1119 ; selection sources. This is required to generate efficient code for
1120 ; vcond.
1121
1122 ; a = b == c;
1123 (define_split
1124 [(set (match_operand:V 0 "register_operand" "")
1125 (if_then_else:V
1126 (eq (match_operand:<tointvec> 3 "register_operand" "")
1127 (match_operand:V 4 "const0_operand" ""))
1128 (match_operand:V 1 "const0_operand" "")
1129 (match_operand:V 2 "all_ones_operand" "")))]
1130 "TARGET_VX"
1131 [(set (match_dup 0) (match_dup 3))]
1132 {
1133 PUT_MODE (operands[3], <V:MODE>mode);
1134 })
1135
1136 ; a = ~(b == c)
1137 (define_split
1138 [(set (match_operand:V 0 "register_operand" "")
1139 (if_then_else:V
1140 (eq (match_operand:<tointvec> 3 "register_operand" "")
1141 (match_operand:V 4 "const0_operand" ""))
1142 (match_operand:V 1 "all_ones_operand" "")
1143 (match_operand:V 2 "const0_operand" "")))]
1144 "TARGET_VX"
1145 [(set (match_dup 0) (not:V (match_dup 3)))]
1146 {
1147 PUT_MODE (operands[3], <V:MODE>mode);
1148 })
1149
1150 ; a = b != c
1151 (define_split
1152 [(set (match_operand:V 0 "register_operand" "")
1153 (if_then_else:V
1154 (ne (match_operand:<tointvec> 3 "register_operand" "")
1155 (match_operand:V 4 "const0_operand" ""))
1156 (match_operand:V 1 "all_ones_operand" "")
1157 (match_operand:V 2 "const0_operand" "")))]
1158 "TARGET_VX"
1159 [(set (match_dup 0) (match_dup 3))]
1160 {
1161 PUT_MODE (operands[3], <V:MODE>mode);
1162 })
1163
1164 ; a = ~(b != c)
1165 (define_split
1166 [(set (match_operand:V 0 "register_operand" "")
1167 (if_then_else:V
1168 (ne (match_operand:<tointvec> 3 "register_operand" "")
1169 (match_operand:V 4 "const0_operand" ""))
1170 (match_operand:V 1 "const0_operand" "")
1171 (match_operand:V 2 "all_ones_operand" "")))]
1172 "TARGET_VX"
1173 [(set (match_dup 0) (not:V (match_dup 3)))]
1174 {
1175 PUT_MODE (operands[3], <V:MODE>mode);
1176 })
1177
1178 ; op0 = op3 == 0 ? op1 : op2
1179 (define_insn "*vec_sel0<mode>"
1180 [(set (match_operand:V 0 "register_operand" "=v")
1181 (if_then_else:V
1182 (eq (match_operand:<tointvec> 3 "register_operand" "v")
1183 (match_operand:<tointvec> 4 "const0_operand" ""))
1184 (match_operand:V 1 "register_operand" "v")
1185 (match_operand:V 2 "register_operand" "v")))]
1186 "TARGET_VX"
1187 "vsel\t%v0,%2,%1,%3"
1188 [(set_attr "op_type" "VRR")])
1189
1190 ; op0 = !op3 == 0 ? op1 : op2
1191 (define_insn "*vec_sel0<mode>"
1192 [(set (match_operand:V 0 "register_operand" "=v")
1193 (if_then_else:V
1194 (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
1195 (match_operand:<tointvec> 4 "const0_operand" ""))
1196 (match_operand:V 1 "register_operand" "v")
1197 (match_operand:V 2 "register_operand" "v")))]
1198 "TARGET_VX"
1199 "vsel\t%v0,%1,%2,%3"
1200 [(set_attr "op_type" "VRR")])
1201
1202 ; op0 = op3 == -1 ? op1 : op2
1203 (define_insn "*vec_sel1<mode>"
1204 [(set (match_operand:V 0 "register_operand" "=v")
1205 (if_then_else:V
1206 (eq (match_operand:<tointvec> 3 "register_operand" "v")
1207 (match_operand:<tointvec> 4 "all_ones_operand" ""))
1208 (match_operand:V 1 "register_operand" "v")
1209 (match_operand:V 2 "register_operand" "v")))]
1210 "TARGET_VX"
1211 "vsel\t%v0,%1,%2,%3"
1212 [(set_attr "op_type" "VRR")])
1213
1214 ; op0 = !op3 == -1 ? op1 : op2
1215 (define_insn "*vec_sel1<mode>"
1216 [(set (match_operand:V 0 "register_operand" "=v")
1217 (if_then_else:V
1218 (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
1219 (match_operand:<tointvec> 4 "all_ones_operand" ""))
1220 (match_operand:V 1 "register_operand" "v")
1221 (match_operand:V 2 "register_operand" "v")))]
1222 "TARGET_VX"
1223 "vsel\t%v0,%2,%1,%3"
1224 [(set_attr "op_type" "VRR")])
1225
1226
1227
1228 ; reduc_smin
1229 ; reduc_smax
1230 ; reduc_umin
1231 ; reduc_umax
1232
1233 ; vec_shl vrep + vsl
1234 ; vec_shr
1235
1236 ; vec_pack_trunc
1237 ; vec_pack_ssat
1238 ; vec_pack_usat
1239 ; vec_pack_sfix_trunc
1240 ; vec_pack_ufix_trunc
1241 ; vec_unpacks_hi
1242 ; vec_unpacks_low
1243 ; vec_unpacku_hi
1244 ; vec_unpacku_low
1245 ; vec_unpacks_float_hi
1246 ; vec_unpacks_float_lo
1247 ; vec_unpacku_float_hi
1248 ; vec_unpacku_float_lo
1249