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