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