vector.md revision 1.1.1.3 1 ;;- Instruction patterns for the System z vector facility
2 ;; Copyright (C) 2015-2017 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 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 (V4SF "TARGET_VXE") (V1TF "TARGET_VXE")])
33 (define_mode_iterator V_HW2 [V16QI V8HI V4SI V2DI V2DF (V4SF "TARGET_VXE") (V1TF "TARGET_VXE")])
34
35 (define_mode_iterator V_HW_64 [V2DI V2DF])
36
37 ; Including TI for instructions that support it (va, vn, ...)
38 (define_mode_iterator VT_HW [V16QI V8HI V4SI V2DI V2DF V1TI TI (V4SF "TARGET_VXE") (V1TF "TARGET_VXE")])
39
40 ; All full size integer vector modes supported in a vector register + TImode
41 (define_mode_iterator VIT_HW [V16QI V8HI V4SI V2DI V1TI TI])
42 (define_mode_iterator VI_HW [V16QI V8HI V4SI V2DI])
43 (define_mode_iterator VI_HW_QHS [V16QI V8HI V4SI])
44 (define_mode_iterator VI_HW_HSD [V8HI V4SI V2DI])
45 (define_mode_iterator VI_HW_HS [V8HI V4SI])
46 (define_mode_iterator VI_HW_QH [V16QI V8HI])
47 (define_mode_iterator VI_HW_4 [V4SI V4SF])
48
49 ; All integer vector modes supported in a vector register + TImode
50 (define_mode_iterator VIT [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1TI TI])
51 (define_mode_iterator VI [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI])
52 (define_mode_iterator VI_QHS [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI])
53
54 (define_mode_iterator VFT [(V1SF "TARGET_VXE") (V2SF "TARGET_VXE") (V4SF "TARGET_VXE")
55 V1DF V2DF
56 (V1TF "TARGET_VXE")])
57
58 ; FP vector modes directly supported by the HW. This does not include
59 ; vector modes using only part of a vector register and should be used
60 ; for instructions which might trigger IEEE exceptions.
61 (define_mode_iterator VF_HW [(V4SF "TARGET_VXE") V2DF (V1TF "TARGET_VXE")])
62
63 (define_mode_iterator V_8 [V1QI])
64 (define_mode_iterator V_16 [V2QI V1HI])
65 (define_mode_iterator V_32 [V4QI V2HI V1SI V1SF])
66 (define_mode_iterator V_64 [V8QI V4HI V2SI V2SF V1DI V1DF])
67 (define_mode_iterator V_128 [V16QI V8HI V4SI V4SF V2DI V2DF V1TI V1TF])
68
69 (define_mode_iterator V_128_NOSINGLE [V16QI V8HI V4SI V4SF V2DI V2DF])
70
71 ; Empty string for all but TImode. This is used to hide the TImode
72 ; expander name in case it is defined already. See addti3 for an
73 ; example.
74 (define_mode_attr ti* [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "")
75 (V1HI "") (V2HI "") (V4HI "") (V8HI "")
76 (V1SI "") (V2SI "") (V4SI "")
77 (V1DI "") (V2DI "")
78 (V1TI "") (TI "*")
79 (V1SF "") (V2SF "") (V4SF "")
80 (V1DF "") (V2DF "")
81 (V1TF "") (TF "")])
82
83 ; The element type of the vector.
84 (define_mode_attr non_vec[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI")
85 (V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI")
86 (V1SI "SI") (V2SI "SI") (V4SI "SI")
87 (V1DI "DI") (V2DI "DI")
88 (V1TI "TI") (TI "TI")
89 (V1SF "SF") (V2SF "SF") (V4SF "SF")
90 (V1DF "DF") (V2DF "DF")
91 (V1TF "TF") (TF "TF")])
92
93 ; The instruction suffix for integer instructions and instructions
94 ; which do not care about whether it is floating point or integer.
95 (define_mode_attr bhfgq[(V1QI "b") (V2QI "b") (V4QI "b") (V8QI "b") (V16QI "b")
96 (V1HI "h") (V2HI "h") (V4HI "h") (V8HI "h")
97 (V1SI "f") (V2SI "f") (V4SI "f")
98 (V1DI "g") (V2DI "g")
99 (V1TI "q") (TI "q")
100 (V1SF "f") (V2SF "f") (V4SF "f")
101 (V1DF "g") (V2DF "g")
102 (V1TF "q")])
103
104 ; This is for vmalhw. It gets an 'w' attached to avoid confusion with
105 ; multiply and add logical high vmalh.
106 (define_mode_attr w [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "")
107 (V1HI "w") (V2HI "w") (V4HI "w") (V8HI "w")
108 (V1SI "") (V2SI "") (V4SI "")
109 (V1DI "") (V2DI "")])
110
111 ; Resulting mode of a vector comparison. For floating point modes an
112 ; integer vector mode with the same element size is picked.
113 (define_mode_attr tointvec [(V1QI "V1QI") (V2QI "V2QI") (V4QI "V4QI") (V8QI "V8QI") (V16QI "V16QI")
114 (V1HI "V1HI") (V2HI "V2HI") (V4HI "V4HI") (V8HI "V8HI")
115 (V1SI "V1SI") (V2SI "V2SI") (V4SI "V4SI")
116 (V1DI "V1DI") (V2DI "V2DI")
117 (V1TI "V1TI")
118 (V1SF "V1SI") (V2SF "V2SI") (V4SF "V4SI")
119 (V1DF "V1DI") (V2DF "V2DI")
120 (V1TF "V1TI")])
121 (define_mode_attr vw [(SF "w") (V1SF "w") (V2SF "v") (V4SF "v")
122 (DF "w") (V1DF "w") (V2DF "v")
123 (TF "w") (V1TF "w")])
124
125 (define_mode_attr sdx [(SF "s") (V1SF "s") (V2SF "s") (V4SF "s")
126 (DF "d") (V1DF "d") (V2DF "d")
127 (TF "x") (V1TF "x")])
128
129 ; Vector with doubled element size.
130 (define_mode_attr vec_double [(V1QI "V1HI") (V2QI "V1HI") (V4QI "V2HI") (V8QI "V4HI") (V16QI "V8HI")
131 (V1HI "V1SI") (V2HI "V1SI") (V4HI "V2SI") (V8HI "V4SI")
132 (V1SI "V1DI") (V2SI "V1DI") (V4SI "V2DI")
133 (V1DI "V1TI") (V2DI "V1TI")
134 (V1SF "V1DF") (V2SF "V1DF") (V4SF "V2DF")])
135
136 ; Vector with half the element size.
137 (define_mode_attr vec_half [(V1HI "V2QI") (V2HI "V4QI") (V4HI "V8QI") (V8HI "V16QI")
138 (V1SI "V2HI") (V2SI "V4HI") (V4SI "V8HI")
139 (V1DI "V2SI") (V2DI "V4SI")
140 (V1TI "V2DI")
141 (V1DF "V2SF") (V2DF "V4SF")
142 (V1TF "V1DF")])
143
144 ; Vector with half the element size AND half the number of elements.
145 (define_mode_attr vec_halfhalf
146 [(V2HI "V2QI") (V4HI "V4QI") (V8HI "V8QI")
147 (V2SI "V2HI") (V4SI "V4HI")
148 (V2DI "V2SI")
149 (V2DF "V2SF")])
150
151 (define_mode_attr vec_halfnumelts
152 [(V4SF "V2SF") (V4SI "V2SI")])
153
154 ; The comparisons not setting CC iterate over the rtx code.
155 (define_code_iterator VFCMP_HW_OP [eq gt ge])
156 (define_code_attr asm_fcmp_op [(eq "e") (gt "h") (ge "he")])
157
158
159
160 ; Comparison operators on int and fp compares which are directly
161 ; supported by the HW.
162 (define_code_iterator VICMP_HW_OP [eq gt gtu])
163 ; For int insn_cmp_op can be used in the insn name as well as in the asm output.
164 (define_code_attr insn_cmp_op [(eq "eq") (gt "h") (gtu "hl") (ge "he")])
165
166 ; Flags for vector string instructions (vfae all 4, vfee only ZS and CS, vstrc all 4)
167 (define_constants
168 [(VSTRING_FLAG_IN 8) ; invert result
169 (VSTRING_FLAG_RT 4) ; result type
170 (VSTRING_FLAG_ZS 2) ; zero search
171 (VSTRING_FLAG_CS 1)]) ; condition code set
172
173 (include "vx-builtins.md")
174
175 ; Full HW vector size moves
176
177 ; We don't use lm/stm for 128 bit moves since these are slower than
178 ; splitting it into separate moves.
179
180 ; FIXME: More constants are possible by enabling jxx, jyy constraints
181 ; for TImode (use double-int for the calculations)
182
183 ; vgmb, vgmh, vgmf, vgmg, vrepib, vrepih, vrepif, vrepig
184 (define_insn "mov<mode>"
185 [(set (match_operand:V_128 0 "nonimmediate_operand" "=v,v,R, v, v, v, v, v,v,*d,*d,?o")
186 (match_operand:V_128 1 "general_operand" " v,R,v,j00,jm1,jyy,jxx,jKK,d, v,dT,*d"))]
187 ""
188 "@
189 vlr\t%v0,%v1
190 vl\t%v0,%1
191 vst\t%v1,%0
192 vzero\t%v0
193 vone\t%v0
194 vgbm\t%v0,%t1
195 vgm<bhfgq>\t%v0,%s1,%e1
196 vrepi<bhfgq>\t%v0,%h1
197 vlvgp\t%v0,%1,%N1
198 #
199 #
200 #"
201 [(set_attr "cpu_facility" "vx,vx,vx,vx,vx,vx,vx,vx,vx,vx,*,*")
202 (set_attr "op_type" "VRR,VRX,VRX,VRI,VRI,VRI,VRI,VRI,VRR,*,*,*")])
203
204 ; VR -> GPR, no instruction so split it into 64 element sets.
205 (define_split
206 [(set (match_operand:V_128 0 "register_operand" "")
207 (match_operand:V_128 1 "register_operand" ""))]
208 "TARGET_VX && GENERAL_REG_P (operands[0]) && VECTOR_REG_P (operands[1])"
209 [(set (match_dup 2)
210 (unspec:DI [(subreg:V2DI (match_dup 1) 0)
211 (const_int 0)] UNSPEC_VEC_EXTRACT))
212 (set (match_dup 3)
213 (unspec:DI [(subreg:V2DI (match_dup 1) 0)
214 (const_int 1)] UNSPEC_VEC_EXTRACT))]
215 {
216 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
217 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
218 })
219
220 ; Split the 128 bit GPR move into two word mode moves
221 ; s390_split_ok_p decides which part needs to be moved first.
222
223 (define_split
224 [(set (match_operand:V_128 0 "nonimmediate_operand" "")
225 (match_operand:V_128 1 "general_operand" ""))]
226 "reload_completed
227 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
228 [(set (match_dup 2) (match_dup 4))
229 (set (match_dup 3) (match_dup 5))]
230 {
231 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
232 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
233 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
234 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
235 })
236
237 (define_split
238 [(set (match_operand:V_128 0 "nonimmediate_operand" "")
239 (match_operand:V_128 1 "general_operand" ""))]
240 "reload_completed
241 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
242 [(set (match_dup 2) (match_dup 4))
243 (set (match_dup 3) (match_dup 5))]
244 {
245 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
246 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
247 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
248 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
249 })
250
251 ; This is the vector equivalent to the TImode splitter in s390.md. It
252 ; is required if both target GPRs occur in the source address operand.
253
254 ; For non-s_operands at least one of the target GPRs does not conflict
255 ; with the address operand and one of the splitters above will take
256 ; over.
257 (define_split
258 [(set (match_operand:V_128 0 "register_operand" "")
259 (match_operand:V_128 1 "memory_operand" ""))]
260 "TARGET_ZARCH && reload_completed
261 && !VECTOR_REG_P (operands[0])
262 && !s_operand (operands[1], VOIDmode)"
263 [(set (match_dup 0) (match_dup 1))]
264 {
265 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
266 addr = gen_lowpart (Pmode, addr);
267 s390_load_address (addr, XEXP (operands[1], 0));
268 operands[1] = replace_equiv_address (operands[1], addr);
269 })
270
271 ; Moves for smaller vector modes.
272
273 ; In these patterns only the vlr, vone, and vzero instructions write
274 ; VR bytes outside the mode. This should be ok since we disallow
275 ; formerly bigger modes being accessed with smaller modes via
276 ; subreg. Note: The vone, vzero instructions could easily be replaced
277 ; with vlei which would only access the bytes belonging to the mode.
278 ; However, this would probably be slower.
279
280 (define_insn "mov<mode>"
281 [(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d,v,R, v, v, v, v,d, Q, S, Q, S, d, d,d,d,d,R,T")
282 (match_operand:V_8 1 "general_operand" " v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,j00,jm1,jm1,j00,jm1,R,T,b,d,d"))]
283 ""
284 "@
285 vlr\t%v0,%v1
286 vlvgb\t%v0,%1,0
287 vlgvb\t%0,%v1,0
288 vleb\t%v0,%1,0
289 vsteb\t%v1,%0,0
290 vzero\t%v0
291 vone\t%v0
292 vgbm\t%v0,%t1
293 vgm\t%v0,%s1,%e1
294 lr\t%0,%1
295 mvi\t%0,0
296 mviy\t%0,0
297 mvi\t%0,-1
298 mviy\t%0,-1
299 lhi\t%0,0
300 lhi\t%0,-1
301 lh\t%0,%1
302 lhy\t%0,%1
303 lhrl\t%0,%1
304 stc\t%1,%0
305 stcy\t%1,%0"
306 [(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")])
307
308 (define_insn "mov<mode>"
309 [(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d,v,R, v, v, v, v,d, Q, Q, d, d,d,d,d,R,T,b")
310 (match_operand:V_16 1 "general_operand" " v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
311 ""
312 "@
313 vlr\t%v0,%v1
314 vlvgh\t%v0,%1,0
315 vlgvh\t%0,%v1,0
316 vleh\t%v0,%1,0
317 vsteh\t%v1,%0,0
318 vzero\t%v0
319 vone\t%v0
320 vgbm\t%v0,%t1
321 vgm\t%v0,%s1,%e1
322 lr\t%0,%1
323 mvhhi\t%0,0
324 mvhhi\t%0,-1
325 lhi\t%0,0
326 lhi\t%0,-1
327 lh\t%0,%1
328 lhy\t%0,%1
329 lhrl\t%0,%1
330 sth\t%1,%0
331 sthy\t%1,%0
332 sthrl\t%1,%0"
333 [(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")])
334
335 (define_insn "mov<mode>"
336 [(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d,v,R, f, v, v, v, v, Q, Q, d, d,d,d,d,d,R,T,b")
337 (match_operand:V_32 1 "general_operand" " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
338 "TARGET_VX"
339 "@
340 ldr\t%v0,%v1
341 lde\t%0,%1
342 ley\t%0,%1
343 ste\t%1,%0
344 stey\t%1,%0
345 vlr\t%v0,%v1
346 vlvgf\t%v0,%1,0
347 vlgvf\t%0,%v1,0
348 vlef\t%v0,%1,0
349 vstef\t%1,%0,0
350 lzer\t%v0
351 vzero\t%v0
352 vone\t%v0
353 vgbm\t%v0,%t1
354 vgm\t%v0,%s1,%e1
355 mvhi\t%0,0
356 mvhi\t%0,-1
357 lhi\t%0,0
358 lhi\t%0,-1
359 lrl\t%0,%1
360 lr\t%0,%1
361 l\t%0,%1
362 ly\t%0,%1
363 st\t%1,%0
364 sty\t%1,%0
365 strl\t%1,%0"
366 [(set_attr "op_type" "RR,RXE,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,SIL,SIL,RI,RI,
367 RIL,RR,RX,RXY,RX,RXY,RIL")])
368
369 (define_insn "mov<mode>"
370 [(set (match_operand:V_64 0 "nonimmediate_operand"
371 "=f,f,f,R,T,v,v,d,v,R, f, v, v, v, v, Q, Q, d, d,f,d,d,d,d,T,b")
372 (match_operand:V_64 1 "general_operand"
373 " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,d,f,b,d,T,d,d"))]
374 "TARGET_ZARCH"
375 "@
376 ldr\t%0,%1
377 ld\t%0,%1
378 ldy\t%0,%1
379 std\t%1,%0
380 stdy\t%1,%0
381 vlr\t%v0,%v1
382 vlvgg\t%v0,%1,0
383 vlgvg\t%0,%v1,0
384 vleg\t%v0,%1,0
385 vsteg\t%v1,%0,0
386 lzdr\t%0
387 vzero\t%v0
388 vone\t%v0
389 vgbm\t%v0,%t1
390 vgm\t%v0,%s1,%e1
391 mvghi\t%0,0
392 mvghi\t%0,-1
393 lghi\t%0,0
394 lghi\t%0,-1
395 ldgr\t%0,%1
396 lgdr\t%0,%1
397 lgrl\t%0,%1
398 lgr\t%0,%1
399 lg\t%0,%1
400 stg\t%1,%0
401 stgrl\t%1,%0"
402 [(set_attr "op_type" "RRE,RX,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,
403 SIL,SIL,RI,RI,RRE,RRE,RIL,RR,RXY,RXY,RIL")])
404
405
406 ; vec_load_lanes?
407
408 ; vec_store_lanes?
409
410 ; vec_set is supposed to *modify* an existing vector so operand 0 is
411 ; duplicated as input operand.
412 (define_expand "vec_set<mode>"
413 [(set (match_operand:V 0 "register_operand" "")
414 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "")
415 (match_operand:SI 2 "nonmemory_operand" "")
416 (match_dup 0)]
417 UNSPEC_VEC_SET))]
418 "TARGET_VX")
419
420 ; FIXME: Support also vector mode operands for 1
421 ; FIXME: A target memory operand seems to be useful otherwise we end
422 ; up with vl vlvgg vst. Shouldn't the middle-end be able to handle
423 ; that itself?
424 ; vlvgb, vlvgh, vlvgf, vlvgg, vleb, vleh, vlef, vleg, vleib, vleih, vleif, vleig
425 (define_insn "*vec_set<mode>"
426 [(set (match_operand:V 0 "register_operand" "=v,v,v")
427 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,R,K")
428 (match_operand:SI 2 "nonmemory_operand" "an,I,I")
429 (match_operand:V 3 "register_operand" "0,0,0")]
430 UNSPEC_VEC_SET))]
431 "TARGET_VX
432 && (!CONST_INT_P (operands[2])
433 || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
434 "@
435 vlvg<bhfgq>\t%v0,%1,%Y2
436 vle<bhfgq>\t%v0,%1,%2
437 vlei<bhfgq>\t%v0,%1,%2"
438 [(set_attr "op_type" "VRS,VRX,VRI")])
439
440 ; vlvgb, vlvgh, vlvgf, vlvgg
441 (define_insn "*vec_set<mode>_plus"
442 [(set (match_operand:V 0 "register_operand" "=v")
443 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d")
444 (plus:SI (match_operand:SI 2 "register_operand" "a")
445 (match_operand:SI 4 "const_int_operand" "n"))
446 (match_operand:V 3 "register_operand" "0")]
447 UNSPEC_VEC_SET))]
448 "TARGET_VX"
449 "vlvg<bhfgq>\t%v0,%1,%Y4(%2)"
450 [(set_attr "op_type" "VRS")])
451
452
453 ; FIXME: Support also vector mode operands for 0
454 ; FIXME: This should be (vec_select ..) or something but it does only allow constant selectors :(
455 ; This is used via RTL standard name as well as for expanding the builtin
456 (define_expand "vec_extract<mode>"
457 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "")
458 (unspec:<non_vec> [(match_operand:V 1 "register_operand" "")
459 (match_operand:SI 2 "nonmemory_operand" "")]
460 UNSPEC_VEC_EXTRACT))]
461 "TARGET_VX")
462
463 ; vlgvb, vlgvh, vlgvf, vlgvg, vsteb, vsteh, vstef, vsteg
464 (define_insn "*vec_extract<mode>"
465 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,R")
466 (unspec:<non_vec> [(match_operand:V 1 "register_operand" "v,v")
467 (match_operand:SI 2 "nonmemory_operand" "an,I")]
468 UNSPEC_VEC_EXTRACT))]
469 "TARGET_VX
470 && (!CONST_INT_P (operands[2])
471 || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
472 "@
473 vlgv<bhfgq>\t%0,%v1,%Y2
474 vste<bhfgq>\t%v1,%0,%2"
475 [(set_attr "op_type" "VRS,VRX")])
476
477 ; vlgvb, vlgvh, vlgvf, vlgvg
478 (define_insn "*vec_extract<mode>_plus"
479 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d")
480 (unspec:<non_vec> [(match_operand:V 1 "register_operand" "v")
481 (plus:SI (match_operand:SI 2 "nonmemory_operand" "a")
482 (match_operand:SI 3 "const_int_operand" "n"))]
483 UNSPEC_VEC_EXTRACT))]
484 "TARGET_VX"
485 "vlgv<bhfgq>\t%0,%v1,%Y3(%2)"
486 [(set_attr "op_type" "VRS")])
487
488 (define_expand "vec_init<mode>"
489 [(match_operand:V_128 0 "register_operand" "")
490 (match_operand:V_128 1 "nonmemory_operand" "")]
491 "TARGET_VX"
492 {
493 s390_expand_vec_init (operands[0], operands[1]);
494 DONE;
495 })
496
497 (define_insn "*vec_vllezlf<mode>"
498 [(set (match_operand:VI_HW_4 0 "register_operand" "=v")
499 (vec_concat:VI_HW_4
500 (vec_concat:<vec_halfnumelts>
501 (match_operand:<non_vec> 1 "memory_operand" "R")
502 (const_int 0))
503 (vec_concat:<vec_halfnumelts>
504 (const_int 0)
505 (const_int 0))))]
506 "TARGET_VXE"
507 "vllezlf\t%v0,%1"
508 [(set_attr "op_type" "VRX")])
509
510 ; Replicate from vector element
511 ; vrepb, vreph, vrepf, vrepg
512 (define_insn "*vec_splat<mode>"
513 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v")
514 (vec_duplicate:V_128_NOSINGLE
515 (vec_select:<non_vec>
516 (match_operand:V_128_NOSINGLE 1 "register_operand" "v")
517 (parallel
518 [(match_operand:QI 2 "const_mask_operand" "C")]))))]
519 "TARGET_VX && UINTVAL (operands[2]) < GET_MODE_NUNITS (<MODE>mode)"
520 "vrep<bhfgq>\t%v0,%v1,%2"
521 [(set_attr "op_type" "VRI")])
522
523 ; vlrepb, vlreph, vlrepf, vlrepg, vrepib, vrepih, vrepif, vrepig, vrepb, vreph, vrepf, vrepg
524 (define_insn "*vec_splats<mode>"
525 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v,v,v,v")
526 (vec_duplicate:V_128_NOSINGLE (match_operand:<non_vec> 1 "general_operand" " R,K,v,d")))]
527 "TARGET_VX"
528 "@
529 vlrep<bhfgq>\t%v0,%1
530 vrepi<bhfgq>\t%v0,%h1
531 vrep<bhfgq>\t%v0,%v1,0
532 #"
533 [(set_attr "op_type" "VRX,VRI,VRI,*")])
534
535 ; A TFmode operand resides in FPR register pairs while V1TF is in a
536 ; single vector register.
537 (define_insn "*vec_tf_to_v1tf"
538 [(set (match_operand:V1TF 0 "nonimmediate_operand" "=v,v,R,v,v")
539 (vec_duplicate:V1TF (match_operand:TF 1 "general_operand" "v,R,v,G,d")))]
540 "TARGET_VX"
541 "@
542 vmrhg\t%v0,%1,%N1
543 vl\t%v0,%1
544 vst\t%v1,%0
545 vzero\t%v0
546 vlvgp\t%v0,%1,%N1"
547 [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRR")])
548
549 (define_insn "*vec_ti_to_v1ti"
550 [(set (match_operand:V1TI 0 "nonimmediate_operand" "=v,v,R, v, v,v")
551 (vec_duplicate:V1TI (match_operand:TI 1 "general_operand" "v,R,v,j00,jm1,d")))]
552 "TARGET_VX"
553 "@
554 vlr\t%v0,%v1
555 vl\t%v0,%1
556 vst\t%v1,%0
557 vzero\t%v0
558 vone\t%v0
559 vlvgp\t%v0,%1,%N1"
560 [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRI,VRR")])
561
562 ; vec_splats is supposed to replicate op1 into all elements of op0
563 ; This splitter first sets the rightmost element of op0 to op1 and
564 ; then does a vec_splat to replicate that element into all other
565 ; elements.
566 (define_split
567 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "")
568 (vec_duplicate:V_128_NOSINGLE (match_operand:<non_vec> 1 "register_operand" "")))]
569 "TARGET_VX && GENERAL_REG_P (operands[1])"
570 [(set (match_dup 0)
571 (unspec:V_128_NOSINGLE [(match_dup 1) (match_dup 2) (match_dup 0)] UNSPEC_VEC_SET))
572 (set (match_dup 0)
573 (vec_duplicate:V_128_NOSINGLE
574 (vec_select:<non_vec>
575 (match_dup 0) (parallel [(match_dup 2)]))))]
576 {
577 operands[2] = GEN_INT (GET_MODE_NUNITS (<MODE>mode) - 1);
578 })
579
580 (define_expand "vcond<V_HW:mode><V_HW2:mode>"
581 [(set (match_operand:V_HW 0 "register_operand" "")
582 (if_then_else:V_HW
583 (match_operator 3 "comparison_operator"
584 [(match_operand:V_HW2 4 "register_operand" "")
585 (match_operand:V_HW2 5 "nonmemory_operand" "")])
586 (match_operand:V_HW 1 "nonmemory_operand" "")
587 (match_operand:V_HW 2 "nonmemory_operand" "")))]
588 "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)"
589 {
590 s390_expand_vcond (operands[0], operands[1], operands[2],
591 GET_CODE (operands[3]), operands[4], operands[5]);
592 DONE;
593 })
594
595 (define_expand "vcondu<V_HW:mode><V_HW2:mode>"
596 [(set (match_operand:V_HW 0 "register_operand" "")
597 (if_then_else:V_HW
598 (match_operator 3 "comparison_operator"
599 [(match_operand:V_HW2 4 "register_operand" "")
600 (match_operand:V_HW2 5 "nonmemory_operand" "")])
601 (match_operand:V_HW 1 "nonmemory_operand" "")
602 (match_operand:V_HW 2 "nonmemory_operand" "")))]
603 "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)"
604 {
605 s390_expand_vcond (operands[0], operands[1], operands[2],
606 GET_CODE (operands[3]), operands[4], operands[5]);
607 DONE;
608 })
609
610 ; We only have HW support for byte vectors. The middle-end is
611 ; supposed to lower the mode if required.
612 (define_insn "vec_permv16qi"
613 [(set (match_operand:V16QI 0 "register_operand" "=v")
614 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
615 (match_operand:V16QI 2 "register_operand" "v")
616 (match_operand:V16QI 3 "register_operand" "v")]
617 UNSPEC_VEC_PERM))]
618 "TARGET_VX"
619 "vperm\t%v0,%v1,%v2,%v3"
620 [(set_attr "op_type" "VRR")])
621
622 ; vec_perm_const for V2DI using vpdi?
623
624 ;;
625 ;; Vector integer arithmetic instructions
626 ;;
627
628 ; vab, vah, vaf, vag, vaq
629
630 ; We use nonimmediate_operand instead of register_operand since it is
631 ; better to have the reloads into VRs instead of splitting the
632 ; operation into two DImode ADDs.
633 (define_insn "<ti*>add<mode>3"
634 [(set (match_operand:VIT 0 "nonimmediate_operand" "=v")
635 (plus:VIT (match_operand:VIT 1 "nonimmediate_operand" "%v")
636 (match_operand:VIT 2 "general_operand" "v")))]
637 "TARGET_VX"
638 "va<bhfgq>\t%v0,%v1,%v2"
639 [(set_attr "op_type" "VRR")])
640
641 ; vsb, vsh, vsf, vsg, vsq
642 (define_insn "<ti*>sub<mode>3"
643 [(set (match_operand:VIT 0 "nonimmediate_operand" "=v")
644 (minus:VIT (match_operand:VIT 1 "nonimmediate_operand" "v")
645 (match_operand:VIT 2 "general_operand" "v")))]
646 "TARGET_VX"
647 "vs<bhfgq>\t%v0,%v1,%v2"
648 [(set_attr "op_type" "VRR")])
649
650 ; vmlb, vmlhw, vmlf
651 (define_insn "mul<mode>3"
652 [(set (match_operand:VI_QHS 0 "register_operand" "=v")
653 (mult:VI_QHS (match_operand:VI_QHS 1 "register_operand" "%v")
654 (match_operand:VI_QHS 2 "register_operand" "v")))]
655 "TARGET_VX"
656 "vml<bhfgq><w>\t%v0,%v1,%v2"
657 [(set_attr "op_type" "VRR")])
658
659 ; vlcb, vlch, vlcf, vlcg
660 (define_insn "neg<mode>2"
661 [(set (match_operand:VI 0 "register_operand" "=v")
662 (neg:VI (match_operand:VI 1 "register_operand" "v")))]
663 "TARGET_VX"
664 "vlc<bhfgq>\t%v0,%v1"
665 [(set_attr "op_type" "VRR")])
666
667 ; vlpb, vlph, vlpf, vlpg
668 (define_insn "abs<mode>2"
669 [(set (match_operand:VI 0 "register_operand" "=v")
670 (abs:VI (match_operand:VI 1 "register_operand" "v")))]
671 "TARGET_VX"
672 "vlp<bhfgq>\t%v0,%v1"
673 [(set_attr "op_type" "VRR")])
674
675
676 ; Vector sum across
677
678 ; Sum across DImode parts of the 1st operand and add the rightmost
679 ; element of 2nd operand
680 ; vsumgh, vsumgf
681 (define_insn "*vec_sum2<mode>"
682 [(set (match_operand:V2DI 0 "register_operand" "=v")
683 (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "v")
684 (match_operand:VI_HW_HS 2 "register_operand" "v")]
685 UNSPEC_VEC_VSUMG))]
686 "TARGET_VX"
687 "vsumg<bhfgq>\t%v0,%v1,%v2"
688 [(set_attr "op_type" "VRR")])
689
690 ; vsumb, vsumh
691 (define_insn "*vec_sum4<mode>"
692 [(set (match_operand:V4SI 0 "register_operand" "=v")
693 (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "v")
694 (match_operand:VI_HW_QH 2 "register_operand" "v")]
695 UNSPEC_VEC_VSUM))]
696 "TARGET_VX"
697 "vsum<bhfgq>\t%v0,%v1,%v2"
698 [(set_attr "op_type" "VRR")])
699
700 ;;
701 ;; Vector bit instructions (int + fp)
702 ;;
703
704 ; Vector and
705
706 (define_insn "and<mode>3"
707 [(set (match_operand:VT 0 "register_operand" "=v")
708 (and:VT (match_operand:VT 1 "register_operand" "%v")
709 (match_operand:VT 2 "register_operand" "v")))]
710 "TARGET_VX"
711 "vn\t%v0,%v1,%v2"
712 [(set_attr "op_type" "VRR")])
713
714 ; Vector not and
715
716 (define_insn "notand<mode>3"
717 [(set (match_operand:VT 0 "register_operand" "=v")
718 (ior:VT (not:VT (match_operand:VT 1 "register_operand" "%v"))
719 (not:VT (match_operand:VT 2 "register_operand" "v"))))]
720 "TARGET_VXE"
721 "vnn\t%v0,%v1,%v2"
722 [(set_attr "op_type" "VRR")])
723
724 ; Vector or
725
726 (define_insn "ior<mode>3"
727 [(set (match_operand:VT 0 "register_operand" "=v")
728 (ior:VT (match_operand:VT 1 "register_operand" "%v")
729 (match_operand:VT 2 "register_operand" "v")))]
730 "TARGET_VX"
731 "vo\t%v0,%v1,%v2"
732 [(set_attr "op_type" "VRR")])
733
734 ; Vector or with complement
735
736 (define_insn "ior_not<mode>3"
737 [(set (match_operand:VT 0 "register_operand" "=v")
738 (ior:VT (not:VT (match_operand:VT 2 "register_operand" "v"))
739 (match_operand:VT 1 "register_operand" "%v")))]
740 "TARGET_VXE"
741 "voc\t%v0,%v1,%v2"
742 [(set_attr "op_type" "VRR")])
743
744 ; Vector xor
745
746 (define_insn "xor<mode>3"
747 [(set (match_operand:VT 0 "register_operand" "=v")
748 (xor:VT (match_operand:VT 1 "register_operand" "%v")
749 (match_operand:VT 2 "register_operand" "v")))]
750 "TARGET_VX"
751 "vx\t%v0,%v1,%v2"
752 [(set_attr "op_type" "VRR")])
753
754 ; Vector not xor
755
756 (define_insn "notxor<mode>3"
757 [(set (match_operand:VT 0 "register_operand" "=v")
758 (not:VT (xor:VT (match_operand:VT 1 "register_operand" "%v")
759 (match_operand:VT 2 "register_operand" "v"))))]
760 "TARGET_VXE"
761 "vnx\t%v0,%v1,%v2"
762 [(set_attr "op_type" "VRR")])
763
764 ; Bitwise inversion of a vector
765 (define_insn "one_cmpl<mode>2"
766 [(set (match_operand:VT 0 "register_operand" "=v")
767 (not:VT (match_operand:VT 1 "register_operand" "v")))]
768 "TARGET_VX"
769 "vnot\t%v0,%v1"
770 [(set_attr "op_type" "VRR")])
771
772 ; Vector population count
773
774 (define_expand "popcount<mode>2"
775 [(set (match_operand:VI_HW 0 "register_operand" "=v")
776 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")]
777 UNSPEC_POPCNT))]
778 "TARGET_VX"
779 {
780 if (TARGET_VXE)
781 emit_insn (gen_popcount<mode>2_vxe (operands[0], operands[1]));
782 else
783 emit_insn (gen_popcount<mode>2_vx (operands[0], operands[1]));
784 DONE;
785 })
786
787 ; vpopctb, vpopcth, vpopctf, vpopctg
788 (define_insn "popcount<mode>2_vxe"
789 [(set (match_operand:VI_HW 0 "register_operand" "=v")
790 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")]
791 UNSPEC_POPCNT))]
792 "TARGET_VXE"
793 "vpopct<bhfgq>\t%v0,%v1"
794 [(set_attr "op_type" "VRR")])
795
796 (define_insn "popcountv16qi2_vx"
797 [(set (match_operand:V16QI 0 "register_operand" "=v")
798 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
799 UNSPEC_POPCNT))]
800 "TARGET_VX && !TARGET_VXE"
801 "vpopct\t%v0,%v1,0"
802 [(set_attr "op_type" "VRR")])
803
804 ; vpopct only counts bits in byte elements. Bigger element sizes need
805 ; to be emulated. Word and doubleword elements can use the sum across
806 ; instructions. For halfword sized elements we do a shift of a copy
807 ; of the result, add it to the result and extend it to halfword
808 ; element size (unpack).
809
810 (define_expand "popcountv8hi2_vx"
811 [(set (match_dup 2)
812 (unspec:V16QI [(subreg:V16QI (match_operand:V8HI 1 "register_operand" "v") 0)]
813 UNSPEC_POPCNT))
814 ; Make a copy of the result
815 (set (match_dup 3) (match_dup 2))
816 ; Generate the shift count operand in a VR (8->byte 7)
817 (set (match_dup 4) (match_dup 5))
818 (set (match_dup 4) (unspec:V16QI [(const_int 8)
819 (const_int 7)
820 (match_dup 4)] UNSPEC_VEC_SET))
821 ; Vector shift right logical by one byte
822 (set (match_dup 3)
823 (unspec:V16QI [(match_dup 3) (match_dup 4)] UNSPEC_VEC_SRLB))
824 ; Add the shifted and the original result
825 (set (match_dup 2)
826 (plus:V16QI (match_dup 2) (match_dup 3)))
827 ; Generate mask for the odd numbered byte elements
828 (set (match_dup 3)
829 (const_vector:V16QI [(const_int 0) (const_int 255)
830 (const_int 0) (const_int 255)
831 (const_int 0) (const_int 255)
832 (const_int 0) (const_int 255)
833 (const_int 0) (const_int 255)
834 (const_int 0) (const_int 255)
835 (const_int 0) (const_int 255)
836 (const_int 0) (const_int 255)]))
837 ; Zero out the even indexed bytes
838 (set (match_operand:V8HI 0 "register_operand" "=v")
839 (and:V8HI (subreg:V8HI (match_dup 2) 0)
840 (subreg:V8HI (match_dup 3) 0)))
841 ]
842 "TARGET_VX && !TARGET_VXE"
843 {
844 operands[2] = gen_reg_rtx (V16QImode);
845 operands[3] = gen_reg_rtx (V16QImode);
846 operands[4] = gen_reg_rtx (V16QImode);
847 operands[5] = CONST0_RTX (V16QImode);
848 })
849
850 (define_expand "popcountv4si2_vx"
851 [(set (match_dup 2)
852 (unspec:V16QI [(subreg:V16QI (match_operand:V4SI 1 "register_operand" "v") 0)]
853 UNSPEC_POPCNT))
854 (set (match_operand:V4SI 0 "register_operand" "=v")
855 (unspec:V4SI [(match_dup 2) (match_dup 3)]
856 UNSPEC_VEC_VSUM))]
857 "TARGET_VX && !TARGET_VXE"
858 {
859 operands[2] = gen_reg_rtx (V16QImode);
860 operands[3] = force_reg (V16QImode, CONST0_RTX (V16QImode));
861 })
862
863 (define_expand "popcountv2di2_vx"
864 [(set (match_dup 2)
865 (unspec:V16QI [(subreg:V16QI (match_operand:V2DI 1 "register_operand" "v") 0)]
866 UNSPEC_POPCNT))
867 (set (match_dup 3)
868 (unspec:V4SI [(match_dup 2) (match_dup 4)]
869 UNSPEC_VEC_VSUM))
870 (set (match_operand:V2DI 0 "register_operand" "=v")
871 (unspec:V2DI [(match_dup 3) (match_dup 5)]
872 UNSPEC_VEC_VSUMG))]
873 "TARGET_VX && !TARGET_VXE"
874 {
875 operands[2] = gen_reg_rtx (V16QImode);
876 operands[3] = gen_reg_rtx (V4SImode);
877 operands[4] = force_reg (V16QImode, CONST0_RTX (V16QImode));
878 operands[5] = force_reg (V4SImode, CONST0_RTX (V4SImode));
879 })
880
881 ; Count leading zeros
882 ; vclzb, vclzh, vclzf, vclzg
883 (define_insn "clz<mode>2"
884 [(set (match_operand:V 0 "register_operand" "=v")
885 (clz:V (match_operand:V 1 "register_operand" "v")))]
886 "TARGET_VX"
887 "vclz<bhfgq>\t%v0,%v1"
888 [(set_attr "op_type" "VRR")])
889
890 ; Count trailing zeros
891 ; vctzb, vctzh, vctzf, vctzg
892 (define_insn "ctz<mode>2"
893 [(set (match_operand:V 0 "register_operand" "=v")
894 (ctz:V (match_operand:V 1 "register_operand" "v")))]
895 "TARGET_VX"
896 "vctz<bhfgq>\t%v0,%v1"
897 [(set_attr "op_type" "VRR")])
898
899
900
901 ; Each vector element rotated by the corresponding vector element
902 ; verllvb, verllvh, verllvf, verllvg
903 (define_insn "vrotl<mode>3"
904 [(set (match_operand:VI 0 "register_operand" "=v")
905 (rotate:VI (match_operand:VI 1 "register_operand" "v")
906 (match_operand:VI 2 "register_operand" "v")))]
907 "TARGET_VX"
908 "verllv<bhfgq>\t%v0,%v1,%v2"
909 [(set_attr "op_type" "VRR")])
910
911
912 ; Vector rotate and shift by scalar instructions
913
914 (define_code_iterator VEC_SHIFTS [ashift ashiftrt lshiftrt rotate])
915 (define_code_attr vec_shifts_name [(ashift "ashl") (ashiftrt "ashr")
916 (lshiftrt "lshr") (rotate "rotl")])
917 (define_code_attr vec_shifts_mnem [(ashift "vesl") (ashiftrt "vesra")
918 (lshiftrt "vesrl") (rotate "verll")])
919
920 ; Each vector element rotated by a scalar
921 (define_expand "<vec_shifts_name><mode>3"
922 [(set (match_operand:VI 0 "register_operand" "")
923 (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "")
924 (match_operand:SI 2 "nonmemory_operand" "")))]
925 "TARGET_VX")
926
927 ; verllb, verllh, verllf, verllg
928 ; veslb, veslh, veslf, veslg
929 ; vesrab, vesrah, vesraf, vesrag
930 ; vesrlb, vesrlh, vesrlf, vesrlg
931 (define_insn "*<vec_shifts_name><mode>3<addr_style_op>"
932 [(set (match_operand:VI 0 "register_operand" "=v")
933 (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "v")
934 (match_operand:SI 2 "nonmemory_operand" "an")))]
935 "TARGET_VX"
936 "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2"
937 [(set_attr "op_type" "VRS")])
938
939 ; Shift each element by corresponding vector element
940
941 ; veslvb, veslvh, veslvf, veslvg
942 (define_insn "vashl<mode>3"
943 [(set (match_operand:VI 0 "register_operand" "=v")
944 (ashift:VI (match_operand:VI 1 "register_operand" "v")
945 (match_operand:VI 2 "register_operand" "v")))]
946 "TARGET_VX"
947 "veslv<bhfgq>\t%v0,%v1,%v2"
948 [(set_attr "op_type" "VRR")])
949
950 ; vesravb, vesravh, vesravf, vesravg
951 (define_insn "vashr<mode>3"
952 [(set (match_operand:VI 0 "register_operand" "=v")
953 (ashiftrt:VI (match_operand:VI 1 "register_operand" "v")
954 (match_operand:VI 2 "register_operand" "v")))]
955 "TARGET_VX"
956 "vesrav<bhfgq>\t%v0,%v1,%v2"
957 [(set_attr "op_type" "VRR")])
958
959 ; vesrlvb, vesrlvh, vesrlvf, vesrlvg
960 (define_insn "vlshr<mode>3"
961 [(set (match_operand:VI 0 "register_operand" "=v")
962 (lshiftrt:VI (match_operand:VI 1 "register_operand" "v")
963 (match_operand:VI 2 "register_operand" "v")))]
964 "TARGET_VX"
965 "vesrlv<bhfgq>\t%v0,%v1,%v2"
966 [(set_attr "op_type" "VRR")])
967
968 ; Vector shift right logical by byte
969
970 ; Pattern used by e.g. popcount
971 (define_insn "*vec_srb<mode>"
972 [(set (match_operand:V_HW 0 "register_operand" "=v")
973 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
974 (match_operand:<tointvec> 2 "register_operand" "v")]
975 UNSPEC_VEC_SRLB))]
976 "TARGET_VX"
977 "vsrlb\t%v0,%v1,%v2"
978 [(set_attr "op_type" "VRR")])
979
980
981 ; vmnb, vmnh, vmnf, vmng
982 (define_insn "smin<mode>3"
983 [(set (match_operand:VI 0 "register_operand" "=v")
984 (smin:VI (match_operand:VI 1 "register_operand" "%v")
985 (match_operand:VI 2 "register_operand" "v")))]
986 "TARGET_VX"
987 "vmn<bhfgq>\t%v0,%v1,%v2"
988 [(set_attr "op_type" "VRR")])
989
990 ; vmxb, vmxh, vmxf, vmxg
991 (define_insn "smax<mode>3"
992 [(set (match_operand:VI 0 "register_operand" "=v")
993 (smax:VI (match_operand:VI 1 "register_operand" "%v")
994 (match_operand:VI 2 "register_operand" "v")))]
995 "TARGET_VX"
996 "vmx<bhfgq>\t%v0,%v1,%v2"
997 [(set_attr "op_type" "VRR")])
998
999 ; vmnlb, vmnlh, vmnlf, vmnlg
1000 (define_insn "umin<mode>3"
1001 [(set (match_operand:VI 0 "register_operand" "=v")
1002 (umin:VI (match_operand:VI 1 "register_operand" "%v")
1003 (match_operand:VI 2 "register_operand" "v")))]
1004 "TARGET_VX"
1005 "vmnl<bhfgq>\t%v0,%v1,%v2"
1006 [(set_attr "op_type" "VRR")])
1007
1008 ; vmxlb, vmxlh, vmxlf, vmxlg
1009 (define_insn "umax<mode>3"
1010 [(set (match_operand:VI 0 "register_operand" "=v")
1011 (umax:VI (match_operand:VI 1 "register_operand" "%v")
1012 (match_operand:VI 2 "register_operand" "v")))]
1013 "TARGET_VX"
1014 "vmxl<bhfgq>\t%v0,%v1,%v2"
1015 [(set_attr "op_type" "VRR")])
1016
1017 ; vmeb, vmeh, vmef
1018 (define_insn "vec_widen_smult_even_<mode>"
1019 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
1020 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
1021 (match_operand:VI_QHS 2 "register_operand" "v")]
1022 UNSPEC_VEC_SMULT_EVEN))]
1023 "TARGET_VX"
1024 "vme<bhfgq>\t%v0,%v1,%v2"
1025 [(set_attr "op_type" "VRR")])
1026
1027 ; vmleb, vmleh, vmlef
1028 (define_insn "vec_widen_umult_even_<mode>"
1029 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
1030 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
1031 (match_operand:VI_QHS 2 "register_operand" "v")]
1032 UNSPEC_VEC_UMULT_EVEN))]
1033 "TARGET_VX"
1034 "vmle<bhfgq>\t%v0,%v1,%v2"
1035 [(set_attr "op_type" "VRR")])
1036
1037 ; vmob, vmoh, vmof
1038 (define_insn "vec_widen_smult_odd_<mode>"
1039 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
1040 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
1041 (match_operand:VI_QHS 2 "register_operand" "v")]
1042 UNSPEC_VEC_SMULT_ODD))]
1043 "TARGET_VX"
1044 "vmo<bhfgq>\t%v0,%v1,%v2"
1045 [(set_attr "op_type" "VRR")])
1046
1047 ; vmlob, vmloh, vmlof
1048 (define_insn "vec_widen_umult_odd_<mode>"
1049 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
1050 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
1051 (match_operand:VI_QHS 2 "register_operand" "v")]
1052 UNSPEC_VEC_UMULT_ODD))]
1053 "TARGET_VX"
1054 "vmlo<bhfgq>\t%v0,%v1,%v2"
1055 [(set_attr "op_type" "VRR")])
1056
1057 ; vec_widen_umult_hi
1058 ; vec_widen_umult_lo
1059 ; vec_widen_smult_hi
1060 ; vec_widen_smult_lo
1061
1062 ; vec_widen_ushiftl_hi
1063 ; vec_widen_ushiftl_lo
1064 ; vec_widen_sshiftl_hi
1065 ; vec_widen_sshiftl_lo
1066
1067 ;;
1068 ;; Vector floating point arithmetic instructions
1069 ;;
1070
1071 ; vfasb, vfadb, wfasb, wfadb, wfaxb
1072 (define_insn "add<mode>3"
1073 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1074 (plus:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
1075 (match_operand:VF_HW 2 "register_operand" "v")))]
1076 "TARGET_VX"
1077 "<vw>fa<sdx>b\t%v0,%v1,%v2"
1078 [(set_attr "op_type" "VRR")])
1079
1080 ; vfssb, vfsdb, wfssb, wfsdb, wfsxb
1081 (define_insn "sub<mode>3"
1082 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1083 (minus:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
1084 (match_operand:VF_HW 2 "register_operand" "v")))]
1085 "TARGET_VX"
1086 "<vw>fs<sdx>b\t%v0,%v1,%v2"
1087 [(set_attr "op_type" "VRR")])
1088
1089 ; vfmsb, vfmdb, wfmsb, wfmdb, wfmxb
1090 (define_insn "mul<mode>3"
1091 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1092 (mult:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
1093 (match_operand:VF_HW 2 "register_operand" "v")))]
1094 "TARGET_VX"
1095 "<vw>fm<sdx>b\t%v0,%v1,%v2"
1096 [(set_attr "op_type" "VRR")])
1097
1098 ; vfdsb, vfddb, wfdsb, wfddb, wfdxb
1099 (define_insn "div<mode>3"
1100 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1101 (div:VF_HW (match_operand:VF_HW 1 "register_operand" "v")
1102 (match_operand:VF_HW 2 "register_operand" "v")))]
1103 "TARGET_VX"
1104 "<vw>fd<sdx>b\t%v0,%v1,%v2"
1105 [(set_attr "op_type" "VRR")])
1106
1107 ; vfsqsb, vfsqdb, wfsqsb, wfsqdb, wfsqxb
1108 (define_insn "sqrt<mode>2"
1109 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1110 (sqrt:VF_HW (match_operand:VF_HW 1 "register_operand" "v")))]
1111 "TARGET_VX"
1112 "<vw>fsq<sdx>b\t%v0,%v1"
1113 [(set_attr "op_type" "VRR")])
1114
1115 ; vfmasb, vfmadb, wfmasb, wfmadb, wfmaxb
1116 (define_insn "fma<mode>4"
1117 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1118 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
1119 (match_operand:VF_HW 2 "register_operand" "v")
1120 (match_operand:VF_HW 3 "register_operand" "v")))]
1121 "TARGET_VX"
1122 "<vw>fma<sdx>b\t%v0,%v1,%v2,%v3"
1123 [(set_attr "op_type" "VRR")])
1124
1125 ; vfmssb, vfmsdb, wfmssb, wfmsdb, wfmsxb
1126 (define_insn "fms<mode>4"
1127 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1128 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
1129 (match_operand:VF_HW 2 "register_operand" "v")
1130 (neg:VF_HW (match_operand:VF_HW 3 "register_operand" "v"))))]
1131 "TARGET_VX"
1132 "<vw>fms<sdx>b\t%v0,%v1,%v2,%v3"
1133 [(set_attr "op_type" "VRR")])
1134
1135 ; vfnmasb, vfnmadb, wfnmasb, wfnmadb, wfnmaxb
1136 (define_insn "neg_fma<mode>4"
1137 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1138 (neg:VF_HW
1139 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
1140 (match_operand:VF_HW 2 "register_operand" "v")
1141 (match_operand:VF_HW 3 "register_operand" "v"))))]
1142 "TARGET_VXE"
1143 "<vw>fnma<sdx>b\t%v0,%v1,%v2,%v3"
1144 [(set_attr "op_type" "VRR")])
1145
1146 ; vfnmssb, vfnmsdb, wfnmssb, wfnmsdb, wfnmsxb
1147 (define_insn "neg_fms<mode>4"
1148 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1149 (neg:VF_HW
1150 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
1151 (match_operand:VF_HW 2 "register_operand" "v")
1152 (neg:VF_HW (match_operand:VF_HW 3 "register_operand" "v")))))]
1153 "TARGET_VXE"
1154 "<vw>fnms<sdx>b\t%v0,%v1,%v2,%v3"
1155 [(set_attr "op_type" "VRR")])
1156
1157 ; vflcsb, vflcdb, wflcsb, wflcdb, wflcxb
1158 (define_insn "neg<mode>2"
1159 [(set (match_operand:VFT 0 "register_operand" "=v")
1160 (neg:VFT (match_operand:VFT 1 "register_operand" "v")))]
1161 "TARGET_VX"
1162 "<vw>flc<sdx>b\t%v0,%v1"
1163 [(set_attr "op_type" "VRR")])
1164
1165 ; vflpsb, vflpdb, wflpsb, wflpdb, wflpxb
1166 (define_insn "abs<mode>2"
1167 [(set (match_operand:VFT 0 "register_operand" "=v")
1168 (abs:VFT (match_operand:VFT 1 "register_operand" "v")))]
1169 "TARGET_VX"
1170 "<vw>flp<sdx>b\t%v0,%v1"
1171 [(set_attr "op_type" "VRR")])
1172
1173 ; vflnsb, vflndb, wflnsb, wflndb, wflnxb
1174 (define_insn "negabs<mode>2"
1175 [(set (match_operand:VFT 0 "register_operand" "=v")
1176 (neg:VFT (abs:VFT (match_operand:VFT 1 "register_operand" "v"))))]
1177 "TARGET_VX"
1178 "<vw>fln<sdx>b\t%v0,%v1"
1179 [(set_attr "op_type" "VRR")])
1180
1181 (define_expand "smax<mode>3"
1182 [(set (match_operand:VF_HW 0 "register_operand")
1183 (smax:VF_HW (match_operand:VF_HW 1 "register_operand")
1184 (match_operand:VF_HW 2 "register_operand")))]
1185 "TARGET_VX")
1186
1187 ; vfmaxsb, vfmaxdb, wfmaxsb, wfmaxdb, wfmaxxb
1188 (define_insn "*smax<mode>3_vxe"
1189 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1190 (smax:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
1191 (match_operand:VF_HW 2 "register_operand" "v")))]
1192 "TARGET_VXE"
1193 "<vw>fmax<sdx>b\t%v0,%v1,%v2,4"
1194 [(set_attr "op_type" "VRR")])
1195
1196 ; Emulate with compare + select
1197 (define_insn_and_split "*smaxv2df3_vx"
1198 [(set (match_operand:V2DF 0 "register_operand" "=v")
1199 (smax:V2DF (match_operand:V2DF 1 "register_operand" "%v")
1200 (match_operand:V2DF 2 "register_operand" "v")))]
1201 "TARGET_VX && !TARGET_VXE"
1202 "#"
1203 "&& 1"
1204 [(set (match_dup 3)
1205 (gt:V2DI (match_dup 1) (match_dup 2)))
1206 (set (match_dup 0)
1207 (if_then_else:V2DF
1208 (eq (match_dup 3) (match_dup 4))
1209 (match_dup 2)
1210 (match_dup 1)))]
1211 {
1212 operands[3] = gen_reg_rtx (V2DImode);
1213 operands[4] = CONST0_RTX (V2DImode);
1214 })
1215
1216 (define_expand "smin<mode>3"
1217 [(set (match_operand:VF_HW 0 "register_operand")
1218 (smin:VF_HW (match_operand:VF_HW 1 "register_operand")
1219 (match_operand:VF_HW 2 "register_operand")))]
1220 "TARGET_VX")
1221
1222 ; vfminsb, vfmindb, wfminsb, wfmindb, wfminxb
1223 (define_insn "*smin<mode>3_vxe"
1224 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1225 (smin:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
1226 (match_operand:VF_HW 2 "register_operand" "v")))]
1227 "TARGET_VXE"
1228 "<vw>fmin<sdx>b\t%v0,%v1,%v2,4"
1229 [(set_attr "op_type" "VRR")])
1230
1231 ; Emulate with compare + select
1232 (define_insn_and_split "*sminv2df3_vx"
1233 [(set (match_operand:V2DF 0 "register_operand" "=v")
1234 (smin:V2DF (match_operand:V2DF 1 "register_operand" "%v")
1235 (match_operand:V2DF 2 "register_operand" "v")))]
1236 "TARGET_VX && !TARGET_VXE"
1237 "#"
1238 "&& 1"
1239 [(set (match_dup 3)
1240 (gt:V2DI (match_dup 1) (match_dup 2)))
1241 (set (match_dup 0)
1242 (if_then_else:V2DF
1243 (eq (match_dup 3) (match_dup 4))
1244 (match_dup 1)
1245 (match_dup 2)))]
1246 {
1247 operands[3] = gen_reg_rtx (V2DImode);
1248 operands[4] = CONST0_RTX (V2DImode);
1249 })
1250
1251
1252 ;;
1253 ;; Integer compares
1254 ;;
1255
1256 (define_insn "*vec_cmp<VICMP_HW_OP:code><VI:mode>_nocc"
1257 [(set (match_operand:VI 2 "register_operand" "=v")
1258 (VICMP_HW_OP:VI (match_operand:VI 0 "register_operand" "v")
1259 (match_operand:VI 1 "register_operand" "v")))]
1260 "TARGET_VX"
1261 "vc<VICMP_HW_OP:insn_cmp_op><VI:bhfgq>\t%v2,%v0,%v1"
1262 [(set_attr "op_type" "VRR")])
1263
1264
1265 ;;
1266 ;; Floating point compares
1267 ;;
1268
1269 ; EQ, GT, GE
1270 ; vfcesb, vfcedb, wfcexb, vfchsb, vfchdb, wfchxb, vfchesb, vfchedb, wfchexb
1271 (define_insn "*vec_cmp<VFCMP_HW_OP:code><mode>_nocc"
1272 [(set (match_operand:<tointvec> 0 "register_operand" "=v")
1273 (VFCMP_HW_OP:<tointvec> (match_operand:VFT 1 "register_operand" "v")
1274 (match_operand:VFT 2 "register_operand" "v")))]
1275 "TARGET_VX"
1276 "<vw>fc<VFCMP_HW_OP:asm_fcmp_op><sdx>b\t%v0,%v1,%v2"
1277 [(set_attr "op_type" "VRR")])
1278
1279 ; Expanders for not directly supported comparisons
1280
1281 ; UNEQ a u== b -> !(a > b | b > a)
1282 (define_expand "vec_cmpuneq<mode>"
1283 [(set (match_operand:<tointvec> 0 "register_operand" "=v")
1284 (gt:<tointvec> (match_operand:VFT 1 "register_operand" "v")
1285 (match_operand:VFT 2 "register_operand" "v")))
1286 (set (match_dup 3)
1287 (gt:<tointvec> (match_dup 2) (match_dup 1)))
1288 (set (match_dup 0) (ior:<tointvec> (match_dup 0) (match_dup 3)))
1289 (set (match_dup 0) (not:<tointvec> (match_dup 0)))]
1290 "TARGET_VX"
1291 {
1292 operands[3] = gen_reg_rtx (<tointvec>mode);
1293 })
1294
1295 ; LTGT a <> b -> a > b | b > a
1296 (define_expand "vec_cmpltgt<mode>"
1297 [(set (match_operand:<tointvec> 0 "register_operand" "=v")
1298 (gt:<tointvec> (match_operand:VFT 1 "register_operand" "v")
1299 (match_operand:VFT 2 "register_operand" "v")))
1300 (set (match_dup 3) (gt:<tointvec> (match_dup 2) (match_dup 1)))
1301 (set (match_dup 0) (ior:<tointvec> (match_dup 0) (match_dup 3)))]
1302 "TARGET_VX"
1303 {
1304 operands[3] = gen_reg_rtx (<tointvec>mode);
1305 })
1306
1307 ; ORDERED (a, b): a >= b | b > a
1308 (define_expand "vec_ordered<mode>"
1309 [(set (match_operand:<tointvec> 0 "register_operand" "=v")
1310 (ge:<tointvec> (match_operand:VFT 1 "register_operand" "v")
1311 (match_operand:VFT 2 "register_operand" "v")))
1312 (set (match_dup 3) (gt:<tointvec> (match_dup 2) (match_dup 1)))
1313 (set (match_dup 0) (ior:<tointvec> (match_dup 0) (match_dup 3)))]
1314 "TARGET_VX"
1315 {
1316 operands[3] = gen_reg_rtx (<tointvec>mode);
1317 })
1318
1319 ; UNORDERED (a, b): !ORDERED (a, b)
1320 (define_expand "vec_unordered<mode>"
1321 [(set (match_operand:<tointvec> 0 "register_operand" "=v")
1322 (ge:<tointvec> (match_operand:VFT 1 "register_operand" "v")
1323 (match_operand:VFT 2 "register_operand" "v")))
1324 (set (match_dup 3) (gt:<tointvec> (match_dup 2) (match_dup 1)))
1325 (set (match_dup 0) (ior:<tointvec> (match_dup 0) (match_dup 3)))
1326 (set (match_dup 0) (not:<tointvec> (match_dup 0)))]
1327 "TARGET_VX"
1328 {
1329 operands[3] = gen_reg_rtx (<tointvec>mode);
1330 })
1331
1332 (define_insn "*vec_load_pair<mode>"
1333 [(set (match_operand:V_HW_64 0 "register_operand" "=v,v")
1334 (vec_concat:V_HW_64 (match_operand:<non_vec> 1 "register_operand" "d,v")
1335 (match_operand:<non_vec> 2 "register_operand" "d,v")))]
1336 "TARGET_VX"
1337 "@
1338 vlvgp\t%v0,%1,%2
1339 vmrhg\t%v0,%v1,%v2"
1340 [(set_attr "op_type" "VRR,VRR")])
1341
1342 (define_insn "vllv16qi"
1343 [(set (match_operand:V16QI 0 "register_operand" "=v")
1344 (unspec:V16QI [(match_operand:SI 1 "register_operand" "d")
1345 (match_operand:BLK 2 "memory_operand" "Q")]
1346 UNSPEC_VEC_LOAD_LEN))]
1347 "TARGET_VX"
1348 "vll\t%v0,%1,%2"
1349 [(set_attr "op_type" "VRS")])
1350
1351 ; vfenebs, vfenehs, vfenefs
1352 ; vfenezbs, vfenezhs, vfenezfs
1353 (define_insn "vec_vfenes<mode>"
1354 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1355 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1356 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1357 (match_operand:QI 3 "const_mask_operand" "C")]
1358 UNSPEC_VEC_VFENE))
1359 (set (reg:CCRAW CC_REGNUM)
1360 (unspec:CCRAW [(match_dup 1)
1361 (match_dup 2)
1362 (match_dup 3)]
1363 UNSPEC_VEC_VFENECC))]
1364 "TARGET_VX"
1365 {
1366 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1367
1368 gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
1369 flags &= ~VSTRING_FLAG_CS;
1370
1371 if (flags == VSTRING_FLAG_ZS)
1372 return "vfenez<bhfgq>s\t%v0,%v1,%v2";
1373 return "vfene<bhfgq>s\t%v0,%v1,%v2";
1374 }
1375 [(set_attr "op_type" "VRR")])
1376
1377
1378 ; Vector select
1379
1380 ; The following splitters simplify vec_sel for constant 0 or -1
1381 ; selection sources. This is required to generate efficient code for
1382 ; vcond.
1383
1384 ; a = b == c;
1385 (define_split
1386 [(set (match_operand:V 0 "register_operand" "")
1387 (if_then_else:V
1388 (eq (match_operand:<tointvec> 3 "register_operand" "")
1389 (match_operand:V 4 "const0_operand" ""))
1390 (match_operand:V 1 "const0_operand" "")
1391 (match_operand:V 2 "all_ones_operand" "")))]
1392 "TARGET_VX"
1393 [(set (match_dup 0) (match_dup 3))]
1394 {
1395 PUT_MODE (operands[3], <V:MODE>mode);
1396 })
1397
1398 ; a = ~(b == c)
1399 (define_split
1400 [(set (match_operand:V 0 "register_operand" "")
1401 (if_then_else:V
1402 (eq (match_operand:<tointvec> 3 "register_operand" "")
1403 (match_operand:V 4 "const0_operand" ""))
1404 (match_operand:V 1 "all_ones_operand" "")
1405 (match_operand:V 2 "const0_operand" "")))]
1406 "TARGET_VX"
1407 [(set (match_dup 0) (not:V (match_dup 3)))]
1408 {
1409 PUT_MODE (operands[3], <V:MODE>mode);
1410 })
1411
1412 ; a = b != c
1413 (define_split
1414 [(set (match_operand:V 0 "register_operand" "")
1415 (if_then_else:V
1416 (ne (match_operand:<tointvec> 3 "register_operand" "")
1417 (match_operand:V 4 "const0_operand" ""))
1418 (match_operand:V 1 "all_ones_operand" "")
1419 (match_operand:V 2 "const0_operand" "")))]
1420 "TARGET_VX"
1421 [(set (match_dup 0) (match_dup 3))]
1422 {
1423 PUT_MODE (operands[3], <V:MODE>mode);
1424 })
1425
1426 ; a = ~(b != c)
1427 (define_split
1428 [(set (match_operand:V 0 "register_operand" "")
1429 (if_then_else:V
1430 (ne (match_operand:<tointvec> 3 "register_operand" "")
1431 (match_operand:V 4 "const0_operand" ""))
1432 (match_operand:V 1 "const0_operand" "")
1433 (match_operand:V 2 "all_ones_operand" "")))]
1434 "TARGET_VX"
1435 [(set (match_dup 0) (not:V (match_dup 3)))]
1436 {
1437 PUT_MODE (operands[3], <V:MODE>mode);
1438 })
1439
1440 ; op0 = op3 == 0 ? op1 : op2
1441 (define_insn "*vec_sel0<mode>"
1442 [(set (match_operand:V 0 "register_operand" "=v")
1443 (if_then_else:V
1444 (eq (match_operand:<tointvec> 3 "register_operand" "v")
1445 (match_operand:<tointvec> 4 "const0_operand" ""))
1446 (match_operand:V 1 "register_operand" "v")
1447 (match_operand:V 2 "register_operand" "v")))]
1448 "TARGET_VX"
1449 "vsel\t%v0,%2,%1,%3"
1450 [(set_attr "op_type" "VRR")])
1451
1452 ; op0 = !op3 == 0 ? op1 : op2
1453 (define_insn "*vec_sel0<mode>"
1454 [(set (match_operand:V 0 "register_operand" "=v")
1455 (if_then_else:V
1456 (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
1457 (match_operand:<tointvec> 4 "const0_operand" ""))
1458 (match_operand:V 1 "register_operand" "v")
1459 (match_operand:V 2 "register_operand" "v")))]
1460 "TARGET_VX"
1461 "vsel\t%v0,%1,%2,%3"
1462 [(set_attr "op_type" "VRR")])
1463
1464 ; op0 = op3 == -1 ? op1 : op2
1465 (define_insn "*vec_sel1<mode>"
1466 [(set (match_operand:V 0 "register_operand" "=v")
1467 (if_then_else:V
1468 (eq (match_operand:<tointvec> 3 "register_operand" "v")
1469 (match_operand:<tointvec> 4 "all_ones_operand" ""))
1470 (match_operand:V 1 "register_operand" "v")
1471 (match_operand:V 2 "register_operand" "v")))]
1472 "TARGET_VX"
1473 "vsel\t%v0,%1,%2,%3"
1474 [(set_attr "op_type" "VRR")])
1475
1476 ; op0 = !op3 == -1 ? op1 : op2
1477 (define_insn "*vec_sel1<mode>"
1478 [(set (match_operand:V 0 "register_operand" "=v")
1479 (if_then_else:V
1480 (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
1481 (match_operand:<tointvec> 4 "all_ones_operand" ""))
1482 (match_operand:V 1 "register_operand" "v")
1483 (match_operand:V 2 "register_operand" "v")))]
1484 "TARGET_VX"
1485 "vsel\t%v0,%2,%1,%3"
1486 [(set_attr "op_type" "VRR")])
1487
1488 ; vec_pack_trunc
1489
1490 ; vpkh, vpkf, vpkg
1491 (define_insn "vec_pack_trunc_<mode>"
1492 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
1493 (vec_concat:<vec_half>
1494 (truncate:<vec_halfhalf>
1495 (match_operand:VI_HW_HSD 1 "register_operand" "v"))
1496 (truncate:<vec_halfhalf>
1497 (match_operand:VI_HW_HSD 2 "register_operand" "v"))))]
1498 "TARGET_VX"
1499 "vpk<bhfgq>\t%0,%1,%2"
1500 [(set_attr "op_type" "VRR")])
1501
1502 ; vpksh, vpksf, vpksg
1503 (define_insn "vec_pack_ssat_<mode>"
1504 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
1505 (vec_concat:<vec_half>
1506 (ss_truncate:<vec_halfhalf>
1507 (match_operand:VI_HW_HSD 1 "register_operand" "v"))
1508 (ss_truncate:<vec_halfhalf>
1509 (match_operand:VI_HW_HSD 2 "register_operand" "v"))))]
1510 "TARGET_VX"
1511 "vpks<bhfgq>\t%0,%1,%2"
1512 [(set_attr "op_type" "VRR")])
1513
1514 ; vpklsh, vpklsf, vpklsg
1515 (define_insn "vec_pack_usat_<mode>"
1516 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
1517 (vec_concat:<vec_half>
1518 (us_truncate:<vec_halfhalf>
1519 (match_operand:VI_HW_HSD 1 "register_operand" "v"))
1520 (us_truncate:<vec_halfhalf>
1521 (match_operand:VI_HW_HSD 2 "register_operand" "v"))))]
1522 "TARGET_VX"
1523 "vpkls<bhfgq>\t%0,%1,%2"
1524 [(set_attr "op_type" "VRR")])
1525
1526 ;; vector unpack v16qi
1527
1528 ; signed
1529
1530 (define_insn "vec_unpacks_hi_v16qi"
1531 [(set (match_operand:V8HI 0 "register_operand" "=v")
1532 (sign_extend:V8HI
1533 (vec_select:V8QI
1534 (match_operand:V16QI 1 "register_operand" "v")
1535 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
1536 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
1537 "TARGET_VX"
1538 "vuphb\t%0,%1"
1539 [(set_attr "op_type" "VRR")])
1540
1541 (define_insn "vec_unpacks_low_v16qi"
1542 [(set (match_operand:V8HI 0 "register_operand" "=v")
1543 (sign_extend:V8HI
1544 (vec_select:V8QI
1545 (match_operand:V16QI 1 "register_operand" "v")
1546 (parallel [(const_int 8) (const_int 9) (const_int 10)(const_int 11)
1547 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
1548 "TARGET_VX"
1549 "vuplb\t%0,%1"
1550 [(set_attr "op_type" "VRR")])
1551
1552 ; unsigned
1553
1554 (define_insn "vec_unpacku_hi_v16qi"
1555 [(set (match_operand:V8HI 0 "register_operand" "=v")
1556 (zero_extend:V8HI
1557 (vec_select:V8QI
1558 (match_operand:V16QI 1 "register_operand" "v")
1559 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
1560 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
1561 "TARGET_VX"
1562 "vuplhb\t%0,%1"
1563 [(set_attr "op_type" "VRR")])
1564
1565 (define_insn "vec_unpacku_low_v16qi"
1566 [(set (match_operand:V8HI 0 "register_operand" "=v")
1567 (zero_extend:V8HI
1568 (vec_select:V8QI
1569 (match_operand:V16QI 1 "register_operand" "v")
1570 (parallel [(const_int 8) (const_int 9) (const_int 10)(const_int 11)
1571 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
1572 "TARGET_VX"
1573 "vupllb\t%0,%1"
1574 [(set_attr "op_type" "VRR")])
1575
1576 ;; vector unpack v8hi
1577
1578 ; signed
1579
1580 (define_insn "vec_unpacks_hi_v8hi"
1581 [(set (match_operand:V4SI 0 "register_operand" "=v")
1582 (sign_extend:V4SI
1583 (vec_select:V4HI
1584 (match_operand:V8HI 1 "register_operand" "v")
1585 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
1586 "TARGET_VX"
1587 "vuphh\t%0,%1"
1588 [(set_attr "op_type" "VRR")])
1589
1590 (define_insn "vec_unpacks_lo_v8hi"
1591 [(set (match_operand:V4SI 0 "register_operand" "=v")
1592 (sign_extend:V4SI
1593 (vec_select:V4HI
1594 (match_operand:V8HI 1 "register_operand" "v")
1595 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
1596 "TARGET_VX"
1597 "vuplhw\t%0,%1"
1598 [(set_attr "op_type" "VRR")])
1599
1600 ; unsigned
1601
1602 (define_insn "vec_unpacku_hi_v8hi"
1603 [(set (match_operand:V4SI 0 "register_operand" "=v")
1604 (zero_extend:V4SI
1605 (vec_select:V4HI
1606 (match_operand:V8HI 1 "register_operand" "v")
1607 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
1608 "TARGET_VX"
1609 "vuplhh\t%0,%1"
1610 [(set_attr "op_type" "VRR")])
1611
1612 (define_insn "vec_unpacku_lo_v8hi"
1613 [(set (match_operand:V4SI 0 "register_operand" "=v")
1614 (zero_extend:V4SI
1615 (vec_select:V4HI
1616 (match_operand:V8HI 1 "register_operand" "v")
1617 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
1618 "TARGET_VX"
1619 "vupllh\t%0,%1"
1620 [(set_attr "op_type" "VRR")])
1621
1622 ;; vector unpack v4si
1623
1624 ; signed
1625
1626 (define_insn "vec_unpacks_hi_v4si"
1627 [(set (match_operand:V2DI 0 "register_operand" "=v")
1628 (sign_extend:V2DI
1629 (vec_select:V2SI
1630 (match_operand:V4SI 1 "register_operand" "v")
1631 (parallel [(const_int 0)(const_int 1)]))))]
1632 "TARGET_VX"
1633 "vuphf\t%0,%1"
1634 [(set_attr "op_type" "VRR")])
1635
1636 (define_insn "vec_unpacks_lo_v4si"
1637 [(set (match_operand:V2DI 0 "register_operand" "=v")
1638 (sign_extend:V2DI
1639 (vec_select:V2SI
1640 (match_operand:V4SI 1 "register_operand" "v")
1641 (parallel [(const_int 2)(const_int 3)]))))]
1642 "TARGET_VX"
1643 "vuplf\t%0,%1"
1644 [(set_attr "op_type" "VRR")])
1645
1646 ; unsigned
1647
1648 (define_insn "vec_unpacku_hi_v4si"
1649 [(set (match_operand:V2DI 0 "register_operand" "=v")
1650 (zero_extend:V2DI
1651 (vec_select:V2SI
1652 (match_operand:V4SI 1 "register_operand" "v")
1653 (parallel [(const_int 0)(const_int 1)]))))]
1654 "TARGET_VX"
1655 "vuplhf\t%0,%1"
1656 [(set_attr "op_type" "VRR")])
1657
1658 (define_insn "vec_unpacku_lo_v4si"
1659 [(set (match_operand:V2DI 0 "register_operand" "=v")
1660 (zero_extend:V2DI
1661 (vec_select:V2SI
1662 (match_operand:V4SI 1 "register_operand" "v")
1663 (parallel [(const_int 2)(const_int 3)]))))]
1664 "TARGET_VX"
1665 "vupllf\t%0,%1"
1666 [(set_attr "op_type" "VRR")])
1667
1668 ;; vector load lengthened
1669
1670 ; vflls
1671 (define_insn "*vec_extendv4sf"
1672 [(set (match_operand:V2DF 0 "register_operand" "=v")
1673 (float_extend:V2DF
1674 (vec_select:V2SF
1675 (match_operand:V4SF 1 "register_operand" "v")
1676 (parallel [(const_int 0) (const_int 2)]))))]
1677 "TARGET_VX"
1678 "vldeb\t%v0,%v1"
1679 [(set_attr "op_type" "VRR")])
1680
1681 (define_insn "*vec_extendv2df"
1682 [(set (match_operand:V1TF 0 "register_operand" "=v")
1683 (float_extend:V1TF
1684 (vec_select:V1DF
1685 (match_operand:V2DF 1 "register_operand" "v")
1686 (parallel [(const_int 0)]))))]
1687 "TARGET_VXE"
1688 "wflld\t%v0,%v1"
1689 [(set_attr "op_type" "VRR")])
1690
1691 ; reduc_smin
1692 ; reduc_smax
1693 ; reduc_umin
1694 ; reduc_umax
1695
1696 ; vec_shl vrep + vsl
1697 ; vec_shr
1698
1699 ; vec_pack_sfix_trunc: convert + pack ?
1700 ; vec_pack_ufix_trunc
1701 ; vec_unpacks_float_hi
1702 ; vec_unpacks_float_lo
1703 ; vec_unpacku_float_hi
1704 ; vec_unpacku_float_lo
1705