Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/s390/vx-builtins.md @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 ;;- Instruction patterns for the System z vector facility builtins. | |
2 ;; Copyright (C) 2015-2017 Free Software Foundation, Inc. | |
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 ; The patterns in this file are enabled with -mzvector | |
22 | |
23 (define_mode_iterator V_HW_32_64 [V4SI V2DI V2DF (V4SF "TARGET_VXE")]) | |
24 (define_mode_iterator VI_HW_SD [V4SI V2DI]) | |
25 (define_mode_iterator V_HW_HSD [V8HI V4SI V2DI V2DF]) | |
26 (define_mode_iterator V_HW_4 [V4SI V4SF]) | |
27 ; Full size vector modes with more than one element which are directly supported in vector registers by the hardware. | |
28 (define_mode_iterator VEC_HW [V16QI V8HI V4SI V2DI V2DF (V4SF "TARGET_VXE")]) | |
29 (define_mode_iterator VECF_HW [(V4SF "TARGET_VXE") V2DF]) | |
30 | |
31 ; The element type of the vector with floating point modes translated | |
32 ; to int modes of the same size. | |
33 (define_mode_attr non_vec_int[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI") | |
34 (V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI") | |
35 (V1SI "SI") (V2SI "SI") (V4SI "SI") | |
36 (V1DI "DI") (V2DI "DI") | |
37 (V1SF "SI") (V2SF "SI") (V4SF "SI") | |
38 (V1DF "DI") (V2DF "DI")]) | |
39 | |
40 ; Condition code modes generated by int comparisons | |
41 (define_mode_iterator VICMP [CCVEQ CCVIH CCVIHU]) | |
42 | |
43 ; Comparisons supported by the vec_cmp* builtins | |
44 (define_code_iterator intcmp [eq gt gtu ge geu lt ltu le leu]) | |
45 (define_code_iterator fpcmp [eq gt ge lt le]) | |
46 | |
47 ; Comparisons supported by the vec_all/any* builtins | |
48 (define_code_iterator intcmpcc [eq ne gt ge lt le gtu geu ltu leu]) | |
49 (define_code_iterator fpcmpcc [eq ne gt ge unle unlt lt le]) | |
50 | |
51 ; Flags for vector string instructions (vfae all 4, vfee only ZS and CS, vstrc all 4) | |
52 (define_constants | |
53 [(VSTRING_FLAG_IN 8) ; invert result | |
54 (VSTRING_FLAG_RT 4) ; result type | |
55 (VSTRING_FLAG_ZS 2) ; zero search | |
56 (VSTRING_FLAG_CS 1)]) ; condition code set | |
57 | |
58 ; Rounding modes as being used for e.g. VFI | |
59 (define_constants | |
60 [(VEC_RND_CURRENT 0) | |
61 (VEC_RND_NEAREST_AWAY_FROM_ZERO 1) | |
62 (VEC_RND_SHORT_PREC 3) | |
63 (VEC_RND_NEAREST_TO_EVEN 4) | |
64 (VEC_RND_TO_ZERO 5) | |
65 (VEC_RND_TO_INF 6) | |
66 (VEC_RND_TO_MINF 7)]) | |
67 | |
68 ; Inexact suppression facility flag as being used for e.g. VFI | |
69 (define_constants | |
70 [(VEC_INEXACT 0) | |
71 (VEC_NOINEXACT 4)]) | |
72 | |
73 | |
74 ; Vector gather element | |
75 | |
76 ; vgef, vgeg | |
77 (define_insn "vec_gather_element<mode>" | |
78 [(set (match_operand:V_HW_32_64 0 "register_operand" "=v") | |
79 (unspec:V_HW_32_64 [(match_operand:V_HW_32_64 1 "register_operand" "0") | |
80 (match_operand:<tointvec> 2 "register_operand" "v") | |
81 (match_operand:BLK 3 "memory_operand" "R") | |
82 (match_operand:QI 4 "const_mask_operand" "C")] | |
83 UNSPEC_VEC_GATHER))] | |
84 "TARGET_VX && UINTVAL (operands[4]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)" | |
85 "vge<bhfgq>\t%0,%O3(%v2,%R3),%b4" | |
86 [(set_attr "op_type" "VRV")]) | |
87 | |
88 (define_expand "vec_genmask<mode>" | |
89 [(match_operand:VI_HW 0 "register_operand" "=v") | |
90 (match_operand:QI 1 "const_int_operand" "C") | |
91 (match_operand:QI 2 "const_int_operand" "C")] | |
92 "TARGET_VX" | |
93 { | |
94 int nunits = GET_MODE_NUNITS (<VI_HW:MODE>mode); | |
95 int bitlen = GET_MODE_UNIT_BITSIZE (<VI_HW:MODE>mode); | |
96 /* To bit little endian style. */ | |
97 int end = bitlen - 1 - INTVAL (operands[1]); | |
98 int start = bitlen - 1 - INTVAL (operands[2]); | |
99 rtx const_vec[16]; | |
100 int i; | |
101 unsigned HOST_WIDE_INT mask; | |
102 bool swapped_p = false; | |
103 | |
104 if (start > end) | |
105 { | |
106 i = start - 1; start = end + 1; end = i; | |
107 swapped_p = true; | |
108 } | |
109 if (end == 63) | |
110 mask = HOST_WIDE_INT_M1U; | |
111 else | |
112 mask = (HOST_WIDE_INT_1U << (end + 1)) - 1; | |
113 | |
114 mask &= ~((HOST_WIDE_INT_1U << start) - 1); | |
115 | |
116 if (swapped_p) | |
117 mask = ~mask; | |
118 | |
119 for (i = 0; i < nunits; i++) | |
120 const_vec[i] = GEN_INT (trunc_int_for_mode (mask, | |
121 GET_MODE_INNER (<VI_HW:MODE>mode))); | |
122 | |
123 emit_insn (gen_rtx_SET (operands[0], | |
124 gen_rtx_CONST_VECTOR (<VI_HW:MODE>mode, | |
125 gen_rtvec_v (nunits, const_vec)))); | |
126 DONE; | |
127 }) | |
128 | |
129 (define_expand "vec_genbytemaskv16qi" | |
130 [(match_operand:V16QI 0 "register_operand" "") | |
131 (match_operand:HI 1 "const_int_operand" "")] | |
132 "TARGET_VX" | |
133 { | |
134 int i; | |
135 unsigned mask = 0x8000; | |
136 rtx const_vec[16]; | |
137 unsigned HOST_WIDE_INT byte_mask = UINTVAL (operands[1]); | |
138 | |
139 for (i = 0; i < 16; i++) | |
140 { | |
141 if (mask & byte_mask) | |
142 const_vec[i] = constm1_rtx; | |
143 else | |
144 const_vec[i] = const0_rtx; | |
145 mask = mask >> 1; | |
146 } | |
147 emit_insn (gen_rtx_SET (operands[0], | |
148 gen_rtx_CONST_VECTOR (V16QImode, | |
149 gen_rtvec_v (16, const_vec)))); | |
150 DONE; | |
151 }) | |
152 | |
153 (define_expand "vec_splats<mode>" | |
154 [(set (match_operand:VEC_HW 0 "register_operand" "") | |
155 (vec_duplicate:VEC_HW (match_operand:<non_vec> 1 "general_operand" "")))] | |
156 "TARGET_VX") | |
157 | |
158 (define_expand "vec_insert<mode>" | |
159 [(set (match_operand:VEC_HW 0 "register_operand" "") | |
160 (unspec:VEC_HW [(match_operand:<non_vec> 2 "register_operand" "") | |
161 (match_operand:SI 3 "nonmemory_operand" "") | |
162 (match_operand:VEC_HW 1 "register_operand" "")] | |
163 UNSPEC_VEC_SET))] | |
164 "TARGET_VX" | |
165 "") | |
166 | |
167 ; This is vec_set + modulo arithmetic on the element selector (op 2) | |
168 (define_expand "vec_promote<mode>" | |
169 [(set (match_operand:VEC_HW 0 "register_operand" "") | |
170 (unspec:VEC_HW [(match_operand:<non_vec> 1 "register_operand" "") | |
171 (match_operand:SI 2 "nonmemory_operand" "") | |
172 (match_dup 0)] | |
173 UNSPEC_VEC_SET))] | |
174 "TARGET_VX" | |
175 "") | |
176 | |
177 ; vec_extract is also an RTL standard name -> vector.md | |
178 | |
179 ; vllezb, vllezh, vllezf, vllezg | |
180 (define_insn "vec_insert_and_zero<mode>" | |
181 [(set (match_operand:VEC_HW 0 "register_operand" "=v") | |
182 (unspec:VEC_HW [(match_operand:<non_vec> 1 "memory_operand" "R")] | |
183 UNSPEC_VEC_INSERT_AND_ZERO))] | |
184 "TARGET_VX" | |
185 "vllez<bhfgq>\t%v0,%1" | |
186 [(set_attr "op_type" "VRX")]) | |
187 | |
188 (define_insn "vlbb" | |
189 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
190 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "R") | |
191 (match_operand:QI 2 "const_mask_operand" "C")] | |
192 UNSPEC_VEC_LOAD_BNDRY))] | |
193 "TARGET_VX && UINTVAL (operands[2]) < 7" | |
194 "vlbb\t%v0,%1,%2" | |
195 [(set_attr "op_type" "VRX")]) | |
196 | |
197 (define_insn "vlrlrv16qi" | |
198 [(set (match_operand:V16QI 0 "register_operand" "=v,v") | |
199 (unspec:V16QI [(match_operand:BLK 2 "memory_operand" "Q,Q") | |
200 (match_operand:SI 1 "nonmemory_operand" "d,C")] | |
201 UNSPEC_VEC_LOAD_LEN_R))] | |
202 "TARGET_VXE" | |
203 "@ | |
204 vlrlr\t%v0,%1,%2 | |
205 vlrl\t%v0,%2,%1" | |
206 [(set_attr "op_type" "VRS,VSI")]) | |
207 | |
208 | |
209 ; FIXME: The following two patterns might using vec_merge. But what is | |
210 ; the canonical form: (vec_select (vec_merge op0 op1)) or (vec_merge | |
211 ; (vec_select op0) (vec_select op1) | |
212 ; vmrhb, vmrhh, vmrhf, vmrhg | |
213 (define_insn "vec_mergeh<mode>" | |
214 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v") | |
215 (unspec:V_128_NOSINGLE [(match_operand:V_128_NOSINGLE 1 "register_operand" "v") | |
216 (match_operand:V_128_NOSINGLE 2 "register_operand" "v")] | |
217 UNSPEC_VEC_MERGEH))] | |
218 "TARGET_VX" | |
219 "vmrh<bhfgq>\t%v0,%1,%2" | |
220 [(set_attr "op_type" "VRR")]) | |
221 | |
222 ; vmrlb, vmrlh, vmrlf, vmrlg | |
223 (define_insn "vec_mergel<mode>" | |
224 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v") | |
225 (unspec:V_128_NOSINGLE [(match_operand:V_128_NOSINGLE 1 "register_operand" "v") | |
226 (match_operand:V_128_NOSINGLE 2 "register_operand" "v")] | |
227 UNSPEC_VEC_MERGEL))] | |
228 "TARGET_VX" | |
229 "vmrl<bhfgq>\t%v0,%1,%2" | |
230 [(set_attr "op_type" "VRR")]) | |
231 | |
232 | |
233 ; Vector pack | |
234 | |
235 ; vpkh, vpkf, vpkg | |
236 (define_insn "vec_pack<mode>" | |
237 [(set (match_operand:<vec_half> 0 "register_operand" "=v") | |
238 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v") | |
239 (match_operand:VI_HW_HSD 2 "register_operand" "v")] | |
240 UNSPEC_VEC_PACK))] | |
241 "TARGET_VX" | |
242 "vpk<bhfgq>\t%v0,%v1,%v2" | |
243 [(set_attr "op_type" "VRR")]) | |
244 | |
245 | |
246 ; Vector pack saturate | |
247 | |
248 ; vpksh, vpksf, vpksg | |
249 (define_insn "vec_packs<mode>" | |
250 [(set (match_operand:<vec_half> 0 "register_operand" "=v") | |
251 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v") | |
252 (match_operand:VI_HW_HSD 2 "register_operand" "v")] | |
253 UNSPEC_VEC_PACK_SATURATE))] | |
254 "TARGET_VX" | |
255 "vpks<bhfgq>\t%v0,%v1,%v2" | |
256 [(set_attr "op_type" "VRR")]) | |
257 | |
258 | |
259 ; This is vec_packs_cc + loading cc into a caller specified memory location. | |
260 (define_expand "vec_packs_cc<mode>" | |
261 [(parallel | |
262 [(set (reg:CCRAW CC_REGNUM) | |
263 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "") | |
264 (match_operand:VI_HW_HSD 2 "register_operand" "")] | |
265 UNSPEC_VEC_PACK_SATURATE_GENCC)) | |
266 (set (match_operand:<vec_half> 0 "register_operand" "") | |
267 (unspec:<vec_half> [(match_dup 1) (match_dup 2)] | |
268 UNSPEC_VEC_PACK_SATURATE_CC))]) | |
269 (set (match_dup 4) | |
270 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT)) | |
271 (set (match_operand:SI 3 "memory_operand" "") | |
272 (match_dup 4))] | |
273 "TARGET_VX" | |
274 { | |
275 operands[4] = gen_reg_rtx (SImode); | |
276 }) | |
277 | |
278 ; vpksh, vpksf, vpksg | |
279 (define_insn "*vec_packs_cc<mode>" | |
280 [(set (reg:CCRAW CC_REGNUM) | |
281 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v") | |
282 (match_operand:VI_HW_HSD 2 "register_operand" "v")] | |
283 UNSPEC_VEC_PACK_SATURATE_GENCC)) | |
284 (set (match_operand:<vec_half> 0 "register_operand" "=v") | |
285 (unspec:<vec_half> [(match_dup 1) (match_dup 2)] | |
286 UNSPEC_VEC_PACK_SATURATE_CC))] | |
287 "TARGET_VX" | |
288 "vpks<bhfgq>s\t%v0,%v1,%v2" | |
289 [(set_attr "op_type" "VRR")]) | |
290 | |
291 | |
292 ; Vector pack logical saturate | |
293 | |
294 ; vpklsh, vpklsf, vpklsg | |
295 (define_insn "vec_packsu<mode>" | |
296 [(set (match_operand:<vec_half> 0 "register_operand" "=v") | |
297 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v") | |
298 (match_operand:VI_HW_HSD 2 "register_operand" "v")] | |
299 UNSPEC_VEC_PACK_UNSIGNED_SATURATE))] | |
300 "TARGET_VX" | |
301 "vpkls<bhfgq>\t%v0,%v1,%v2" | |
302 [(set_attr "op_type" "VRR")]) | |
303 | |
304 ; Emulate saturate unsigned pack on signed operands. | |
305 ; Zero out negative elements and continue with the unsigned saturating pack. | |
306 (define_expand "vec_packsu_u<mode>" | |
307 [(set (match_operand:<vec_half> 0 "register_operand" "=v") | |
308 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v") | |
309 (match_operand:VI_HW_HSD 2 "register_operand" "v")] | |
310 UNSPEC_VEC_PACK_UNSIGNED_SATURATE))] | |
311 "TARGET_VX" | |
312 { | |
313 rtx null_vec = CONST0_RTX(<MODE>mode); | |
314 machine_mode half_mode; | |
315 switch (<MODE>mode) | |
316 { | |
317 case E_V8HImode: half_mode = V16QImode; break; | |
318 case E_V4SImode: half_mode = V8HImode; break; | |
319 case E_V2DImode: half_mode = V4SImode; break; | |
320 default: gcc_unreachable (); | |
321 } | |
322 s390_expand_vcond (operands[1], operands[1], null_vec, | |
323 GE, operands[1], null_vec); | |
324 s390_expand_vcond (operands[2], operands[2], null_vec, | |
325 GE, operands[2], null_vec); | |
326 emit_insn (gen_rtx_SET (operands[0], | |
327 gen_rtx_UNSPEC (half_mode, | |
328 gen_rtvec (2, operands[1], operands[2]), | |
329 UNSPEC_VEC_PACK_UNSIGNED_SATURATE))); | |
330 DONE; | |
331 }) | |
332 | |
333 ; This is vec_packsu_cc + loading cc into a caller specified memory location. | |
334 ; FIXME: The reg to target mem copy should be issued by reload?! | |
335 (define_expand "vec_packsu_cc<mode>" | |
336 [(parallel | |
337 [(set (reg:CCRAW CC_REGNUM) | |
338 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "") | |
339 (match_operand:VI_HW_HSD 2 "register_operand" "")] | |
340 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC)) | |
341 (set (match_operand:<vec_half> 0 "register_operand" "") | |
342 (unspec:<vec_half> [(match_dup 1) (match_dup 2)] | |
343 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))]) | |
344 (set (match_dup 4) | |
345 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT)) | |
346 (set (match_operand:SI 3 "memory_operand" "") | |
347 (match_dup 4))] | |
348 "TARGET_VX" | |
349 { | |
350 operands[4] = gen_reg_rtx (SImode); | |
351 }) | |
352 | |
353 ; vpklsh, vpklsf, vpklsg | |
354 (define_insn "*vec_packsu_cc<mode>" | |
355 [(set (reg:CCRAW CC_REGNUM) | |
356 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v") | |
357 (match_operand:VI_HW_HSD 2 "register_operand" "v")] | |
358 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC)) | |
359 (set (match_operand:<vec_half> 0 "register_operand" "=v") | |
360 (unspec:<vec_half> [(match_dup 1) (match_dup 2)] | |
361 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))] | |
362 "TARGET_VX" | |
363 "vpkls<bhfgq>s\t%v0,%v1,%v2" | |
364 [(set_attr "op_type" "VRR")]) | |
365 | |
366 | |
367 ; Vector permute | |
368 | |
369 ; vec_perm is also RTL standard name, but we can only use it for V16QI | |
370 | |
371 (define_insn "vec_zperm<mode>" | |
372 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v") | |
373 (unspec:V_HW_HSD [(match_operand:V_HW_HSD 1 "register_operand" "v") | |
374 (match_operand:V_HW_HSD 2 "register_operand" "v") | |
375 (match_operand:V16QI 3 "register_operand" "v")] | |
376 UNSPEC_VEC_PERM))] | |
377 "TARGET_VX" | |
378 "vperm\t%v0,%v1,%v2,%v3" | |
379 [(set_attr "op_type" "VRR")]) | |
380 | |
381 (define_expand "vec_permi<mode>" | |
382 [(set (match_operand:V_HW_64 0 "register_operand" "") | |
383 (unspec:V_HW_64 [(match_operand:V_HW_64 1 "register_operand" "") | |
384 (match_operand:V_HW_64 2 "register_operand" "") | |
385 (match_operand:QI 3 "const_mask_operand" "")] | |
386 UNSPEC_VEC_PERMI))] | |
387 "TARGET_VX" | |
388 { | |
389 HOST_WIDE_INT val = INTVAL (operands[3]); | |
390 operands[3] = GEN_INT ((val & 1) | (val & 2) << 1); | |
391 }) | |
392 | |
393 (define_insn "*vec_permi<mode>" | |
394 [(set (match_operand:V_HW_64 0 "register_operand" "=v") | |
395 (unspec:V_HW_64 [(match_operand:V_HW_64 1 "register_operand" "v") | |
396 (match_operand:V_HW_64 2 "register_operand" "v") | |
397 (match_operand:QI 3 "const_mask_operand" "C")] | |
398 UNSPEC_VEC_PERMI))] | |
399 "TARGET_VX && (UINTVAL (operands[3]) & 10) == 0" | |
400 "vpdi\t%v0,%v1,%v2,%b3" | |
401 [(set_attr "op_type" "VRR")]) | |
402 | |
403 | |
404 ; Vector replicate | |
405 | |
406 | |
407 ; Replicate from vector element | |
408 (define_expand "vec_splat<mode>" | |
409 [(set (match_operand:V_HW 0 "register_operand" "") | |
410 (vec_duplicate:V_HW (vec_select:<non_vec> | |
411 (match_operand:V_HW 1 "register_operand" "") | |
412 (parallel | |
413 [(match_operand:QI 2 "const_mask_operand" "")]))))] | |
414 "TARGET_VX") | |
415 | |
416 ; Vector scatter element | |
417 | |
418 ; vscef, vsceg | |
419 | |
420 ; A 64 bit target address generated from 32 bit elements | |
421 (define_insn "vec_scatter_element<V_HW_4:mode>_DI" | |
422 [(set (mem:<non_vec> | |
423 (plus:DI (zero_extend:DI | |
424 (unspec:SI [(match_operand:V4SI 1 "register_operand" "v") | |
425 (match_operand:QI 3 "const_mask_operand" "C")] | |
426 UNSPEC_VEC_EXTRACT)) | |
427 (match_operand:SI 2 "address_operand" "ZQ"))) | |
428 (unspec:<non_vec> [(match_operand:V_HW_4 0 "register_operand" "v") | |
429 (match_dup 3)] UNSPEC_VEC_EXTRACT))] | |
430 "TARGET_VX && TARGET_64BIT && UINTVAL (operands[3]) < 4" | |
431 "vscef\t%v0,%O2(%v1,%R2),%3" | |
432 [(set_attr "op_type" "VRV")]) | |
433 | |
434 ; A 31 bit target address is generated from 64 bit elements | |
435 ; vsceg | |
436 (define_insn "vec_scatter_element<V_HW_64:mode>_SI" | |
437 [(set (mem:<non_vec> | |
438 (plus:SI (subreg:SI | |
439 (unspec:<non_vec_int> [(match_operand:V_HW_64 1 "register_operand" "v") | |
440 (match_operand:QI 3 "const_mask_operand" "C")] | |
441 UNSPEC_VEC_EXTRACT) 4) | |
442 (match_operand:SI 2 "address_operand" "ZQ"))) | |
443 (unspec:<non_vec> [(match_operand:V_HW_64 0 "register_operand" "v") | |
444 (match_dup 3)] UNSPEC_VEC_EXTRACT))] | |
445 "TARGET_VX && !TARGET_64BIT && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_64:MODE>mode)" | |
446 "vsce<V_HW_64:bhfgq>\t%v0,%O2(%v1,%R2),%3" | |
447 [(set_attr "op_type" "VRV")]) | |
448 | |
449 ; Element size and target address size is the same | |
450 ; vscef, vsceg | |
451 (define_insn "vec_scatter_element<mode>_<non_vec_int>" | |
452 [(set (mem:<non_vec> | |
453 (plus:<non_vec_int> (unspec:<non_vec_int> | |
454 [(match_operand:<tointvec> 1 "register_operand" "v") | |
455 (match_operand:QI 3 "const_mask_operand" "C")] | |
456 UNSPEC_VEC_EXTRACT) | |
457 (match_operand:DI 2 "address_operand" "ZQ"))) | |
458 (unspec:<non_vec> [(match_operand:V_HW_32_64 0 "register_operand" "v") | |
459 (match_dup 3)] UNSPEC_VEC_EXTRACT))] | |
460 "TARGET_VX && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)" | |
461 "vsce<bhfgq>\t%v0,%O2(%v1,%R2),%3" | |
462 [(set_attr "op_type" "VRV")]) | |
463 | |
464 ; Depending on the address size we have to expand a different pattern. | |
465 ; This however cannot be represented in s390-builtins.def so we do the | |
466 ; multiplexing here in the expander. | |
467 (define_expand "vec_scatter_element<V_HW_32_64:mode>" | |
468 [(match_operand:V_HW_32_64 0 "register_operand" "") | |
469 (match_operand:<tointvec> 1 "register_operand" "") | |
470 (match_operand 2 "address_operand" "") | |
471 (match_operand:QI 3 "const_mask_operand" "")] | |
472 "TARGET_VX" | |
473 { | |
474 if (TARGET_64BIT) | |
475 { | |
476 PUT_MODE (operands[2], DImode); | |
477 emit_insn ( | |
478 gen_vec_scatter_element<V_HW_32_64:mode>_DI (operands[0], operands[1], | |
479 operands[2], operands[3])); | |
480 } | |
481 else | |
482 { | |
483 PUT_MODE (operands[2], SImode); | |
484 emit_insn ( | |
485 gen_vec_scatter_element<V_HW_32_64:mode>_SI (operands[0], operands[1], | |
486 operands[2], operands[3])); | |
487 } | |
488 DONE; | |
489 }) | |
490 | |
491 | |
492 ; Vector select | |
493 | |
494 ; Operand 3 selects bits from either OP1 (0) or OP2 (1) | |
495 | |
496 ; Comparison operator should not matter as long as we always use the same ?! | |
497 | |
498 ; Operands 1 and 2 are swapped in order to match the altivec builtin. | |
499 ; If operand 3 is a const_int bitmask this would be vec_merge | |
500 (define_expand "vec_sel<mode>" | |
501 [(set (match_operand:V_HW 0 "register_operand" "") | |
502 (if_then_else:V_HW | |
503 (eq (match_operand:<tointvec> 3 "register_operand" "") | |
504 (match_dup 4)) | |
505 (match_operand:V_HW 2 "register_operand" "") | |
506 (match_operand:V_HW 1 "register_operand" "")))] | |
507 "TARGET_VX" | |
508 { | |
509 operands[4] = CONST0_RTX (<tointvec>mode); | |
510 }) | |
511 | |
512 | |
513 ; Vector sign extend to doubleword | |
514 | |
515 ; Sign extend of right most vector element to respective double-word | |
516 ; vsegb, vsegh, vsegf | |
517 (define_insn "vec_extend<mode>" | |
518 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
519 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")] | |
520 UNSPEC_VEC_EXTEND))] | |
521 "TARGET_VX" | |
522 "vseg<bhfgq>\t%v0,%1" | |
523 [(set_attr "op_type" "VRR")]) | |
524 | |
525 | |
526 ; Vector store with length | |
527 | |
528 ; Store bytes in OP1 from OP0 with the highest indexed byte to be | |
529 ; stored from OP0 given by OP2 | |
530 (define_insn "vstl<mode>" | |
531 [(set (match_operand:BLK 2 "memory_operand" "=Q") | |
532 (unspec:BLK [(match_operand:V 0 "register_operand" "v") | |
533 (match_operand:SI 1 "register_operand" "d")] | |
534 UNSPEC_VEC_STORE_LEN))] | |
535 "TARGET_VX" | |
536 "vstl\t%v0,%1,%2" | |
537 [(set_attr "op_type" "VRS")]) | |
538 | |
539 ; Vector store rightmost with length | |
540 | |
541 (define_insn "vstrlrv16qi" | |
542 [(set (match_operand:BLK 2 "memory_operand" "=Q,Q") | |
543 (unspec:BLK [(match_operand:V16QI 0 "register_operand" "v,v") | |
544 (match_operand:SI 1 "nonmemory_operand" "d,C")] | |
545 UNSPEC_VEC_STORE_LEN_R))] | |
546 "TARGET_VXE" | |
547 "@ | |
548 vstrlr\t%v0,%2,%1 | |
549 vstrl\t%v0,%1,%2" | |
550 [(set_attr "op_type" "VRS,VSI")]) | |
551 | |
552 | |
553 | |
554 ; vector bit permute | |
555 | |
556 (define_insn "vbpermv16qi" | |
557 [(set (match_operand:V2DI 0 "register_operand" "=v") | |
558 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "v") | |
559 (match_operand:V16QI 2 "register_operand" "v")] | |
560 UNSPEC_VEC_VBPERM))] | |
561 "TARGET_VXE" | |
562 "vbperm\t%v0,%v1,%v2" | |
563 [(set_attr "op_type" "VRR")]) | |
564 | |
565 ; Vector unpack high | |
566 | |
567 ; vuphb, vuphh, vuphf | |
568 (define_insn "vec_unpackh<mode>" | |
569 [(set (match_operand:<vec_double> 0 "register_operand" "=v") | |
570 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")] | |
571 UNSPEC_VEC_UNPACKH))] | |
572 "TARGET_VX" | |
573 "vuph<bhfgq>\t%v0,%v1" | |
574 [(set_attr "op_type" "VRR")]) | |
575 | |
576 ; vuplhb, vuplhh, vuplhf | |
577 (define_insn "vec_unpackh_l<mode>" | |
578 [(set (match_operand:<vec_double> 0 "register_operand" "=v") | |
579 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")] | |
580 UNSPEC_VEC_UNPACKH_L))] | |
581 "TARGET_VX" | |
582 "vuplh<bhfgq>\t%v0,%v1" | |
583 [(set_attr "op_type" "VRR")]) | |
584 | |
585 | |
586 ; Vector unpack low | |
587 | |
588 ; vuplb, vuplhw, vuplf | |
589 (define_insn "vec_unpackl<mode>" | |
590 [(set (match_operand:<vec_double> 0 "register_operand" "=v") | |
591 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")] | |
592 UNSPEC_VEC_UNPACKL))] | |
593 "TARGET_VX" | |
594 "vupl<bhfgq><w>\t%v0,%v1" | |
595 [(set_attr "op_type" "VRR")]) | |
596 | |
597 ; vupllb, vupllh, vupllf | |
598 (define_insn "vec_unpackl_l<mode>" | |
599 [(set (match_operand:<vec_double> 0 "register_operand" "=v") | |
600 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")] | |
601 UNSPEC_VEC_UNPACKL_L))] | |
602 "TARGET_VX" | |
603 "vupll<bhfgq>\t%v0,%v1" | |
604 [(set_attr "op_type" "VRR")]) | |
605 | |
606 | |
607 ; Vector add | |
608 | |
609 ; Vector add compute carry | |
610 | |
611 ; vaccb, vacch, vaccf, vaccg, vaccq | |
612 (define_insn "vacc<bhfgq>_<mode>" | |
613 [(set (match_operand:VIT_HW 0 "register_operand" "=v") | |
614 (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "%v") | |
615 (match_operand:VIT_HW 2 "register_operand" "v")] | |
616 UNSPEC_VEC_ADDC))] | |
617 "TARGET_VX" | |
618 "vacc<bhfgq>\t%v0,%v1,%v2" | |
619 [(set_attr "op_type" "VRR")]) | |
620 | |
621 ; Vector add with carry | |
622 | |
623 (define_insn "vacq" | |
624 [(set (match_operand:TI 0 "register_operand" "=v") | |
625 (unspec:TI [(match_operand:TI 1 "register_operand" "%v") | |
626 (match_operand:TI 2 "register_operand" "v") | |
627 (match_operand:TI 3 "register_operand" "v")] | |
628 UNSPEC_VEC_ADDE_U128))] | |
629 "TARGET_VX" | |
630 "vacq\t%v0,%v1,%v2,%v3" | |
631 [(set_attr "op_type" "VRR")]) | |
632 | |
633 | |
634 ; Vector add with carry compute carry | |
635 | |
636 (define_insn "vacccq" | |
637 [(set (match_operand:TI 0 "register_operand" "=v") | |
638 (unspec:TI [(match_operand:TI 1 "register_operand" "%v") | |
639 (match_operand:TI 2 "register_operand" "v") | |
640 (match_operand:TI 3 "register_operand" "v")] | |
641 UNSPEC_VEC_ADDEC_U128))] | |
642 "TARGET_VX" | |
643 "vacccq\t%v0,%v1,%v2,%v3" | |
644 [(set_attr "op_type" "VRR")]) | |
645 | |
646 | |
647 ; Vector and | |
648 | |
649 ; Vector and with complement | |
650 | |
651 ; vnc | |
652 (define_insn "vec_andc<mode>3" | |
653 [(set (match_operand:VT_HW 0 "register_operand" "=v") | |
654 (and:VT_HW (not:VT_HW (match_operand:VT_HW 2 "register_operand" "v")) | |
655 (match_operand:VT_HW 1 "register_operand" "v")))] | |
656 "TARGET_VX" | |
657 "vnc\t%v0,%v1,%v2" | |
658 [(set_attr "op_type" "VRR")]) | |
659 | |
660 | |
661 ; Vector average | |
662 | |
663 ; vavgb, vavgh, vavgf, vavgg | |
664 (define_insn "vec_avg<mode>" | |
665 [(set (match_operand:VI_HW 0 "register_operand" "=v") | |
666 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "%v") | |
667 (match_operand:VI_HW 2 "register_operand" "v")] | |
668 UNSPEC_VEC_AVG))] | |
669 "TARGET_VX" | |
670 "vavg<bhfgq>\t%v0,%v1,%v2" | |
671 [(set_attr "op_type" "VRR")]) | |
672 | |
673 ; Vector average logical | |
674 | |
675 ; vavglb, vavglh, vavglf, vavglg | |
676 (define_insn "vec_avgu<mode>" | |
677 [(set (match_operand:VI_HW 0 "register_operand" "=v") | |
678 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "%v") | |
679 (match_operand:VI_HW 2 "register_operand" "v")] | |
680 UNSPEC_VEC_AVGU))] | |
681 "TARGET_VX" | |
682 "vavgl<bhfgq>\t%v0,%v1,%v2" | |
683 [(set_attr "op_type" "VRR")]) | |
684 | |
685 | |
686 ; Vector checksum | |
687 | |
688 (define_insn "vec_checksum" | |
689 [(set (match_operand:V4SI 0 "register_operand" "=v") | |
690 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") | |
691 (match_operand:V4SI 2 "register_operand" "v")] | |
692 UNSPEC_VEC_CHECKSUM))] | |
693 "TARGET_VX" | |
694 "vcksm\t%v0,%v1,%v2" | |
695 [(set_attr "op_type" "VRR")]) | |
696 | |
697 ;; | |
698 ;; Vector compare | |
699 ;; | |
700 | |
701 ; vec_all/any int compares | |
702 | |
703 (define_expand "vec_all_<intcmpcc:code><VI_HW:mode>" | |
704 [(match_operand:SI 0 "register_operand" "") | |
705 (intcmpcc (match_operand:VI_HW 1 "register_operand" "") | |
706 (match_operand:VI_HW 2 "register_operand" ""))] | |
707 "TARGET_VX" | |
708 { | |
709 s390_expand_vec_compare_cc (operands[0], | |
710 <intcmpcc:CODE>, | |
711 operands[1], | |
712 operands[2], | |
713 true); | |
714 DONE; | |
715 }) | |
716 | |
717 (define_expand "vec_any_<intcmpcc:code><VI_HW:mode>" | |
718 [(match_operand:SI 0 "register_operand" "") | |
719 (intcmpcc (match_operand:VI_HW 1 "register_operand" "") | |
720 (match_operand:VI_HW 2 "register_operand" ""))] | |
721 "TARGET_VX" | |
722 { | |
723 s390_expand_vec_compare_cc (operands[0], | |
724 <intcmpcc:CODE>, | |
725 operands[1], | |
726 operands[2], | |
727 false); | |
728 DONE; | |
729 }) | |
730 | |
731 ; vec_all/any fp compares | |
732 | |
733 (define_expand "vec_all_<fpcmpcc:code><mode>" | |
734 [(match_operand:SI 0 "register_operand" "") | |
735 (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "") | |
736 (match_operand:VECF_HW 2 "register_operand" ""))] | |
737 "TARGET_VX" | |
738 { | |
739 s390_expand_vec_compare_cc (operands[0], | |
740 <fpcmpcc:CODE>, | |
741 operands[1], | |
742 operands[2], | |
743 true); | |
744 DONE; | |
745 }) | |
746 | |
747 (define_expand "vec_any_<fpcmpcc:code><mode>" | |
748 [(match_operand:SI 0 "register_operand" "") | |
749 (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "") | |
750 (match_operand:VECF_HW 2 "register_operand" ""))] | |
751 "TARGET_VX" | |
752 { | |
753 s390_expand_vec_compare_cc (operands[0], | |
754 <fpcmpcc:CODE>, | |
755 operands[1], | |
756 operands[2], | |
757 false); | |
758 DONE; | |
759 }) | |
760 | |
761 | |
762 ; Compare without generating CC | |
763 | |
764 (define_expand "vec_cmp<intcmp:code><VI_HW:mode>" | |
765 [(set (match_operand:VI_HW 0 "register_operand" "=v") | |
766 (intcmp:VI_HW (match_operand:VI_HW 1 "register_operand" "v") | |
767 (match_operand:VI_HW 2 "register_operand" "v")))] | |
768 "TARGET_VX" | |
769 { | |
770 s390_expand_vec_compare (operands[0], <intcmp:CODE>, operands[1], operands[2]); | |
771 DONE; | |
772 }) | |
773 | |
774 (define_expand "vec_cmp<fpcmp:code><mode>" | |
775 [(set (match_operand:<tointvec> 0 "register_operand" "=v") | |
776 (fpcmp:<tointvec> (match_operand:VF_HW 1 "register_operand" "v") | |
777 (match_operand:VF_HW 2 "register_operand" "v")))] | |
778 "TARGET_VX" | |
779 { | |
780 s390_expand_vec_compare (operands[0], <fpcmp:CODE>, operands[1], operands[2]); | |
781 DONE; | |
782 }) | |
783 | |
784 | |
785 ; Vector count leading zeros | |
786 | |
787 ; vec_cntlz -> clz | |
788 ; vec_cnttz -> ctz | |
789 | |
790 ; Vector xor | |
791 | |
792 ; vec_xor -> xor | |
793 | |
794 ; Vector Galois field multiply sum | |
795 | |
796 ; vgfmb, vgfmh, vgfmf | |
797 (define_insn "vec_gfmsum<mode>" | |
798 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
799 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") | |
800 (match_operand:VI_HW_QHS 2 "register_operand" "v")] | |
801 UNSPEC_VEC_GFMSUM))] | |
802 "TARGET_VX" | |
803 "vgfm<bhfgq>\t%v0,%v1,%v2" | |
804 [(set_attr "op_type" "VRR")]) | |
805 | |
806 (define_insn "vec_gfmsum_128" | |
807 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
808 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v") | |
809 (match_operand:V2DI 2 "register_operand" "v")] | |
810 UNSPEC_VEC_GFMSUM_128))] | |
811 "TARGET_VX" | |
812 "vgfmg\t%v0,%v1,%v2" | |
813 [(set_attr "op_type" "VRR")]) | |
814 | |
815 ; vgfmab, vgfmah, vgfmaf | |
816 (define_insn "vec_gfmsum_accum<mode>" | |
817 [(set (match_operand:<vec_double> 0 "register_operand" "=v") | |
818 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v") | |
819 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
820 (match_operand:<vec_double> 3 "register_operand" "v")] | |
821 UNSPEC_VEC_GFMSUM_ACCUM))] | |
822 "TARGET_VX" | |
823 "vgfma<bhfgq>\t%v0,%v1,%v2,%v3" | |
824 [(set_attr "op_type" "VRR")]) | |
825 | |
826 (define_insn "vec_gfmsum_accum_128" | |
827 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
828 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v") | |
829 (match_operand:V2DI 2 "register_operand" "v") | |
830 (match_operand:V16QI 3 "register_operand" "v")] | |
831 UNSPEC_VEC_GFMSUM_ACCUM_128))] | |
832 "TARGET_VX" | |
833 "vgfmag\t%v0,%v1,%v2,%v3" | |
834 [(set_attr "op_type" "VRR")]) | |
835 | |
836 | |
837 ; FIXME: vec_neg ? | |
838 | |
839 ; Vector load positive: vec_abs -> abs | |
840 ; Vector maximum vec_max -> smax, logical vec_max -> umax | |
841 ; Vector maximum vec_min -> smin, logical vec_min -> umin | |
842 | |
843 | |
844 ; Vector multiply and add high | |
845 | |
846 ; vec_mladd -> vec_vmal | |
847 ; vmalb, vmalh, vmalf, vmalg | |
848 (define_insn "vec_vmal<mode>" | |
849 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
850 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v") | |
851 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
852 (match_operand:VI_HW_QHS 3 "register_operand" "v")] | |
853 UNSPEC_VEC_VMAL))] | |
854 "TARGET_VX" | |
855 "vmal<bhfgq><w>\t%v0,%v1,%v2,%v3" | |
856 [(set_attr "op_type" "VRR")]) | |
857 | |
858 ; vec_mhadd -> vec_vmah/vec_vmalh | |
859 | |
860 ; vmahb; vmahh, vmahf, vmahg | |
861 (define_insn "vec_vmah<mode>" | |
862 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
863 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v") | |
864 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
865 (match_operand:VI_HW_QHS 3 "register_operand" "v")] | |
866 UNSPEC_VEC_VMAH))] | |
867 "TARGET_VX" | |
868 "vmah<bhfgq>\t%v0,%v1,%v2,%v3" | |
869 [(set_attr "op_type" "VRR")]) | |
870 | |
871 ; vmalhb; vmalhh, vmalhf, vmalhg | |
872 (define_insn "vec_vmalh<mode>" | |
873 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
874 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v") | |
875 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
876 (match_operand:VI_HW_QHS 3 "register_operand" "v")] | |
877 UNSPEC_VEC_VMALH))] | |
878 "TARGET_VX" | |
879 "vmalh<bhfgq>\t%v0,%v1,%v2,%v3" | |
880 [(set_attr "op_type" "VRR")]) | |
881 | |
882 ; vec_meadd -> vec_vmae/vec_vmale | |
883 | |
884 ; vmaeb; vmaeh, vmaef, vmaeg | |
885 (define_insn "vec_vmae<mode>" | |
886 [(set (match_operand:<vec_double> 0 "register_operand" "=v") | |
887 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "%v") | |
888 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
889 (match_operand:<vec_double> 3 "register_operand" "v")] | |
890 UNSPEC_VEC_VMAE))] | |
891 "TARGET_VX" | |
892 "vmae<bhfgq>\t%v0,%v1,%v2,%v3" | |
893 [(set_attr "op_type" "VRR")]) | |
894 | |
895 ; vmaleb; vmaleh, vmalef, vmaleg | |
896 (define_insn "vec_vmale<mode>" | |
897 [(set (match_operand:<vec_double> 0 "register_operand" "=v") | |
898 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "%v") | |
899 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
900 (match_operand:<vec_double> 3 "register_operand" "v")] | |
901 UNSPEC_VEC_VMALE))] | |
902 "TARGET_VX" | |
903 "vmale<bhfgq>\t%v0,%v1,%v2,%v3" | |
904 [(set_attr "op_type" "VRR")]) | |
905 | |
906 ; vec_moadd -> vec_vmao/vec_vmalo | |
907 | |
908 ; vmaob; vmaoh, vmaof, vmaog | |
909 (define_insn "vec_vmao<mode>" | |
910 [(set (match_operand:<vec_double> 0 "register_operand" "=v") | |
911 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "%v") | |
912 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
913 (match_operand:<vec_double> 3 "register_operand" "v")] | |
914 UNSPEC_VEC_VMAO))] | |
915 "TARGET_VX" | |
916 "vmao<bhfgq>\t%v0,%v1,%v2,%v3" | |
917 [(set_attr "op_type" "VRR")]) | |
918 | |
919 ; vmalob; vmaloh, vmalof, vmalog | |
920 (define_insn "vec_vmalo<mode>" | |
921 [(set (match_operand:<vec_double> 0 "register_operand" "=v") | |
922 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v") | |
923 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
924 (match_operand:<vec_double> 3 "register_operand" "v")] | |
925 UNSPEC_VEC_VMALO))] | |
926 "TARGET_VX" | |
927 "vmalo<bhfgq>\t%v0,%v1,%v2,%v3" | |
928 [(set_attr "op_type" "VRR")]) | |
929 | |
930 | |
931 ; Vector multiply high | |
932 | |
933 ; vec_mulh -> vec_smulh/vec_umulh | |
934 | |
935 ; vmhb, vmhh, vmhf | |
936 (define_insn "vec_smulh<mode>" | |
937 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
938 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v") | |
939 (match_operand:VI_HW_QHS 2 "register_operand" "v")] | |
940 UNSPEC_VEC_SMULT_HI))] | |
941 "TARGET_VX" | |
942 "vmh<bhfgq>\t%v0,%v1,%v2" | |
943 [(set_attr "op_type" "VRR")]) | |
944 | |
945 ; vmlhb, vmlhh, vmlhf | |
946 (define_insn "vec_umulh<mode>" | |
947 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
948 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v") | |
949 (match_operand:VI_HW_QHS 2 "register_operand" "v")] | |
950 UNSPEC_VEC_UMULT_HI))] | |
951 "TARGET_VX" | |
952 "vmlh<bhfgq>\t%v0,%v1,%v2" | |
953 [(set_attr "op_type" "VRR")]) | |
954 | |
955 | |
956 ; Vector multiply low | |
957 | |
958 ; vec_mule -> vec_widen_umult_even/vec_widen_smult_even | |
959 ; vec_mulo -> vec_widen_umult_odd/vec_widen_smult_odd | |
960 | |
961 | |
962 ; Vector nor | |
963 | |
964 (define_insn "vec_nor<mode>3" | |
965 [(set (match_operand:VT_HW 0 "register_operand" "=v") | |
966 (not:VT_HW | |
967 (ior:VT_HW (match_operand:VT_HW 1 "register_operand" "%v") | |
968 (match_operand:VT_HW 2 "register_operand" "v"))))] | |
969 "TARGET_VX" | |
970 "vno\t%v0,%v1,%v2" | |
971 [(set_attr "op_type" "VRR")]) | |
972 | |
973 | |
974 ; Vector or | |
975 | |
976 ; Vector population count vec_popcnt -> popcount | |
977 ; Vector element rotate left logical vec_rl -> vrotl, vec_rli -> rot | |
978 | |
979 ; Vector element rotate and insert under mask | |
980 | |
981 ; verimb, verimh, verimf, verimg | |
982 (define_insn "verim<mode>" | |
983 [(set (match_operand:VI_HW 0 "register_operand" "=v") | |
984 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "0") | |
985 (match_operand:VI_HW 2 "register_operand" "v") | |
986 (match_operand:VI_HW 3 "register_operand" "v") | |
987 (match_operand:QI 4 "const_int_operand" "C")] | |
988 UNSPEC_VEC_RL_MASK))] | |
989 "TARGET_VX" | |
990 "verim<bhfgq>\t%v0,%v2,%v3,%b4" | |
991 [(set_attr "op_type" "VRI")]) | |
992 | |
993 | |
994 ; Vector shift left | |
995 | |
996 (define_insn "vec_sll<VI_HW:mode><VI_HW_QHS:mode>" | |
997 [(set (match_operand:VI_HW 0 "register_operand" "=v") | |
998 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v") | |
999 (match_operand:VI_HW_QHS 2 "register_operand" "v")] | |
1000 UNSPEC_VEC_SLL))] | |
1001 "TARGET_VX" | |
1002 "vsl\t%v0,%v1,%v2" | |
1003 [(set_attr "op_type" "VRR")]) | |
1004 | |
1005 | |
1006 ; Vector shift left by byte | |
1007 | |
1008 ; Pattern definition in vector.md, see vec_vslb | |
1009 (define_expand "vec_slb<mode>" | |
1010 [(set (match_operand:V_HW 0 "register_operand" "") | |
1011 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "") | |
1012 (match_operand:<tointvec> 2 "register_operand" "")] | |
1013 UNSPEC_VEC_SLB))] | |
1014 "TARGET_VX" | |
1015 { | |
1016 PUT_MODE (operands[2], V16QImode); | |
1017 }) | |
1018 | |
1019 ; Vector shift left double by byte | |
1020 | |
1021 (define_insn "vec_sld<mode>" | |
1022 [(set (match_operand:V_HW 0 "register_operand" "=v") | |
1023 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v") | |
1024 (match_operand:V_HW 2 "register_operand" "v") | |
1025 (match_operand:QI 3 "const_int_operand" "C")] | |
1026 UNSPEC_VEC_SLDB))] | |
1027 "TARGET_VX" | |
1028 "vsldb\t%v0,%v1,%v2,%b3" | |
1029 [(set_attr "op_type" "VRI")]) | |
1030 | |
1031 (define_expand "vec_sldw<mode>" | |
1032 [(set (match_operand:V_HW 0 "register_operand" "") | |
1033 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "") | |
1034 (match_operand:V_HW 2 "register_operand" "") | |
1035 (match_operand:QI 3 "const_int_operand" "")] | |
1036 UNSPEC_VEC_SLDB))] | |
1037 "TARGET_VX" | |
1038 { | |
1039 operands[3] = GEN_INT (INTVAL (operands[3]) << 2); | |
1040 }) | |
1041 | |
1042 ; Vector shift right arithmetic | |
1043 | |
1044 (define_insn "vec_sral<VI_HW:mode><VI_HW_QHS:mode>" | |
1045 [(set (match_operand:VI_HW 0 "register_operand" "=v") | |
1046 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v") | |
1047 (match_operand:VI_HW_QHS 2 "register_operand" "v")] | |
1048 UNSPEC_VEC_SRAL))] | |
1049 "TARGET_VX" | |
1050 "vsra\t%v0,%v1,%v2" | |
1051 [(set_attr "op_type" "VRR")]) | |
1052 | |
1053 | |
1054 ; Vector shift right arithmetic by byte | |
1055 | |
1056 (define_insn "vec_srab<mode>" | |
1057 [(set (match_operand:V_HW 0 "register_operand" "=v") | |
1058 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v") | |
1059 (match_operand:<tointvec> 2 "register_operand" "v")] | |
1060 UNSPEC_VEC_SRAB))] | |
1061 "TARGET_VX" | |
1062 "vsrab\t%v0,%v1,%v2" | |
1063 [(set_attr "op_type" "VRR")]) | |
1064 | |
1065 | |
1066 ; Vector shift right logical | |
1067 | |
1068 (define_insn "vec_srl<VI_HW:mode><VI_HW_QHS:mode>" | |
1069 [(set (match_operand:VI_HW 0 "register_operand" "=v") | |
1070 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v") | |
1071 (match_operand:VI_HW_QHS 2 "register_operand" "v")] | |
1072 UNSPEC_VEC_SRL))] | |
1073 "TARGET_VX" | |
1074 "vsrl\t%v0,%v1,%v2" | |
1075 [(set_attr "op_type" "VRR")]) | |
1076 | |
1077 | |
1078 ; Vector shift right logical by byte | |
1079 | |
1080 ; Pattern definition in vector.md, see vec_vsrb | |
1081 (define_expand "vec_srb<mode>" | |
1082 [(set (match_operand:V_HW 0 "register_operand" "") | |
1083 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "") | |
1084 (match_operand:<tointvec> 2 "register_operand" "")] | |
1085 UNSPEC_VEC_SRLB))] | |
1086 "TARGET_VX" | |
1087 { | |
1088 PUT_MODE (operands[2], V16QImode); | |
1089 }) | |
1090 | |
1091 ; Vector subtract | |
1092 | |
1093 ; Vector subtract compute borrow indication | |
1094 | |
1095 ; vscbib, vscbih, vscbif, vscbig, vscbiq | |
1096 (define_insn "vscbi<bhfgq>_<mode>" | |
1097 [(set (match_operand:VIT_HW 0 "register_operand" "=v") | |
1098 (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "v") | |
1099 (match_operand:VIT_HW 2 "register_operand" "v")] | |
1100 UNSPEC_VEC_SUBC))] | |
1101 "TARGET_VX" | |
1102 "vscbi<bhfgq>\t%v0,%v1,%v2" | |
1103 [(set_attr "op_type" "VRR")]) | |
1104 | |
1105 ; Vector subtract with borrow indication | |
1106 | |
1107 (define_insn "vsbiq" | |
1108 [(set (match_operand:TI 0 "register_operand" "=v") | |
1109 (unspec:TI [(match_operand:TI 1 "register_operand" "v") | |
1110 (match_operand:TI 2 "register_operand" "v") | |
1111 (match_operand:TI 3 "register_operand" "v")] | |
1112 UNSPEC_VEC_SUBE_U128))] | |
1113 "TARGET_VX" | |
1114 "vsbiq\t%v0,%v1,%v2,%v3" | |
1115 [(set_attr "op_type" "VRR")]) | |
1116 | |
1117 | |
1118 ; Vector subtract with borrow compute and borrow indication | |
1119 | |
1120 (define_insn "vsbcbiq" | |
1121 [(set (match_operand:TI 0 "register_operand" "=v") | |
1122 (unspec:TI [(match_operand:TI 1 "register_operand" "v") | |
1123 (match_operand:TI 2 "register_operand" "v") | |
1124 (match_operand:TI 3 "register_operand" "v")] | |
1125 UNSPEC_VEC_SUBEC_U128))] | |
1126 "TARGET_VX" | |
1127 "vsbcbiq\t%v0,%v1,%v2,%v3" | |
1128 [(set_attr "op_type" "VRR")]) | |
1129 | |
1130 | |
1131 ; Vector sum across | |
1132 | |
1133 ; Sum across DImode parts of the 1st operand and add the rightmost | |
1134 ; element of 2nd operand | |
1135 ; vsumgh, vsumgf | |
1136 (define_expand "vec_sum2<mode>" | |
1137 [(set (match_operand:V2DI 0 "register_operand" "") | |
1138 (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "") | |
1139 (match_operand:VI_HW_HS 2 "register_operand" "")] | |
1140 UNSPEC_VEC_VSUMG))] | |
1141 "TARGET_VX") | |
1142 | |
1143 ; vsumqh, vsumqf | |
1144 (define_insn "vec_sum_u128<mode>" | |
1145 [(set (match_operand:V2DI 0 "register_operand" "=v") | |
1146 (unspec:V2DI [(match_operand:VI_HW_SD 1 "register_operand" "v") | |
1147 (match_operand:VI_HW_SD 2 "register_operand" "v")] | |
1148 UNSPEC_VEC_VSUMQ))] | |
1149 "TARGET_VX" | |
1150 "vsumq<bhfgq>\t%v0,%v1,%v2" | |
1151 [(set_attr "op_type" "VRR")]) | |
1152 | |
1153 ; vsumb, vsumh | |
1154 (define_expand "vec_sum4<mode>" | |
1155 [(set (match_operand:V4SI 0 "register_operand" "") | |
1156 (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "") | |
1157 (match_operand:VI_HW_QH 2 "register_operand" "")] | |
1158 UNSPEC_VEC_VSUM))] | |
1159 "TARGET_VX") | |
1160 | |
1161 | |
1162 ; Vector test under mask | |
1163 | |
1164 (define_expand "vec_test_mask_int<mode>" | |
1165 [(set (reg:CCRAW CC_REGNUM) | |
1166 (unspec:CCRAW [(match_operand:V_HW 1 "register_operand" "") | |
1167 (match_operand:<tointvec> 2 "register_operand" "")] | |
1168 UNSPEC_VEC_TEST_MASK)) | |
1169 (set (match_operand:SI 0 "register_operand" "") | |
1170 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1171 "TARGET_VX") | |
1172 | |
1173 (define_insn "*vec_test_mask<mode>" | |
1174 [(set (reg:CCRAW CC_REGNUM) | |
1175 (unspec:CCRAW [(match_operand:V_HW 0 "register_operand" "v") | |
1176 (match_operand:<tointvec> 1 "register_operand" "v")] | |
1177 UNSPEC_VEC_TEST_MASK))] | |
1178 "TARGET_VX" | |
1179 "vtm\t%v0,%v1" | |
1180 [(set_attr "op_type" "VRR")]) | |
1181 | |
1182 | |
1183 ; Vector multiply sum logical | |
1184 | |
1185 (define_insn "vec_msumv2di" | |
1186 [(set (match_operand:V16QI 0 "register_operand" "=v") | |
1187 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v") | |
1188 (match_operand:V2DI 2 "register_operand" "v") | |
1189 (match_operand:V16QI 3 "register_operand" "v") | |
1190 (match_operand:QI 4 "const_mask_operand" "C")] | |
1191 UNSPEC_VEC_MSUM))] | |
1192 "TARGET_VXE" | |
1193 "vmslg\t%v0,%v1,%v2,%v3,%4" | |
1194 [(set_attr "op_type" "VRR")]) | |
1195 | |
1196 (define_insn "vmslg" | |
1197 [(set (match_operand:TI 0 "register_operand" "=v") | |
1198 (unspec:TI [(match_operand:V2DI 1 "register_operand" "v") | |
1199 (match_operand:V2DI 2 "register_operand" "v") | |
1200 (match_operand:TI 3 "register_operand" "v") | |
1201 (match_operand:QI 4 "const_mask_operand" "C")] | |
1202 UNSPEC_VEC_MSUM))] | |
1203 "TARGET_VXE" | |
1204 "vmslg\t%v0,%v1,%v2,%v3,%4" | |
1205 [(set_attr "op_type" "VRR")]) | |
1206 | |
1207 | |
1208 ; Vector find any element equal | |
1209 | |
1210 ; vfaeb, vfaeh, vfaef | |
1211 ; vfaezb, vfaezh, vfaezf | |
1212 (define_insn "vfae<mode>" | |
1213 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
1214 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") | |
1215 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
1216 (match_operand:QI 3 "const_mask_operand" "C")] | |
1217 UNSPEC_VEC_VFAE))] | |
1218 "TARGET_VX" | |
1219 { | |
1220 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]); | |
1221 | |
1222 if (flags & VSTRING_FLAG_ZS) | |
1223 { | |
1224 flags &= ~VSTRING_FLAG_ZS; | |
1225 operands[3] = GEN_INT (flags); | |
1226 return "vfaez<bhfgq>\t%v0,%v1,%v2,%b3"; | |
1227 } | |
1228 return "vfae<bhfgq>\t%v0,%v1,%v2,%b3"; | |
1229 } | |
1230 [(set_attr "op_type" "VRR")]) | |
1231 | |
1232 ; vfaebs, vfaehs, vfaefs | |
1233 ; vfaezbs, vfaezhs, vfaezfs | |
1234 (define_insn "*vfaes<mode>" | |
1235 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
1236 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") | |
1237 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
1238 (match_operand:QI 3 "const_mask_operand" "C")] | |
1239 UNSPEC_VEC_VFAE)) | |
1240 (set (reg:CCRAW CC_REGNUM) | |
1241 (unspec:CCRAW [(match_dup 1) | |
1242 (match_dup 2) | |
1243 (match_dup 3)] | |
1244 UNSPEC_VEC_VFAECC))] | |
1245 "TARGET_VX" | |
1246 { | |
1247 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]); | |
1248 | |
1249 if (flags & VSTRING_FLAG_ZS) | |
1250 { | |
1251 flags &= ~VSTRING_FLAG_ZS; | |
1252 operands[3] = GEN_INT (flags); | |
1253 return "vfaez<bhfgq>s\t%v0,%v1,%v2,%b3"; | |
1254 } | |
1255 return "vfae<bhfgq>s\t%v0,%v1,%v2,%b3"; | |
1256 } | |
1257 [(set_attr "op_type" "VRR")]) | |
1258 | |
1259 (define_expand "vfaez<mode>" | |
1260 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
1261 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "") | |
1262 (match_operand:VI_HW_QHS 2 "register_operand" "") | |
1263 (match_operand:QI 3 "const_mask_operand" "")] | |
1264 UNSPEC_VEC_VFAE))] | |
1265 "TARGET_VX" | |
1266 { | |
1267 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_ZS); | |
1268 }) | |
1269 | |
1270 (define_expand "vfaes<mode>" | |
1271 [(parallel | |
1272 [(set (match_operand:VI_HW_QHS 0 "register_operand" "") | |
1273 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "") | |
1274 (match_operand:VI_HW_QHS 2 "register_operand" "") | |
1275 (match_operand:QI 3 "const_mask_operand" "")] | |
1276 UNSPEC_VEC_VFAE)) | |
1277 (set (reg:CCRAW CC_REGNUM) | |
1278 (unspec:CCRAW [(match_dup 1) | |
1279 (match_dup 2) | |
1280 (match_dup 3)] | |
1281 UNSPEC_VEC_VFAECC))]) | |
1282 (set (match_operand:SI 4 "memory_operand" "") | |
1283 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1284 "TARGET_VX" | |
1285 { | |
1286 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS); | |
1287 }) | |
1288 | |
1289 (define_expand "vfaezs<mode>" | |
1290 [(parallel | |
1291 [(set (match_operand:VI_HW_QHS 0 "register_operand" "") | |
1292 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "") | |
1293 (match_operand:VI_HW_QHS 2 "register_operand" "") | |
1294 (match_operand:SI 3 "const_mask_operand" "")] | |
1295 UNSPEC_VEC_VFAE)) | |
1296 (set (reg:CCRAW CC_REGNUM) | |
1297 (unspec:CCRAW [(match_dup 1) | |
1298 (match_dup 2) | |
1299 (match_dup 3)] | |
1300 UNSPEC_VEC_VFAECC))]) | |
1301 (set (match_operand:SI 4 "memory_operand" "") | |
1302 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1303 "TARGET_VX" | |
1304 { | |
1305 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS); | |
1306 }) | |
1307 | |
1308 | |
1309 ; Vector find element equal | |
1310 | |
1311 ; vfeebs, vfeehs, vfeefs | |
1312 ; vfeezbs, vfeezhs, vfeezfs | |
1313 (define_insn "*vfees<mode>" | |
1314 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
1315 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") | |
1316 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
1317 (match_operand:QI 3 "const_mask_operand" "C")] | |
1318 UNSPEC_VEC_VFEE)) | |
1319 (set (reg:CCRAW CC_REGNUM) | |
1320 (unspec:CCRAW [(match_dup 1) | |
1321 (match_dup 2) | |
1322 (match_dup 3)] | |
1323 UNSPEC_VEC_VFEECC))] | |
1324 "TARGET_VX" | |
1325 { | |
1326 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]); | |
1327 | |
1328 gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS))); | |
1329 flags &= ~VSTRING_FLAG_CS; | |
1330 | |
1331 if (flags == VSTRING_FLAG_ZS) | |
1332 return "vfeez<bhfgq>s\t%v0,%v1,%v2"; | |
1333 return "vfee<bhfgq>s\t%v0,%v1,%v2,%b3"; | |
1334 } | |
1335 [(set_attr "op_type" "VRR")]) | |
1336 | |
1337 ; vfeeb, vfeeh, vfeef | |
1338 (define_insn "vfee<mode>" | |
1339 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
1340 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") | |
1341 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
1342 (const_int 0)] | |
1343 UNSPEC_VEC_VFEE))] | |
1344 "TARGET_VX" | |
1345 "vfee<bhfgq>\t%v0,%v1,%v2,0" | |
1346 [(set_attr "op_type" "VRR")]) | |
1347 | |
1348 ; vfeezb, vfeezh, vfeezf | |
1349 (define_insn "vfeez<mode>" | |
1350 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
1351 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") | |
1352 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
1353 (const_int VSTRING_FLAG_ZS)] | |
1354 UNSPEC_VEC_VFEE))] | |
1355 "TARGET_VX" | |
1356 "vfeez<bhfgq>s\t%v0,%v1,%v2,2" | |
1357 [(set_attr "op_type" "VRR")]) | |
1358 | |
1359 (define_expand "vfees<mode>" | |
1360 [(parallel | |
1361 [(set (match_operand:VI_HW_QHS 0 "register_operand" "") | |
1362 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "") | |
1363 (match_operand:VI_HW_QHS 2 "register_operand" "") | |
1364 (const_int VSTRING_FLAG_CS)] | |
1365 UNSPEC_VEC_VFEE)) | |
1366 (set (reg:CCRAW CC_REGNUM) | |
1367 (unspec:CCRAW [(match_dup 1) | |
1368 (match_dup 2) | |
1369 (const_int VSTRING_FLAG_CS)] | |
1370 UNSPEC_VEC_VFEECC))]) | |
1371 (set (match_operand:SI 3 "memory_operand" "") | |
1372 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1373 "TARGET_VX") | |
1374 | |
1375 (define_expand "vfeezs<mode>" | |
1376 [(parallel | |
1377 [(set (match_operand:VI_HW_QHS 0 "register_operand" "") | |
1378 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "") | |
1379 (match_operand:VI_HW_QHS 2 "register_operand" "") | |
1380 (match_dup 4)] | |
1381 UNSPEC_VEC_VFEE)) | |
1382 (set (reg:CCRAW CC_REGNUM) | |
1383 (unspec:CCRAW [(match_dup 1) | |
1384 (match_dup 2) | |
1385 (match_dup 4)] | |
1386 UNSPEC_VEC_VFEECC))]) | |
1387 (set (match_operand:SI 3 "memory_operand" "") | |
1388 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1389 "TARGET_VX" | |
1390 { | |
1391 operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS); | |
1392 }) | |
1393 | |
1394 ; Vector find element not equal | |
1395 | |
1396 ; vfeneb, vfeneh, vfenef | |
1397 (define_insn "vfene<mode>" | |
1398 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
1399 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") | |
1400 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
1401 (const_int 0)] | |
1402 UNSPEC_VEC_VFENE))] | |
1403 "TARGET_VX" | |
1404 "vfene<bhfgq>\t%v0,%v1,%v2,0" | |
1405 [(set_attr "op_type" "VRR")]) | |
1406 | |
1407 ; vec_vfenes can be found in vector.md since it is used for strlen | |
1408 | |
1409 ; vfenezb, vfenezh, vfenezf | |
1410 (define_insn "vfenez<mode>" | |
1411 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
1412 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") | |
1413 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
1414 (const_int VSTRING_FLAG_ZS)] | |
1415 UNSPEC_VEC_VFENE))] | |
1416 "TARGET_VX" | |
1417 "vfenez<bhfgq>\t%v0,%v1,%v2" | |
1418 [(set_attr "op_type" "VRR")]) | |
1419 | |
1420 (define_expand "vfenes<mode>" | |
1421 [(parallel | |
1422 [(set (match_operand:VI_HW_QHS 0 "register_operand" "") | |
1423 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "") | |
1424 (match_operand:VI_HW_QHS 2 "register_operand" "") | |
1425 (const_int VSTRING_FLAG_CS)] | |
1426 UNSPEC_VEC_VFENE)) | |
1427 (set (reg:CCRAW CC_REGNUM) | |
1428 (unspec:CCRAW [(match_dup 1) | |
1429 (match_dup 2) | |
1430 (const_int VSTRING_FLAG_CS)] | |
1431 UNSPEC_VEC_VFENECC))]) | |
1432 (set (match_operand:SI 3 "memory_operand" "") | |
1433 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1434 "TARGET_VX") | |
1435 | |
1436 (define_expand "vfenezs<mode>" | |
1437 [(parallel | |
1438 [(set (match_operand:VI_HW_QHS 0 "register_operand" "") | |
1439 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "") | |
1440 (match_operand:VI_HW_QHS 2 "register_operand" "") | |
1441 (match_dup 4)] | |
1442 UNSPEC_VEC_VFENE)) | |
1443 (set (reg:CCRAW CC_REGNUM) | |
1444 (unspec:CCRAW [(match_dup 1) | |
1445 (match_dup 2) | |
1446 (match_dup 4)] | |
1447 UNSPEC_VEC_VFENECC))]) | |
1448 (set (match_operand:SI 3 "memory_operand" "") | |
1449 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1450 "TARGET_VX" | |
1451 { | |
1452 operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS); | |
1453 }) | |
1454 | |
1455 ; Vector isolate string | |
1456 | |
1457 ; vistrb, vistrh, vistrf | |
1458 (define_insn "vistr<mode>" | |
1459 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
1460 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")] | |
1461 UNSPEC_VEC_VISTR))] | |
1462 "TARGET_VX" | |
1463 "vistr<bhfgq>\t%v0,%v1" | |
1464 [(set_attr "op_type" "VRR")]) | |
1465 | |
1466 ; vistrbs, vistrhs, vistrfs | |
1467 (define_insn "*vistrs<mode>" | |
1468 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
1469 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")] | |
1470 UNSPEC_VEC_VISTR)) | |
1471 (set (reg:CCRAW CC_REGNUM) | |
1472 (unspec:CCRAW [(match_dup 1)] UNSPEC_VEC_VISTRCC))] | |
1473 "TARGET_VX" | |
1474 "vistr<bhfgq>s\t%v0,%v1" | |
1475 [(set_attr "op_type" "VRR")]) | |
1476 | |
1477 (define_expand "vistrs<mode>" | |
1478 [(parallel | |
1479 [(set (match_operand:VI_HW_QHS 0 "register_operand" "") | |
1480 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")] | |
1481 UNSPEC_VEC_VISTR)) | |
1482 (set (reg:CCRAW CC_REGNUM) | |
1483 (unspec:CCRAW [(match_dup 1)] | |
1484 UNSPEC_VEC_VISTRCC))]) | |
1485 (set (match_operand:SI 2 "memory_operand" "") | |
1486 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1487 "TARGET_VX") | |
1488 | |
1489 | |
1490 ; Vector compare range | |
1491 | |
1492 ; vstrcb, vstrch, vstrcf | |
1493 ; vstrczb, vstrczh, vstrczf | |
1494 (define_insn "vstrc<mode>" | |
1495 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
1496 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") | |
1497 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
1498 (match_operand:VI_HW_QHS 3 "register_operand" "v") | |
1499 (match_operand:QI 4 "const_mask_operand" "C")] | |
1500 UNSPEC_VEC_VSTRC))] | |
1501 "TARGET_VX" | |
1502 { | |
1503 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]); | |
1504 | |
1505 if (flags & VSTRING_FLAG_ZS) | |
1506 { | |
1507 flags &= ~VSTRING_FLAG_ZS; | |
1508 operands[4] = GEN_INT (flags); | |
1509 return "vstrcz<bhfgq>\t%v0,%v1,%v2,%v3,%b4"; | |
1510 } | |
1511 return "vstrc<bhfgq>\t%v0,%v1,%v2,%v3,%b4"; | |
1512 } | |
1513 [(set_attr "op_type" "VRR")]) | |
1514 | |
1515 ; vstrcbs, vstrchs, vstrcfs | |
1516 ; vstrczbs, vstrczhs, vstrczfs | |
1517 (define_insn "*vstrcs<mode>" | |
1518 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") | |
1519 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") | |
1520 (match_operand:VI_HW_QHS 2 "register_operand" "v") | |
1521 (match_operand:VI_HW_QHS 3 "register_operand" "v") | |
1522 (match_operand:QI 4 "const_mask_operand" "C")] | |
1523 UNSPEC_VEC_VSTRC)) | |
1524 (set (reg:CCRAW CC_REGNUM) | |
1525 (unspec:CCRAW [(match_dup 1) | |
1526 (match_dup 2) | |
1527 (match_dup 3) | |
1528 (match_dup 4)] | |
1529 UNSPEC_VEC_VSTRCCC))] | |
1530 "TARGET_VX" | |
1531 { | |
1532 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]); | |
1533 | |
1534 if (flags & VSTRING_FLAG_ZS) | |
1535 { | |
1536 flags &= ~VSTRING_FLAG_ZS; | |
1537 operands[4] = GEN_INT (flags); | |
1538 return "vstrcz<bhfgq>s\t%v0,%v1,%v2,%v3,%b4"; | |
1539 } | |
1540 return "vstrc<bhfgq>s\t%v0,%v1,%v2,%v3,%b4"; | |
1541 } | |
1542 [(set_attr "op_type" "VRR")]) | |
1543 | |
1544 (define_expand "vstrcz<mode>" | |
1545 [(set (match_operand:VI_HW_QHS 0 "register_operand" "") | |
1546 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "") | |
1547 (match_operand:VI_HW_QHS 2 "register_operand" "") | |
1548 (match_operand:VI_HW_QHS 3 "register_operand" "") | |
1549 (match_operand:QI 4 "const_mask_operand" "")] | |
1550 UNSPEC_VEC_VSTRC))] | |
1551 "TARGET_VX" | |
1552 { | |
1553 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_ZS); | |
1554 }) | |
1555 | |
1556 (define_expand "vstrcs<mode>" | |
1557 [(parallel | |
1558 [(set (match_operand:VI_HW_QHS 0 "register_operand" "") | |
1559 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "") | |
1560 (match_operand:VI_HW_QHS 2 "register_operand" "") | |
1561 (match_operand:VI_HW_QHS 3 "register_operand" "") | |
1562 (match_operand:QI 4 "const_mask_operand" "")] | |
1563 UNSPEC_VEC_VSTRC)) | |
1564 (set (reg:CCRAW CC_REGNUM) | |
1565 (unspec:CCRAW [(match_dup 1) | |
1566 (match_dup 2) | |
1567 (match_dup 3) | |
1568 (match_dup 4)] | |
1569 UNSPEC_VEC_VSTRCCC))]) | |
1570 (set (match_operand:SI 5 "memory_operand" "") | |
1571 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1572 "TARGET_VX" | |
1573 { | |
1574 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS); | |
1575 }) | |
1576 | |
1577 (define_expand "vstrczs<mode>" | |
1578 [(parallel | |
1579 [(set (match_operand:VI_HW_QHS 0 "register_operand" "") | |
1580 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "") | |
1581 (match_operand:VI_HW_QHS 2 "register_operand" "") | |
1582 (match_operand:VI_HW_QHS 3 "register_operand" "") | |
1583 (match_operand:QI 4 "const_mask_operand" "")] | |
1584 UNSPEC_VEC_VSTRC)) | |
1585 (set (reg:CCRAW CC_REGNUM) | |
1586 (unspec:CCRAW [(match_dup 1) | |
1587 (match_dup 2) | |
1588 (match_dup 3) | |
1589 (match_dup 4)] | |
1590 UNSPEC_VEC_VSTRCCC))]) | |
1591 (set (match_operand:SI 5 "memory_operand" "") | |
1592 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1593 "TARGET_VX" | |
1594 { | |
1595 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS); | |
1596 }) | |
1597 | |
1598 (define_insn "vcdgb" | |
1599 [(set (match_operand:V2DF 0 "register_operand" "=v") | |
1600 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "v") | |
1601 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression | |
1602 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode | |
1603 UNSPEC_VEC_VCDGB))] | |
1604 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7" | |
1605 "vcdgb\t%v0,%v1,%b2,%b3" | |
1606 [(set_attr "op_type" "VRR")]) | |
1607 | |
1608 | |
1609 ; The result needs to be multiplied with 2**-op2 | |
1610 (define_expand "vec_ctd_s64" | |
1611 [(set (match_operand:V2DF 0 "register_operand" "") | |
1612 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "") | |
1613 (const_int 4) ; inexact suppressed | |
1614 (const_int VEC_RND_CURRENT)] | |
1615 UNSPEC_VEC_VCDGB)) | |
1616 (use (match_operand:QI 2 "const_int_operand" "")) | |
1617 (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))] | |
1618 "TARGET_VX" | |
1619 { | |
1620 REAL_VALUE_TYPE f; | |
1621 rtx c; | |
1622 | |
1623 real_2expN (&f, -INTVAL (operands[2]), DFmode); | |
1624 c = const_double_from_real_value (f, DFmode); | |
1625 | |
1626 operands[3] = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, c, c)); | |
1627 operands[3] = force_reg (V2DFmode, operands[3]); | |
1628 }) | |
1629 | |
1630 (define_insn "vcdlgb" | |
1631 [(set (match_operand:V2DF 0 "register_operand" "=v") | |
1632 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "v") | |
1633 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression | |
1634 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode | |
1635 UNSPEC_VEC_VCDLGB))] | |
1636 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7" | |
1637 "vcdlgb\t%v0,%v1,%b2,%b3" | |
1638 [(set_attr "op_type" "VRR")]) | |
1639 | |
1640 ; The result needs to be multiplied with 2**-op2 | |
1641 (define_expand "vec_ctd_u64" | |
1642 [(set (match_operand:V2DF 0 "register_operand" "") | |
1643 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "") | |
1644 (const_int 4) ; inexact suppressed | |
1645 (const_int VEC_RND_CURRENT)] | |
1646 UNSPEC_VEC_VCDLGB)) | |
1647 (use (match_operand:QI 2 "const_int_operand" "")) | |
1648 (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))] | |
1649 "TARGET_VX" | |
1650 { | |
1651 REAL_VALUE_TYPE f; | |
1652 rtx c; | |
1653 | |
1654 real_2expN (&f, -INTVAL (operands[2]), DFmode); | |
1655 c = const_double_from_real_value (f, DFmode); | |
1656 | |
1657 operands[3] = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, c, c)); | |
1658 operands[3] = force_reg (V2DFmode, operands[3]); | |
1659 }) | |
1660 | |
1661 (define_insn "vcgdb" | |
1662 [(set (match_operand:V2DI 0 "register_operand" "=v") | |
1663 (unspec:V2DI [(match_operand:V2DF 1 "register_operand" "v") | |
1664 (match_operand:QI 2 "const_mask_operand" "C") | |
1665 (match_operand:QI 3 "const_mask_operand" "C")] | |
1666 UNSPEC_VEC_VCGDB))] | |
1667 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7" | |
1668 "vcgdb\t%v0,%v1,%b2,%b3" | |
1669 [(set_attr "op_type" "VRR")]) | |
1670 | |
1671 ; The input needs to be multiplied with 2**op2 | |
1672 (define_expand "vec_ctsl" | |
1673 [(use (match_operand:QI 2 "const_int_operand" "")) | |
1674 (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "") | |
1675 (match_dup 3))) | |
1676 (set (match_operand:V2DI 0 "register_operand" "") | |
1677 (unspec:V2DI [(match_dup 4) | |
1678 (const_int 4) ; inexact suppressed | |
1679 (const_int VEC_RND_CURRENT)] | |
1680 UNSPEC_VEC_VCGDB))] | |
1681 "TARGET_VX" | |
1682 { | |
1683 REAL_VALUE_TYPE f; | |
1684 rtx c; | |
1685 | |
1686 real_2expN (&f, INTVAL (operands[2]), DFmode); | |
1687 c = const_double_from_real_value (f, DFmode); | |
1688 | |
1689 operands[3] = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, c, c)); | |
1690 operands[3] = force_reg (V2DFmode, operands[3]); | |
1691 operands[4] = gen_reg_rtx (V2DFmode); | |
1692 }) | |
1693 | |
1694 (define_insn "vclgdb" | |
1695 [(set (match_operand:V2DI 0 "register_operand" "=v") | |
1696 (unspec:V2DI [(match_operand:V2DF 1 "register_operand" "v") | |
1697 (match_operand:QI 2 "const_mask_operand" "C") | |
1698 (match_operand:QI 3 "const_mask_operand" "C")] | |
1699 UNSPEC_VEC_VCLGDB))] | |
1700 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7" | |
1701 "vclgdb\t%v0,%v1,%b2,%b3" | |
1702 [(set_attr "op_type" "VRR")]) | |
1703 | |
1704 ; The input needs to be multiplied with 2**op2 | |
1705 (define_expand "vec_ctul" | |
1706 [(use (match_operand:QI 2 "const_int_operand" "")) | |
1707 (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "") | |
1708 (match_dup 3))) | |
1709 (set (match_operand:V2DI 0 "register_operand" "") | |
1710 (unspec:V2DI [(match_dup 4) | |
1711 (const_int 4) ; inexact suppressed | |
1712 (const_int VEC_RND_CURRENT)] | |
1713 UNSPEC_VEC_VCLGDB))] | |
1714 "TARGET_VX" | |
1715 { | |
1716 REAL_VALUE_TYPE f; | |
1717 rtx c; | |
1718 | |
1719 real_2expN (&f, INTVAL (operands[2]), DFmode); | |
1720 c = const_double_from_real_value (f, DFmode); | |
1721 | |
1722 operands[3] = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, c, c)); | |
1723 operands[3] = force_reg (V2DFmode, operands[3]); | |
1724 operands[4] = gen_reg_rtx (V2DFmode); | |
1725 }) | |
1726 | |
1727 ; Vector load fp integer - IEEE inexact exception is suppressed | |
1728 ; vfisb, vfidb, wfisb, wfidb, wfixb | |
1729 (define_insn "vec_fpint<mode>" | |
1730 [(set (match_operand:VFT 0 "register_operand" "=v") | |
1731 (unspec:VFT [(match_operand:VFT 1 "register_operand" "v") | |
1732 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression control | |
1733 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode | |
1734 UNSPEC_VEC_VFI))] | |
1735 "TARGET_VX" | |
1736 "<vw>fi<sdx>b\t%v0,%v1,%b2,%b3" | |
1737 [(set_attr "op_type" "VRR")]) | |
1738 | |
1739 | |
1740 ; Vector load lengthened - V4SF -> V2DF | |
1741 | |
1742 (define_insn "vflls" | |
1743 [(set (match_operand:V2DF 0 "register_operand" "=v") | |
1744 (unspec:V2DF [(match_operand:V4SF 1 "register_operand" "v")] | |
1745 UNSPEC_VEC_VFLL))] | |
1746 "TARGET_VX" | |
1747 "vldeb\t%v0,%v1" | |
1748 [(set_attr "op_type" "VRR")]) | |
1749 | |
1750 (define_expand "vec_ld2f" | |
1751 [; Initialize a vector to all zeroes. FIXME: This should not be | |
1752 ; necessary since all elements of the vector will be set anyway. | |
1753 ; This is just to make it explicit to the data flow framework. | |
1754 (set (match_dup 2) (match_dup 3)) | |
1755 (set (match_dup 2) (unspec:V4SF [(match_operand:SF 1 "memory_operand" "") | |
1756 (const_int 0) | |
1757 (match_dup 2)] | |
1758 UNSPEC_VEC_SET)) | |
1759 (set (match_dup 2) (unspec:V4SF [(match_dup 4) | |
1760 (const_int 2) | |
1761 (match_dup 2)] | |
1762 UNSPEC_VEC_SET)) | |
1763 (set (match_operand:V2DF 0 "register_operand" "") | |
1764 (unspec:V2DF [(match_dup 2)] UNSPEC_VEC_VFLL))] | |
1765 "TARGET_VX" | |
1766 { | |
1767 operands[2] = gen_reg_rtx (V4SFmode); | |
1768 operands[3] = CONST0_RTX (V4SFmode); | |
1769 operands[4] = adjust_address (operands[1], SFmode, 4); | |
1770 }) | |
1771 | |
1772 | |
1773 ; Vector load rounded - V2DF -> V4SF | |
1774 | |
1775 (define_insn "vflrd" | |
1776 [(set (match_operand:V4SF 0 "register_operand" "=v") | |
1777 (unspec:V4SF [(match_operand:V2DF 1 "register_operand" "v") | |
1778 (match_operand:QI 2 "const_mask_operand" "C") | |
1779 (match_operand:QI 3 "const_mask_operand" "C")] | |
1780 UNSPEC_VEC_VFLR))] | |
1781 "TARGET_VX" | |
1782 "vledb\t%v0,%v1,%b2,%b3" | |
1783 [(set_attr "op_type" "VRR")]) | |
1784 | |
1785 (define_expand "vec_st2f" | |
1786 [(set (match_dup 2) | |
1787 (unspec:V4SF [(match_operand:V2DF 0 "register_operand" "") | |
1788 (const_int VEC_INEXACT) | |
1789 (const_int VEC_RND_CURRENT)] | |
1790 UNSPEC_VEC_VFLR)) | |
1791 (set (match_operand:SF 1 "memory_operand" "") | |
1792 (unspec:SF [(match_dup 2) (const_int 0)] UNSPEC_VEC_EXTRACT)) | |
1793 (set (match_dup 3) | |
1794 (unspec:SF [(match_dup 2) (const_int 2)] UNSPEC_VEC_EXTRACT))] | |
1795 "TARGET_VX" | |
1796 { | |
1797 operands[2] = gen_reg_rtx (V4SFmode); | |
1798 operands[3] = adjust_address (operands[1], SFmode, 4); | |
1799 }) | |
1800 | |
1801 | |
1802 ; Vector square root fp vec_sqrt -> sqrt rtx standard name | |
1803 | |
1804 ;; Vector FP test data class immediate | |
1805 | |
1806 ; vec_all_nan, vec_all_numeric, vec_any_nan, vec_any_numeric | |
1807 ; These ignore the vector result and only want CC stored to an int | |
1808 ; pointer. | |
1809 | |
1810 ; vftcisb, vftcidb | |
1811 (define_insn "*vftci<mode>_cconly" | |
1812 [(set (reg:CCRAW CC_REGNUM) | |
1813 (unspec:CCRAW [(match_operand:VECF_HW 1 "register_operand") | |
1814 (match_operand:HI 2 "const_int_operand")] | |
1815 UNSPEC_VEC_VFTCICC)) | |
1816 (clobber (match_scratch:<tointvec> 0))] | |
1817 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")" | |
1818 "vftci<sdx>b\t%v0,%v1,%x2" | |
1819 [(set_attr "op_type" "VRR")]) | |
1820 | |
1821 (define_expand "vftci<mode>_intcconly" | |
1822 [(parallel | |
1823 [(set (reg:CCRAW CC_REGNUM) | |
1824 (unspec:CCRAW [(match_operand:VECF_HW 0 "register_operand") | |
1825 (match_operand:HI 1 "const_int_operand")] | |
1826 UNSPEC_VEC_VFTCICC)) | |
1827 (clobber (scratch:<tointvec>))]) | |
1828 (set (match_operand:SI 2 "register_operand" "") | |
1829 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1830 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")") | |
1831 | |
1832 ; vec_fp_test_data_class wants the result vector and the CC stored to | |
1833 ; an int pointer. | |
1834 | |
1835 ; vftcisb, vftcidb | |
1836 (define_insn "*vftci<mode>" | |
1837 [(set (match_operand:VECF_HW 0 "register_operand" "=v") | |
1838 (unspec:VECF_HW [(match_operand:VECF_HW 1 "register_operand" "v") | |
1839 (match_operand:HI 2 "const_int_operand" "J")] | |
1840 UNSPEC_VEC_VFTCI)) | |
1841 (set (reg:CCRAW CC_REGNUM) | |
1842 (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))] | |
1843 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")" | |
1844 "vftci<sdx>b\t%v0,%v1,%x2" | |
1845 [(set_attr "op_type" "VRR")]) | |
1846 | |
1847 (define_expand "vftci<mode>_intcc" | |
1848 [(parallel | |
1849 [(set (match_operand:VECF_HW 0 "register_operand") | |
1850 (unspec:VECF_HW [(match_operand:VECF_HW 1 "register_operand") | |
1851 (match_operand:HI 2 "const_int_operand")] | |
1852 UNSPEC_VEC_VFTCI)) | |
1853 (set (reg:CCRAW CC_REGNUM) | |
1854 (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))]) | |
1855 (set (match_operand:SI 3 "memory_operand" "") | |
1856 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1857 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")") | |
1858 | |
1859 ;; | |
1860 ;; Integer compares | |
1861 ;; | |
1862 | |
1863 ; All comparisons which produce a CC need fully populated (VI_HW) | |
1864 ; vector arguments. Otherwise the any/all CCs would be just bogus. | |
1865 | |
1866 (define_insn "*vec_cmp<VICMP:insn_cmp><VI_HW:mode>_cconly" | |
1867 [(set (reg:VICMP CC_REGNUM) | |
1868 (compare:VICMP (match_operand:VI_HW 0 "register_operand" "v") | |
1869 (match_operand:VI_HW 1 "register_operand" "v"))) | |
1870 (clobber (match_scratch:VI_HW 2 "=v"))] | |
1871 "TARGET_VX" | |
1872 "vc<VICMP:insn_cmp><VI_HW:bhfgq>s\t%v2,%v0,%v1" | |
1873 [(set_attr "op_type" "VRR")]) | |
1874 | |
1875 ; FIXME: The following 2x3 definitions should be merged into 2 with | |
1876 ; VICMP like above but I could not find a way to set the comparison | |
1877 ; operator (eq) depending on the mode CCVEQ (mode_iterator). Or the | |
1878 ; other way around - setting the mode depending on the code | |
1879 ; (code_iterator). | |
1880 (define_expand "vec_cmpeq<VI_HW:mode>_cc" | |
1881 [(parallel | |
1882 [(set (reg:CCVEQ CC_REGNUM) | |
1883 (compare:CCVEQ (match_operand:VI_HW 1 "register_operand" "v") | |
1884 (match_operand:VI_HW 2 "register_operand" "v"))) | |
1885 (set (match_operand:VI_HW 0 "register_operand" "=v") | |
1886 (eq:VI_HW (match_dup 1) (match_dup 2)))]) | |
1887 (set (match_operand:SI 3 "memory_operand" "") | |
1888 (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1889 "TARGET_VX") | |
1890 | |
1891 (define_expand "vec_cmph<VI_HW:mode>_cc" | |
1892 [(parallel | |
1893 [(set (reg:CCVIH CC_REGNUM) | |
1894 (compare:CCVIH (match_operand:VI_HW 1 "register_operand" "v") | |
1895 (match_operand:VI_HW 2 "register_operand" "v"))) | |
1896 (set (match_operand:VI_HW 0 "register_operand" "=v") | |
1897 (gt:VI_HW (match_dup 1) (match_dup 2)))]) | |
1898 (set (match_operand:SI 3 "memory_operand" "") | |
1899 (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1900 "TARGET_VX") | |
1901 | |
1902 (define_expand "vec_cmphl<VI_HW:mode>_cc" | |
1903 [(parallel | |
1904 [(set (reg:CCVIHU CC_REGNUM) | |
1905 (compare:CCVIHU (match_operand:VI_HW 1 "register_operand" "v") | |
1906 (match_operand:VI_HW 2 "register_operand" "v"))) | |
1907 (set (match_operand:VI_HW 0 "register_operand" "=v") | |
1908 (gtu:VI_HW (match_dup 1) (match_dup 2)))]) | |
1909 (set (match_operand:SI 3 "memory_operand" "") | |
1910 (unspec:SI [(reg:CCVIHU CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1911 "TARGET_VX") | |
1912 | |
1913 | |
1914 (define_insn "*vec_cmpeq<VI_HW:mode>_cc" | |
1915 [(set (reg:CCVEQ CC_REGNUM) | |
1916 (compare:CCVEQ (match_operand:VI_HW 0 "register_operand" "v") | |
1917 (match_operand:VI_HW 1 "register_operand" "v"))) | |
1918 (set (match_operand:VI_HW 2 "register_operand" "=v") | |
1919 (eq:VI_HW (match_dup 0) (match_dup 1)))] | |
1920 "TARGET_VX" | |
1921 "vceq<VI_HW:bhfgq>s\t%v2,%v0,%v1" | |
1922 [(set_attr "op_type" "VRR")]) | |
1923 | |
1924 (define_insn "*vec_cmph<VI_HW:mode>_cc" | |
1925 [(set (reg:CCVIH CC_REGNUM) | |
1926 (compare:CCVIH (match_operand:VI_HW 0 "register_operand" "v") | |
1927 (match_operand:VI_HW 1 "register_operand" "v"))) | |
1928 (set (match_operand:VI_HW 2 "register_operand" "=v") | |
1929 (gt:VI_HW (match_dup 0) (match_dup 1)))] | |
1930 "TARGET_VX" | |
1931 "vch<VI_HW:bhfgq>s\t%v2,%v0,%v1" | |
1932 [(set_attr "op_type" "VRR")]) | |
1933 | |
1934 (define_insn "*vec_cmphl<VI_HW:mode>_cc" | |
1935 [(set (reg:CCVIHU CC_REGNUM) | |
1936 (compare:CCVIHU (match_operand:VI_HW 0 "register_operand" "v") | |
1937 (match_operand:VI_HW 1 "register_operand" "v"))) | |
1938 (set (match_operand:VI_HW 2 "register_operand" "=v") | |
1939 (gtu:VI_HW (match_dup 0) (match_dup 1)))] | |
1940 "TARGET_VX" | |
1941 "vchl<VI_HW:bhfgq>s\t%v2,%v0,%v1" | |
1942 [(set_attr "op_type" "VRR")]) | |
1943 | |
1944 ;; | |
1945 ;; Floating point compares | |
1946 ;; | |
1947 | |
1948 ; vfcesbs, vfcedbs, wfcexbs, vfchsbs, vfchdbs, wfchxbs, vfchesbs, vfchedbs, wfchexbs | |
1949 (define_insn "*vec_cmp<insn_cmp><mode>_cconly" | |
1950 [(set (reg:VFCMP CC_REGNUM) | |
1951 (compare:VFCMP (match_operand:VF_HW 0 "register_operand" "v") | |
1952 (match_operand:VF_HW 1 "register_operand" "v"))) | |
1953 (clobber (match_scratch:<tointvec> 2 "=v"))] | |
1954 "TARGET_VX" | |
1955 "<vw>fc<asm_fcmp><sdx>bs\t%v2,%v0,%v1" | |
1956 [(set_attr "op_type" "VRR")]) | |
1957 | |
1958 ; FIXME: Merge the following 2x3 patterns with VFCMP | |
1959 (define_expand "vec_cmpeq<mode>_cc" | |
1960 [(parallel | |
1961 [(set (reg:CCVEQ CC_REGNUM) | |
1962 (compare:CCVEQ (match_operand:VF_HW 1 "register_operand" "v") | |
1963 (match_operand:VF_HW 2 "register_operand" "v"))) | |
1964 (set (match_operand:<tointvec> 0 "register_operand" "=v") | |
1965 (eq:<tointvec> (match_dup 1) (match_dup 2)))]) | |
1966 (set (match_operand:SI 3 "memory_operand" "") | |
1967 (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1968 "TARGET_VX") | |
1969 | |
1970 (define_expand "vec_cmph<mode>_cc" | |
1971 [(parallel | |
1972 [(set (reg:CCVFH CC_REGNUM) | |
1973 (compare:CCVFH (match_operand:VF_HW 1 "register_operand" "v") | |
1974 (match_operand:VF_HW 2 "register_operand" "v"))) | |
1975 (set (match_operand:<tointvec> 0 "register_operand" "=v") | |
1976 (gt:<tointvec> (match_dup 1) (match_dup 2)))]) | |
1977 (set (match_operand:SI 3 "memory_operand" "") | |
1978 (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1979 "TARGET_VX") | |
1980 | |
1981 (define_expand "vec_cmphe<mode>_cc" | |
1982 [(parallel | |
1983 [(set (reg:CCVFHE CC_REGNUM) | |
1984 (compare:CCVFHE (match_operand:VF_HW 1 "register_operand" "v") | |
1985 (match_operand:VF_HW 2 "register_operand" "v"))) | |
1986 (set (match_operand:<tointvec> 0 "register_operand" "=v") | |
1987 (ge:<tointvec> (match_dup 1) (match_dup 2)))]) | |
1988 (set (match_operand:SI 3 "memory_operand" "") | |
1989 (unspec:SI [(reg:CCVFHE CC_REGNUM)] UNSPEC_CC_TO_INT))] | |
1990 "TARGET_VX") | |
1991 | |
1992 ; These 3 cannot be merged as the insn defintion above since it also | |
1993 ; requires to rewrite the RTL equality operator that the same time as | |
1994 ; the CC mode. | |
1995 | |
1996 ; vfcesbs, vfcedbs, wfcexbs | |
1997 (define_insn "*vec_cmpeq<mode>_cc" | |
1998 [(set (reg:CCVEQ CC_REGNUM) | |
1999 (compare:CCVEQ (match_operand:VF_HW 0 "register_operand" "v") | |
2000 (match_operand:VF_HW 1 "register_operand" "v"))) | |
2001 (set (match_operand:<tointvec> 2 "register_operand" "=v") | |
2002 (eq:<tointvec> (match_dup 0) (match_dup 1)))] | |
2003 "TARGET_VX" | |
2004 "<vw>fce<sdx>bs\t%v2,%v0,%v1" | |
2005 [(set_attr "op_type" "VRR")]) | |
2006 | |
2007 ; vfchsbs, vfchdbs, wfchxbs | |
2008 (define_insn "*vec_cmph<mode>_cc" | |
2009 [(set (reg:CCVFH CC_REGNUM) | |
2010 (compare:CCVFH (match_operand:VF_HW 0 "register_operand" "v") | |
2011 (match_operand:VF_HW 1 "register_operand" "v"))) | |
2012 (set (match_operand:<tointvec> 2 "register_operand" "=v") | |
2013 (gt:<tointvec> (match_dup 0) (match_dup 1)))] | |
2014 "TARGET_VX" | |
2015 "<vw>fch<sdx>bs\t%v2,%v0,%v1" | |
2016 [(set_attr "op_type" "VRR")]) | |
2017 | |
2018 ; vfchesbs, vfchedbs, wfchexbs | |
2019 (define_insn "*vec_cmphe<mode>_cc" | |
2020 [(set (reg:CCVFHE CC_REGNUM) | |
2021 (compare:CCVFHE (match_operand:VF_HW 0 "register_operand" "v") | |
2022 (match_operand:VF_HW 1 "register_operand" "v"))) | |
2023 (set (match_operand:<tointvec> 2 "register_operand" "=v") | |
2024 (ge:<tointvec> (match_dup 0) (match_dup 1)))] | |
2025 "TARGET_VX" | |
2026 "<vw>fche<sdx>bs\t%v2,%v0,%v1" | |
2027 [(set_attr "op_type" "VRR")]) | |
2028 | |
2029 (define_expand "vec_double_s64" | |
2030 [(set (match_operand:V2DF 0 "register_operand") | |
2031 (unspec:V2DF [(match_operand:V2DI 1 "register_operand") | |
2032 (const_int 0) ; inexact suppression disabled | |
2033 (const_int VEC_RND_CURRENT)] | |
2034 UNSPEC_VEC_VCDGB))] | |
2035 "TARGET_VX") | |
2036 | |
2037 (define_expand "vec_double_u64" | |
2038 [(set (match_operand:V2DF 0 "register_operand") | |
2039 (unspec:V2DF [(match_operand:V2DI 1 "register_operand") | |
2040 (const_int 0) ; inexact suppression disabled | |
2041 (const_int VEC_RND_CURRENT)] | |
2042 UNSPEC_VEC_VCDLGB))] | |
2043 "TARGET_VX") | |
2044 | |
2045 | |
2046 (define_insn "vfmin<mode>" | |
2047 [(set (match_operand:VF_HW 0 "register_operand" "=v") | |
2048 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "%v") | |
2049 (match_operand:VF_HW 2 "register_operand" "v") | |
2050 (match_operand:QI 3 "const_mask_operand" "C")] | |
2051 UNSPEC_VEC_VFMIN))] | |
2052 "TARGET_VXE" | |
2053 "<vw>fmin<sdx>b\t%v0,%v1,%v2,%b3" | |
2054 [(set_attr "op_type" "VRR")]) | |
2055 | |
2056 (define_insn "vfmax<mode>" | |
2057 [(set (match_operand:VF_HW 0 "register_operand" "=v") | |
2058 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "%v") | |
2059 (match_operand:VF_HW 2 "register_operand" "v") | |
2060 (match_operand:QI 3 "const_mask_operand" "C")] | |
2061 UNSPEC_VEC_VFMAX))] | |
2062 "TARGET_VXE" | |
2063 "<vw>fmax<sdx>b\t%v0,%v1,%v2,%b3" | |
2064 [(set_attr "op_type" "VRR")]) |