1 ;;- Instruction patterns for the System z vector facility
2 ;; Copyright (C) 2015-2024 Free Software Foundation, Inc.
3 ;; Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
5 ;; This file is part of GCC.
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
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
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/>.
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
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])
29 ; All modes directly supported by the hardware having full vector reg size
30 (define_mode_iterator V_HW [V16QI V8HI V4SI V2DI V1TI TI V2DF
31 (V4SF "TARGET_VXE") (V1TF "TARGET_VXE")
34 (define_mode_iterator VT_HW_HSDT [V8HI V4SI V4SF V2DI V2DF V1TI V1TF TI TF])
35 (define_mode_iterator V_HW_HSD [V8HI V4SI (V4SF "TARGET_VXE") V2DI V2DF])
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")])
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_HSDT [V8HI V4SI V2DI V1TI TI])
46 (define_mode_iterator VI_HW_HS [V8HI V4SI])
47 (define_mode_iterator VI_HW_QH [V16QI V8HI])
48 (define_mode_iterator VI_HW_T [V1TI TI])
50 ; Directly supported vector modes with a certain number of elements
51 (define_mode_iterator V_HW_2 [V2DI V2DF])
52 (define_mode_iterator V_HW_4 [V4SI V4SF])
54 ; All integer vector modes supported in a vector register + TImode
55 (define_mode_iterator VIT [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1TI TI])
56 (define_mode_iterator VI [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI])
57 (define_mode_iterator VI_QHS [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI])
59 (define_mode_iterator VFT [(V1SF "TARGET_VXE") (V2SF "TARGET_VXE") (V4SF "TARGET_VXE")
61 (V1TF "TARGET_VXE") (TF "TARGET_VXE")])
63 ; All modes present in V_HW and VFT.
64 (define_mode_iterator V_HW_FT [V16QI V8HI V4SI V2DI (V1TI "TARGET_VXE") V1DF
65 V2DF (V1SF "TARGET_VXE") (V2SF "TARGET_VXE")
66 (V4SF "TARGET_VXE") (V1TF "TARGET_VXE")
69 ; FP vector modes directly supported by the HW. This does not include
70 ; vector modes using only part of a vector register and should be used
71 ; for instructions which might trigger IEEE exceptions.
72 (define_mode_iterator VF_HW [(V4SF "TARGET_VXE") V2DF (V1TF "TARGET_VXE")
75 (define_mode_iterator V_8 [V1QI])
76 (define_mode_iterator V_16 [V2QI V1HI])
77 (define_mode_iterator V_32 [V4QI V2HI V1SI V1SF])
78 (define_mode_iterator V_64 [V8QI V4HI V2SI V2SF V1DI V1DF])
79 (define_mode_iterator V_128 [V16QI V8HI V4SI V4SF V2DI V2DF V1TI V1TF
81 (define_mode_iterator V_128_NOSINGLE [V16QI V8HI V4SI V4SF V2DI V2DF])
83 ; 32 bit int<->fp vector conversion instructions are available since VXE2 (z15).
84 (define_mode_iterator VX_VEC_CONV_BFP [V2DF (V4SF "TARGET_VXE2")])
86 (define_mode_iterator VI_EXTEND [V2QI V2HI V2SI V4QI V4HI])
88 ; Empty string for all but TImode. This is used to hide the TImode
89 ; expander name in case it is defined already. See addti3 for an
91 (define_mode_attr ti* [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "")
92 (V1HI "") (V2HI "") (V4HI "") (V8HI "")
93 (V1SI "") (V2SI "") (V4SI "")
96 (V1SF "") (V2SF "") (V4SF "")
100 ;; Facilitate dispatching TFmode expanders on z14+.
101 (define_mode_attr tf_vr [(TF "_vr") (V4SF "") (V2DF "") (V1TF "") (V1SF "")
102 (V2SF "") (V1DF "") (V16QI "") (V8HI "") (V4SI "")
103 (V2DI "") (V1TI "")])
105 ; The element type of the vector.
106 (define_mode_attr non_vec[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI")
107 (V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI")
108 (V1SI "SI") (V2SI "SI") (V4SI "SI")
109 (V1DI "DI") (V2DI "DI")
110 (V1TI "TI") (TI "TI")
111 (V1SF "SF") (V2SF "SF") (V4SF "SF")
112 (V1DF "DF") (V2DF "DF")
113 (V1TF "TF") (TF "TF")])
115 ; Like above, but in lower case.
116 (define_mode_attr non_vec_l[(V1QI "qi") (V2QI "qi") (V4QI "qi") (V8QI "qi")
118 (V1HI "hi") (V2HI "hi") (V4HI "hi") (V8HI "hi")
119 (V1SI "si") (V2SI "si") (V4SI "si")
120 (V1DI "di") (V2DI "di")
121 (V1TI "ti") (TI "ti")
122 (V1SF "sf") (V2SF "sf") (V4SF "sf")
123 (V1DF "df") (V2DF "df")
124 (V1TF "tf") (TF "tf")])
126 ; The instruction suffix for integer instructions and instructions
127 ; which do not care about whether it is floating point or integer.
128 (define_mode_attr bhfgq[(V1QI "b") (V2QI "b") (V4QI "b") (V8QI "b") (V16QI "b")
129 (V1HI "h") (V2HI "h") (V4HI "h") (V8HI "h")
130 (V1SI "f") (V2SI "f") (V4SI "f")
131 (V1DI "g") (V2DI "g")
133 (V1SF "f") (V2SF "f") (V4SF "f")
134 (V1DF "g") (V2DF "g")
135 (V1TF "q") (TF "q")])
137 ; This is for vmalhw. It gets an 'w' attached to avoid confusion with
138 ; multiply and add logical high vmalh.
139 (define_mode_attr w [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "")
140 (V1HI "w") (V2HI "w") (V4HI "w") (V8HI "w")
141 (V1SI "") (V2SI "") (V4SI "")
142 (V1DI "") (V2DI "")])
144 ; Resulting mode of a vector comparison. For floating point modes an
145 ; integer vector mode with the same element size is picked.
146 (define_mode_attr TOINTVEC [(V1QI "V1QI") (V2QI "V2QI") (V4QI "V4QI") (V8QI "V8QI") (V16QI "V16QI")
147 (V1HI "V1HI") (V2HI "V2HI") (V4HI "V4HI") (V8HI "V8HI")
148 (V1SI "V1SI") (V2SI "V2SI") (V4SI "V4SI")
149 (V1DI "V1DI") (V2DI "V2DI")
150 (V1TI "V1TI") (TI "V1TI")
151 (V1SF "V1SI") (V2SF "V2SI") (V4SF "V4SI")
152 (V1DF "V1DI") (V2DF "V2DI")
153 (V1TF "V1TI") (TF "V1TI")])
155 (define_mode_attr tointvec [(V1QI "v1qi") (V2QI "v2qi") (V4QI "v4qi") (V8QI "v8qi") (V16QI "v16qi")
156 (V1HI "v1hi") (V2HI "v2hi") (V4HI "v4hi") (V8HI "v8hi")
157 (V1SI "v1si") (V2SI "v2si") (V4SI "v4si")
158 (V1DI "v1di") (V2DI "v2di")
159 (V1TI "v1ti") (TI "v1ti")
160 (V1SF "v1si") (V2SF "v2si") (V4SF "v4si")
161 (V1DF "v1di") (V2DF "v2di")
162 (V1TF "v1ti") (TF "v1ti")])
164 (define_mode_attr vw [(SF "w") (V1SF "w") (V2SF "v") (V4SF "v")
165 (DF "w") (V1DF "w") (V2DF "v")
166 (TF "w") (V1TF "w")])
168 (define_mode_attr sdx [(SF "s") (V1SF "s") (V2SF "s") (V4SF "s")
169 (DF "d") (V1DF "d") (V2DF "d")
170 (TF "x") (V1TF "x")])
172 ; Vector with widened element size but half the number of elements.
173 (define_mode_attr vec_double [(V1QI "V1HI") (V2QI "V1HI") (V4QI "V2HI") (V8QI "V4HI") (V16QI "V8HI")
174 (V1HI "V1SI") (V2HI "V1SI") (V4HI "V2SI") (V8HI "V4SI")
175 (V1SI "V1DI") (V2SI "V1DI") (V4SI "V2DI")
176 (V1DI "V1TI") (V2DI "V1TI")
177 (V1SF "V1DF") (V2SF "V1DF") (V4SF "V2DF")])
179 ; Vector with shrinked element size but twice the number of elements.
180 (define_mode_attr vec_half [(V1HI "V2QI") (V2HI "V4QI") (V4HI "V8QI") (V8HI "V16QI")
181 (V1SI "V2HI") (V2SI "V4HI") (V4SI "V8HI")
182 (V1DI "V2SI") (V2DI "V4SI")
184 (V1DF "V2SF") (V2DF "V4SF")
187 ; Vector with twice the number of elements but same element size.
188 (define_mode_attr vec_2x_nelts [(V1QI "V2QI") (V2QI "V4QI") (V4QI "V8QI") (V8QI "V16QI") (V16QI "V32QI")
189 (V1HI "V2HI") (V2HI "V4HI") (V4HI "V8HI") (V8HI "V16HI")
190 (V1SI "V2SI") (V2SI "V4SI") (V4SI "V8SI")
191 (V1DI "V2DI") (V2DI "V4DI")
192 (V1SF "V2SF") (V2SF "V4SF") (V4SF "V8SF")
193 (V1DF "V2DF") (V2DF "V4DF")])
195 ; Vector with widened element size and the same number of elements.
196 (define_mode_attr VEC_2X_WIDE [(V1QI "V1HI") (V2QI "V2HI") (V4QI "V4HI") (V8QI "V8HI") (V16QI "V16HI")
197 (V1HI "V1SI") (V2HI "V2SI") (V4HI "V4SI") (V8HI "V8SI")
198 (V1SI "V1DI") (V2SI "V2DI") (V4SI "V4DI")
199 (V1DI "V1TI") (V2DI "V2TI")
200 (V1SF "V1DF") (V2SF "V2DF") (V4SF "V4DF")
201 (V1DF "V1TF") (V2DF "V2TF")])
203 (define_mode_attr vec_2x_wide [(V1QI "v1hi") (V2QI "v2hi") (V4QI "v4hi") (V8QI "v8hi") (V16QI "v16hi")
204 (V1HI "v1si") (V2HI "v2si") (V4HI "v4si") (V8HI "v8si")
205 (V1SI "v1di") (V2SI "v2di") (V4SI "v4di")
206 (V1DI "v1ti") (V2DI "v2ti")
207 (V1SF "v1df") (V2SF "v2df") (V4SF "v4df")
208 (V1DF "v1tf") (V2DF "v2tf")])
210 ; Vector with half the element size AND half the number of elements.
211 (define_mode_attr vec_halfhalf
212 [(V2HI "V2QI") (V4HI "V4QI") (V8HI "V8QI")
213 (V2SI "V2HI") (V4SI "V4HI")
217 (define_mode_attr vec_halfnumelts
218 [(V4SF "V2SF") (V4SI "V2SI")])
222 ; Comparison operators on int and fp compares which are directly
223 ; supported by the HW.
224 (define_code_iterator VICMP_HW_OP [eq gt gtu])
225 ; For int insn_cmp_op can be used in the insn name as well as in the asm output.
226 (define_code_attr insn_cmp_op [(eq "eq") (gt "h") (gtu "hl") (ge "he")])
228 ; Flags for vector string instructions (vfae all 4, vfee only ZS and CS, vstrc all 4)
230 [(VSTRING_FLAG_IN 8) ; invert result
231 (VSTRING_FLAG_RT 4) ; result type
232 (VSTRING_FLAG_ZS 2) ; zero search
233 (VSTRING_FLAG_CS 1)]) ; condition code set
235 (include "vx-builtins.md")
237 ; Full HW vector size moves
239 ; We don't use lm/stm for 128 bit moves since these are slower than
240 ; splitting it into separate moves.
242 ; FIXME: More constants are possible by enabling jxx, jyy constraints
243 ; for TImode (use double-int for the calculations)
245 ; vgmb, vgmh, vgmf, vgmg, vrepib, vrepih, vrepif, vrepig
246 (define_insn "mov<mode><tf_vr>"
247 [(set (match_operand:V_128 0 "nonimmediate_operand" "=v,v,R, v, v, v, v, v,v,*d,*d,?o")
248 (match_operand:V_128 1 "general_operand" " v,R,v,j00,jm1,jyy,jxx,jzz,d, v,dT,*d"))]
263 [(set_attr "cpu_facility" "vx,vx,vx,vx,vx,vx,vx,vx,vx,vx,*,*")
264 (set_attr "op_type" "VRR,VRX,VRX,VRI,VRI,VRI,VRI,VRI,VRR,*,*,*")])
266 (define_expand "movtf"
267 [(match_operand:TF 0 "nonimmediate_operand" "")
268 (match_operand:TF 1 "general_operand" "")]
270 { EXPAND_MOVTF(movtf); })
272 ; VR -> GPR, no instruction so split it into 64 element sets.
274 [(set (match_operand:V_128 0 "register_operand" "")
275 (match_operand:V_128 1 "register_operand" ""))]
276 "TARGET_VX && GENERAL_REG_P (operands[0]) && VECTOR_REG_P (operands[1])"
279 (subreg:V2DI (match_dup 1) 0)
280 (parallel [(const_int 0)])))
283 (subreg:V2DI (match_dup 1) 0)
284 (parallel [(const_int 1)])))]
286 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
287 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
290 ; Split the 128 bit GPR move into two word mode moves
291 ; s390_split_ok_p decides which part needs to be moved first.
294 [(set (match_operand:V_128 0 "nonimmediate_operand" "")
295 (match_operand:V_128 1 "general_operand" ""))]
297 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
298 [(set (match_dup 2) (match_dup 4))
299 (set (match_dup 3) (match_dup 5))]
301 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
302 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
303 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
304 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
308 [(set (match_operand:V_128 0 "nonimmediate_operand" "")
309 (match_operand:V_128 1 "general_operand" ""))]
311 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
312 [(set (match_dup 2) (match_dup 4))
313 (set (match_dup 3) (match_dup 5))]
315 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
316 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
317 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
318 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
321 ; This is the vector equivalent to the TImode splitter in s390.md. It
322 ; is required if both target GPRs occur in the source address operand.
324 ; For non-s_operands at least one of the target GPRs does not conflict
325 ; with the address operand and one of the splitters above will take
328 [(set (match_operand:V_128 0 "register_operand" "")
329 (match_operand:V_128 1 "memory_operand" ""))]
330 "TARGET_ZARCH && reload_completed
331 && !VECTOR_REG_P (operands[0])
332 && !s_operand (operands[1], VOIDmode)"
333 [(set (match_dup 0) (match_dup 1))]
335 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
336 addr = gen_lowpart (Pmode, addr);
337 s390_load_address (addr, XEXP (operands[1], 0));
338 operands[1] = replace_equiv_address (operands[1], addr);
341 ; Moves for smaller vector modes.
343 ; In these patterns only the vlr, vone, and vzero instructions write
344 ; VR bytes outside the mode. This should be ok since we disallow
345 ; formerly bigger modes being accessed with smaller modes via
346 ; subreg. Note: The vone, vzero instructions could easily be replaced
347 ; with vlei which would only access the bytes belonging to the mode.
348 ; However, this would probably be slower.
350 (define_insn "mov<mode>"
351 [(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d,v,R, v, v, v, v, v,d, Q, S, Q, S, d, d,d,R,T")
352 (match_operand:V_8 1 "general_operand" " v,d,v,R,v,j00,jm1,jyy,jxx,jzz,d,j00,j00,jm1,jm1,j00,jm1,T,d,d"))]
375 [(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,VRI,RR,SI,SIY,SI,SIY,RI,RI,RXY,RX,RXY")])
377 (define_insn "mov<mode>"
378 [(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d,v,R, v, v, v, v, v,d, Q, Q, d, d,d,d,d,R,T,b")
379 (match_operand:V_16 1 "general_operand" " v,d,v,R,v,j00,jm1,jyy,jxx,jzz,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
403 [(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")])
405 (define_insn "mov<mode>"
406 [(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d,v,R, f, v, v, v, v, v, Q, Q, d, d,d,d,d,d,R,T,b")
407 (match_operand:V_32 1 "general_operand" " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,jzz,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
437 [(set_attr "op_type" "RR,RXE,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,VRI,SIL,SIL,RI,RI,
438 RIL,RR,RX,RXY,RX,RXY,RIL")])
440 (define_insn "mov<mode>"
441 [(set (match_operand:V_64 0 "nonimmediate_operand"
442 "=f,f,f,R,T,v,v,d,v,R, f, v, v, v, v, v, Q, Q, d, d,f,d,d,d,d,T,b")
443 (match_operand:V_64 1 "general_operand"
444 " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,jzz,j00,jm1,j00,jm1,d,f,b,d,T,d,d"))]
474 [(set_attr "op_type" "RRE,RX,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,VRI,
475 SIL,SIL,RI,RI,RRE,RRE,RIL,RR,RXY,RXY,RIL")])
482 ; vec_set is supposed to *modify* an existing vector so operand 0 is
483 ; duplicated as input operand.
484 (define_expand "vec_set<mode>"
485 [(set (match_operand:V 0 "register_operand" "")
486 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "")
487 (match_operand:SI 2 "nonmemory_operand" "")
492 ; FIXME: Support also vector mode operands for 1
493 ; FIXME: A target memory operand seems to be useful otherwise we end
494 ; up with vl vlvgg vst. Shouldn't the middle-end be able to handle
496 ; vlvgb, vlvgh, vlvgf, vlvgg, vleb, vleh, vlef, vleg, vleib, vleih, vleif, vleig
497 (define_insn "*vec_set<mode>"
498 [(set (match_operand:V 0 "register_operand" "=v,v,v")
499 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,R,K")
500 (match_operand:SI 2 "nonmemory_operand" "an,I,I")
501 (match_operand:V 3 "register_operand" "0,0,0")]
504 && (!CONST_INT_P (operands[2])
505 || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
507 vlvg<bhfgq>\t%v0,%1,%Y2
508 vle<bhfgq>\t%v0,%1,%2
509 vlei<bhfgq>\t%v0,%1,%2"
510 [(set_attr "op_type" "VRS,VRX,VRI")])
512 ; vlvgb, vlvgh, vlvgf, vlvgg
513 (define_insn "*vec_set<mode>_plus"
514 [(set (match_operand:V 0 "register_operand" "=v")
515 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d")
516 (plus:SI (match_operand:SI 2 "register_operand" "a")
517 (match_operand:SI 4 "const_int_operand" "n"))
518 (match_operand:V 3 "register_operand" "0")]
521 "vlvg<bhfgq>\t%v0,%1,%Y4(%2)"
522 [(set_attr "op_type" "VRS")])
525 ;; FIXME: Support also vector mode operands for 0
526 ;; This is used via RTL standard name as well as for expanding the builtin
527 (define_expand "vec_extract<mode><non_vec_l>"
528 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "")
529 (vec_select:<non_vec>
530 (match_operand:V 1 "register_operand" "")
532 [(match_operand:SI 2 "nonmemory_operand" "")])))]
536 ; vlgvb, vlgvh, vlgvf, vlgvg, vsteb, vsteh, vstef, vsteg
537 (define_insn "*vec_extract<mode>"
538 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,R")
539 (vec_select:<non_vec>
540 (match_operand:V 1 "nonmemory_operand" "v,v")
542 [(match_operand:SI 2 "nonmemory_operand" "an,I")])))]
545 if (CONST_INT_P (operands[2]))
546 operands[2] = GEN_INT (UINTVAL (operands[2]) & (GET_MODE_NUNITS (<V:MODE>mode) - 1));
547 if (which_alternative == 0)
548 return "vlgv<bhfgq>\t%0,%v1,%Y2";
549 return "vste<bhfgq>\t%v1,%0,%2";
551 [(set_attr "op_type" "VRS,VRX")])
553 ; vlgvb, vlgvh, vlgvf, vlgvg
554 (define_insn "*vec_extract<mode>_plus"
555 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d")
556 (vec_select:<non_vec>
557 (match_operand:V 1 "register_operand" "v")
558 (plus:SI (match_operand:SI 2 "nonmemory_operand" "a")
559 (parallel [(match_operand:SI 3 "const_int_operand" "n")]))))]
561 "vlgv<bhfgq>\t%0,%v1,%Y3(%2)"
562 [(set_attr "op_type" "VRS")])
564 (define_expand "vec_init<mode><non_vec_l>"
565 [(match_operand:V_128 0 "register_operand" "")
566 (match_operand:V_128 1 "nonmemory_operand" "")]
569 s390_expand_vec_init (operands[0], operands[1]);
573 (define_insn "*vec_vllezlf<mode>"
574 [(set (match_operand:V_HW_4 0 "register_operand" "=v")
576 (vec_concat:<vec_halfnumelts>
577 (match_operand:<non_vec> 1 "memory_operand" "R")
579 (vec_concat:<vec_halfnumelts>
584 [(set_attr "op_type" "VRX")])
586 ; Replicate from vector element
587 ; vrepb, vreph, vrepf, vrepg
588 (define_insn "*vec_splat<mode>"
589 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v")
590 (vec_duplicate:V_128_NOSINGLE
591 (vec_select:<non_vec>
592 (match_operand:V_128_NOSINGLE 1 "register_operand" "v")
594 [(match_operand:QI 2 "const_mask_operand" "C")]))))]
595 "TARGET_VX && UINTVAL (operands[2]) < GET_MODE_NUNITS (<MODE>mode)"
596 "vrep<bhfgq>\t%v0,%v1,%2"
597 [(set_attr "op_type" "VRI")])
599 ; vlrepb, vlreph, vlrepf, vlrepg, vrepib, vrepih, vrepif, vrepig, vrepb, vreph, vrepf, vrepg
600 (define_insn "*vec_splats<mode>"
601 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v,v,v,v")
602 (vec_duplicate:V_128_NOSINGLE (match_operand:<non_vec> 1 "general_operand" " R,K,v,d")))]
606 vrepi<bhfgq>\t%v0,%h1
607 vrep<bhfgq>\t%v0,%v1,0
609 [(set_attr "op_type" "VRX,VRI,VRI,*")])
611 ; vlbrreph, vlbrrepf, vlbrrepg
612 (define_insn "*vec_splats_bswap_vec<mode>"
613 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
615 (vec_duplicate:V_HW_HSD (match_operand:<non_vec> 1 "memory_operand" "R"))))
616 (use (match_operand:V16QI 2 "permute_pattern_operand" "X"))]
618 "vlbrrep<bhfgq>\t%v0,%1"
619 [(set_attr "op_type" "VRX")])
621 ; Why do we need both? Shouldn't there be a canonical form?
622 ; vlbrreph, vlbrrepf, vlbrrepg
623 (define_insn "*vec_splats_bswap_elem<mode>"
624 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
625 (vec_duplicate:V_HW_HSD
626 (bswap:<non_vec> (match_operand:<non_vec> 1 "memory_operand" "R"))))]
628 "vlbrrep<bhfgq>\t%v0,%1"
629 [(set_attr "op_type" "VRX")])
631 ; A TFmode operand resides in FPR register pairs while V1TF is in a
632 ; single vector register.
633 (define_insn "*vec_tf_to_v1tf_fpr"
634 [(set (match_operand:V1TF 0 "nonimmediate_operand" "=v,v,R,v,v")
635 (vec_duplicate:V1TF (match_operand:TF 1 "general_operand" "f,R,f,G,d")))]
636 "TARGET_VX && !TARGET_VXE"
643 [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRR")])
645 ; Both TFmode and V1TFmode operands reside in vector registers.
646 (define_insn "*vec_tf_to_v1tf_vr"
647 [(set (match_operand:V1TF 0 "nonimmediate_operand" "=v,v,R,v,v")
648 (vec_duplicate:V1TF (match_operand:TF 1 "general_operand" "v,R,v,G,d")))]
656 [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRR")])
658 (define_insn_and_split "fprx2_to_tf"
659 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,AR")
660 (subreg:TF (match_operand:FPRX2 1 "general_operand" "f,f") 0))]
665 "!(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))"
666 [(set (match_dup 2) (match_dup 3))
667 (set (match_dup 4) (match_dup 5))]
669 operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, 0);
670 operands[3] = simplify_gen_subreg (DFmode, operands[1], FPRX2mode, 0);
671 operands[4] = simplify_gen_subreg (DFmode, operands[0], TFmode, 8);
672 operands[5] = simplify_gen_subreg (DFmode, operands[1], FPRX2mode, 8);
674 [(set_attr "op_type" "VRR,*")])
676 (define_insn "*vec_ti_to_v1ti"
677 [(set (match_operand:V1TI 0 "nonimmediate_operand" "=v,v,R, v, v,v")
678 (vec_duplicate:V1TI (match_operand:TI 1 "general_operand" "v,R,v,j00,jm1,d")))]
687 [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRI,VRR")])
689 ; vec_splats is supposed to replicate op1 into all elements of op0
690 ; This splitter first sets the rightmost element of op0 to op1 and
691 ; then does a vec_splat to replicate that element into all other
694 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "")
695 (vec_duplicate:V_128_NOSINGLE (match_operand:<non_vec> 1 "register_operand" "")))]
696 "TARGET_VX && GENERAL_REG_P (operands[1])"
698 (unspec:V_128_NOSINGLE [(match_dup 1) (match_dup 2) (match_dup 0)] UNSPEC_VEC_SET))
700 (vec_duplicate:V_128_NOSINGLE
701 (vec_select:<non_vec>
702 (match_dup 0) (parallel [(match_dup 2)]))))]
704 operands[2] = GEN_INT (GET_MODE_NUNITS (<MODE>mode) - 1);
707 (define_predicate "vcond_comparison_operator"
708 (match_operand 0 "comparison_operator")
710 if (!HONOR_NANS (GET_MODE (XEXP (op, 0)))
711 && !HONOR_NANS (GET_MODE (XEXP (op, 1))))
713 switch (GET_CODE (op))
720 /* Signaling vector comparisons are supported only on z14+. */
721 return TARGET_VXE || TARGET_NONSIGNALING_VECTOR_COMPARE_OK;
727 (define_expand "vcond_mask_<mode><tointvec>"
728 [(set (match_operand:VT 0 "register_operand" "")
730 (eq (match_operand:<TOINTVEC> 3 "register_operand" "")
732 (match_operand:VT 2 "register_operand" "")
733 (match_operand:VT 1 "register_operand" "")))]
735 "operands[4] = CONST0_RTX (<TOINTVEC>mode);")
738 ; We only have HW support for byte vectors. The middle-end is
739 ; supposed to lower the mode if required.
740 (define_insn "vec_permv16qi"
741 [(set (match_operand:V16QI 0 "register_operand" "=v")
742 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
743 (match_operand:V16QI 2 "register_operand" "v")
744 (match_operand:V16QI 3 "register_operand" "v")]
747 "vperm\t%v0,%v1,%v2,%v3"
748 [(set_attr "op_type" "VRR")])
750 (define_insn "*vec_perm<mode>"
751 [(set (match_operand:VT_HW 0 "register_operand" "=v")
752 (subreg:VT_HW (unspec:V16QI [(subreg:V16QI (match_operand:VT_HW 1 "register_operand" "v") 0)
753 (subreg:V16QI (match_operand:VT_HW 2 "register_operand" "v") 0)
754 (match_operand:V16QI 3 "register_operand" "v")]
755 UNSPEC_VEC_PERM) 0))]
757 "vperm\t%v0,%v1,%v2,%v3"
758 [(set_attr "op_type" "VRR")])
761 ; First DW of op1 and second DW of op2
762 (define_insn "@vpdi1<mode>"
763 [(set (match_operand:V_HW_2 0 "register_operand" "=v")
765 (vec_concat:<vec_2x_nelts>
766 (match_operand:V_HW_2 1 "register_operand" "v")
767 (match_operand:V_HW_2 2 "register_operand" "v"))
768 (parallel [(const_int 0) (const_int 3)])))]
770 "vpdi\t%v0,%v1,%v2,1"
771 [(set_attr "op_type" "VRR")])
773 ; Second DW of op1 and first of op2
774 (define_insn "@vpdi4<mode>"
775 [(set (match_operand:V_HW_2 0 "register_operand" "=v")
777 (vec_concat:<vec_2x_nelts>
778 (match_operand:V_HW_2 1 "register_operand" "v")
779 (match_operand:V_HW_2 2 "register_operand" "v"))
780 (parallel [(const_int 1) (const_int 2)])))]
782 "vpdi\t%v0,%v1,%v2,4"
783 [(set_attr "op_type" "VRR")])
785 ; Second DW of op1 and first DW of op2 (when interpreted as 2-element vector).
786 (define_insn "@vpdi4_2<mode>"
787 [(set (match_operand:V_HW_4 0 "register_operand" "=v")
789 (vec_concat:<vec_2x_nelts>
790 (match_operand:V_HW_4 1 "register_operand" "v")
791 (match_operand:V_HW_4 2 "register_operand" "v"))
792 (parallel [(const_int 2) (const_int 3) (const_int 4) (const_int 5)])))]
794 "vpdi\t%v0,%v1,%v2,4"
795 [(set_attr "op_type" "VRR")])
797 (define_insn "*vmrhb"
798 [(set (match_operand:V16QI 0 "register_operand" "=v")
800 (vec_concat:V32QI (match_operand:V16QI 1 "register_operand" "v")
801 (match_operand:V16QI 2 "register_operand" "v"))
802 (parallel [(const_int 0) (const_int 16)
803 (const_int 1) (const_int 17)
804 (const_int 2) (const_int 18)
805 (const_int 3) (const_int 19)
806 (const_int 4) (const_int 20)
807 (const_int 5) (const_int 21)
808 (const_int 6) (const_int 22)
809 (const_int 7) (const_int 23)])))]
812 [(set_attr "op_type" "VRR")])
814 (define_insn "*vmrlb"
815 [(set (match_operand:V16QI 0 "register_operand" "=v")
817 (vec_concat:V32QI (match_operand:V16QI 1 "register_operand" "v")
818 (match_operand:V16QI 2 "register_operand" "v"))
819 (parallel [(const_int 8) (const_int 24)
820 (const_int 9) (const_int 25)
821 (const_int 10) (const_int 26)
822 (const_int 11) (const_int 27)
823 (const_int 12) (const_int 28)
824 (const_int 13) (const_int 29)
825 (const_int 14) (const_int 30)
826 (const_int 15) (const_int 31)])))]
829 [(set_attr "op_type" "VRR")])
831 (define_insn "*vmrhh"
832 [(set (match_operand:V8HI 0 "register_operand" "=v")
834 (vec_concat:V16HI (match_operand:V8HI 1 "register_operand" "v")
835 (match_operand:V8HI 2 "register_operand" "v"))
836 (parallel [(const_int 0) (const_int 8)
837 (const_int 1) (const_int 9)
838 (const_int 2) (const_int 10)
839 (const_int 3) (const_int 11)])))]
842 [(set_attr "op_type" "VRR")])
844 (define_insn "*vmrlh"
845 [(set (match_operand:V8HI 0 "register_operand" "=v")
847 (vec_concat:V16HI (match_operand:V8HI 1 "register_operand" "v")
848 (match_operand:V8HI 2 "register_operand" "v"))
849 (parallel [(const_int 4) (const_int 12)
850 (const_int 5) (const_int 13)
851 (const_int 6) (const_int 14)
852 (const_int 7) (const_int 15)])))]
855 [(set_attr "op_type" "VRR")])
857 (define_insn "*vmrhf"
858 [(set (match_operand:V_HW_4 0 "register_operand" "=v")
860 (vec_concat:<vec_2x_nelts> (match_operand:V_HW_4 1 "register_operand" "v")
861 (match_operand:V_HW_4 2 "register_operand" "v"))
862 (parallel [(const_int 0) (const_int 4)
863 (const_int 1) (const_int 5)])))]
866 [(set_attr "op_type" "VRR")])
868 (define_insn "*vmrhf_half<mode>"
869 [(set (match_operand:V_HW_4 0 "register_operand" "=v")
871 (vec_concat:V_HW_4 (match_operand:<vec_halfnumelts> 1 "register_operand" "v")
872 (match_operand:<vec_halfnumelts> 2 "register_operand" "v"))
873 (parallel [(const_int 0) (const_int 2)
874 (const_int 1) (const_int 3)])))]
877 [(set_attr "op_type" "VRR")])
879 (define_insn "*vmrlf"
880 [(set (match_operand:V_HW_4 0 "register_operand" "=v")
882 (vec_concat:<vec_2x_nelts> (match_operand:V_HW_4 1 "register_operand" "v")
883 (match_operand:V_HW_4 2 "register_operand" "v"))
884 (parallel [(const_int 2) (const_int 6)
885 (const_int 3) (const_int 7)])))]
888 [(set_attr "op_type" "VRR")])
890 (define_insn "*vmrhg"
891 [(set (match_operand:V_HW_2 0 "register_operand" "=v")
893 (vec_concat:<vec_2x_nelts> (match_operand:V_HW_2 1 "register_operand" "v")
894 (match_operand:V_HW_2 2 "register_operand" "v"))
895 (parallel [(const_int 0) (const_int 2)])))]
898 [(set_attr "op_type" "VRR")])
900 (define_insn "*vmrlg"
901 [(set (match_operand:V_HW_2 0 "register_operand" "=v")
903 (vec_concat:<vec_2x_nelts> (match_operand:V_HW_2 1 "register_operand" "v")
904 (match_operand:V_HW_2 2 "register_operand" "v"))
905 (parallel [(const_int 1) (const_int 3)])))]
908 [(set_attr "op_type" "VRR")])
910 (define_insn "tf_to_fprx2"
911 [(set (match_operand:FPRX2 0 "register_operand" "=f,f ,f")
912 (unspec:FPRX2 [(match_operand:TF 1 "general_operand" "v,AR,AT")]
913 UNSPEC_TF_TO_FPRX2))]
917 const char *reg_pair = reg_names[REGNO (operands[0]) + 1];
918 switch (which_alternative)
921 if (REGNO (operands[0]) == REGNO (operands[1]))
923 reg_pair += 2; // get rid of prefix %f
924 snprintf (buf, sizeof (buf), "vpdi\t%%%%v%s,%%v1,%%%%v%s,5", reg_pair, reg_pair);
925 output_asm_insn (buf, operands);
930 reg_pair += 2; // get rid of prefix %f
931 snprintf (buf, sizeof (buf), "ldr\t%%f0,%%f1;vpdi\t%%%%v%s,%%v1,%%%%v%s,5", reg_pair, reg_pair);
932 output_asm_insn (buf, operands);
937 snprintf (buf, sizeof (buf), "ld\t%%f0,%%1;ld\t%%%s,8+%%1", reg_pair);
938 output_asm_insn (buf, operands);
943 snprintf (buf, sizeof (buf), "ldy\t%%f0,%%1;ldy\t%%%s,8+%%1", reg_pair);
944 output_asm_insn (buf, operands);
947 default: gcc_unreachable ();
951 ;; VECTOR REVERSE ELEMENTS V16QI
953 (define_expand "eltswapv16qi"
955 [(set (match_operand:V16QI 0 "nonimmediate_operand")
957 (match_operand:V16QI 1 "nonimmediate_operand")
959 (use (match_dup 3))])]
962 rtvec vec = rtvec_alloc (16);
963 for (int i = 0; i < 16; ++i)
964 RTVEC_ELT (vec, i) = GEN_INT (15 - i);
965 operands[2] = gen_rtx_PARALLEL (VOIDmode, vec);
966 operands[3] = gen_rtx_CONST_VECTOR (V16QImode, vec);
969 (define_insn_and_split "*eltswapv16qi"
970 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=v,^R,^v")
972 (match_operand:V16QI 1 "nonimmediate_operand" "v,^v,^R")
973 (parallel [(const_int 15)
989 (use (match_operand:V16QI 2 "permute_pattern_operand" "v,X,X"))]
995 "&& reload_completed && REG_P (operands[0]) && REG_P (operands[1])"
997 (unspec:V16QI [(match_dup 1)
1002 [(set_attr "cpu_facility" "*,vxe2,vxe2")
1003 (set_attr "op_type" "*,VRX,VRX")])
1005 ;; VECTOR REVERSE ELEMENTS V8HI
1007 (define_insn_and_split "eltswapv8hi"
1008 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=v,R,v")
1010 (match_operand:V8HI 1 "nonimmediate_operand" "v,v,R")
1011 (parallel [(const_int 7)
1019 (clobber (match_scratch:V2DI 2 "=&v,X,X"))
1020 (clobber (match_scratch:V4SI 3 "=&v,X,X"))]
1026 "&& reload_completed && REG_P (operands[0]) && REG_P (operands[1])"
1028 (subreg:V2DI (match_dup 1) 0))
1032 (parallel [(const_int 1) (const_int 0)])))
1038 (subreg:V4SI (match_dup 2) 0))
1044 (subreg:V8HI (match_dup 3) 0))]
1046 [(set_attr "cpu_facility" "*,vxe2,vxe2")
1047 (set_attr "op_type" "*,VRX,VRX")])
1049 ;; VECTOR REVERSE ELEMENTS V4SI / V4SF
1051 (define_insn_and_split "eltswap<mode>"
1052 [(set (match_operand:V_HW_4 0 "nonimmediate_operand" "=v,R,v")
1054 (match_operand:V_HW_4 1 "nonimmediate_operand" "v,v,R")
1055 (parallel [(const_int 3)
1059 (clobber (match_scratch:V2DI 2 "=&v,X,X"))]
1065 "&& reload_completed && REG_P (operands[0]) && REG_P (operands[1])"
1067 (subreg:V2DI (match_dup 1) 0))
1071 (parallel [(const_int 1) (const_int 0)])))
1077 (subreg:V_HW_4 (match_dup 2) 0))]
1079 [(set_attr "cpu_facility" "*,vxe2,vxe2")
1080 (set_attr "op_type" "*,VRX,VRX")])
1082 ;; VECTOR REVERSE ELEMENTS V2DI / V2DF
1084 (define_insn "eltswap<mode>"
1085 [(set (match_operand:V_HW_2 0 "nonimmediate_operand" "=v,R,v")
1087 (match_operand:V_HW_2 1 "nonimmediate_operand" "v,v,R")
1088 (parallel [(const_int 1)
1095 [(set_attr "cpu_facility" "vx,vxe2,vxe2")
1096 (set_attr "op_type" "VRR,VRX,VRX")])
1099 ;; Vector integer arithmetic instructions
1102 ; vab, vah, vaf, vag, vaq
1104 ; We use nonimmediate_operand instead of register_operand since it is
1105 ; better to have the reloads into VRs instead of splitting the
1106 ; operation into two DImode ADDs.
1107 (define_insn "<ti*>add<mode>3"
1108 [(set (match_operand:VIT 0 "nonimmediate_operand" "=v")
1109 (plus:VIT (match_operand:VIT 1 "nonimmediate_operand" "v")
1110 (match_operand:VIT 2 "general_operand" "v")))]
1112 "va<bhfgq>\t%v0,%v1,%v2"
1113 [(set_attr "op_type" "VRR")])
1115 ; vsb, vsh, vsf, vsg, vsq
1116 (define_insn "<ti*>sub<mode>3"
1117 [(set (match_operand:VIT 0 "nonimmediate_operand" "=v")
1118 (minus:VIT (match_operand:VIT 1 "nonimmediate_operand" "v")
1119 (match_operand:VIT 2 "general_operand" "v")))]
1121 "vs<bhfgq>\t%v0,%v1,%v2"
1122 [(set_attr "op_type" "VRR")])
1125 (define_insn "mul<mode>3"
1126 [(set (match_operand:VI_QHS 0 "register_operand" "=v")
1127 (mult:VI_QHS (match_operand:VI_QHS 1 "register_operand" "v")
1128 (match_operand:VI_QHS 2 "register_operand" "v")))]
1130 "vml<bhfgq><w>\t%v0,%v1,%v2"
1131 [(set_attr "op_type" "VRR")])
1133 ; vlcb, vlch, vlcf, vlcg
1134 (define_insn "neg<mode>2"
1135 [(set (match_operand:VI 0 "register_operand" "=v")
1136 (neg:VI (match_operand:VI 1 "register_operand" "v")))]
1138 "vlc<bhfgq>\t%v0,%v1"
1139 [(set_attr "op_type" "VRR")])
1141 ; vlpb, vlph, vlpf, vlpg
1142 (define_insn "abs<mode>2"
1143 [(set (match_operand:VI 0 "register_operand" "=v")
1144 (abs:VI (match_operand:VI 1 "register_operand" "v")))]
1146 "vlp<bhfgq>\t%v0,%v1"
1147 [(set_attr "op_type" "VRR")])
1152 ; Sum across DImode parts of the 1st operand and add the rightmost
1153 ; element of 2nd operand
1155 (define_insn "*vec_sum2<mode>"
1156 [(set (match_operand:V2DI 0 "register_operand" "=v")
1157 (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "v")
1158 (match_operand:VI_HW_HS 2 "register_operand" "v")]
1161 "vsumg<bhfgq>\t%v0,%v1,%v2"
1162 [(set_attr "op_type" "VRR")])
1165 (define_insn "*vec_sum4<mode>"
1166 [(set (match_operand:V4SI 0 "register_operand" "=v")
1167 (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "v")
1168 (match_operand:VI_HW_QH 2 "register_operand" "v")]
1171 "vsum<bhfgq>\t%v0,%v1,%v2"
1172 [(set_attr "op_type" "VRR")])
1175 ;; Vector bit instructions (int + fp)
1180 (define_insn "and<mode>3"
1181 [(set (match_operand:VT 0 "register_operand" "=v")
1182 (and:VT (match_operand:VT 1 "register_operand" "v")
1183 (match_operand:VT 2 "register_operand" "v")))]
1186 [(set_attr "op_type" "VRR")])
1190 (define_insn "notand<mode>3"
1191 [(set (match_operand:VT 0 "register_operand" "=v")
1192 (ior:VT (not:VT (match_operand:VT 1 "register_operand" "v"))
1193 (not:VT (match_operand:VT 2 "register_operand" "v"))))]
1196 [(set_attr "op_type" "VRR")])
1200 (define_insn "ior<mode>3"
1201 [(set (match_operand:VT 0 "register_operand" "=v")
1202 (ior:VT (match_operand:VT 1 "register_operand" "v")
1203 (match_operand:VT 2 "register_operand" "v")))]
1206 [(set_attr "op_type" "VRR")])
1208 ; Vector or with complement
1210 (define_insn "ior_not<mode>3"
1211 [(set (match_operand:VT 0 "register_operand" "=v")
1212 (ior:VT (not:VT (match_operand:VT 2 "register_operand" "v"))
1213 (match_operand:VT 1 "register_operand" "v")))]
1216 [(set_attr "op_type" "VRR")])
1220 (define_insn "xor<mode>3"
1221 [(set (match_operand:VT 0 "register_operand" "=v")
1222 (xor:VT (match_operand:VT 1 "register_operand" "v")
1223 (match_operand:VT 2 "register_operand" "v")))]
1226 [(set_attr "op_type" "VRR")])
1230 (define_insn "notxor<mode>3"
1231 [(set (match_operand:VT 0 "register_operand" "=v")
1232 (not:VT (xor:VT (match_operand:VT 1 "register_operand" "v")
1233 (match_operand:VT 2 "register_operand" "v"))))]
1236 [(set_attr "op_type" "VRR")])
1238 ; Bitwise inversion of a vector
1239 (define_insn "one_cmpl<mode>2"
1240 [(set (match_operand:VT 0 "register_operand" "=v")
1241 (not:VT (match_operand:VT 1 "register_operand" "v")))]
1244 [(set_attr "op_type" "VRR")])
1246 ; Vector population count
1248 (define_expand "popcount<mode>2"
1249 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1250 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")]
1255 emit_insn (gen_popcount<mode>2_vxe (operands[0], operands[1]));
1257 emit_insn (gen_popcount<mode>2_vx (operands[0], operands[1]));
1261 ; vpopctb, vpopcth, vpopctf, vpopctg
1262 (define_insn "popcount<mode>2_vxe"
1263 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1264 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")]
1267 "vpopct<bhfgq>\t%v0,%v1"
1268 [(set_attr "op_type" "VRR")])
1270 (define_insn "popcountv16qi2_vx"
1271 [(set (match_operand:V16QI 0 "register_operand" "=v")
1272 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
1274 "TARGET_VX && !TARGET_VXE"
1276 [(set_attr "op_type" "VRR")])
1278 ; vpopct only counts bits in byte elements. Bigger element sizes need
1279 ; to be emulated. Word and doubleword elements can use the sum across
1280 ; instructions. For halfword sized elements we do a shift of a copy
1281 ; of the result, add it to the result and extend it to halfword
1282 ; element size (unpack).
1284 (define_expand "popcountv8hi2_vx"
1286 (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")]
1288 ; Make a copy of the result
1289 (set (match_dup 3) (match_dup 2))
1290 ; Generate the shift count operand in a VR (8->byte 7)
1291 (set (match_dup 4) (match_dup 5))
1292 (set (match_dup 4) (unspec:V16QI [(const_int 8)
1294 (match_dup 4)] UNSPEC_VEC_SET))
1295 ; Vector shift right logical by one byte
1297 (unspec:V16QI [(match_dup 3) (match_dup 4)] UNSPEC_VEC_SRLB))
1298 ; Add the shifted and the original result
1300 (plus:V16QI (match_dup 2) (match_dup 3)))
1301 ; Generate mask for the odd numbered byte elements
1303 (const_vector:V16QI [(const_int 0) (const_int -1)
1304 (const_int 0) (const_int -1)
1305 (const_int 0) (const_int -1)
1306 (const_int 0) (const_int -1)
1307 (const_int 0) (const_int -1)
1308 (const_int 0) (const_int -1)
1309 (const_int 0) (const_int -1)
1310 (const_int 0) (const_int -1)]))
1311 ; Zero out the even indexed bytes
1312 (set (match_operand:V8HI 0 "register_operand" "=v")
1313 (and:V8HI (subreg:V8HI (match_dup 2) 0)
1314 (subreg:V8HI (match_dup 3) 0)))
1316 "TARGET_VX && !TARGET_VXE"
1318 operands[1] = simplify_gen_subreg (V16QImode, operands[1],
1320 operands[2] = gen_reg_rtx (V16QImode);
1321 operands[3] = gen_reg_rtx (V16QImode);
1322 operands[4] = gen_reg_rtx (V16QImode);
1323 operands[5] = CONST0_RTX (V16QImode);
1326 (define_expand "popcountv4si2_vx"
1328 (unspec:V16QI [(match_operand:V4SI 1 "register_operand" "v")]
1330 (set (match_operand:V4SI 0 "register_operand" "=v")
1331 (unspec:V4SI [(match_dup 2) (match_dup 3)]
1333 "TARGET_VX && !TARGET_VXE"
1335 operands[1] = simplify_gen_subreg (V16QImode, operands[1], V4SImode, 0);
1336 operands[2] = gen_reg_rtx (V16QImode);
1337 operands[3] = force_reg (V16QImode, CONST0_RTX (V16QImode));
1340 (define_expand "popcountv2di2_vx"
1342 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")]
1345 (unspec:V4SI [(match_dup 2) (match_dup 4)]
1347 (set (match_operand:V2DI 0 "register_operand" "=v")
1348 (unspec:V2DI [(match_dup 3) (match_dup 5)]
1350 "TARGET_VX && !TARGET_VXE"
1352 operands[1] = simplify_gen_subreg (V16QImode, operands[1], V2DImode, 0);
1353 operands[2] = gen_reg_rtx (V16QImode);
1354 operands[3] = gen_reg_rtx (V4SImode);
1355 operands[4] = force_reg (V16QImode, CONST0_RTX (V16QImode));
1356 operands[5] = force_reg (V4SImode, CONST0_RTX (V4SImode));
1359 ; Count leading zeros
1360 ; vclzb, vclzh, vclzf, vclzg
1361 (define_insn "clz<mode>2"
1362 [(set (match_operand:V 0 "register_operand" "=v")
1363 (clz:V (match_operand:V 1 "register_operand" "v")))]
1365 "vclz<bhfgq>\t%v0,%v1"
1366 [(set_attr "op_type" "VRR")])
1368 ; Count trailing zeros
1369 ; vctzb, vctzh, vctzf, vctzg
1370 (define_insn "ctz<mode>2"
1371 [(set (match_operand:V 0 "register_operand" "=v")
1372 (ctz:V (match_operand:V 1 "register_operand" "v")))]
1374 "vctz<bhfgq>\t%v0,%v1"
1375 [(set_attr "op_type" "VRR")])
1379 ; Each vector element rotated by the corresponding vector element
1380 ; verllvb, verllvh, verllvf, verllvg
1381 (define_insn "vrotl<mode>3"
1382 [(set (match_operand:VI 0 "register_operand" "=v")
1383 (rotate:VI (match_operand:VI 1 "register_operand" "v")
1384 (match_operand:VI 2 "register_operand" "v")))]
1386 "verllv<bhfgq>\t%v0,%v1,%v2"
1387 [(set_attr "op_type" "VRR")])
1390 ; Vector rotate and shift by scalar instructions
1392 (define_code_iterator VEC_SHIFTS [ashift ashiftrt lshiftrt rotate])
1393 (define_code_attr vec_shifts_name [(ashift "ashl") (ashiftrt "ashr")
1394 (lshiftrt "lshr") (rotate "rotl")])
1395 (define_code_attr vec_shifts_mnem [(ashift "vesl") (ashiftrt "vesra")
1396 (lshiftrt "vesrl") (rotate "verll")])
1398 ; Each vector element rotated by a scalar
1399 (define_expand "<vec_shifts_name><mode>3"
1400 [(set (match_operand:VI 0 "register_operand" "")
1401 (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "")
1402 (match_operand:QI 2 "shift_count_operand" "")))]
1405 ; verllb, verllh, verllf, verllg
1406 ; veslb, veslh, veslf, veslg
1407 ; vesrab, vesrah, vesraf, vesrag
1408 ; vesrlb, vesrlh, vesrlf, vesrlg
1409 (define_insn "*<vec_shifts_name><mode>3"
1410 [(set (match_operand:VI 0 "register_operand" "=v")
1411 (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "v")
1412 (match_operand:QI 2 "shift_count_operand_vec" "jsc")))]
1414 && s390_valid_shift_count (operands[2],
1415 GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) - 1)
1417 "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2"
1418 [(set_attr "op_type" "VRS")])
1420 ; verllg for V4SI/V4SF. This swaps the first and the second two
1421 ; elements of a vector and is only valid in that context.
1422 (define_expand "rotl<mode>3_di"
1425 (subreg:V2DI (match_operand:V_HW_4 1) 0))
1430 (set (match_operand:V_HW_4 0)
1431 (subreg:V_HW_4 (match_dup 3) 0))]
1434 operands[2] = gen_reg_rtx (V2DImode);
1435 operands[3] = gen_reg_rtx (V2DImode);
1438 ; Shift each element by corresponding vector element
1440 ; veslvb, veslvh, veslvf, veslvg
1441 (define_insn "vashl<mode>3"
1442 [(set (match_operand:VI 0 "register_operand" "=v")
1443 (ashift:VI (match_operand:VI 1 "register_operand" "v")
1444 (match_operand:VI 2 "register_operand" "v")))]
1446 "veslv<bhfgq>\t%v0,%v1,%v2"
1447 [(set_attr "op_type" "VRR")])
1449 ; vesravb, vesravh, vesravf, vesravg
1450 (define_insn "vashr<mode>3"
1451 [(set (match_operand:VI 0 "register_operand" "=v")
1452 (ashiftrt:VI (match_operand:VI 1 "register_operand" "v")
1453 (match_operand:VI 2 "register_operand" "v")))]
1455 "vesrav<bhfgq>\t%v0,%v1,%v2"
1456 [(set_attr "op_type" "VRR")])
1458 ; vesrlvb, vesrlvh, vesrlvf, vesrlvg
1459 (define_insn "vlshr<mode>3"
1460 [(set (match_operand:VI 0 "register_operand" "=v")
1461 (lshiftrt:VI (match_operand:VI 1 "register_operand" "v")
1462 (match_operand:VI 2 "register_operand" "v")))]
1464 "vesrlv<bhfgq>\t%v0,%v1,%v2"
1465 [(set_attr "op_type" "VRR")])
1467 ; Vector shift right logical by byte
1469 ; Pattern used by e.g. popcount
1470 (define_insn "*vec_srb<mode>"
1471 [(set (match_operand:V_128 0 "register_operand" "=v")
1472 (unspec:V_128 [(match_operand:V_128 1 "register_operand" "v")
1473 (match_operand:V16QI 2 "register_operand" "v")]
1476 "vsrlb\t%v0,%v1,%v2"
1477 [(set_attr "op_type" "VRR")])
1480 ; Vector shift left by byte
1482 (define_insn "*vec_slb<mode>"
1483 [(set (match_operand:V_128 0 "register_operand" "=v")
1484 (unspec:V_128 [(match_operand:V_128 1 "register_operand" "v")
1485 (match_operand:V16QI 2 "register_operand" "v")]
1489 [(set_attr "op_type" "VRR")])
1491 ; vec_shr is defined as shift towards element 0
1492 ; this means it is a left shift on BE targets!
1493 (define_expand "vec_shr_<mode>"
1495 (unspec:V16QI [(match_operand:SI 2 "const_shift_by_byte_operand" "")
1499 (set (match_operand:V_128 0 "register_operand" "")
1500 (unspec:V_128 [(match_operand:V_128 1 "register_operand" "")
1505 operands[3] = gen_reg_rtx(V16QImode);
1508 ; vmnb, vmnh, vmnf, vmng
1509 (define_insn "smin<mode>3"
1510 [(set (match_operand:VI 0 "register_operand" "=v")
1511 (smin:VI (match_operand:VI 1 "register_operand" "v")
1512 (match_operand:VI 2 "register_operand" "v")))]
1514 "vmn<bhfgq>\t%v0,%v1,%v2"
1515 [(set_attr "op_type" "VRR")])
1517 ; vmxb, vmxh, vmxf, vmxg
1518 (define_insn "smax<mode>3"
1519 [(set (match_operand:VI 0 "register_operand" "=v")
1520 (smax:VI (match_operand:VI 1 "register_operand" "v")
1521 (match_operand:VI 2 "register_operand" "v")))]
1523 "vmx<bhfgq>\t%v0,%v1,%v2"
1524 [(set_attr "op_type" "VRR")])
1526 ; vmnlb, vmnlh, vmnlf, vmnlg
1527 (define_insn "umin<mode>3"
1528 [(set (match_operand:VI 0 "register_operand" "=v")
1529 (umin:VI (match_operand:VI 1 "register_operand" "v")
1530 (match_operand:VI 2 "register_operand" "v")))]
1532 "vmnl<bhfgq>\t%v0,%v1,%v2"
1533 [(set_attr "op_type" "VRR")])
1535 ; vmxlb, vmxlh, vmxlf, vmxlg
1536 (define_insn "umax<mode>3"
1537 [(set (match_operand:VI 0 "register_operand" "=v")
1538 (umax:VI (match_operand:VI 1 "register_operand" "v")
1539 (match_operand:VI 2 "register_operand" "v")))]
1541 "vmxl<bhfgq>\t%v0,%v1,%v2"
1542 [(set_attr "op_type" "VRR")])
1545 (define_insn "vec_widen_smult_even_<mode>"
1546 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
1547 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "v")
1548 (match_operand:VI_QHS 2 "register_operand" "v")]
1549 UNSPEC_VEC_SMULT_EVEN))]
1551 "vme<bhfgq>\t%v0,%v1,%v2"
1552 [(set_attr "op_type" "VRR")])
1554 ; vmleb, vmleh, vmlef
1555 (define_insn "vec_widen_umult_even_<mode>"
1556 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
1557 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "v")
1558 (match_operand:VI_QHS 2 "register_operand" "v")]
1559 UNSPEC_VEC_UMULT_EVEN))]
1561 "vmle<bhfgq>\t%v0,%v1,%v2"
1562 [(set_attr "op_type" "VRR")])
1565 (define_insn "vec_widen_smult_odd_<mode>"
1566 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
1567 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "v")
1568 (match_operand:VI_QHS 2 "register_operand" "v")]
1569 UNSPEC_VEC_SMULT_ODD))]
1571 "vmo<bhfgq>\t%v0,%v1,%v2"
1572 [(set_attr "op_type" "VRR")])
1574 ; vmlob, vmloh, vmlof
1575 (define_insn "vec_widen_umult_odd_<mode>"
1576 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
1577 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "v")
1578 (match_operand:VI_QHS 2 "register_operand" "v")]
1579 UNSPEC_VEC_UMULT_ODD))]
1581 "vmlo<bhfgq>\t%v0,%v1,%v2"
1582 [(set_attr "op_type" "VRR")])
1585 ; Widening hi/lo multiplications
1587 ; The S/390 instructions vml and vmh return the low or high parts of
1588 ; the double sized result elements in the corresponding elements of
1589 ; the target register. That's NOT what the vec_widen_umult_lo/hi
1590 ; patterns are expected to do.
1592 ; We emulate the widening lo/hi multiplies with the even/odd versions
1593 ; followed by a vector merge
1596 (define_expand "vec_widen_umult_lo_<mode>"
1598 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "")
1599 (match_operand:VI_QHS 2 "register_operand" "")]
1600 UNSPEC_VEC_UMULT_EVEN))
1602 (unspec:<vec_double> [(match_dup 1) (match_dup 2)]
1603 UNSPEC_VEC_UMULT_ODD))
1604 (set (match_operand:<vec_double> 0 "register_operand" "")
1605 (vec_select:<vec_double>
1606 (vec_concat:<VEC_2X_WIDE> (match_dup 3) (match_dup 4))
1610 operands[3] = gen_reg_rtx (<vec_double>mode);
1611 operands[4] = gen_reg_rtx (<vec_double>mode);
1612 operands[5] = s390_expand_merge_perm_const (<vec_double>mode, false);
1615 (define_expand "vec_widen_umult_hi_<mode>"
1617 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "")
1618 (match_operand:VI_QHS 2 "register_operand" "")]
1619 UNSPEC_VEC_UMULT_EVEN))
1621 (unspec:<vec_double> [(match_dup 1) (match_dup 2)]
1622 UNSPEC_VEC_UMULT_ODD))
1623 (set (match_operand:<vec_double> 0 "register_operand" "")
1624 (vec_select:<vec_double>
1625 (vec_concat:<VEC_2X_WIDE> (match_dup 3) (match_dup 4))
1629 operands[3] = gen_reg_rtx (<vec_double>mode);
1630 operands[4] = gen_reg_rtx (<vec_double>mode);
1631 operands[5] = s390_expand_merge_perm_const (<vec_double>mode, true);
1634 (define_expand "vec_widen_smult_lo_<mode>"
1636 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "")
1637 (match_operand:VI_QHS 2 "register_operand" "")]
1638 UNSPEC_VEC_SMULT_EVEN))
1640 (unspec:<vec_double> [(match_dup 1) (match_dup 2)]
1641 UNSPEC_VEC_SMULT_ODD))
1642 (set (match_operand:<vec_double> 0 "register_operand" "")
1643 (vec_select:<vec_double>
1644 (vec_concat:<VEC_2X_WIDE> (match_dup 3) (match_dup 4))
1648 operands[3] = gen_reg_rtx (<vec_double>mode);
1649 operands[4] = gen_reg_rtx (<vec_double>mode);
1650 operands[5] = s390_expand_merge_perm_const (<vec_double>mode, false);
1653 (define_expand "vec_widen_smult_hi_<mode>"
1655 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "")
1656 (match_operand:VI_QHS 2 "register_operand" "")]
1657 UNSPEC_VEC_SMULT_EVEN))
1659 (unspec:<vec_double> [(match_dup 1) (match_dup 2)]
1660 UNSPEC_VEC_SMULT_ODD))
1661 (set (match_operand:<vec_double> 0 "register_operand" "")
1662 (vec_select:<vec_double>
1663 (vec_concat:<VEC_2X_WIDE> (match_dup 3) (match_dup 4))
1667 operands[3] = gen_reg_rtx (<vec_double>mode);
1668 operands[4] = gen_reg_rtx (<vec_double>mode);
1669 operands[5] = s390_expand_merge_perm_const (<vec_double>mode, true);
1672 ; vec_widen_ushiftl_hi
1673 ; vec_widen_ushiftl_lo
1674 ; vec_widen_sshiftl_hi
1675 ; vec_widen_sshiftl_lo
1678 ;; Vector floating point arithmetic instructions
1681 ; vfasb, vfadb, wfasb, wfadb, wfaxb
1682 (define_insn "add<mode>3<tf_vr>"
1683 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1684 (plus:VF_HW (match_operand:VF_HW 1 "register_operand" "v")
1685 (match_operand:VF_HW 2 "register_operand" "v")))]
1687 "<vw>fa<sdx>b\t%v0,%v1,%v2"
1688 [(set_attr "op_type" "VRR")])
1690 (define_expand "addtf3"
1691 [(match_operand:TF 0 "register_operand" "")
1692 (match_operand:TF 1 "nonimmediate_operand" "")
1693 (match_operand:TF 2 "general_operand" "")]
1695 { EXPAND_TF (addtf3, 3); })
1697 ; vfssb, vfsdb, wfssb, wfsdb, wfsxb
1698 (define_insn "sub<mode>3<tf_vr>"
1699 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1700 (minus:VF_HW (match_operand:VF_HW 1 "register_operand" "v")
1701 (match_operand:VF_HW 2 "register_operand" "v")))]
1703 "<vw>fs<sdx>b\t%v0,%v1,%v2"
1704 [(set_attr "op_type" "VRR")])
1706 (define_expand "subtf3"
1707 [(match_operand:TF 0 "register_operand" "")
1708 (match_operand:TF 1 "register_operand" "")
1709 (match_operand:TF 2 "general_operand" "")]
1711 { EXPAND_TF (subtf3, 3); })
1713 ; vfmsb, vfmdb, wfmsb, wfmdb, wfmxb
1714 (define_insn "mul<mode>3<tf_vr>"
1715 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1716 (mult:VF_HW (match_operand:VF_HW 1 "register_operand" "v")
1717 (match_operand:VF_HW 2 "register_operand" "v")))]
1719 "<vw>fm<sdx>b\t%v0,%v1,%v2"
1720 [(set_attr "op_type" "VRR")])
1722 (define_expand "multf3"
1723 [(match_operand:TF 0 "register_operand" "")
1724 (match_operand:TF 1 "nonimmediate_operand" "")
1725 (match_operand:TF 2 "general_operand" "")]
1727 { EXPAND_TF (multf3, 3); })
1729 ; vfdsb, vfddb, wfdsb, wfddb, wfdxb
1730 (define_insn "div<mode>3<tf_vr>"
1731 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1732 (div:VF_HW (match_operand:VF_HW 1 "register_operand" "v")
1733 (match_operand:VF_HW 2 "register_operand" "v")))]
1735 "<vw>fd<sdx>b\t%v0,%v1,%v2"
1736 [(set_attr "op_type" "VRR")])
1738 (define_expand "divtf3"
1739 [(match_operand:TF 0 "register_operand" "")
1740 (match_operand:TF 1 "register_operand" "")
1741 (match_operand:TF 2 "general_operand" "")]
1743 { EXPAND_TF (divtf3, 3); })
1745 ; vfsqsb, vfsqdb, wfsqsb, wfsqdb, wfsqxb
1746 (define_insn "sqrt<mode>2<tf_vr>"
1747 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1748 (sqrt:VF_HW (match_operand:VF_HW 1 "register_operand" "v")))]
1750 "<vw>fsq<sdx>b\t%v0,%v1"
1751 [(set_attr "op_type" "VRR")])
1753 (define_expand "sqrttf2"
1754 [(match_operand:TF 0 "register_operand" "")
1755 (match_operand:TF 1 "general_operand" "")]
1757 { EXPAND_TF (sqrttf2, 2); })
1759 ; vfmasb, vfmadb, wfmasb, wfmadb, wfmaxb
1760 (define_insn "fma<mode>4"
1761 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1762 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "v")
1763 (match_operand:VF_HW 2 "register_operand" "v")
1764 (match_operand:VF_HW 3 "register_operand" "v")))]
1765 "TARGET_VX && s390_fma_allowed_p (<MODE>mode)"
1766 "<vw>fma<sdx>b\t%v0,%v1,%v2,%v3"
1767 [(set_attr "op_type" "VRR")])
1769 ; vfmssb, vfmsdb, wfmssb, wfmsdb, wfmsxb
1770 (define_insn "fms<mode>4"
1771 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1772 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "v")
1773 (match_operand:VF_HW 2 "register_operand" "v")
1774 (neg:VF_HW (match_operand:VF_HW 3 "register_operand" "v"))))]
1775 "TARGET_VX && s390_fma_allowed_p (<MODE>mode)"
1776 "<vw>fms<sdx>b\t%v0,%v1,%v2,%v3"
1777 [(set_attr "op_type" "VRR")])
1779 ; vfnmasb, vfnmadb, wfnmasb, wfnmadb, wfnmaxb
1780 (define_insn "neg_fma<mode>4"
1781 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1783 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "v")
1784 (match_operand:VF_HW 2 "register_operand" "v")
1785 (match_operand:VF_HW 3 "register_operand" "v"))))]
1786 "TARGET_VXE && s390_fma_allowed_p (<MODE>mode)"
1787 "<vw>fnma<sdx>b\t%v0,%v1,%v2,%v3"
1788 [(set_attr "op_type" "VRR")])
1790 ; vfnmssb, vfnmsdb, wfnmssb, wfnmsdb, wfnmsxb
1791 (define_insn "neg_fms<mode>4"
1792 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1794 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "v")
1795 (match_operand:VF_HW 2 "register_operand" "v")
1796 (neg:VF_HW (match_operand:VF_HW 3 "register_operand" "v")))))]
1797 "TARGET_VXE && s390_fma_allowed_p (<MODE>mode)"
1798 "<vw>fnms<sdx>b\t%v0,%v1,%v2,%v3"
1799 [(set_attr "op_type" "VRR")])
1801 ; vflcsb, vflcdb, wflcsb, wflcdb, wflcxb
1802 (define_insn "neg<mode>2<tf_vr>"
1803 [(set (match_operand:VFT 0 "register_operand" "=v")
1804 (neg:VFT (match_operand:VFT 1 "register_operand" "v")))]
1806 "<vw>flc<sdx>b\t%v0,%v1"
1807 [(set_attr "op_type" "VRR")])
1809 (define_expand "negtf2"
1810 [(match_operand:TF 0 "register_operand" "")
1811 (match_operand:TF 1 "register_operand" "")]
1813 { EXPAND_TF (negtf2, 2); })
1815 ; vflpsb, vflpdb, wflpsb, wflpdb, wflpxb
1816 (define_insn "abs<mode>2<tf_vr>"
1817 [(set (match_operand:VFT 0 "register_operand" "=v")
1818 (abs:VFT (match_operand:VFT 1 "register_operand" "v")))]
1820 "<vw>flp<sdx>b\t%v0,%v1"
1821 [(set_attr "op_type" "VRR")])
1823 (define_expand "abstf2"
1824 [(match_operand:TF 0 "register_operand" "")
1825 (match_operand:TF 1 "register_operand" "")]
1827 { EXPAND_TF (abstf2, 2); })
1829 ; vflnsb, vflndb, wflnsb, wflndb, wflnxb
1830 (define_insn "negabs<mode>2"
1831 [(set (match_operand:VFT 0 "register_operand" "=v")
1832 (neg:VFT (abs:VFT (match_operand:VFT 1 "register_operand" "v"))))]
1834 "<vw>fln<sdx>b\t%v0,%v1"
1835 [(set_attr "op_type" "VRR")])
1837 (define_expand "smax<mode>3"
1838 [(set (match_operand:VF_HW 0 "register_operand")
1839 (smax:VF_HW (match_operand:VF_HW 1 "register_operand")
1840 (match_operand:VF_HW 2 "register_operand")))]
1843 ; vfmaxsb, vfmaxdb, wfmaxsb, wfmaxdb, wfmaxxb
1844 (define_insn "*smax<mode>3_vxe"
1845 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1846 (smax:VF_HW (match_operand:VF_HW 1 "register_operand" "v")
1847 (match_operand:VF_HW 2 "register_operand" "v")))]
1849 "<vw>fmax<sdx>b\t%v0,%v1,%v2,4"
1850 [(set_attr "op_type" "VRR")])
1852 ; Emulate with compare + select
1853 (define_insn_and_split "*smaxv2df3_vx"
1854 [(set (match_operand:V2DF 0 "register_operand" "=v")
1855 (smax:V2DF (match_operand:V2DF 1 "register_operand" "v")
1856 (match_operand:V2DF 2 "register_operand" "v")))]
1857 "TARGET_VX && !TARGET_VXE"
1862 (unge:V2DI (match_dup 2) (match_dup 1))))
1865 (eq (match_dup 3) (match_dup 4))
1869 operands[3] = gen_reg_rtx (V2DImode);
1870 operands[4] = CONST0_RTX (V2DImode);
1873 (define_expand "smin<mode>3"
1874 [(set (match_operand:VF_HW 0 "register_operand")
1875 (smin:VF_HW (match_operand:VF_HW 1 "register_operand")
1876 (match_operand:VF_HW 2 "register_operand")))]
1879 ; vfminsb, vfmindb, wfminsb, wfmindb, wfminxb
1880 (define_insn "*smin<mode>3_vxe"
1881 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1882 (smin:VF_HW (match_operand:VF_HW 1 "register_operand" "v")
1883 (match_operand:VF_HW 2 "register_operand" "v")))]
1885 "<vw>fmin<sdx>b\t%v0,%v1,%v2,4"
1886 [(set_attr "op_type" "VRR")])
1888 ; Emulate with compare + select
1889 (define_insn_and_split "*sminv2df3_vx"
1890 [(set (match_operand:V2DF 0 "register_operand" "=v")
1891 (smin:V2DF (match_operand:V2DF 1 "register_operand" "v")
1892 (match_operand:V2DF 2 "register_operand" "v")))]
1893 "TARGET_VX && !TARGET_VXE"
1898 (unge:V2DI (match_dup 2) (match_dup 1))))
1901 (eq (match_dup 3) (match_dup 4))
1905 operands[3] = gen_reg_rtx (V2DImode);
1906 operands[4] = CONST0_RTX (V2DImode);
1909 ; Vector copysign, implement using vector select
1910 (define_expand "copysign<mode>3"
1911 [(set (match_operand:VFT 0 "register_operand" "")
1913 (and:VFT (match_operand:VFT 2 "register_operand" "")
1915 (and:VFT (not:VFT (match_dup 3))
1916 (match_operand:VFT 1 "register_operand" ""))))]
1919 rtx mask = s390_build_signbit_mask (<MODE>mode);
1920 operands[3] = force_reg (<MODE>mode, mask);
1927 (define_expand "vec_cmp<mode><tointvec>"
1928 [(set (match_operand:<TOINTVEC> 0 "register_operand" "")
1929 (match_operator:<TOINTVEC> 1 "vcond_comparison_operator"
1930 [(match_operand:V_HW 2 "register_operand" "")
1931 (match_operand:V_HW 3 "nonmemory_operand" "")]))]
1934 s390_expand_vec_compare (operands[0], GET_CODE(operands[1]), operands[2], operands[3]);
1938 (define_expand "vec_cmpu<VIT_HW:mode><VIT_HW:mode>"
1939 [(set (match_operand:VIT_HW 0 "register_operand" "")
1940 (match_operator:VIT_HW 1 ""
1941 [(match_operand:VIT_HW 2 "register_operand" "")
1942 (match_operand:VIT_HW 3 "register_operand" "")]))]
1945 s390_expand_vec_compare (operands[0], GET_CODE(operands[1]), operands[2], operands[3]);
1949 (define_insn "*vec_cmp<VICMP_HW_OP:code><VI:mode><VI:mode>_nocc"
1950 [(set (match_operand:VI 2 "register_operand" "=v")
1951 (VICMP_HW_OP:VI (match_operand:VI 0 "register_operand" "v")
1952 (match_operand:VI 1 "register_operand" "v")))]
1954 "vc<VICMP_HW_OP:insn_cmp_op><VI:bhfgq>\t%v2,%v0,%v1"
1955 [(set_attr "op_type" "VRR")])
1957 (define_insn_and_split "*vec_cmpeq<mode><mode>_nocc_emu"
1958 [(set (match_operand:VI_HW_T 0 "register_operand" "=v")
1959 (eq:VI_HW_T (match_operand:VI_HW_T 1 "register_operand" "v")
1960 (match_operand:VI_HW_T 2 "register_operand" "v")))]
1963 "&& can_create_pseudo_p ()"
1965 (eq:V2DI (match_dup 1) (match_dup 2)))
1967 (vec_select:V2DI (match_dup 3) (parallel [(const_int 1) (const_int 0)])))
1969 (and:V2DI (match_dup 3) (match_dup 4)))
1971 (subreg:<MODE> (match_dup 3) 0))]
1973 operands[1] = simplify_gen_subreg (V2DImode, operands[1], <MODE>mode, 0);
1974 operands[2] = simplify_gen_subreg (V2DImode, operands[2], <MODE>mode, 0);
1975 operands[3] = gen_reg_rtx (V2DImode);
1976 operands[4] = gen_reg_rtx (V2DImode);
1979 (define_insn_and_split "*vec_cmpgt<mode><mode>_nocc_emu"
1980 [(set (match_operand:VI_HW_T 0 "register_operand" "=v")
1981 (gt:VI_HW_T (match_operand:VI_HW_T 1 "register_operand" "v")
1982 (match_operand:VI_HW_T 2 "register_operand" "v")))]
1985 "&& can_create_pseudo_p ()"
1987 (gt:V2DI (match_dup 1) (match_dup 2)))
1989 (eq:V2DI (match_dup 1) (match_dup 2)))
1991 (gtu:V2DI (match_dup 1) (match_dup 2)))
1993 (vec_select:V2DI (match_dup 5) (parallel [(const_int 1) (const_int 0)])))
1995 (and:V2DI (match_dup 4) (match_dup 5)))
1997 (ior:V2DI (match_dup 3) (match_dup 4)))
2002 (parallel [(const_int 1)]))))
2004 (subreg:<MODE> (match_dup 4) 0))]
2006 operands[1] = simplify_gen_subreg (V2DImode, operands[1], <MODE>mode, 0);
2007 operands[2] = simplify_gen_subreg (V2DImode, operands[2], <MODE>mode, 0);
2008 operands[3] = gen_reg_rtx (V2DImode);
2009 operands[4] = gen_reg_rtx (V2DImode);
2010 operands[5] = gen_reg_rtx (V2DImode);
2013 (define_insn_and_split "*vec_cmpgtu<mode><mode>_nocc_emu"
2014 [(set (match_operand:VI_HW_T 0 "register_operand" "=v")
2015 (gtu:VI_HW_T (match_operand:VI_HW_T 1 "register_operand" "v")
2016 (match_operand:VI_HW_T 2 "register_operand" "v")))]
2019 "&& can_create_pseudo_p ()"
2021 (gtu:V2DI (match_dup 1) (match_dup 2)))
2023 (eq:V2DI (match_dup 1) (match_dup 2)))
2025 (vec_select:V2DI (match_dup 3) (parallel [(const_int 1) (const_int 0)])))
2027 (and:V2DI (match_dup 4) (match_dup 5)))
2029 (ior:V2DI (match_dup 3) (match_dup 4)))
2034 (parallel [(const_int 1)]))))
2036 (subreg:<MODE> (match_dup 4) 0))]
2038 operands[1] = simplify_gen_subreg (V2DImode, operands[1], <MODE>mode, 0);
2039 operands[2] = simplify_gen_subreg (V2DImode, operands[2], <MODE>mode, 0);
2040 operands[3] = gen_reg_rtx (V2DImode);
2041 operands[4] = gen_reg_rtx (V2DImode);
2042 operands[5] = gen_reg_rtx (V2DImode);
2047 ;; Floating point compares
2050 ; vfcesb, vfcedb, wfcexb: non-signaling "==" comparison (a == b)
2051 (define_insn "*vec_cmpeq<mode>_quiet_nocc"
2052 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2053 (eq:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
2054 (match_operand:VFT 2 "register_operand" "v")))]
2056 "<vw>fce<sdx>b\t%v0,%v1,%v2"
2057 [(set_attr "op_type" "VRR")])
2059 ; vfchsb, vfchdb, wfchxb: non-signaling > comparison (!(b u>= a))
2060 (define_insn "vec_cmpgt<mode>_quiet_nocc"
2061 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2063 (unge:<TOINTVEC> (match_operand:VFT 2 "register_operand" "v")
2064 (match_operand:VFT 1 "register_operand" "v"))))]
2066 "<vw>fch<sdx>b\t%v0,%v1,%v2"
2067 [(set_attr "op_type" "VRR")])
2069 (define_expand "vec_cmplt<mode>_quiet_nocc"
2070 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2072 (unge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
2073 (match_operand:VFT 2 "register_operand" "v"))))]
2076 ; vfchesb, vfchedb, wfchexb: non-signaling >= comparison (!(a u< b))
2077 (define_insn "vec_cmpge<mode>_quiet_nocc"
2078 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2080 (unlt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
2081 (match_operand:VFT 2 "register_operand" "v"))))]
2083 "<vw>fche<sdx>b\t%v0,%v1,%v2"
2084 [(set_attr "op_type" "VRR")])
2086 (define_expand "vec_cmple<mode>_quiet_nocc"
2087 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2089 (unlt:<TOINTVEC> (match_operand:VFT 2 "register_operand" "v")
2090 (match_operand:VFT 1 "register_operand" "v"))))]
2093 ; vfkesb, vfkedb, wfkexb: signaling == comparison ((a >= b) & (b >= a))
2094 (define_insn "*vec_cmpeq<mode>_signaling_nocc"
2095 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2097 (ge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
2098 (match_operand:VFT 2 "register_operand" "v"))
2099 (ge:<TOINTVEC> (match_dup 2)
2102 "<vw>fke<sdx>b\t%v0,%v1,%v2"
2103 [(set_attr "op_type" "VRR")])
2105 ; vfkhsb, vfkhdb, wfkhxb: signaling > comparison (a > b)
2106 (define_insn "*vec_cmpgt<mode>_signaling_nocc"
2107 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2108 (gt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
2109 (match_operand:VFT 2 "register_operand" "v")))]
2111 "<vw>fkh<sdx>b\t%v0,%v1,%v2"
2112 [(set_attr "op_type" "VRR")])
2114 (define_insn "*vec_cmpgt<mode>_signaling_finite_nocc"
2115 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2116 (gt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
2117 (match_operand:VFT 2 "register_operand" "v")))]
2118 "TARGET_NONSIGNALING_VECTOR_COMPARE_OK"
2119 "<vw>fch<sdx>b\t%v0,%v1,%v2"
2120 [(set_attr "op_type" "VRR")])
2122 ; vfkhesb, vfkhedb, wfkhexb: signaling >= comparison (a >= b)
2123 (define_insn "*vec_cmpge<mode>_signaling_nocc"
2124 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2125 (ge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
2126 (match_operand:VFT 2 "register_operand" "v")))]
2128 "<vw>fkhe<sdx>b\t%v0,%v1,%v2"
2129 [(set_attr "op_type" "VRR")])
2131 (define_insn "*vec_cmpge<mode>_signaling_finite_nocc"
2132 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2133 (ge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
2134 (match_operand:VFT 2 "register_operand" "v")))]
2135 "TARGET_NONSIGNALING_VECTOR_COMPARE_OK"
2136 "<vw>fche<sdx>b\t%v0,%v1,%v2"
2137 [(set_attr "op_type" "VRR")])
2139 ; Expanders for not directly supported comparisons
2140 ; Signaling comparisons must be expressed via signaling rtxes only,
2141 ; and quiet comparisons must be expressed via quiet rtxes only.
2143 ; UNGT a u> b -> !!(b u< a)
2144 (define_expand "vec_cmpungt<mode>"
2145 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2147 (unlt:<TOINTVEC> (match_operand:VFT 2 "register_operand" "v")
2148 (match_operand:VFT 1 "register_operand" "v"))))
2150 (not:<TOINTVEC> (match_dup 0)))]
2153 ; UNGE a u>= b -> !!(a u>= b)
2154 (define_expand "vec_cmpunge<mode>"
2155 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2157 (unge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
2158 (match_operand:VFT 2 "register_operand" "v"))))
2160 (not:<TOINTVEC> (match_dup 0)))]
2163 ; UNEQ a u== b -> !(!(a u>= b) | !(b u>= a))
2164 (define_expand "vec_cmpuneq<mode>"
2165 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2167 (unge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
2168 (match_operand:VFT 2 "register_operand" "v"))))
2171 (unge:<TOINTVEC> (match_dup 2)
2174 (ior:<TOINTVEC> (match_dup 0)
2177 (not:<TOINTVEC> (match_dup 0)))]
2180 operands[3] = gen_reg_rtx (<TOINTVEC>mode);
2183 ; LTGT a <> b -> a > b | b > a
2184 (define_expand "vec_cmpltgt<mode>"
2185 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2186 (gt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
2187 (match_operand:VFT 2 "register_operand" "v")))
2188 (set (match_dup 3) (gt:<TOINTVEC> (match_dup 2) (match_dup 1)))
2189 (set (match_dup 0) (ior:<TOINTVEC> (match_dup 0) (match_dup 3)))]
2192 operands[3] = gen_reg_rtx (<TOINTVEC>mode);
2195 ; ORDERED (a, b): !(a u< b) | !(a u>= b)
2196 (define_expand "vec_cmpordered<mode>"
2197 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2199 (unlt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
2200 (match_operand:VFT 2 "register_operand" "v"))))
2203 (unge:<TOINTVEC> (match_dup 1)
2206 (ior:<TOINTVEC> (match_dup 0)
2210 operands[3] = gen_reg_rtx (<TOINTVEC>mode);
2213 ; UNORDERED (a, b): !ORDERED (a, b)
2214 (define_expand "vec_cmpunordered<mode>"
2215 [(match_operand:<TOINTVEC> 0 "register_operand" "=v")
2216 (match_operand:VFT 1 "register_operand" "v")
2217 (match_operand:VFT 2 "register_operand" "v")]
2220 emit_insn (gen_vec_cmpordered<mode> (operands[0], operands[1], operands[2]));
2221 emit_insn (gen_rtx_SET (operands[0],
2222 gen_rtx_NOT (<TOINTVEC>mode, operands[0])));
2226 (define_code_iterator VEC_CMP_EXPAND
2227 [ungt unge uneq ltgt ordered unordered])
2229 (define_expand "vec_cmp<code>"
2230 [(match_operand 0 "register_operand" "")
2231 (VEC_CMP_EXPAND (match_operand 1 "register_operand" "")
2232 (match_operand 2 "register_operand" ""))]
2235 if (GET_MODE (operands[1]) == V4SFmode)
2236 emit_insn (gen_vec_cmp<code>v4sf (operands[0], operands[1], operands[2]));
2237 else if (GET_MODE (operands[1]) == V2DFmode)
2238 emit_insn (gen_vec_cmp<code>v2df (operands[0], operands[1], operands[2]));
2245 (define_insn "*vec_load_pair<mode>"
2246 [(set (match_operand:V_HW_2 0 "register_operand" "=v,v")
2247 (vec_concat:V_HW_2 (match_operand:<non_vec> 1 "register_operand" "d,v")
2248 (match_operand:<non_vec> 2 "register_operand" "d,v")))]
2253 [(set_attr "op_type" "VRR,VRR")])
2255 (define_insn "vllv16qi"
2256 [(set (match_operand:V16QI 0 "register_operand" "=v")
2257 (unspec:V16QI [(match_operand:SI 1 "register_operand" "d")
2258 (match_operand:BLK 2 "memory_operand" "Q")]
2259 UNSPEC_VEC_LOAD_LEN))]
2262 [(set_attr "op_type" "VRS")])
2264 ; vfeebs, vfeehs, vfeefs
2265 ; vfeezbs, vfeezhs, vfeezfs
2266 (define_insn "@vec_vfees<mode>"
2267 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
2268 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
2269 (match_operand:VI_HW_QHS 2 "register_operand" "v")
2270 (match_operand:QI 3 "const_mask_operand" "C")]
2272 (set (reg:CCRAW CC_REGNUM)
2273 (unspec:CCRAW [(match_dup 1)
2276 UNSPEC_VEC_VFEECC))]
2279 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
2281 gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
2282 flags &= ~VSTRING_FLAG_CS;
2284 if (flags == VSTRING_FLAG_ZS)
2285 return "vfeez<bhfgq>s\t%v0,%v1,%v2";
2286 return "vfee<bhfgq>s\t%v0,%v1,%v2";
2288 [(set_attr "op_type" "VRR")])
2290 ; vfenebs, vfenehs, vfenefs
2291 ; vfenezbs, vfenezhs, vfenezfs
2292 (define_insn "vec_vfenes<mode>"
2293 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
2294 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
2295 (match_operand:VI_HW_QHS 2 "register_operand" "v")
2296 (match_operand:QI 3 "const_mask_operand" "C")]
2298 (set (reg:CCRAW CC_REGNUM)
2299 (unspec:CCRAW [(match_dup 1)
2302 UNSPEC_VEC_VFENECC))]
2305 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
2307 gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
2308 flags &= ~VSTRING_FLAG_CS;
2310 if (flags == VSTRING_FLAG_ZS)
2311 return "vfenez<bhfgq>s\t%v0,%v1,%v2";
2312 return "vfene<bhfgq>s\t%v0,%v1,%v2";
2314 [(set_attr "op_type" "VRR")])
2319 ; The following splitters simplify vec_sel for constant 0 or -1
2320 ; selection sources. This is required to generate efficient code for
2325 [(set (match_operand:V 0 "register_operand" "")
2327 (eq (match_operand:<TOINTVEC> 3 "register_operand" "")
2328 (match_operand:V 4 "const0_operand" ""))
2329 (match_operand:V 1 "const0_operand" "")
2330 (match_operand:V 2 "all_ones_operand" "")))]
2332 [(set (match_dup 0) (match_dup 3))]
2334 PUT_MODE (operands[3], <V:MODE>mode);
2339 [(set (match_operand:V 0 "register_operand" "")
2341 (eq (match_operand:<TOINTVEC> 3 "register_operand" "")
2342 (match_operand:V 4 "const0_operand" ""))
2343 (match_operand:V 1 "all_ones_operand" "")
2344 (match_operand:V 2 "const0_operand" "")))]
2346 [(set (match_dup 0) (not:V (match_dup 3)))]
2348 PUT_MODE (operands[3], <V:MODE>mode);
2353 [(set (match_operand:V 0 "register_operand" "")
2355 (ne (match_operand:<TOINTVEC> 3 "register_operand" "")
2356 (match_operand:V 4 "const0_operand" ""))
2357 (match_operand:V 1 "all_ones_operand" "")
2358 (match_operand:V 2 "const0_operand" "")))]
2360 [(set (match_dup 0) (match_dup 3))]
2362 PUT_MODE (operands[3], <V:MODE>mode);
2367 [(set (match_operand:V 0 "register_operand" "")
2369 (ne (match_operand:<TOINTVEC> 3 "register_operand" "")
2370 (match_operand:V 4 "const0_operand" ""))
2371 (match_operand:V 1 "const0_operand" "")
2372 (match_operand:V 2 "all_ones_operand" "")))]
2374 [(set (match_dup 0) (not:V (match_dup 3)))]
2376 PUT_MODE (operands[3], <V:MODE>mode);
2379 ; op0 = op3 == 0 ? op1 : op2
2380 (define_insn "*vec_sel0<mode>"
2381 [(set (match_operand:VT 0 "register_operand" "=v")
2383 (eq (match_operand:<TOINTVEC> 3 "register_operand" "v")
2384 (match_operand:<TOINTVEC> 4 "const0_operand" ""))
2385 (match_operand:VT 1 "register_operand" "v")
2386 (match_operand:VT 2 "register_operand" "v")))]
2388 "vsel\t%v0,%2,%1,%3"
2389 [(set_attr "op_type" "VRR")])
2391 ; op0 = !op3 == 0 ? op1 : op2
2392 (define_insn "*vec_sel0<mode>"
2393 [(set (match_operand:V 0 "register_operand" "=v")
2395 (eq (not:<TOINTVEC> (match_operand:<TOINTVEC> 3 "register_operand" "v"))
2396 (match_operand:<TOINTVEC> 4 "const0_operand" ""))
2397 (match_operand:V 1 "register_operand" "v")
2398 (match_operand:V 2 "register_operand" "v")))]
2400 "vsel\t%v0,%1,%2,%3"
2401 [(set_attr "op_type" "VRR")])
2403 ; op0 = op3 == -1 ? op1 : op2
2404 (define_insn "*vec_sel1<mode>"
2405 [(set (match_operand:V 0 "register_operand" "=v")
2407 (eq (match_operand:<TOINTVEC> 3 "register_operand" "v")
2408 (match_operand:<TOINTVEC> 4 "all_ones_operand" ""))
2409 (match_operand:V 1 "register_operand" "v")
2410 (match_operand:V 2 "register_operand" "v")))]
2412 "vsel\t%v0,%1,%2,%3"
2413 [(set_attr "op_type" "VRR")])
2415 ; op0 = !op3 == -1 ? op1 : op2
2416 (define_insn "*vec_sel1<mode>"
2417 [(set (match_operand:V 0 "register_operand" "=v")
2419 (eq (not:<TOINTVEC> (match_operand:<TOINTVEC> 3 "register_operand" "v"))
2420 (match_operand:<TOINTVEC> 4 "all_ones_operand" ""))
2421 (match_operand:V 1 "register_operand" "v")
2422 (match_operand:V 2 "register_operand" "v")))]
2424 "vsel\t%v0,%2,%1,%3"
2425 [(set_attr "op_type" "VRR")])
2430 (define_insn "vec_pack_trunc_<mode>"
2431 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
2432 (vec_concat:<vec_half>
2433 (truncate:<vec_halfhalf>
2434 (match_operand:VI_HW_HSD 1 "register_operand" "v"))
2435 (truncate:<vec_halfhalf>
2436 (match_operand:VI_HW_HSD 2 "register_operand" "v"))))]
2438 "vpk<bhfgq>\t%0,%1,%2"
2439 [(set_attr "op_type" "VRR")])
2441 ; vpksh, vpksf, vpksg
2442 (define_insn "vec_pack_ssat_<mode>"
2443 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
2444 (vec_concat:<vec_half>
2445 (ss_truncate:<vec_halfhalf>
2446 (match_operand:VI_HW_HSD 1 "register_operand" "v"))
2447 (ss_truncate:<vec_halfhalf>
2448 (match_operand:VI_HW_HSD 2 "register_operand" "v"))))]
2450 "vpks<bhfgq>\t%0,%1,%2"
2451 [(set_attr "op_type" "VRR")])
2453 ; vpklsh, vpklsf, vpklsg
2454 (define_insn "vec_pack_usat_<mode>"
2455 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
2456 (vec_concat:<vec_half>
2457 (us_truncate:<vec_halfhalf>
2458 (match_operand:VI_HW_HSD 1 "register_operand" "v"))
2459 (us_truncate:<vec_halfhalf>
2460 (match_operand:VI_HW_HSD 2 "register_operand" "v"))))]
2462 "vpkls<bhfgq>\t%0,%1,%2"
2463 [(set_attr "op_type" "VRR")])
2465 ;; vector unpack / extend
2467 (define_insn "<extend_insn><VI_EXTEND:mode><vec_2x_wide>2"
2468 [(set (match_operand:<VEC_2X_WIDE> 0 "register_operand" "=v")
2469 (any_extend:<VEC_2X_WIDE>
2470 (match_operand:VI_EXTEND 1 "register_operand" "v")))]
2472 "vup<zero_extend>h<bhfgq>\t%0,%1"
2473 [(set_attr "op_type" "VRR")])
2475 (define_expand "extendv2sfv2df2"
2478 (vec_concat:V4SF (match_operand:V2SF 1 "register_operand")
2480 (parallel [(const_int 0) (const_int 2)
2481 (const_int 1) (const_int 3)])))
2482 (set (match_operand:V2DF 0 "register_operand")
2486 (parallel [(const_int 0) (const_int 2)]))))]
2489 operands[2] = gen_reg_rtx (V4SFmode);
2492 ;; vector unpack v16qi
2496 (define_insn "vec_unpacks_hi_v16qi"
2497 [(set (match_operand:V8HI 0 "register_operand" "=v")
2500 (match_operand:V16QI 1 "register_operand" "v")
2501 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
2502 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
2505 [(set_attr "op_type" "VRR")])
2507 (define_insn "vec_unpacks_lo_v16qi"
2508 [(set (match_operand:V8HI 0 "register_operand" "=v")
2511 (match_operand:V16QI 1 "register_operand" "v")
2512 (parallel [(const_int 8) (const_int 9) (const_int 10)(const_int 11)
2513 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
2516 [(set_attr "op_type" "VRR")])
2520 (define_insn "vec_unpacku_hi_v16qi"
2521 [(set (match_operand:V8HI 0 "register_operand" "=v")
2524 (match_operand:V16QI 1 "register_operand" "v")
2525 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
2526 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
2529 [(set_attr "op_type" "VRR")])
2531 (define_insn "vec_unpacku_lo_v16qi"
2532 [(set (match_operand:V8HI 0 "register_operand" "=v")
2535 (match_operand:V16QI 1 "register_operand" "v")
2536 (parallel [(const_int 8) (const_int 9) (const_int 10)(const_int 11)
2537 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
2540 [(set_attr "op_type" "VRR")])
2542 ;; vector unpack v8hi
2546 (define_insn "vec_unpacks_hi_v8hi"
2547 [(set (match_operand:V4SI 0 "register_operand" "=v")
2550 (match_operand:V8HI 1 "register_operand" "v")
2551 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
2554 [(set_attr "op_type" "VRR")])
2556 (define_insn "vec_unpacks_lo_v8hi"
2557 [(set (match_operand:V4SI 0 "register_operand" "=v")
2560 (match_operand:V8HI 1 "register_operand" "v")
2561 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
2564 [(set_attr "op_type" "VRR")])
2568 (define_insn "vec_unpacku_hi_v8hi"
2569 [(set (match_operand:V4SI 0 "register_operand" "=v")
2572 (match_operand:V8HI 1 "register_operand" "v")
2573 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
2576 [(set_attr "op_type" "VRR")])
2578 (define_insn "vec_unpacku_lo_v8hi"
2579 [(set (match_operand:V4SI 0 "register_operand" "=v")
2582 (match_operand:V8HI 1 "register_operand" "v")
2583 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
2586 [(set_attr "op_type" "VRR")])
2588 ;; vector unpack v4si
2592 (define_insn "vec_unpacks_hi_v4si"
2593 [(set (match_operand:V2DI 0 "register_operand" "=v")
2596 (match_operand:V4SI 1 "register_operand" "v")
2597 (parallel [(const_int 0)(const_int 1)]))))]
2600 [(set_attr "op_type" "VRR")])
2602 (define_insn "vec_unpacks_lo_v4si"
2603 [(set (match_operand:V2DI 0 "register_operand" "=v")
2606 (match_operand:V4SI 1 "register_operand" "v")
2607 (parallel [(const_int 2)(const_int 3)]))))]
2610 [(set_attr "op_type" "VRR")])
2614 (define_insn "vec_unpacku_hi_v4si"
2615 [(set (match_operand:V2DI 0 "register_operand" "=v")
2618 (match_operand:V4SI 1 "register_operand" "v")
2619 (parallel [(const_int 0)(const_int 1)]))))]
2622 [(set_attr "op_type" "VRR")])
2624 (define_insn "vec_unpacku_lo_v4si"
2625 [(set (match_operand:V2DI 0 "register_operand" "=v")
2628 (match_operand:V4SI 1 "register_operand" "v")
2629 (parallel [(const_int 2)(const_int 3)]))))]
2632 [(set_attr "op_type" "VRR")])
2634 ;; vector load lengthened
2636 ; vflls float -> double
2637 (define_insn "*vec_extendv4sf"
2638 [(set (match_operand:V2DF 0 "register_operand" "=v")
2641 (match_operand:V4SF 1 "register_operand" "v")
2642 (parallel [(const_int 0) (const_int 2)]))))]
2645 [(set_attr "op_type" "VRR")])
2647 (define_expand "vec_unpacks_lo_v4sf"
2650 (vec_concat:V8SF (match_operand:V4SF 1 "register_operand" "") (match_dup 1))
2652 (set (match_operand:V2DF 0 "register_operand" "")
2656 (parallel [(const_int 0) (const_int 2)]))))]
2659 operands[2] = gen_reg_rtx(V4SFmode);
2660 operands[3] = s390_expand_merge_perm_const (V4SFmode, false);
2663 (define_expand "vec_unpacks_hi_v4sf"
2666 (vec_concat:V8SF (match_operand:V4SF 1 "register_operand" "") (match_dup 1))
2668 (set (match_operand:V2DF 0 "register_operand" "")
2672 (parallel [(const_int 0) (const_int 2)]))))]
2675 operands[2] = gen_reg_rtx(V4SFmode);
2676 operands[3] = s390_expand_merge_perm_const (V4SFmode, true);
2680 ; double -> long double
2681 (define_insn "*vec_extendv2df"
2682 [(set (match_operand:V1TF 0 "register_operand" "=v")
2685 (match_operand:V2DF 1 "register_operand" "v")
2686 (parallel [(const_int 0)]))))]
2689 [(set_attr "op_type" "VRR")])
2691 (define_expand "vec_unpacks_lo_v2df"
2694 (vec_concat:V4DF (match_operand:V2DF 1 "register_operand" "") (match_dup 1))
2696 (set (match_operand:V1TF 0 "register_operand" "")
2700 (parallel [(const_int 0)]))))]
2703 operands[2] = gen_reg_rtx (V2DFmode);
2704 operands[3] = s390_expand_merge_perm_const (V2DFmode, false);
2707 (define_expand "vec_unpacks_hi_v2df"
2710 (vec_concat:V4DF (match_operand:V2DF 1 "register_operand" "") (match_dup 1))
2712 (set (match_operand:V1TF 0 "register_operand" "")
2716 (parallel [(const_int 0)]))))]
2719 operands[2] = gen_reg_rtx (V2DFmode);
2720 operands[3] = s390_expand_merge_perm_const (V2DFmode, true);
2724 ; 2 x v2df -> 1 x v4sf
2725 (define_expand "vec_pack_trunc_v2df"
2727 (unspec:V4SF [(match_operand:V2DF 1 "register_operand" "")
2728 (const_int VEC_INEXACT)
2729 (const_int VEC_RND_CURRENT)]
2732 (unspec:V4SF [(match_operand:V2DF 2 "register_operand" "")
2733 (const_int VEC_INEXACT)
2734 (const_int VEC_RND_CURRENT)]
2737 (unspec:V16QI [(subreg:V16QI (match_dup 3) 0)
2738 (subreg:V16QI (match_dup 4) 0)
2741 (set (match_operand:V4SF 0 "register_operand" "")
2742 (subreg:V4SF (match_dup 6) 0))]
2745 rtx constv, perm[16];
2748 for (i = 0; i < 4; ++i)
2750 perm[i] = GEN_INT (i);
2751 perm[i + 4] = GEN_INT (i + 8);
2752 perm[i + 8] = GEN_INT (i + 16);
2753 perm[i + 12] = GEN_INT (i + 24);
2755 constv = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm));
2757 operands[3] = gen_reg_rtx (V4SFmode);
2758 operands[4] = gen_reg_rtx (V4SFmode);
2759 operands[5] = force_reg (V16QImode, constv);
2760 operands[6] = gen_reg_rtx (V16QImode);
2764 ; BFP <-> integer conversions
2767 ; signed integer to floating point
2769 ; op2: inexact exception not suppressed (IEEE 754 2008)
2770 ; op3: according to current rounding mode
2772 (define_insn "float<tointvec><mode>2"
2773 [(set (match_operand:VX_VEC_CONV_BFP 0 "register_operand" "=v")
2774 (float:VX_VEC_CONV_BFP (match_operand:<TOINTVEC> 1 "register_operand" "v")))]
2776 "vc<xde><bhfgq>b\t%v0,%v1,0,0"
2777 [(set_attr "op_type" "VRR")])
2779 ; There is no instruction for loading a signed integer into an extended BFP
2780 ; operand in a VR, therefore we need to load it into a FPR pair first.
2781 (define_expand "float<mode>tf2_vr"
2783 (float:FPRX2 (match_operand:DSI 1 "register_operand" "")))
2784 (set (match_operand:TF 0 "register_operand" "")
2785 (subreg:TF (match_dup 2) 0))]
2788 operands[2] = gen_reg_rtx (FPRX2mode);
2791 (define_expand "float<mode>tf2"
2792 [(match_operand:TF 0 "register_operand" "")
2793 (match_operand:DSI 1 "register_operand" "")]
2794 "HAVE_TF (float<mode>tf2)"
2795 { EXPAND_TF (float<mode>tf2, 2); })
2797 ; unsigned integer to floating point
2799 ; op2: inexact exception not suppressed (IEEE 754 2008)
2800 ; op3: according to current rounding mode
2802 (define_insn "floatuns<tointvec><mode>2"
2803 [(set (match_operand:VX_VEC_CONV_BFP 0 "register_operand" "=v")
2804 (unsigned_float:VX_VEC_CONV_BFP (match_operand:<TOINTVEC> 1 "register_operand" "v")))]
2806 "vc<xde>l<bhfgq>b\t%v0,%v1,0,0"
2807 [(set_attr "op_type" "VRR")])
2809 ; There is no instruction for loading an unsigned integer into an extended BFP
2810 ; operand in a VR, therefore load it into a FPR pair first.
2811 (define_expand "floatuns<mode>tf2_vr"
2813 (unsigned_float:FPRX2 (match_operand:GPR 1 "register_operand" "")))
2814 (set (match_operand:TF 0 "register_operand" "")
2815 (subreg:TF (match_dup 2) 0))]
2818 operands[2] = gen_reg_rtx (FPRX2mode);
2821 (define_expand "floatuns<mode>tf2"
2822 [(match_operand:TF 0 "register_operand" "")
2823 (match_operand:GPR 1 "register_operand" "")]
2824 "HAVE_TF (floatuns<mode>tf2)"
2825 { EXPAND_TF (floatuns<mode>tf2, 2); })
2827 ; floating point to signed integer
2829 ; op2: inexact exception not suppressed (IEEE 754 2008)
2830 ; op3: rounding mode 5 (round towards 0 C11 6.3.1.4)
2832 (define_insn "fix_trunc<mode><tointvec>2"
2833 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2834 (fix:<TOINTVEC> (match_operand:VX_VEC_CONV_BFP 1 "register_operand" "v")))]
2836 "vc<bhfgq><xde>b\t%v0,%v1,0,5"
2837 [(set_attr "op_type" "VRR")])
2839 ; There is no instruction for rounding an extended BFP operand in a VR into
2840 ; a signed integer, therefore copy it into a FPR pair first.
2841 (define_expand "fix_trunctf<mode>2_vr"
2843 (unspec:FPRX2 [(match_operand:TF 1 "register_operand")] UNSPEC_TF_TO_FPRX2))
2844 (parallel [(set (match_operand:GPR 0 "register_operand" "")
2845 (fix:GPR (match_dup 2)))
2846 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
2847 (clobber (reg:CC CC_REGNUM))])]
2850 operands[2] = gen_reg_rtx (FPRX2mode);
2853 (define_expand "fix_trunctf<mode>2"
2854 [(match_operand:GPR 0 "register_operand" "")
2855 (match_operand:TF 1 "register_operand" "")]
2856 "HAVE_TF (fix_trunctf<mode>2)"
2857 { EXPAND_TF (fix_trunctf<mode>2, 2); })
2859 ; floating point to unsigned integer
2861 ; op2: inexact exception not suppressed (IEEE 754 2008)
2862 ; op3: rounding mode 5 (round towards 0 C11 6.3.1.4)
2864 (define_insn "fixuns_trunc<VX_VEC_CONV_BFP:mode><tointvec>2"
2865 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2866 (unsigned_fix:<TOINTVEC> (match_operand:VX_VEC_CONV_BFP 1 "register_operand" "v")))]
2868 "vcl<bhfgq><xde>b\t%v0,%v1,0,5"
2869 [(set_attr "op_type" "VRR")])
2871 ; There is no instruction for rounding an extended BFP operand in a VR into
2872 ; an unsigned integer, therefore copy it into a FPR pair first.
2873 (define_expand "fixuns_trunctf<mode>2_vr"
2875 (unspec:FPRX2 [(match_operand:TF 1 "register_operand")] UNSPEC_TF_TO_FPRX2))
2876 (parallel [(set (match_operand:GPR 0 "register_operand" "")
2877 (unsigned_fix:GPR (match_dup 2)))
2878 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
2879 (clobber (reg:CC CC_REGNUM))])]
2882 operands[2] = gen_reg_rtx (FPRX2mode);
2885 (define_expand "fixuns_trunctf<mode>2"
2886 [(match_operand:GPR 0 "register_operand" "")
2887 (match_operand:TF 1 "register_operand" "")]
2888 "HAVE_TF (fixuns_trunctf<mode>2)"
2889 { EXPAND_TF (fixuns_trunctf<mode>2, 2); })
2893 ; vfisb, wfisb, vfidb, wfidb, wfixb; suppress inexact exceptions
2894 (define_insn "<FPINT:fpint_name><VF_HW:mode>2<VF_HW:tf_vr>"
2895 [(set (match_operand:VF_HW 0 "register_operand" "=v")
2896 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v")]
2899 "<vw>fi<VF_HW:sdx>b\t%v0,%v1,4,<FPINT:fpint_roundingmode>"
2900 [(set_attr "op_type" "VRR")])
2902 (define_expand "<FPINT:fpint_name>tf2"
2903 [(match_operand:TF 0 "register_operand" "")
2904 (match_operand:TF 1 "register_operand" "")
2905 ; recognize FPINT as an iterator
2906 (unspec:TF [(match_dup 1)] FPINT)]
2907 "HAVE_TF (<FPINT:fpint_name>tf2)"
2908 { EXPAND_TF (<FPINT:fpint_name>tf2, 2); })
2910 ; vfisb, wfisb, vfidb, wfidb, wfixb; raise inexact exceptions
2911 (define_insn "rint<mode>2<tf_vr>"
2912 [(set (match_operand:VF_HW 0 "register_operand" "=v")
2913 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v")]
2914 UNSPEC_FPINT_RINT))]
2916 "<vw>fi<sdx>b\t%v0,%v1,0,0"
2917 [(set_attr "op_type" "VRR")])
2919 (define_expand "rinttf2"
2920 [(match_operand:TF 0 "register_operand" "")
2921 (match_operand:TF 1 "register_operand" "")]
2923 { EXPAND_TF (rinttf2, 2); })
2928 (define_insn "*trunctfdf2_vr"
2929 [(set (match_operand:DF 0 "register_operand" "=f")
2930 (float_truncate:DF (match_operand:TF 1 "register_operand" "v")))
2931 (unspec:DF [(match_operand 2 "const_int_operand" "")]
2934 "wflrx\t%v0,%v1,0,%2"
2935 [(set_attr "op_type" "VRR")])
2937 (define_expand "trunctfdf2_vr"
2939 (set (match_operand:DF 0 "register_operand" "")
2940 (float_truncate:DF (match_operand:TF 1 "register_operand" "")))
2941 (unspec:DF [(const_int BFP_RND_CURRENT)] UNSPEC_ROUND)])]
2944 (define_expand "trunctfdf2"
2945 [(match_operand:DF 0 "register_operand" "")
2946 (match_operand:TF 1 "register_operand" "")]
2947 "HAVE_TF (trunctfdf2)"
2948 { EXPAND_TF (trunctfdf2, 2); })
2950 ; wflrx + (ledbr|wledb)
2951 (define_expand "trunctfsf2_vr"
2954 (float_truncate:DF (match_operand:TF 1 "register_operand" "")))
2955 (unspec:DF [(const_int BFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)])
2956 (set (match_operand:SF 0 "register_operand" "")
2957 (float_truncate:SF (match_dup 2)))]
2960 operands[2] = gen_reg_rtx(DFmode);
2963 (define_expand "trunctfsf2"
2964 [(match_operand:SF 0 "register_operand" "")
2965 (match_operand:TF 1 "register_operand" "")]
2966 "HAVE_TF (trunctfsf2)"
2967 { EXPAND_TF (trunctfsf2, 2); })
2969 (define_expand "trunctf<DFP_ALL:mode>2_vr"
2970 [(match_operand:DFP_ALL 0 "nonimmediate_operand" "")
2971 (match_operand:TF 1 "nonimmediate_operand" "")]
2973 && GET_MODE_SIZE (TFmode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)
2976 rtx fprx2 = gen_reg_rtx (FPRX2mode);
2977 emit_insn (gen_tf_to_fprx2 (fprx2, operands[1]));
2978 emit_insn (gen_truncfprx2<DFP_ALL:mode>2 (operands[0], fprx2));
2982 (define_expand "trunctf<DFP_ALL:mode>2"
2983 [(match_operand:DFP_ALL 0 "nonimmediate_operand" "")
2984 (match_operand:TF 1 "nonimmediate_operand" "")]
2985 "HAVE_TF (trunctf<DFP_ALL:mode>2)"
2986 { EXPAND_TF (trunctf<DFP_ALL:mode>2, 2); })
2988 (define_expand "trunctdtf2_vr"
2989 [(match_operand:TF 0 "nonimmediate_operand" "")
2990 (match_operand:TD 1 "nonimmediate_operand" "")]
2991 "TARGET_HARD_DFP && TARGET_VXE"
2993 rtx fprx2 = gen_reg_rtx (FPRX2mode);
2994 emit_insn (gen_trunctdfprx22 (fprx2, operands[1]));
2995 emit_insn (gen_fprx2_to_tf (operands[0], fprx2));
2999 (define_expand "trunctdtf2"
3000 [(match_operand:TF 0 "nonimmediate_operand" "")
3001 (match_operand:TD 1 "nonimmediate_operand" "")]
3002 "HAVE_TF (trunctdtf2)"
3003 { EXPAND_TF (trunctdtf2, 2); })
3007 (define_insn "extenddftf2_vr"
3008 [(set (match_operand:TF 0 "register_operand" "=v")
3009 (float_extend:TF (match_operand:DF 1 "register_operand" "f")))]
3012 [(set_attr "op_type" "VRR")])
3014 (define_expand "extenddftf2"
3015 [(match_operand:TF 0 "register_operand" "")
3016 (match_operand:DF 1 "nonimmediate_operand" "")]
3017 "HAVE_TF (extenddftf2)"
3018 { EXPAND_TF (extenddftf2, 2); })
3020 (define_expand "extendsftf2_vr"
3022 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))
3023 (set (match_operand:TF 0 "register_operand" "")
3024 (float_extend:TF (match_dup 2)))]
3027 operands[2] = gen_reg_rtx(DFmode);
3030 (define_expand "extendsftf2"
3031 [(match_operand:TF 0 "register_operand" "")
3032 (match_operand:SF 1 "nonimmediate_operand" "")]
3033 "HAVE_TF (extendsftf2)"
3034 { EXPAND_TF (extendsftf2, 2); })
3036 (define_expand "extend<DFP_ALL:mode>tf2_vr"
3037 [(match_operand:TF 0 "nonimmediate_operand" "")
3038 (match_operand:DFP_ALL 1 "nonimmediate_operand" "")]
3040 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (TFmode)
3043 rtx fprx2 = gen_reg_rtx (FPRX2mode);
3044 emit_insn (gen_extend<DFP_ALL:mode>fprx22 (fprx2, operands[1]));
3045 emit_insn (gen_fprx2_to_tf (operands[0], fprx2));
3049 (define_expand "extend<DFP_ALL:mode>tf2"
3050 [(match_operand:TF 0 "nonimmediate_operand" "")
3051 (match_operand:DFP_ALL 1 "nonimmediate_operand" "")]
3052 "HAVE_TF (extend<DFP_ALL:mode>tf2)"
3053 { EXPAND_TF (extend<DFP_ALL:mode>tf2, 2); })
3055 (define_expand "extendtftd2_vr"
3056 [(match_operand:TD 0 "nonimmediate_operand" "")
3057 (match_operand:TF 1 "nonimmediate_operand" "")]
3058 "TARGET_HARD_DFP && TARGET_VXE"
3060 rtx fprx2 = gen_reg_rtx (FPRX2mode);
3061 emit_insn (gen_tf_to_fprx2 (fprx2, operands[1]));
3062 emit_insn (gen_extendfprx2td2 (operands[0], fprx2));
3066 (define_expand "extendtftd2"
3067 [(match_operand:TD 0 "nonimmediate_operand" "")
3068 (match_operand:TF 1 "nonimmediate_operand" "")]
3069 "HAVE_TF (extendtftd2)"
3070 { EXPAND_TF (extendtftd2, 2); })
3074 (define_expand "signbittf2_vr"
3076 [(set (reg:CCRAW CC_REGNUM)
3077 (unspec:CCRAW [(match_operand:TF 1 "register_operand" "")
3079 UNSPEC_VEC_VFTCICC))
3080 (clobber (scratch:V1TI))])
3081 (set (match_operand:SI 0 "register_operand" "")
3084 (if_then_else:SI (eq (reg:CCRAW CC_REGNUM) (const_int 8))
3089 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3092 (define_expand "signbittf2"
3093 [(match_operand:SI 0 "register_operand" "")
3094 (match_operand:TF 1 "register_operand" "")]
3095 "HAVE_TF (signbittf2)"
3096 { EXPAND_TF (signbittf2, 2); })
3098 (define_expand "isinftf2_vr"
3100 [(set (reg:CCRAW CC_REGNUM)
3101 (unspec:CCRAW [(match_operand:TF 1 "register_operand" "")
3103 UNSPEC_VEC_VFTCICC))
3104 (clobber (scratch:V1TI))])
3105 (set (match_operand:SI 0 "register_operand" "")
3108 (if_then_else:SI (eq (reg:CCRAW CC_REGNUM) (const_int 8))
3113 operands[2] = GEN_INT (S390_TDC_INFINITY);
3116 (define_expand "isinftf2"
3117 [(match_operand:SI 0 "register_operand" "")
3118 (match_operand:TF 1 "register_operand" "")]
3119 "HAVE_TF (isinftf2)"
3120 { EXPAND_TF (isinftf2, 2); })
3123 ; Vector byte swap patterns
3126 ; FIXME: The bswap rtl standard name currently does not appear to be
3127 ; used for vector modes.
3128 (define_expand "bswap<mode>"
3130 [(set (match_operand:VT_HW_HSDT 0 "nonimmediate_operand" "")
3131 (bswap:VT_HW_HSDT (match_operand:VT_HW_HSDT 1 "nonimmediate_operand" "")))
3132 (use (match_dup 2))])]
3135 static const char p[4][16] =
3136 { { 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14 }, /* H */
3137 { 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 }, /* S */
3138 { 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 }, /* D */
3139 { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 } }; /* T */
3143 switch (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)))
3145 case 2: perm = p[0]; break;
3146 case 4: perm = p[1]; break;
3147 case 8: perm = p[2]; break;
3148 case 16: perm = p[3]; break;
3149 default: gcc_unreachable ();
3151 for (int i = 0; i < 16; i++)
3152 perm_rtx[i] = GEN_INT (perm[i]);
3154 operands[2] = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm_rtx));
3156 /* Without vxe2 we do not have byte swap instructions dealing
3157 directly with memory operands. So instead of waiting until
3158 reload to fix that up switch over to vector permute right
3162 rtx in = force_reg (V16QImode, simplify_gen_subreg (V16QImode, operands[1], <MODE>mode, 0));
3163 rtx permute = force_reg (V16QImode, force_const_mem (V16QImode, operands[2]));
3164 rtx out = gen_reg_rtx (V16QImode);
3166 emit_insn (gen_vec_permv16qi (out, in, in, permute));
3167 emit_move_insn (operands[0], simplify_gen_subreg (<MODE>mode, out, V16QImode, 0));
3172 ; Switching late to the reg-reg variant requires the vector permute
3173 ; pattern to be pushed into literal pool and allocating a vector
3174 ; register to load it into. We rely on both being provided by LRA
3175 ; when fixing up the v constraint for operand 2.
3177 ; permute_pattern_operand: general_operand would reject the permute
3178 ; pattern constants since these are not accepted by
3179 ; s390_legimitate_constant_p
3181 ; ^R: Prevent these alternatives from being chosen if it would require
3182 ; pushing the operand into memory first
3184 ; vlbrh, vlbrf, vlbrg, vlbrq, vstbrh, vstbrf, vstbrg, vstbrq
3185 (define_insn_and_split "*bswap<mode>"
3186 [(set (match_operand:VT_HW_HSDT 0 "nonimmediate_operand" "=v, v,^R")
3187 (bswap:VT_HW_HSDT (match_operand:VT_HW_HSDT 1 "nonimmediate_operand" "v,^R, v")))
3188 (use (match_operand:V16QI 2 "permute_pattern_operand" "v, X, X"))]
3193 vstbr<bhfgq>\t%v1,%0"
3194 "&& reload_completed
3195 && !memory_operand (operands[0], <MODE>mode)
3196 && !memory_operand (operands[1], <MODE>mode)"
3199 (unspec:V16QI [(subreg:V16QI (match_dup 1) 0)
3200 (subreg:V16QI (match_dup 1) 0)
3202 UNSPEC_VEC_PERM) 0))]
3204 [(set_attr "op_type" "*,VRX,VRX")])
3206 (define_insn "*vstbr<mode>"
3207 [(set (match_operand:VI_HW_HSDT 0 "memory_operand" "=R")
3208 (bswap:VI_HW_HSDT (match_operand:VI_HW_HSDT 1 "register_operand" "v")))]
3210 "vstbr<bhfgq>\t%v1,%0"
3211 [(set_attr "op_type" "VRX")])
3214 ; Implement len_load/len_store optabs with vll/vstl.
3215 (define_expand "len_load_v16qi"
3216 [(match_operand:V16QI 0 "register_operand")
3217 (match_operand:V16QI 1 "memory_operand")
3218 (match_operand:QI 2 "register_operand")
3219 (match_operand:QI 3 "vll_bias_operand")
3221 "TARGET_VX && TARGET_64BIT"
3223 rtx mem = adjust_address (operands[1], BLKmode, 0);
3225 rtx len = gen_reg_rtx (SImode);
3226 emit_move_insn (len, gen_rtx_ZERO_EXTEND (SImode, operands[2]));
3227 emit_insn (gen_vllv16qi (operands[0], len, mem));
3231 (define_expand "len_store_v16qi"
3232 [(match_operand:V16QI 0 "memory_operand")
3233 (match_operand:V16QI 1 "register_operand")
3234 (match_operand:QI 2 "register_operand")
3235 (match_operand:QI 3 "vll_bias_operand")
3237 "TARGET_VX && TARGET_64BIT"
3239 rtx mem = adjust_address (operands[0], BLKmode, 0);
3241 rtx len = gen_reg_rtx (SImode);
3242 emit_move_insn (len, gen_rtx_ZERO_EXTEND (SImode, operands[2]));
3243 emit_insn (gen_vstlv16qi (operands[1], len, mem));
3253 ; vec_pack_sfix_trunc: convert + pack ?
3254 ; vec_pack_ufix_trunc
3255 ; vec_unpacks_float_hi
3256 ; vec_unpacks_float_lo
3257 ; vec_unpacku_float_hi
3258 ; vec_unpacku_float_lo