[PR testsuite/116860] Testsuite adjustment for recently added tests
[official-gcc.git] / gcc / config / loongarch / lsx.md
blobca0066a21ed61b1fb5c7bf88dbd9b798fc67b3f1
1 ;; Machine Description for LARCH Loongson SX ASE
2 ;;
3 ;; Copyright (C) 2018-2025 Free Software Foundation, Inc.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
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/>.
22 (define_c_enum "unspec" [
23   UNSPEC_LSX_VAVG_S
24   UNSPEC_LSX_VAVG_U
25   UNSPEC_LSX_VAVGR_S
26   UNSPEC_LSX_VAVGR_U
27   UNSPEC_LSX_VBITCLR
28   UNSPEC_LSX_VBITCLRI
29   UNSPEC_LSX_VBITREV
30   UNSPEC_LSX_VBITREVI
31   UNSPEC_LSX_VBITSET
32   UNSPEC_LSX_VBITSETI
33   UNSPEC_LSX_BRANCH_V
34   UNSPEC_LSX_BRANCH
35   UNSPEC_LSX_VFCLASS
36   UNSPEC_LSX_VFCVT
37   UNSPEC_LSX_VFCVTH
38   UNSPEC_LSX_VFCVTL
39   UNSPEC_LSX_VFLOGB
40   UNSPEC_LSX_VFRECIPE
41   UNSPEC_LSX_VFRSQRT
42   UNSPEC_LSX_VFRSQRTE
43   UNSPEC_LSX_VFTINT_U
44   UNSPEC_LSX_VSAT_S
45   UNSPEC_LSX_VSAT_U
46   UNSPEC_LSX_VSRAR
47   UNSPEC_LSX_VSRARI
48   UNSPEC_LSX_VSRLR
49   UNSPEC_LSX_VSRLRI
50   UNSPEC_LSX_VSHUF
51   UNSPEC_LSX_VEXTW_S
52   UNSPEC_LSX_VEXTW_U
53   UNSPEC_LSX_VSLLWIL_S
54   UNSPEC_LSX_VSLLWIL_U
55   UNSPEC_LSX_VSRAN
56   UNSPEC_LSX_VSSRAN_S
57   UNSPEC_LSX_VSSRAN_U
58   UNSPEC_LSX_VSRAIN
59   UNSPEC_LSX_VSRAINS_S
60   UNSPEC_LSX_VSRAINS_U
61   UNSPEC_LSX_VSRARN
62   UNSPEC_LSX_VSRLN
63   UNSPEC_LSX_VSRLRN
64   UNSPEC_LSX_VSSRLRN_U
65   UNSPEC_LSX_VFRSTPI
66   UNSPEC_LSX_VFRSTP
67   UNSPEC_LSX_VSHUF4I
68   UNSPEC_LSX_VBSRL_V
69   UNSPEC_LSX_VBSLL_V
70   UNSPEC_LSX_VEXTRINS
71   UNSPEC_LSX_VMSKLTZ
72   UNSPEC_LSX_VSIGNCOV
73   UNSPEC_LSX_VFTINT_W_D
74   UNSPEC_LSX_VFTINTRP_W_D
75   UNSPEC_LSX_VFTINTRM_W_D
76   UNSPEC_LSX_VFTINTRNE_W_D
77   UNSPEC_LSX_VFTINTL_L_S
78   UNSPEC_LSX_VFTINTRPL_L_S
79   UNSPEC_LSX_VFTINTRPH_L_S
80   UNSPEC_LSX_VFTINTRMH_L_S
81   UNSPEC_LSX_VFTINTRML_L_S
82   UNSPEC_LSX_VFTINTRNEL_L_S
83   UNSPEC_LSX_VFTINTRNEH_L_S
84   UNSPEC_LSX_VFTINTH_L_H
85   UNSPEC_LSX_VSSRARN_S
86   UNSPEC_LSX_VSSRARN_U
87   UNSPEC_LSX_VSSRLN_U
88   UNSPEC_LSX_VSSRLN
89   UNSPEC_LSX_VSSRLRN
90   UNSPEC_LSX_VLDI
91   UNSPEC_LSX_VSHUF_B
92   UNSPEC_LSX_VLDX
93   UNSPEC_LSX_VSTX
94   UNSPEC_LSX_VEXTL_QU_DU
95   UNSPEC_LSX_VSETEQZ_V
96   UNSPEC_LSX_VADDWEV
97   UNSPEC_LSX_VADDWEV2
98   UNSPEC_LSX_VADDWEV3
99   UNSPEC_LSX_VADDWOD
100   UNSPEC_LSX_VADDWOD2
101   UNSPEC_LSX_VADDWOD3
102   UNSPEC_LSX_VSUBWEV
103   UNSPEC_LSX_VSUBWEV2
104   UNSPEC_LSX_VSUBWOD
105   UNSPEC_LSX_VSUBWOD2
106   UNSPEC_LSX_VMULWEV
107   UNSPEC_LSX_VMULWEV2
108   UNSPEC_LSX_VMULWEV3
109   UNSPEC_LSX_VMULWOD
110   UNSPEC_LSX_VMULWOD2
111   UNSPEC_LSX_VMULWOD3
112   UNSPEC_LSX_VHADDW_Q_D
113   UNSPEC_LSX_VHADDW_QU_DU
114   UNSPEC_LSX_VHSUBW_Q_D
115   UNSPEC_LSX_VHSUBW_QU_DU
116   UNSPEC_LSX_VMADDWEV
117   UNSPEC_LSX_VMADDWEV2
118   UNSPEC_LSX_VMADDWEV3
119   UNSPEC_LSX_VMADDWOD
120   UNSPEC_LSX_VMADDWOD2
121   UNSPEC_LSX_VMADDWOD3
122   UNSPEC_LSX_VADD_Q
123   UNSPEC_LSX_VSUB_Q
124   UNSPEC_LSX_VEXTH_Q_D
125   UNSPEC_LSX_VEXTH_QU_DU
126   UNSPEC_LSX_VMSKGEZ
127   UNSPEC_LSX_VMSKNZ
128   UNSPEC_LSX_VEXTL_Q_D
129   UNSPEC_LSX_VSRLNI
130   UNSPEC_LSX_VSRLRNI
131   UNSPEC_LSX_VSSRLNI
132   UNSPEC_LSX_VSSRLNI2
133   UNSPEC_LSX_VSSRLRNI
134   UNSPEC_LSX_VSSRLRNI2
135   UNSPEC_LSX_VSRANI
136   UNSPEC_LSX_VSRARNI
137   UNSPEC_LSX_VSSRANI
138   UNSPEC_LSX_VSSRANI2
139   UNSPEC_LSX_VSSRARNI
140   UNSPEC_LSX_VSSRARNI2
141   UNSPEC_LSX_VPERMI
142   UNSPEC_LSX_VILVL_INTERNAL
143   UNSPEC_LSX_VREPLVEI_MIRROR
146 ;; This attribute gives suffix for integers in VHMODE.
147 (define_mode_attr dlsxfmt
148   [(V2DI "q")
149    (V4SI "d")
150    (V8HI "w")
151    (V16QI "h")])
153 (define_mode_attr dlsxfmt_u
154   [(V2DI "qu")
155    (V4SI "du")
156    (V8HI "wu")
157    (V16QI "hu")])
159 ;; Only used for vilvh and splitting insert_d and copy_{u,s}.d.
160 (define_mode_iterator LSX_D    [V2DI V2DF])
162 ;; Only used for copy_{u,s}.w and vilvh.
163 (define_mode_iterator LSX_W    [V4SI V4SF])
165 ;; As ILSX but excludes V16QI.
166 (define_mode_iterator ILSX_DWH [V2DI V4SI V8HI])
168 ;; As LSX but excludes V16QI.
169 (define_mode_iterator LSX_DWH  [V2DF V4SF V2DI V4SI V8HI])
171 ;; As ILSX but excludes V2DI.
172 (define_mode_iterator ILSX_WHB [V4SI V8HI V16QI])
174 ;; Only integer modes equal or larger than a word.
175 (define_mode_iterator ILSX_DW  [V2DI V4SI])
177 ;; Only integer modes smaller than a word.
178 (define_mode_iterator ILSX_HB  [V8HI V16QI])
180 ;;;; Only integer modes for fixed-point madd_q/maddr_q.
181 ;;(define_mode_iterator ILSX_WH  [V4SI V8HI])
183 ;; Only used for immediate set shuffle elements instruction.
184 (define_mode_iterator LSX_WHB_W [V4SI V8HI V16QI V4SF])
186 ;; The attribute gives half modes for vector modes.
187 (define_mode_attr VHMODE
188   [(V8HI "V16QI")
189    (V4SI "V8HI")
190    (V2DI "V4SI")])
192 ;; Signed and unsigned max operations.
193 (define_code_iterator SU_MAX [smax umax])
195 (define_code_attr su_min [(smax "smin") (umax "umin")])
197 ;; The attribute gives double modes for vector modes.
198 (define_mode_attr VDMODE
199   [(V2DI "V2DI")
200    (V4SI "V2DI")
201    (V8HI "V4SI")
202    (V16QI "V8HI")])
204 ;; The attribute gives half modes with same number of elements for vector modes.
205 (define_mode_attr VTRUNCMODE
206   [(V8HI "V8QI")
207    (V4SI "V4HI")
208    (V2DI "V2SI")])
210 ;; Double-sized Vector MODE with same elemet type. "Vector, Enlarged-MODE"
211 (define_mode_attr VEMODE
212   [(V4SF "V8SF")
213    (V4SI "V8SI")
214    (V2DI "V4DI")
215    (V2DF "V4DF")])
217 ;; This attribute gives the mode of the result for "vpickve2gr_b, copy_u_b" etc.
218 (define_mode_attr VRES
219   [(V2DF "DF")
220    (V4SF "SF")
221    (V2DI "DI")
222    (V4SI "SI")
223    (V8HI "SI")
224    (V16QI "SI")])
226 ;; Only used with LSX_D iterator.
227 (define_mode_attr lsx_d
228   [(V2DI "reg_or_0")
229    (V2DF "register")])
231 ;; This attribute gives the integer vector mode with same size.
232 (define_mode_attr mode_i
233   [(V2DF "v2di")
234    (V4SF "v4si")
235    (V2DI "v2di")
236    (V4SI "v4si")
237    (V8HI "v8hi")
238    (V16QI "v16qi")])
240 ;; This attribute gives suffix for LSX instructions.
241 (define_mode_attr lsxfmt
242   [(V2DF "d")
243    (V4SF "w")
244    (V2DI "d")
245    (V4SI "w")
246    (V8HI "h")
247    (V16QI "b")])
249 ;; This attribute gives suffix for LSX instructions.
250 (define_mode_attr lsxfmt_u
251   [(V2DF "du")
252    (V4SF "wu")
253    (V2DI "du")
254    (V4SI "wu")
255    (V8HI "hu")
256    (V16QI "bu")])
258 ;; This attribute gives suffix for integers in VHMODE.
259 (define_mode_attr hlsxfmt
260   [(V2DI "w")
261    (V4SI "h")
262    (V8HI "b")])
264 ;; This attribute gives suffix for integers in VHMODE.
265 (define_mode_attr hlsxfmt_u
266   [(V2DI "wu")
267    (V4SI "hu")
268    (V8HI "bu")])
270 ;; This attribute gives define_insn suffix for LSX instructions that need
271 ;; distinction between integer and floating point.
272 (define_mode_attr lsxfmt_f
273   [(V2DF "d_f")
274    (V4SF "w_f")
275    (V2DI "d")
276    (V4SI "w")
277    (V8HI "h")
278    (V16QI "b")])
280 (define_mode_attr flsxfmt
281   [(V2DF "d")
282    (V4SF "s")
283    (V2DI "d")
284    (V4SI "s")])
286 (define_mode_attr ilsxfmt
287   [(V2DF "l")
288    (V4SF "w")])
290 (define_mode_attr ilsxfmt_u
291   [(V2DF "lu")
292    (V4SF "wu")])
294 ;; This is used to form an immediate operand constraint using
295 ;; "const_<indeximm>_operand".
296 (define_mode_attr indeximm
297   [(V2DF "0_or_1")
298    (V4SF "0_to_3")
299    (V2DI "0_or_1")
300    (V4SI "0_to_3")
301    (V8HI "uimm3")
302    (V16QI "uimm4")])
304 ;; This attribute represents bitmask needed for vec_merge using
305 ;; "const_<bitmask>_operand".
306 (define_mode_attr bitmask
307   [(V2DF "exp_2")
308    (V4SF "exp_4")
309    (V2DI "exp_2")
310    (V4SI "exp_4")
311    (V8HI "exp_8")
312    (V16QI "exp_16")])
314 (define_expand "vec_init<mode><unitmode>"
315   [(match_operand:LSX 0 "register_operand")
316    (match_operand:LSX 1 "")]
317   "ISA_HAS_LSX"
319   loongarch_expand_vector_init (operands[0], operands[1]);
320   DONE;
323 ;; vpickev pattern with implicit type conversion.
324 (define_insn "vec_pack_trunc_<mode>"
325   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
326         (vec_concat:<VHMODE>
327           (truncate:<VTRUNCMODE>
328             (match_operand:ILSX_DWH 1 "register_operand" "f"))
329           (truncate:<VTRUNCMODE>
330             (match_operand:ILSX_DWH 2 "register_operand" "f"))))]
331   "ISA_HAS_LSX"
332   "vpickev.<hlsxfmt>\t%w0,%w2,%w1"
333   [(set_attr "type" "simd_permute")
334    (set_attr "mode" "<MODE>")])
336 (define_expand "vec_unpacks_lo_<mode>"
337   [(match_operand:<VDMODE> 0 "register_operand")
338    (match_operand:ILSX_WHB 1 "register_operand")]
339   "ISA_HAS_LSX"
341   if (ISA_HAS_LASX)
342     emit_insn (gen_vec_unpacks_lo_<mode>_internal (operands[0], operands[1]));
343   else
344     loongarch_expand_vec_unpack (operands, false/*unsigned_p*/);
345   DONE;
348 (define_expand "vec_unpacku_lo_<mode>"
349   [(match_operand:<VDMODE> 0 "register_operand")
350    (match_operand:ILSX_WHB 1 "register_operand")]
351   "ISA_HAS_LSX"
353   if (ISA_HAS_LASX)
354     emit_insn (gen_vec_unpacku_lo_<mode>_internal (operands[0], operands[1]));
355   else
356     loongarch_expand_vec_unpack (operands, true/*unsigned_p*/);
357   DONE;
360 (define_expand "vec_extract<mode><unitmode>"
361   [(match_operand:<UNITMODE> 0 "register_operand")
362    (match_operand:ILSX 1 "register_operand")
363    (match_operand 2 "const_<indeximm>_operand")]
364   "ISA_HAS_LSX"
366   if (<UNITMODE>mode == QImode || <UNITMODE>mode == HImode)
367     {
368       rtx dest1 = gen_reg_rtx (SImode);
369       emit_insn (gen_lsx_vpickve2gr_<lsxfmt> (dest1, operands[1], operands[2]));
370       emit_move_insn (operands[0],
371                       gen_lowpart (<UNITMODE>mode, dest1));
372     }
373   else
374     emit_insn (gen_lsx_vpickve2gr_<lsxfmt> (operands[0], operands[1], operands[2]));
375   DONE;
378 (define_expand "vec_extract<mode><unitmode>"
379   [(match_operand:<UNITMODE> 0 "register_operand")
380    (match_operand:FLSX 1 "register_operand")
381    (match_operand 2 "const_<indeximm>_operand")]
382   "ISA_HAS_LSX"
384   rtx temp;
385   HOST_WIDE_INT val = INTVAL (operands[2]);
387   if (val == 0)
388     temp = operands[1];
389   else
390     {
391       rtx n = GEN_INT (val * GET_MODE_SIZE (<UNITMODE>mode));
392       temp = gen_reg_rtx (<MODE>mode);
393       emit_insn (gen_lsx_vbsrl_<lsxfmt_f> (temp, operands[1], n));
394     }
395   emit_insn (gen_lsx_vec_extract_<lsxfmt_f> (operands[0], temp));
396   DONE;
399 (define_insn_and_split "lsx_vec_extract_<lsxfmt_f>"
400   [(set (match_operand:<UNITMODE> 0 "register_operand" "=f")
401         (vec_select:<UNITMODE>
402           (match_operand:FLSX 1 "register_operand" "f")
403           (parallel [(const_int 0)])))]
404   "ISA_HAS_LSX"
405   "#"
406   "&& reload_completed"
407   [(set (match_dup 0) (match_dup 1))]
409   operands[1] = gen_rtx_REG (<UNITMODE>mode, REGNO (operands[1]));
411   [(set_attr "move_type" "fmove")
412    (set_attr "mode" "<UNITMODE>")])
414 (define_expand "vec_set<mode>"
415   [(match_operand:ILSX 0 "register_operand")
416    (match_operand:<UNITMODE> 1 "reg_or_0_operand")
417    (match_operand 2 "const_<indeximm>_operand")]
418   "ISA_HAS_LSX"
420   rtx index = GEN_INT (1 << INTVAL (operands[2]));
421   emit_insn (gen_lsx_vinsgr2vr_<lsxfmt> (operands[0], operands[1],
422                                          operands[0], index));
423   DONE;
426 (define_expand "vec_set<mode>"
427   [(match_operand:FLSX 0 "register_operand")
428    (match_operand:<UNITMODE> 1 "register_operand")
429    (match_operand 2 "const_<indeximm>_operand")]
430   "ISA_HAS_LSX"
432   rtx index = GEN_INT (1 << INTVAL (operands[2]));
433   emit_insn (gen_lsx_vextrins_<lsxfmt_f>_scalar (operands[0], operands[1],
434                                                  operands[0], index));
435   DONE;
438 (define_expand "vcond_mask_<mode><mode_i>"
439   [(match_operand:LSX 0 "register_operand")
440    (match_operand:LSX 1 "reg_or_m1_operand")
441    (match_operand:LSX 2 "reg_or_0_operand")
442    (match_operand:<VIMODE> 3 "register_operand")]
443   "ISA_HAS_LSX"
445   loongarch_expand_vec_cond_mask_expr (<MODE>mode,
446                                        <VIMODE>mode, operands);
447   DONE;
450 (define_insn "lsx_vinsgr2vr_<lsxfmt>"
451   [(set (match_operand:ILSX 0 "register_operand" "=f")
452         (vec_merge:ILSX
453           (vec_duplicate:ILSX
454             (match_operand:<UNITMODE> 1 "reg_or_0_operand" "rJ"))
455           (match_operand:ILSX 2 "register_operand" "0")
456           (match_operand 3 "const_<bitmask>_operand" "")))]
457   "ISA_HAS_LSX"
459   return "vinsgr2vr.<lsxfmt>\t%w0,%z1,%y3";
461   [(set_attr "type" "simd_insert")
462    (set_attr "mode" "<MODE>")])
464 (define_insn "lsx_vextrins_<lsxfmt_f>_internal"
465   [(set (match_operand:LSX 0 "register_operand" "=f")
466         (vec_merge:LSX
467           (vec_duplicate:LSX
468             (vec_select:<UNITMODE>
469               (match_operand:LSX 1 "register_operand" "f")
470               (parallel [(const_int 0)])))
471           (match_operand:LSX 2 "register_operand" "0")
472           (match_operand 3 "const_<bitmask>_operand" "")))]
473   "ISA_HAS_LSX"
474   "vextrins.<lsxfmt>\t%w0,%w1,%y3<<4"
475   [(set_attr "type" "simd_insert")
476    (set_attr "mode" "<MODE>")])
478 ;; Operand 3 is a scalar.
479 (define_insn "lsx_vextrins_<lsxfmt_f>_scalar"
480   [(set (match_operand:FLSX 0 "register_operand" "=f")
481         (vec_merge:FLSX
482           (vec_duplicate:FLSX
483             (match_operand:<UNITMODE> 1 "register_operand" "f"))
484           (match_operand:FLSX 2 "register_operand" "0")
485           (match_operand 3 "const_<bitmask>_operand" "")))]
486   "ISA_HAS_LSX"
487   "vextrins.<lsxfmt>\t%w0,%w1,%y3<<4"
488   [(set_attr "type" "simd_insert")
489    (set_attr "mode" "<MODE>")])
491 (define_insn "lsx_vpickve2gr_<lsxfmt><u>"
492   [(set (match_operand:<VRES> 0 "register_operand" "=r")
493         (any_extend:<VRES>
494           (vec_select:<UNITMODE>
495             (match_operand:ILSX_HB 1 "register_operand" "f")
496             (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))]
497   "ISA_HAS_LSX"
498   "vpickve2gr.<lsxfmt><u>\t%0,%w1,%2"
499   [(set_attr "type" "simd_copy")
500    (set_attr "mode" "<MODE>")])
502 (define_insn "lsx_vpickve2gr_<lsxfmt_f><u>"
503   [(set (match_operand:<UNITMODE> 0 "register_operand" "=r")
504         (any_extend:<UNITMODE>
505           (vec_select:<UNITMODE>
506             (match_operand:LSX_W 1 "register_operand" "f")
507             (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))]
508   "ISA_HAS_LSX"
509   "vpickve2gr.<lsxfmt><u>\t%0,%w1,%2"
510   [(set_attr "type" "simd_copy")
511    (set_attr "mode" "<MODE>")])
513 (define_insn "lsx_vpickve2gr_du"
514   [(set (match_operand:DI 0 "register_operand" "=r")
515         (vec_select:DI
516           (match_operand:V2DI 1 "register_operand" "f")
517           (parallel [(match_operand 2 "const_0_or_1_operand" "")])))]
518   "ISA_HAS_LSX"
519   "vpickve2gr.du\t%0,%w1,%2"
520   [(set_attr "type" "simd_copy")
521    (set_attr "mode" "V2DI")])
523 (define_insn "lsx_vpickve2gr_<lsxfmt_f>"
524   [(set (match_operand:<UNITMODE> 0 "register_operand" "=r")
525         (vec_select:<UNITMODE>
526           (match_operand:LSX_D 1 "register_operand" "f")
527           (parallel [(match_operand 2 "const_<indeximm>_operand" "")])))]
528   "ISA_HAS_LSX"
529   "vpickve2gr.<lsxfmt>\t%0,%w1,%2"
530   [(set_attr "type" "simd_copy")
531    (set_attr "mode" "<MODE>")])
533 (define_expand "neg<mode>2"
534   [(set (match_operand:ILSX 0 "register_operand")
535         (neg:ILSX (match_operand:ILSX 1 "register_operand")))]
536   "ISA_HAS_LSX"
538   emit_insn (gen_vneg<mode>2 (operands[0], operands[1]));
539   DONE;
542 (define_expand "lsx_vrepli<mode>"
543   [(match_operand:ILSX 0 "register_operand")
544    (match_operand 1 "const_imm10_operand")]
545   "ISA_HAS_LSX"
547   if (<MODE>mode == V16QImode)
548     operands[1] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1]),
549                                                <UNITMODE>mode));
550   emit_move_insn (operands[0],
551                   loongarch_gen_const_int_vector (<MODE>mode, INTVAL (operands[1])));
552   DONE;
555 (define_expand "vec_perm<mode>"
556  [(match_operand:LSX 0 "register_operand")
557   (match_operand:LSX 1 "register_operand")
558   (match_operand:LSX 2 "register_operand")
559   (match_operand:<VIMODE> 3 "register_operand")]
560   "ISA_HAS_LSX"
562   loongarch_expand_vec_perm (operands[0], operands[1],
563                              operands[2], operands[3]);
564   DONE;
567 (define_insn "lsx_vshuf_<lsxfmt_f>"
568   [(set (match_operand:LSX_DWH 0 "register_operand" "=f")
569         (unspec:LSX_DWH [(match_operand:LSX_DWH 1 "register_operand" "0")
570                          (match_operand:LSX_DWH 2 "register_operand" "f")
571                          (match_operand:LSX_DWH 3 "register_operand" "f")]
572                         UNSPEC_LSX_VSHUF))]
573   "ISA_HAS_LSX"
574   "vshuf.<lsxfmt>\t%w0,%w2,%w3"
575   [(set_attr "type" "simd_sld")
576    (set_attr "mode" "<MODE>")])
578 (define_expand "mov<mode>"
579   [(set (match_operand:LSX 0)
580         (match_operand:LSX 1))]
581   "ISA_HAS_LSX"
583   if (loongarch_legitimize_move (<MODE>mode, operands[0], operands[1]))
584     DONE;
587 (define_expand "movmisalign<mode>"
588   [(set (match_operand:LSX 0)
589         (match_operand:LSX 1))]
590   "ISA_HAS_LSX"
592   if (loongarch_legitimize_move (<MODE>mode, operands[0], operands[1]))
593     DONE;
596 (define_insn "mov<mode>_lsx"
597   [(set (match_operand:LSX 0 "nonimmediate_operand" "=f,f,R,*r,*f,*r")
598         (match_operand:LSX 1 "move_operand" "fYGYI,R,f,*f,*r,*r"))]
599   "ISA_HAS_LSX"
600 { return loongarch_output_move (operands); }
601   [(set_attr "type" "simd_move,simd_load,simd_store,simd_copy,simd_insert,simd_copy")
602    (set_attr "mode" "<MODE>")])
604 (define_split
605   [(set (match_operand:LSX 0 "nonimmediate_operand")
606         (match_operand:LSX 1 "move_operand"))]
607   "reload_completed && ISA_HAS_LSX
608    && loongarch_split_move_p (operands[0], operands[1])"
609   [(const_int 0)]
611   loongarch_split_move (operands[0], operands[1]);
612   DONE;
615 ;; Integer operations
616 (define_insn "add<mode>3"
617   [(set (match_operand:ILSX 0 "register_operand" "=f,f,f")
618         (plus:ILSX
619           (match_operand:ILSX 1 "register_operand" "f,f,f")
620           (match_operand:ILSX 2 "reg_or_vector_same_ximm5_operand" "f,Unv5,Uuv5")))]
621   "ISA_HAS_LSX"
623   switch (which_alternative)
624     {
625     case 0:
626       return "vadd.<lsxfmt>\t%w0,%w1,%w2";
627     case 1:
628       {
629         HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (operands[2], 0));
631         operands[2] = GEN_INT (-val);
632         return "vsubi.<lsxfmt_u>\t%w0,%w1,%d2";
633       }
634     case 2:
635       return "vaddi.<lsxfmt_u>\t%w0,%w1,%E2";
636     default:
637       gcc_unreachable ();
638     }
640   [(set_attr "alu_type" "simd_add")
641    (set_attr "type" "simd_int_arith")
642    (set_attr "mode" "<MODE>")])
644 (define_insn "sub<mode>3"
645   [(set (match_operand:ILSX 0 "register_operand" "=f,f")
646         (minus:ILSX
647           (match_operand:ILSX 1 "register_operand" "f,f")
648           (match_operand:ILSX 2 "reg_or_vector_same_uimm5_operand" "f,Uuv5")))]
649   "ISA_HAS_LSX"
650   "@
651    vsub.<lsxfmt>\t%w0,%w1,%w2
652    vsubi.<lsxfmt_u>\t%w0,%w1,%E2"
653   [(set_attr "alu_type" "simd_add")
654    (set_attr "type" "simd_int_arith")
655    (set_attr "mode" "<MODE>")])
657 (define_insn "mul<mode>3"
658   [(set (match_operand:ILSX 0 "register_operand" "=f")
659         (mult:ILSX (match_operand:ILSX 1 "register_operand" "f")
660                    (match_operand:ILSX 2 "register_operand" "f")))]
661   "ISA_HAS_LSX"
662   "vmul.<lsxfmt>\t%w0,%w1,%w2"
663   [(set_attr "type" "simd_mul")
664    (set_attr "mode" "<MODE>")])
666 (define_insn "lsx_vmadd_<lsxfmt>"
667   [(set (match_operand:ILSX 0 "register_operand" "=f")
668         (plus:ILSX (mult:ILSX (match_operand:ILSX 2 "register_operand" "f")
669                               (match_operand:ILSX 3 "register_operand" "f"))
670                    (match_operand:ILSX 1 "register_operand" "0")))]
671   "ISA_HAS_LSX"
672   "vmadd.<lsxfmt>\t%w0,%w2,%w3"
673   [(set_attr "type" "simd_mul")
674    (set_attr "mode" "<MODE>")])
676 (define_insn "lsx_vmsub_<lsxfmt>"
677   [(set (match_operand:ILSX 0 "register_operand" "=f")
678         (minus:ILSX (match_operand:ILSX 1 "register_operand" "0")
679                     (mult:ILSX (match_operand:ILSX 2 "register_operand" "f")
680                                (match_operand:ILSX 3 "register_operand" "f"))))]
681   "ISA_HAS_LSX"
682   "vmsub.<lsxfmt>\t%w0,%w2,%w3"
683   [(set_attr "type" "simd_mul")
684    (set_attr "mode" "<MODE>")])
686 (define_insn "div<mode>3"
687   [(set (match_operand:ILSX 0 "register_operand" "=f")
688         (div:ILSX (match_operand:ILSX 1 "register_operand" "f")
689                   (match_operand:ILSX 2 "register_operand" "f")))]
690   "ISA_HAS_LSX"
691 { return loongarch_lsx_output_division ("vdiv.<lsxfmt>\t%w0,%w1,%w2", operands); }
692   [(set_attr "type" "simd_div")
693    (set_attr "mode" "<MODE>")])
695 (define_insn "udiv<mode>3"
696   [(set (match_operand:ILSX 0 "register_operand" "=f")
697         (udiv:ILSX (match_operand:ILSX 1 "register_operand" "f")
698                    (match_operand:ILSX 2 "register_operand" "f")))]
699   "ISA_HAS_LSX"
700 { return loongarch_lsx_output_division ("vdiv.<lsxfmt_u>\t%w0,%w1,%w2", operands); }
701   [(set_attr "type" "simd_div")
702    (set_attr "mode" "<MODE>")])
704 (define_insn "mod<mode>3"
705   [(set (match_operand:ILSX 0 "register_operand" "=f")
706         (mod:ILSX (match_operand:ILSX 1 "register_operand" "f")
707                   (match_operand:ILSX 2 "register_operand" "f")))]
708   "ISA_HAS_LSX"
709 { return loongarch_lsx_output_division ("vmod.<lsxfmt>\t%w0,%w1,%w2", operands); }
710   [(set_attr "type" "simd_div")
711    (set_attr "mode" "<MODE>")])
713 (define_insn "umod<mode>3"
714   [(set (match_operand:ILSX 0 "register_operand" "=f")
715         (umod:ILSX (match_operand:ILSX 1 "register_operand" "f")
716                    (match_operand:ILSX 2 "register_operand" "f")))]
717   "ISA_HAS_LSX"
718 { return loongarch_lsx_output_division ("vmod.<lsxfmt_u>\t%w0,%w1,%w2", operands); }
719   [(set_attr "type" "simd_div")
720    (set_attr "mode" "<MODE>")])
722 (define_insn "xor<mode>3"
723   [(set (match_operand:LSX 0 "register_operand" "=f,f,f")
724         (xor:LSX
725           (match_operand:LSX 1 "register_operand" "f,f,f")
726           (match_operand:LSX 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
727   "ISA_HAS_LSX"
728   "@
729    vxor.v\t%w0,%w1,%w2
730    vbitrevi.%v0\t%w0,%w1,%V2
731    vxori.b\t%w0,%w1,%B2"
732   [(set_attr "type" "simd_logic,simd_bit,simd_logic")
733    (set_attr "mode" "<MODE>")])
735 (define_insn "ior<mode>3"
736   [(set (match_operand:LSX 0 "register_operand" "=f,f,f")
737         (ior:LSX
738           (match_operand:LSX 1 "register_operand" "f,f,f")
739           (match_operand:LSX 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
740   "ISA_HAS_LSX"
741   "@
742    vor.v\t%w0,%w1,%w2
743    vbitseti.%v0\t%w0,%w1,%V2
744    vori.b\t%w0,%w1,%B2"
745   [(set_attr "type" "simd_logic,simd_bit,simd_logic")
746    (set_attr "mode" "<MODE>")])
748 (define_insn "and<mode>3"
749   [(set (match_operand:LSX 0 "register_operand" "=f,f,f")
750         (and:LSX
751           (match_operand:LSX 1 "register_operand" "f,f,f")
752           (match_operand:LSX 2 "reg_or_vector_same_val_operand" "f,YZ,Urv8")))]
753   "ISA_HAS_LSX"
755   switch (which_alternative)
756     {
757     case 0:
758       return "vand.v\t%w0,%w1,%w2";
759     case 1:
760       {
761         rtx elt0 = CONST_VECTOR_ELT (operands[2], 0);
762         unsigned HOST_WIDE_INT val = ~UINTVAL (elt0);
763         operands[2] = loongarch_gen_const_int_vector (<MODE>mode, val & (-val));
764         return "vbitclri.%v0\t%w0,%w1,%V2";
765       }
766     case 2:
767       return "vandi.b\t%w0,%w1,%B2";
768     default:
769       gcc_unreachable ();
770     }
772   [(set_attr "type" "simd_logic,simd_bit,simd_logic")
773    (set_attr "mode" "<MODE>")])
775 (define_insn "one_cmpl<mode>2"
776   [(set (match_operand:ILSX 0 "register_operand" "=f")
777         (not:ILSX (match_operand:ILSX 1 "register_operand" "f")))]
778   "ISA_HAS_LSX"
779   "vnor.v\t%w0,%w1,%w1"
780   [(set_attr "type" "simd_logic")
781    (set_attr "mode" "TI")])
783 (define_insn "vlshr<mode>3"
784   [(set (match_operand:ILSX 0 "register_operand" "=f,f")
785         (lshiftrt:ILSX
786           (match_operand:ILSX 1 "register_operand" "f,f")
787           (match_operand:ILSX 2 "reg_or_vector_same_uimm_operand" "f,Uuvx")))]
788   "ISA_HAS_LSX"
790   switch (which_alternative)
791     {
792     case 0:
793       return "vsrl.<lsxfmt>\t%w0,%w1,%w2";
794     case 1:
795       {
796         unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (operands[2], 0));
797         operands[2] = GEN_INT (val & (GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1));
798         return "vsrli.<lsxfmt>\t%w0,%w1,%d2";
799       }
800     default:
801       gcc_unreachable ();
802     }
804   [(set_attr "type" "simd_shift")
805    (set_attr "mode" "<MODE>")])
807 (define_insn "vashr<mode>3"
808   [(set (match_operand:ILSX 0 "register_operand" "=f,f")
809         (ashiftrt:ILSX
810           (match_operand:ILSX 1 "register_operand" "f,f")
811           (match_operand:ILSX 2 "reg_or_vector_same_uimm_operand" "f,Uuvx")))]
812   "ISA_HAS_LSX"
814   switch (which_alternative)
815     {
816     case 0:
817       return "vsra.<lsxfmt>\t%w0,%w1,%w2";
818     case 1:
819       {
820         unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (operands[2], 0));
821         operands[2] = GEN_INT (val & (GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1));
822         return "vsrai.<lsxfmt>\t%w0,%w1,%d2";
823       }
824     default:
825       gcc_unreachable ();
826     }
828   [(set_attr "type" "simd_shift")
829    (set_attr "mode" "<MODE>")])
831 (define_insn "vashl<mode>3"
832   [(set (match_operand:ILSX 0 "register_operand" "=f,f")
833         (ashift:ILSX
834           (match_operand:ILSX 1 "register_operand" "f,f")
835           (match_operand:ILSX 2 "reg_or_vector_same_uimm_operand" "f,Uuvx")))]
836   "ISA_HAS_LSX"
838   switch (which_alternative)
839     {
840     case 0:
841       return "vsll.<lsxfmt>\t%w0,%w1,%w2";
842     case 1:
843       {
844         unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (operands[2], 0));
845         operands[2] = GEN_INT (val & (GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1));
846         return "vslli.<lsxfmt>\t%w0,%w1,%d2";
847       }
848     default:
849       gcc_unreachable ();
850     }
852   [(set_attr "type" "simd_shift")
853    (set_attr "mode" "<MODE>")])
855 ;; Floating-point operations
856 (define_insn "add<mode>3"
857   [(set (match_operand:FLSX 0 "register_operand" "=f")
858         (plus:FLSX (match_operand:FLSX 1 "register_operand" "f")
859                    (match_operand:FLSX 2 "register_operand" "f")))]
860   "ISA_HAS_LSX"
861   "vfadd.<flsxfmt>\t%w0,%w1,%w2"
862   [(set_attr "type" "simd_fadd")
863    (set_attr "mode" "<MODE>")])
865 (define_insn "sub<mode>3"
866   [(set (match_operand:FLSX 0 "register_operand" "=f")
867         (minus:FLSX (match_operand:FLSX 1 "register_operand" "f")
868                     (match_operand:FLSX 2 "register_operand" "f")))]
869   "ISA_HAS_LSX"
870   "vfsub.<flsxfmt>\t%w0,%w1,%w2"
871   [(set_attr "type" "simd_fadd")
872    (set_attr "mode" "<MODE>")])
874 (define_insn "mul<mode>3"
875   [(set (match_operand:FLSX 0 "register_operand" "=f")
876         (mult:FLSX (match_operand:FLSX 1 "register_operand" "f")
877                    (match_operand:FLSX 2 "register_operand" "f")))]
878   "ISA_HAS_LSX"
879   "vfmul.<flsxfmt>\t%w0,%w1,%w2"
880   [(set_attr "type" "simd_fmul")
881    (set_attr "mode" "<MODE>")])
883 (define_expand "div<mode>3"
884   [(set (match_operand:FLSX 0 "register_operand")
885     (div:FLSX (match_operand:FLSX 1 "reg_or_vecotr_1_operand")
886               (match_operand:FLSX 2 "register_operand")))]
887   "ISA_HAS_LSX"
889   if (<MODE>mode == V4SFmode
890     && TARGET_RECIP_VEC_DIV
891     && optimize_insn_for_speed_p ()
892     && flag_finite_math_only && !flag_trapping_math
893     && flag_unsafe_math_optimizations)
894   {
895     loongarch_emit_swdivsf (operands[0], operands[1],
896         operands[2], V4SFmode);
897     DONE;
898   }
901 (define_insn "*div<mode>3"
902   [(set (match_operand:FLSX 0 "register_operand" "=f")
903         (div:FLSX (match_operand:FLSX 1 "register_operand" "f")
904                   (match_operand:FLSX 2 "register_operand" "f")))]
905   "ISA_HAS_LSX"
906   "vfdiv.<flsxfmt>\t%w0,%w1,%w2"
907   [(set_attr "type" "simd_fdiv")
908    (set_attr "mode" "<MODE>")])
910 (define_insn "fma<mode>4"
911   [(set (match_operand:FLSX 0 "register_operand" "=f")
912         (fma:FLSX (match_operand:FLSX 1 "register_operand" "f")
913                   (match_operand:FLSX 2 "register_operand" "f")
914                   (match_operand:FLSX 3 "register_operand" "f")))]
915   "ISA_HAS_LSX"
916   "vfmadd.<flsxfmt>\t%w0,%w1,%w2,%w3"
917   [(set_attr "type" "simd_fmadd")
918    (set_attr "mode" "<MODE>")])
920 (define_insn "fnma<mode>4"
921   [(set (match_operand:FLSX 0 "register_operand" "=f")
922         (fma:FLSX (neg:FLSX (match_operand:FLSX 1 "register_operand" "f"))
923                   (match_operand:FLSX 2 "register_operand" "f")
924                   (match_operand:FLSX 3 "register_operand" "0")))]
925   "ISA_HAS_LSX"
926   "vfnmsub.<flsxfmt>\t%w0,%w1,%w2,%w0"
927   [(set_attr "type" "simd_fmadd")
928    (set_attr "mode" "<MODE>")])
930 (define_expand "sqrt<mode>2"
931   [(set (match_operand:FLSX 0 "register_operand")
932     (sqrt:FLSX (match_operand:FLSX 1 "register_operand")))]
933   "ISA_HAS_LSX"
935   if (<MODE>mode == V4SFmode
936       && TARGET_RECIP_VEC_SQRT
937       && flag_unsafe_math_optimizations
938       && optimize_insn_for_speed_p ()
939       && flag_finite_math_only && !flag_trapping_math)
940     {
941       loongarch_emit_swrsqrtsf (operands[0], operands[1], V4SFmode, 0);
942       DONE;
943     }
946 (define_insn "*sqrt<mode>2"
947   [(set (match_operand:FLSX 0 "register_operand" "=f")
948         (sqrt:FLSX (match_operand:FLSX 1 "register_operand" "f")))]
949   "ISA_HAS_LSX"
950   "vfsqrt.<flsxfmt>\t%w0,%w1"
951   [(set_attr "type" "simd_fdiv")
952    (set_attr "mode" "<MODE>")])
954 ;; Built-in functions
955 (define_insn "lsx_vadda_<lsxfmt>"
956   [(set (match_operand:ILSX 0 "register_operand" "=f")
957         (plus:ILSX (abs:ILSX (match_operand:ILSX 1 "register_operand" "f"))
958                    (abs:ILSX (match_operand:ILSX 2 "register_operand" "f"))))]
959   "ISA_HAS_LSX"
960   "vadda.<lsxfmt>\t%w0,%w1,%w2"
961   [(set_attr "type" "simd_int_arith")
962    (set_attr "mode" "<MODE>")])
964 (define_insn "ssadd<mode>3"
965   [(set (match_operand:ILSX 0 "register_operand" "=f")
966         (ss_plus:ILSX (match_operand:ILSX 1 "register_operand" "f")
967                       (match_operand:ILSX 2 "register_operand" "f")))]
968   "ISA_HAS_LSX"
969   "vsadd.<lsxfmt>\t%w0,%w1,%w2"
970   [(set_attr "type" "simd_int_arith")
971    (set_attr "mode" "<MODE>")])
973 (define_insn "usadd<mode>3"
974   [(set (match_operand:ILSX 0 "register_operand" "=f")
975         (us_plus:ILSX (match_operand:ILSX 1 "register_operand" "f")
976                       (match_operand:ILSX 2 "register_operand" "f")))]
977   "ISA_HAS_LSX"
978   "vsadd.<lsxfmt_u>\t%w0,%w1,%w2"
979   [(set_attr "type" "simd_int_arith")
980    (set_attr "mode" "<MODE>")])
982 (define_insn "<su>abd<mode>3"
983   [(set (match_operand:ILSX 0 "register_operand" "=f")
984         (minus:ILSX
985           (SU_MAX:ILSX
986             (match_operand:ILSX 1 "register_operand" "f")
987             (match_operand:ILSX 2 "register_operand" "f"))
988           (<su_min>:ILSX
989             (match_dup 1)
990             (match_dup 2))))]
991   "ISA_HAS_LSX"
992   "vabsd.<lsxfmt><u>\t%w0,%w1,%w2"
993   [(set_attr "type" "simd_int_arith")
994    (set_attr "mode" "<MODE>")])
996 (define_insn "lsx_vavg_s_<lsxfmt>"
997   [(set (match_operand:ILSX 0 "register_operand" "=f")
998         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
999                       (match_operand:ILSX 2 "register_operand" "f")]
1000                      UNSPEC_LSX_VAVG_S))]
1001   "ISA_HAS_LSX"
1002   "vavg.<lsxfmt>\t%w0,%w1,%w2"
1003   [(set_attr "type" "simd_int_arith")
1004    (set_attr "mode" "<MODE>")])
1006 (define_insn "lsx_vavg_u_<lsxfmt_u>"
1007   [(set (match_operand:ILSX 0 "register_operand" "=f")
1008         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1009                       (match_operand:ILSX 2 "register_operand" "f")]
1010                      UNSPEC_LSX_VAVG_U))]
1011   "ISA_HAS_LSX"
1012   "vavg.<lsxfmt_u>\t%w0,%w1,%w2"
1013   [(set_attr "type" "simd_int_arith")
1014    (set_attr "mode" "<MODE>")])
1016 (define_insn "lsx_vavgr_s_<lsxfmt>"
1017   [(set (match_operand:ILSX 0 "register_operand" "=f")
1018         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1019                       (match_operand:ILSX 2 "register_operand" "f")]
1020                      UNSPEC_LSX_VAVGR_S))]
1021   "ISA_HAS_LSX"
1022   "vavgr.<lsxfmt>\t%w0,%w1,%w2"
1023   [(set_attr "type" "simd_int_arith")
1024    (set_attr "mode" "<MODE>")])
1026 (define_insn "lsx_vavgr_u_<lsxfmt_u>"
1027   [(set (match_operand:ILSX 0 "register_operand" "=f")
1028         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1029                       (match_operand:ILSX 2 "register_operand" "f")]
1030                      UNSPEC_LSX_VAVGR_U))]
1031   "ISA_HAS_LSX"
1032   "vavgr.<lsxfmt_u>\t%w0,%w1,%w2"
1033   [(set_attr "type" "simd_int_arith")
1034    (set_attr "mode" "<MODE>")])
1036 (define_insn "lsx_vbitclr_<lsxfmt>"
1037   [(set (match_operand:ILSX 0 "register_operand" "=f")
1038         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1039                       (match_operand:ILSX 2 "register_operand" "f")]
1040                      UNSPEC_LSX_VBITCLR))]
1041   "ISA_HAS_LSX"
1042   "vbitclr.<lsxfmt>\t%w0,%w1,%w2"
1043   [(set_attr "type" "simd_bit")
1044    (set_attr "mode" "<MODE>")])
1046 (define_insn "lsx_vbitclri_<lsxfmt>"
1047   [(set (match_operand:ILSX 0 "register_operand" "=f")
1048         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1049                       (match_operand 2 "const_<bitimm>_operand" "")]
1050                      UNSPEC_LSX_VBITCLRI))]
1051   "ISA_HAS_LSX"
1052   "vbitclri.<lsxfmt>\t%w0,%w1,%2"
1053   [(set_attr "type" "simd_bit")
1054    (set_attr "mode" "<MODE>")])
1056 (define_insn "lsx_vbitrev_<lsxfmt>"
1057   [(set (match_operand:ILSX 0 "register_operand" "=f")
1058         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1059                       (match_operand:ILSX 2 "register_operand" "f")]
1060                      UNSPEC_LSX_VBITREV))]
1061   "ISA_HAS_LSX"
1062   "vbitrev.<lsxfmt>\t%w0,%w1,%w2"
1063   [(set_attr "type" "simd_bit")
1064    (set_attr "mode" "<MODE>")])
1066 (define_insn "lsx_vbitrevi_<lsxfmt>"
1067   [(set (match_operand:ILSX 0 "register_operand" "=f")
1068         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1069                        (match_operand 2 "const_lsx_branch_operand" "")]
1070                      UNSPEC_LSX_VBITREVI))]
1071   "ISA_HAS_LSX"
1072   "vbitrevi.<lsxfmt>\t%w0,%w1,%2"
1073   [(set_attr "type" "simd_bit")
1074    (set_attr "mode" "<MODE>")])
1076 (define_insn "lsx_vbitsel_<lsxfmt>"
1077   [(set (match_operand:ILSX 0 "register_operand" "=f")
1078         (ior:ILSX (and:ILSX (not:ILSX
1079                               (match_operand:ILSX 3 "register_operand" "f"))
1080                             (match_operand:ILSX 1 "register_operand" "f"))
1081                   (and:ILSX (match_dup 3)
1082                             (match_operand:ILSX 2 "register_operand" "f"))))]
1083   "ISA_HAS_LSX"
1084   "vbitsel.v\t%w0,%w1,%w2,%w3"
1085   [(set_attr "type" "simd_bitmov")
1086    (set_attr "mode" "<MODE>")])
1088 (define_insn "lsx_vbitseli_b"
1089   [(set (match_operand:V16QI 0 "register_operand" "=f")
1090         (ior:V16QI (and:V16QI (not:V16QI
1091                                 (match_operand:V16QI 1 "register_operand" "0"))
1092                               (match_operand:V16QI 2 "register_operand" "f"))
1093                    (and:V16QI (match_dup 1)
1094                               (match_operand:V16QI 3 "const_vector_same_val_operand" "Urv8"))))]
1095   "ISA_HAS_LSX"
1096   "vbitseli.b\t%w0,%w2,%B3"
1097   [(set_attr "type" "simd_bitmov")
1098    (set_attr "mode" "V16QI")])
1100 (define_insn "lsx_vbitset_<lsxfmt>"
1101   [(set (match_operand:ILSX 0 "register_operand" "=f")
1102         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1103                       (match_operand:ILSX 2 "register_operand" "f")]
1104                      UNSPEC_LSX_VBITSET))]
1105   "ISA_HAS_LSX"
1106   "vbitset.<lsxfmt>\t%w0,%w1,%w2"
1107   [(set_attr "type" "simd_bit")
1108    (set_attr "mode" "<MODE>")])
1110 (define_insn "lsx_vbitseti_<lsxfmt>"
1111   [(set (match_operand:ILSX 0 "register_operand" "=f")
1112         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1113                       (match_operand 2 "const_<bitimm>_operand" "")]
1114                      UNSPEC_LSX_VBITSETI))]
1115   "ISA_HAS_LSX"
1116   "vbitseti.<lsxfmt>\t%w0,%w1,%2"
1117   [(set_attr "type" "simd_bit")
1118    (set_attr "mode" "<MODE>")])
1120 (define_code_iterator ICC [eq le leu lt ltu])
1122 (define_code_attr icc
1123   [(eq  "eq")
1124    (le  "le")
1125    (leu "le")
1126    (lt  "lt")
1127    (ltu "lt")])
1129 (define_code_attr icci
1130   [(eq  "eqi")
1131    (le  "lei")
1132    (leu "lei")
1133    (lt  "lti")
1134    (ltu "lti")])
1136 (define_code_attr cmpi
1137   [(eq   "s")
1138    (le   "s")
1139    (leu  "u")
1140    (lt   "s")
1141    (ltu  "u")])
1143 (define_code_attr cmpi_1
1144   [(eq   "")
1145    (le   "")
1146    (leu  "u")
1147    (lt   "")
1148    (ltu  "u")])
1150 (define_insn "lsx_vs<ICC:icc>_<ILSX:lsxfmt><ICC:cmpi_1>"
1151   [(set (match_operand:ILSX 0 "register_operand" "=f,f")
1152         (ICC:ILSX
1153           (match_operand:ILSX 1 "register_operand" "f,f")
1154           (match_operand:ILSX 2 "reg_or_vector_same_<ICC:cmpi>imm5_operand" "f,U<ICC:cmpi>v5")))]
1155   "ISA_HAS_LSX"
1156   "@
1157    vs<ICC:icc>.<ILSX:lsxfmt><ICC:cmpi_1>\t%w0,%w1,%w2
1158    vs<ICC:icci>.<ILSX:lsxfmt><ICC:cmpi_1>\t%w0,%w1,%E2"
1159   [(set_attr "type" "simd_int_arith")
1160    (set_attr "mode" "<MODE>")])
1162 (define_insn "lsx_vfclass_<flsxfmt>"
1163   [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
1164         (unspec:<VIMODE> [(match_operand:FLSX 1 "register_operand" "f")]
1165                          UNSPEC_LSX_VFCLASS))]
1166   "ISA_HAS_LSX"
1167   "vfclass.<flsxfmt>\t%w0,%w1"
1168   [(set_attr "type" "simd_fclass")
1169    (set_attr "mode" "<MODE>")])
1171 (define_mode_attr fint
1172   [(V4SF "v4si")
1173    (V2DF "v2di")])
1175 (define_mode_attr FINTCNV
1176   [(V4SF "I2S")
1177    (V2DF "I2D")])
1179 (define_mode_attr FINTCNV_2
1180   [(V4SF "S2I")
1181    (V2DF "D2I")])
1183 (define_insn "float<fint><FLSX:mode>2"
1184   [(set (match_operand:FLSX 0 "register_operand" "=f")
1185         (float:FLSX (match_operand:<VIMODE> 1 "register_operand" "f")))]
1186   "ISA_HAS_LSX"
1187   "vffint.<flsxfmt>.<ilsxfmt>\t%w0,%w1"
1188   [(set_attr "type" "simd_fcvt")
1189    (set_attr "cnv_mode" "<FINTCNV>")
1190    (set_attr "mode" "<MODE>")])
1192 (define_insn "floatuns<fint><FLSX:mode>2"
1193   [(set (match_operand:FLSX 0 "register_operand" "=f")
1194         (unsigned_float:FLSX
1195           (match_operand:<VIMODE> 1 "register_operand" "f")))]
1196   "ISA_HAS_LSX"
1197   "vffint.<flsxfmt>.<ilsxfmt_u>\t%w0,%w1"
1198   [(set_attr "type" "simd_fcvt")
1199    (set_attr "cnv_mode" "<FINTCNV>")
1200    (set_attr "mode" "<MODE>")])
1202 (define_insn "lsx_vreplgr2vr_<lsxfmt_f>"
1203   [(set (match_operand:ILSX 0 "register_operand" "=f,f")
1204         (vec_duplicate:ILSX
1205           (match_operand:<UNITMODE> 1 "reg_or_0_operand" "r,J")))]
1206   "ISA_HAS_LSX"
1208   if (which_alternative == 1)
1209     return "vrepli.b\t%w0,0";
1211   return "vreplgr2vr.<lsxfmt>\t%w0,%z1";
1213   [(set_attr "type" "simd_fill")
1214    (set_attr "mode" "<MODE>")])
1216 (define_insn "logb<mode>2"
1217   [(set (match_operand:FLSX 0 "register_operand" "=f")
1218         (unspec:FLSX [(match_operand:FLSX 1 "register_operand" "f")]
1219                      UNSPEC_LSX_VFLOGB))]
1220   "ISA_HAS_LSX"
1221   "vflogb.<flsxfmt>\t%w0,%w1"
1222   [(set_attr "type" "simd_flog2")
1223    (set_attr "mode" "<MODE>")])
1225 ;; Only for loongarch_expand_vector_init in loongarch.cc.
1226 ;; Merge two scalar floating-point op1 and op2 into a LSX op0.
1227 (define_insn "lsx_vilvl_<lsxfmt_f>_internal"
1228   [(set (match_operand:FLSX 0 "register_operand" "=f")
1229         (unspec:FLSX [(match_operand:<UNITMODE> 1 "register_operand" "f")
1230                       (match_operand:<UNITMODE> 2 "register_operand" "f")]
1231                      UNSPEC_LSX_VILVL_INTERNAL))]
1232   "ISA_HAS_LSX"
1233   "vilvl.<lsxfmt>\t%w0,%w2,%w1"
1234   [(set_attr "type" "simd_permute")
1235    (set_attr "mode" "<MODE>")])
1237 (define_insn "smax<mode>3"
1238   [(set (match_operand:FLSX 0 "register_operand" "=f")
1239         (smax:FLSX (match_operand:FLSX 1 "register_operand" "f")
1240                    (match_operand:FLSX 2 "register_operand" "f")))]
1241   "ISA_HAS_LSX"
1242   "vfmax.<flsxfmt>\t%w0,%w1,%w2"
1243   [(set_attr "type" "simd_fminmax")
1244    (set_attr "mode" "<MODE>")])
1246 (define_insn "lsx_vfmaxa_<flsxfmt>"
1247   [(set (match_operand:FLSX 0 "register_operand" "=f")
1248         (if_then_else:FLSX
1249            (gt (abs:FLSX (match_operand:FLSX 1 "register_operand" "f"))
1250                (abs:FLSX (match_operand:FLSX 2 "register_operand" "f")))
1251            (match_dup 1)
1252            (match_dup 2)))]
1253   "ISA_HAS_LSX"
1254   "vfmaxa.<flsxfmt>\t%w0,%w1,%w2"
1255   [(set_attr "type" "simd_fminmax")
1256    (set_attr "mode" "<MODE>")])
1258 (define_insn "smin<mode>3"
1259   [(set (match_operand:FLSX 0 "register_operand" "=f")
1260         (smin:FLSX (match_operand:FLSX 1 "register_operand" "f")
1261                    (match_operand:FLSX 2 "register_operand" "f")))]
1262   "ISA_HAS_LSX"
1263   "vfmin.<flsxfmt>\t%w0,%w1,%w2"
1264   [(set_attr "type" "simd_fminmax")
1265    (set_attr "mode" "<MODE>")])
1267 (define_insn "lsx_vfmina_<flsxfmt>"
1268   [(set (match_operand:FLSX 0 "register_operand" "=f")
1269         (if_then_else:FLSX
1270            (lt (abs:FLSX (match_operand:FLSX 1 "register_operand" "f"))
1271                (abs:FLSX (match_operand:FLSX 2 "register_operand" "f")))
1272            (match_dup 1)
1273            (match_dup 2)))]
1274   "ISA_HAS_LSX"
1275   "vfmina.<flsxfmt>\t%w0,%w1,%w2"
1276   [(set_attr "type" "simd_fminmax")
1277    (set_attr "mode" "<MODE>")])
1279 (define_insn "recip<mode>3"
1280   [(set (match_operand:FLSX 0 "register_operand" "=f")
1281        (div:FLSX (match_operand:FLSX 1 "const_vector_1_operand" "")
1282                  (match_operand:FLSX 2 "register_operand" "f")))]
1283   "ISA_HAS_LSX"
1284   "vfrecip.<flsxfmt>\t%w0,%w2"
1285   [(set_attr "type" "simd_fdiv")
1286    (set_attr "mode" "<MODE>")])
1288 ;; Approximate Reciprocal Instructions.
1290 (define_insn "lsx_vfrecipe_<flsxfmt>"
1291   [(set (match_operand:FLSX 0 "register_operand" "=f")
1292     (unspec:FLSX [(match_operand:FLSX 1 "register_operand" "f")]
1293                  UNSPEC_LSX_VFRECIPE))]
1294   "ISA_HAS_LSX && ISA_HAS_FRECIPE"
1295   "vfrecipe.<flsxfmt>\t%w0,%w1"
1296   [(set_attr "type" "simd_fdiv")
1297    (set_attr "mode" "<MODE>")])
1299 (define_expand "rsqrt<mode>2"
1300   [(set (match_operand:FLSX 0 "register_operand" "=f")
1301     (unspec:FLSX [(match_operand:FLSX 1 "register_operand" "f")]
1302              UNSPEC_LSX_VFRSQRT))]
1303  "ISA_HAS_LSX"
1305  if (<MODE>mode == V4SFmode && TARGET_RECIP_VEC_RSQRT)
1306    {
1307      loongarch_emit_swrsqrtsf (operands[0], operands[1], V4SFmode, 1);
1308      DONE;
1309    }
1312 (define_insn "*rsqrt<mode>2"
1313   [(set (match_operand:FLSX 0 "register_operand" "=f")
1314     (unspec:FLSX [(match_operand:FLSX 1 "register_operand" "f")]
1315                  UNSPEC_LSX_VFRSQRT))]
1316   "ISA_HAS_LSX"
1317   "vfrsqrt.<flsxfmt>\t%w0,%w1"
1318   [(set_attr "type" "simd_fdiv")
1319    (set_attr "mode" "<MODE>")])
1321 ;; Approximate Reciprocal Square Root Instructions.
1323 (define_insn "lsx_vfrsqrte_<flsxfmt>"
1324   [(set (match_operand:FLSX 0 "register_operand" "=f")
1325     (unspec:FLSX [(match_operand:FLSX 1 "register_operand" "f")]
1326                  UNSPEC_LSX_VFRSQRTE))]
1327   "ISA_HAS_LSX && ISA_HAS_FRECIPE"
1328   "vfrsqrte.<flsxfmt>\t%w0,%w1"
1329   [(set_attr "type" "simd_fdiv")
1330    (set_attr "mode" "<MODE>")])
1332 (define_insn "lsx_vftint_u_<ilsxfmt_u>_<flsxfmt>"
1333   [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
1334         (unspec:<VIMODE> [(match_operand:FLSX 1 "register_operand" "f")]
1335                          UNSPEC_LSX_VFTINT_U))]
1336   "ISA_HAS_LSX"
1337   "vftint.<ilsxfmt_u>.<flsxfmt>\t%w0,%w1"
1338   [(set_attr "type" "simd_fcvt")
1339    (set_attr "cnv_mode" "<FINTCNV_2>")
1340    (set_attr "mode" "<MODE>")])
1342 (define_insn "fixuns_trunc<FLSX:mode><mode_i>2"
1343   [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
1344         (unsigned_fix:<VIMODE> (match_operand:FLSX 1 "register_operand" "f")))]
1345   "ISA_HAS_LSX"
1346   "vftintrz.<ilsxfmt_u>.<flsxfmt>\t%w0,%w1"
1347   [(set_attr "type" "simd_fcvt")
1348    (set_attr "cnv_mode" "<FINTCNV_2>")
1349    (set_attr "mode" "<MODE>")])
1351 (define_insn "lsx_vh<optab>w_h<u>_b<u>"
1352   [(set (match_operand:V8HI 0 "register_operand" "=f")
1353         (addsub:V8HI
1354           (any_extend:V8HI
1355             (vec_select:V8QI
1356               (match_operand:V16QI 1 "register_operand" "f")
1357               (parallel [(const_int 1) (const_int 3)
1358                          (const_int 5) (const_int 7)
1359                          (const_int 9) (const_int 11)
1360                          (const_int 13) (const_int 15)])))
1361           (any_extend:V8HI
1362             (vec_select:V8QI
1363               (match_operand:V16QI 2 "register_operand" "f")
1364               (parallel [(const_int 0) (const_int 2)
1365                          (const_int 4) (const_int 6)
1366                          (const_int 8) (const_int 10)
1367                          (const_int 12) (const_int 14)])))))]
1368   "ISA_HAS_LSX"
1369   "vh<optab>w.h<u>.b<u>\t%w0,%w1,%w2"
1370   [(set_attr "type" "simd_int_arith")
1371    (set_attr "mode" "V8HI")])
1373 (define_insn "lsx_vh<optab>w_w<u>_h<u>"
1374   [(set (match_operand:V4SI 0 "register_operand" "=f")
1375         (addsub:V4SI
1376           (any_extend:V4SI
1377             (vec_select:V4HI
1378               (match_operand:V8HI 1 "register_operand" "f")
1379               (parallel [(const_int 1) (const_int 3)
1380                          (const_int 5) (const_int 7)])))
1381           (any_extend:V4SI
1382             (vec_select:V4HI
1383               (match_operand:V8HI 2 "register_operand" "f")
1384               (parallel [(const_int 0) (const_int 2)
1385                          (const_int 4) (const_int 6)])))))]
1386   "ISA_HAS_LSX"
1387   "vh<optab>w.w<u>.h<u>\t%w0,%w1,%w2"
1388   [(set_attr "type" "simd_int_arith")
1389    (set_attr "mode" "V4SI")])
1391 (define_insn "lsx_vh<optab>w_d<u>_w<u>"
1392   [(set (match_operand:V2DI 0 "register_operand" "=f")
1393         (addsub:V2DI
1394           (any_extend:V2DI
1395             (vec_select:V2SI
1396               (match_operand:V4SI 1 "register_operand" "f")
1397               (parallel [(const_int 1) (const_int 3)])))
1398           (any_extend:V2DI
1399             (vec_select:V2SI
1400               (match_operand:V4SI 2 "register_operand" "f")
1401               (parallel [(const_int 0) (const_int 2)])))))]
1402   "ISA_HAS_LSX"
1403   "vh<optab>w.d<u>.w<u>\t%w0,%w1,%w2"
1404   [(set_attr "type" "simd_int_arith")
1405    (set_attr "mode" "V2DI")])
1407 (define_insn "lsx_vpackev_b"
1408   [(set (match_operand:V16QI 0 "register_operand" "=f")
1409         (vec_select:V16QI
1410           (vec_concat:V32QI
1411             (match_operand:V16QI 1 "register_operand" "f")
1412             (match_operand:V16QI 2 "register_operand" "f"))
1413           (parallel [(const_int 0)  (const_int 16)
1414                      (const_int 2)  (const_int 18)
1415                      (const_int 4)  (const_int 20)
1416                      (const_int 6)  (const_int 22)
1417                      (const_int 8)  (const_int 24)
1418                      (const_int 10) (const_int 26)
1419                      (const_int 12) (const_int 28)
1420                      (const_int 14) (const_int 30)])))]
1421   "ISA_HAS_LSX"
1422   "vpackev.b\t%w0,%w2,%w1"
1423   [(set_attr "type" "simd_permute")
1424    (set_attr "mode" "V16QI")])
1426 (define_insn "lsx_vpackev_h"
1427   [(set (match_operand:V8HI 0 "register_operand" "=f")
1428         (vec_select:V8HI
1429           (vec_concat:V16HI
1430             (match_operand:V8HI 1 "register_operand" "f")
1431             (match_operand:V8HI 2 "register_operand" "f"))
1432           (parallel [(const_int 0) (const_int 8)
1433                      (const_int 2) (const_int 10)
1434                      (const_int 4) (const_int 12)
1435                      (const_int 6) (const_int 14)])))]
1436   "ISA_HAS_LSX"
1437   "vpackev.h\t%w0,%w2,%w1"
1438   [(set_attr "type" "simd_permute")
1439    (set_attr "mode" "V8HI")])
1441 (define_insn "lsx_vpackev_w"
1442   [(set (match_operand:V4SI 0 "register_operand" "=f")
1443         (vec_select:V4SI
1444           (vec_concat:V8SI
1445             (match_operand:V4SI 1 "register_operand" "f")
1446             (match_operand:V4SI 2 "register_operand" "f"))
1447           (parallel [(const_int 0) (const_int 4)
1448                      (const_int 2) (const_int 6)])))]
1449   "ISA_HAS_LSX"
1450   "vpackev.w\t%w0,%w2,%w1"
1451   [(set_attr "type" "simd_permute")
1452    (set_attr "mode" "V4SI")])
1454 (define_insn "lsx_vpackev_w_f"
1455   [(set (match_operand:V4SF 0 "register_operand" "=f")
1456         (vec_select:V4SF
1457           (vec_concat:V8SF
1458             (match_operand:V4SF 1 "register_operand" "f")
1459             (match_operand:V4SF 2 "register_operand" "f"))
1460           (parallel [(const_int 0) (const_int 4)
1461                      (const_int 2) (const_int 6)])))]
1462   "ISA_HAS_LSX"
1463   "vpackev.w\t%w0,%w2,%w1"
1464   [(set_attr "type" "simd_permute")
1465    (set_attr "mode" "V4SF")])
1467 (define_insn "lsx_vilvh_b"
1468   [(set (match_operand:V16QI 0 "register_operand" "=f")
1469         (vec_select:V16QI
1470           (vec_concat:V32QI
1471             (match_operand:V16QI 1 "register_operand" "f")
1472             (match_operand:V16QI 2 "register_operand" "f"))
1473           (parallel [(const_int 8)  (const_int 24)
1474                      (const_int 9)  (const_int 25)
1475                      (const_int 10) (const_int 26)
1476                      (const_int 11) (const_int 27)
1477                      (const_int 12) (const_int 28)
1478                      (const_int 13) (const_int 29)
1479                      (const_int 14) (const_int 30)
1480                      (const_int 15) (const_int 31)])))]
1481   "ISA_HAS_LSX"
1482   "vilvh.b\t%w0,%w2,%w1"
1483   [(set_attr "type" "simd_permute")
1484    (set_attr "mode" "V16QI")])
1486 (define_insn "lsx_vilvh_h"
1487   [(set (match_operand:V8HI 0 "register_operand" "=f")
1488         (vec_select:V8HI
1489           (vec_concat:V16HI
1490             (match_operand:V8HI 1 "register_operand" "f")
1491             (match_operand:V8HI 2 "register_operand" "f"))
1492           (parallel [(const_int 4) (const_int 12)
1493                      (const_int 5) (const_int 13)
1494                      (const_int 6) (const_int 14)
1495                      (const_int 7) (const_int 15)])))]
1496   "ISA_HAS_LSX"
1497   "vilvh.h\t%w0,%w2,%w1"
1498   [(set_attr "type" "simd_permute")
1499    (set_attr "mode" "V8HI")])
1501 (define_mode_attr vilvh_suffix
1502   [(V4SI "") (V4SF "_f")
1503    (V2DI "") (V2DF "_f")])
1505 (define_insn "lsx_vilvh_w<vilvh_suffix>"
1506   [(set (match_operand:LSX_W 0 "register_operand" "=f")
1507         (vec_select:LSX_W
1508           (vec_concat:<VEMODE>
1509             (match_operand:LSX_W 1 "register_operand" "f")
1510             (match_operand:LSX_W 2 "register_operand" "f"))
1511           (parallel [(const_int 2) (const_int 6)
1512                      (const_int 3) (const_int 7)])))]
1513   "ISA_HAS_LSX"
1514   "vilvh.w\t%w0,%w2,%w1"
1515   [(set_attr "type" "simd_permute")
1516    (set_attr "mode" "<MODE>")])
1518 (define_insn "lsx_vilvh_d<vilvh_suffix>"
1519   [(set (match_operand:LSX_D 0 "register_operand" "=f")
1520         (vec_select:LSX_D
1521           (vec_concat:<VEMODE>
1522             (match_operand:LSX_D 1 "register_operand" "f")
1523             (match_operand:LSX_D 2 "register_operand" "f"))
1524           (parallel [(const_int 1) (const_int 3)])))]
1525   "ISA_HAS_LSX"
1526   "vilvh.d\t%w0,%w2,%w1"
1527   [(set_attr "type" "simd_permute")
1528    (set_attr "mode" "<MODE>")])
1530 (define_insn "lsx_vpackod_b"
1531   [(set (match_operand:V16QI 0 "register_operand" "=f")
1532         (vec_select:V16QI
1533           (vec_concat:V32QI
1534             (match_operand:V16QI 1 "register_operand" "f")
1535             (match_operand:V16QI 2 "register_operand" "f"))
1536           (parallel [(const_int 1)  (const_int 17)
1537                      (const_int 3)  (const_int 19)
1538                      (const_int 5)  (const_int 21)
1539                      (const_int 7)  (const_int 23)
1540                      (const_int 9)  (const_int 25)
1541                      (const_int 11) (const_int 27)
1542                      (const_int 13) (const_int 29)
1543                      (const_int 15) (const_int 31)])))]
1544   "ISA_HAS_LSX"
1545   "vpackod.b\t%w0,%w2,%w1"
1546   [(set_attr "type" "simd_permute")
1547    (set_attr "mode" "V16QI")])
1549 (define_insn "lsx_vpackod_h"
1550   [(set (match_operand:V8HI 0 "register_operand" "=f")
1551         (vec_select:V8HI
1552           (vec_concat:V16HI
1553             (match_operand:V8HI 1 "register_operand" "f")
1554             (match_operand:V8HI 2 "register_operand" "f"))
1555           (parallel [(const_int 1) (const_int 9)
1556                      (const_int 3) (const_int 11)
1557                      (const_int 5) (const_int 13)
1558                      (const_int 7) (const_int 15)])))]
1559   "ISA_HAS_LSX"
1560   "vpackod.h\t%w0,%w2,%w1"
1561   [(set_attr "type" "simd_permute")
1562    (set_attr "mode" "V8HI")])
1564 (define_insn "lsx_vpackod_w"
1565   [(set (match_operand:V4SI 0 "register_operand" "=f")
1566         (vec_select:V4SI
1567           (vec_concat:V8SI
1568             (match_operand:V4SI 1 "register_operand" "f")
1569             (match_operand:V4SI 2 "register_operand" "f"))
1570           (parallel [(const_int 1) (const_int 5)
1571                      (const_int 3) (const_int 7)])))]
1572   "ISA_HAS_LSX"
1573   "vpackod.w\t%w0,%w2,%w1"
1574   [(set_attr "type" "simd_permute")
1575    (set_attr "mode" "V4SI")])
1577 (define_insn "lsx_vpackod_w_f"
1578   [(set (match_operand:V4SF 0 "register_operand" "=f")
1579         (vec_select:V4SF
1580           (vec_concat:V8SF
1581             (match_operand:V4SF 1 "register_operand" "f")
1582             (match_operand:V4SF 2 "register_operand" "f"))
1583           (parallel [(const_int 1) (const_int 5)
1584                      (const_int 3) (const_int 7)])))]
1585   "ISA_HAS_LSX"
1586   "vpackod.w\t%w0,%w2,%w1"
1587   [(set_attr "type" "simd_permute")
1588    (set_attr "mode" "V4SF")])
1590 (define_insn "lsx_vilvl_b"
1591   [(set (match_operand:V16QI 0 "register_operand" "=f")
1592         (vec_select:V16QI
1593           (vec_concat:V32QI
1594             (match_operand:V16QI 1 "register_operand" "f")
1595             (match_operand:V16QI 2 "register_operand" "f"))
1596           (parallel [(const_int 0) (const_int 16)
1597                      (const_int 1) (const_int 17)
1598                      (const_int 2) (const_int 18)
1599                      (const_int 3) (const_int 19)
1600                      (const_int 4) (const_int 20)
1601                      (const_int 5) (const_int 21)
1602                      (const_int 6) (const_int 22)
1603                      (const_int 7) (const_int 23)])))]
1604   "ISA_HAS_LSX"
1605   "vilvl.b\t%w0,%w2,%w1"
1606   [(set_attr "type" "simd_permute")
1607    (set_attr "mode" "V16QI")])
1609 (define_insn "lsx_vilvl_h"
1610   [(set (match_operand:V8HI 0 "register_operand" "=f")
1611         (vec_select:V8HI
1612           (vec_concat:V16HI
1613             (match_operand:V8HI 1 "register_operand" "f")
1614             (match_operand:V8HI 2 "register_operand" "f"))
1615           (parallel [(const_int 0) (const_int 8)
1616                      (const_int 1) (const_int 9)
1617                      (const_int 2) (const_int 10)
1618                      (const_int 3) (const_int 11)])))]
1619   "ISA_HAS_LSX"
1620   "vilvl.h\t%w0,%w2,%w1"
1621   [(set_attr "type" "simd_permute")
1622    (set_attr "mode" "V8HI")])
1624 (define_insn "lsx_vilvl_w"
1625   [(set (match_operand:V4SI 0 "register_operand" "=f")
1626         (vec_select:V4SI
1627           (vec_concat:V8SI
1628             (match_operand:V4SI 1 "register_operand" "f")
1629             (match_operand:V4SI 2 "register_operand" "f"))
1630           (parallel [(const_int 0) (const_int 4)
1631                      (const_int 1) (const_int 5)])))]
1632   "ISA_HAS_LSX"
1633   "vilvl.w\t%w0,%w2,%w1"
1634   [(set_attr "type" "simd_permute")
1635    (set_attr "mode" "V4SI")])
1637 (define_insn "lsx_vilvl_w_f"
1638   [(set (match_operand:V4SF 0 "register_operand" "=f")
1639         (vec_select:V4SF
1640           (vec_concat:V8SF
1641             (match_operand:V4SF 1 "register_operand" "f")
1642             (match_operand:V4SF 2 "register_operand" "f"))
1643           (parallel [(const_int 0) (const_int 4)
1644                      (const_int 1) (const_int 5)])))]
1645   "ISA_HAS_LSX"
1646   "vilvl.w\t%w0,%w2,%w1"
1647   [(set_attr "type" "simd_permute")
1648    (set_attr "mode" "V4SF")])
1650 (define_insn "lsx_vilvl_d"
1651   [(set (match_operand:V2DI 0 "register_operand" "=f")
1652         (vec_select:V2DI
1653           (vec_concat:V4DI
1654             (match_operand:V2DI 1 "register_operand" "f")
1655             (match_operand:V2DI 2 "register_operand" "f"))
1656           (parallel [(const_int 0) (const_int 2)])))]
1657   "ISA_HAS_LSX"
1658   "vilvl.d\t%w0,%w2,%w1"
1659   [(set_attr "type" "simd_permute")
1660    (set_attr "mode" "V2DI")])
1662 (define_insn "lsx_vilvl_d_f"
1663   [(set (match_operand:V2DF 0 "register_operand" "=f")
1664         (vec_select:V2DF
1665           (vec_concat:V4DF
1666             (match_operand:V2DF 1 "register_operand" "f")
1667             (match_operand:V2DF 2 "register_operand" "f"))
1668           (parallel [(const_int 0) (const_int 2)])))]
1669   "ISA_HAS_LSX"
1670   "vilvl.d\t%w0,%w2,%w1"
1671   [(set_attr "type" "simd_permute")
1672    (set_attr "mode" "V2DF")])
1674 (define_insn "smax<mode>3"
1675   [(set (match_operand:ILSX 0 "register_operand" "=f,f")
1676         (smax:ILSX (match_operand:ILSX 1 "register_operand" "f,f")
1677                    (match_operand:ILSX 2 "reg_or_vector_same_simm5_operand" "f,Usv5")))]
1678   "ISA_HAS_LSX"
1679   "@
1680    vmax.<lsxfmt>\t%w0,%w1,%w2
1681    vmaxi.<lsxfmt>\t%w0,%w1,%E2"
1682   [(set_attr "type" "simd_int_arith")
1683    (set_attr "mode" "<MODE>")])
1685 (define_insn "umax<mode>3"
1686   [(set (match_operand:ILSX 0 "register_operand" "=f,f")
1687         (umax:ILSX (match_operand:ILSX 1 "register_operand" "f,f")
1688                    (match_operand:ILSX 2 "reg_or_vector_same_uimm5_operand" "f,Uuv5")))]
1689   "ISA_HAS_LSX"
1690   "@
1691    vmax.<lsxfmt_u>\t%w0,%w1,%w2
1692    vmaxi.<lsxfmt_u>\t%w0,%w1,%B2"
1693   [(set_attr "type" "simd_int_arith")
1694    (set_attr "mode" "<MODE>")])
1696 (define_insn "smin<mode>3"
1697   [(set (match_operand:ILSX 0 "register_operand" "=f,f")
1698         (smin:ILSX (match_operand:ILSX 1 "register_operand" "f,f")
1699                    (match_operand:ILSX 2 "reg_or_vector_same_simm5_operand" "f,Usv5")))]
1700   "ISA_HAS_LSX"
1701   "@
1702    vmin.<lsxfmt>\t%w0,%w1,%w2
1703    vmini.<lsxfmt>\t%w0,%w1,%E2"
1704   [(set_attr "type" "simd_int_arith")
1705    (set_attr "mode" "<MODE>")])
1707 (define_insn "umin<mode>3"
1708   [(set (match_operand:ILSX 0 "register_operand" "=f,f")
1709         (umin:ILSX (match_operand:ILSX 1 "register_operand" "f,f")
1710                    (match_operand:ILSX 2 "reg_or_vector_same_uimm5_operand" "f,Uuv5")))]
1711   "ISA_HAS_LSX"
1712   "@
1713    vmin.<lsxfmt_u>\t%w0,%w1,%w2
1714    vmini.<lsxfmt_u>\t%w0,%w1,%B2"
1715   [(set_attr "type" "simd_int_arith")
1716    (set_attr "mode" "<MODE>")])
1718 (define_insn "lsx_vclo_<lsxfmt>"
1719   [(set (match_operand:ILSX 0 "register_operand" "=f")
1720         (clz:ILSX (not:ILSX (match_operand:ILSX 1 "register_operand" "f"))))]
1721   "ISA_HAS_LSX"
1722   "vclo.<lsxfmt>\t%w0,%w1"
1723   [(set_attr "type" "simd_bit")
1724    (set_attr "mode" "<MODE>")])
1726 (define_insn "clz<mode>2"
1727   [(set (match_operand:ILSX 0 "register_operand" "=f")
1728         (clz:ILSX (match_operand:ILSX 1 "register_operand" "f")))]
1729   "ISA_HAS_LSX"
1730   "vclz.<lsxfmt>\t%w0,%w1"
1731   [(set_attr "type" "simd_bit")
1732    (set_attr "mode" "<MODE>")])
1734 (define_insn "lsx_nor_<lsxfmt>"
1735   [(set (match_operand:ILSX 0 "register_operand" "=f,f")
1736         (and:ILSX (not:ILSX (match_operand:ILSX 1 "register_operand" "f,f"))
1737                   (not:ILSX (match_operand:ILSX 2 "reg_or_vector_same_val_operand" "f,Urv8"))))]
1738   "ISA_HAS_LSX"
1739   "@
1740    vnor.v\t%w0,%w1,%w2
1741    vnori.b\t%w0,%w1,%B2"
1742   [(set_attr "type" "simd_logic")
1743    (set_attr "mode" "<MODE>")])
1745 (define_insn "lsx_vpickev_b"
1746 [(set (match_operand:V16QI 0 "register_operand" "=f")
1747       (vec_select:V16QI
1748         (vec_concat:V32QI
1749           (match_operand:V16QI 1 "register_operand" "f")
1750           (match_operand:V16QI 2 "register_operand" "f"))
1751         (parallel [(const_int 0) (const_int 2)
1752                    (const_int 4) (const_int 6)
1753                    (const_int 8) (const_int 10)
1754                    (const_int 12) (const_int 14)
1755                    (const_int 16) (const_int 18)
1756                    (const_int 20) (const_int 22)
1757                    (const_int 24) (const_int 26)
1758                    (const_int 28) (const_int 30)])))]
1759   "ISA_HAS_LSX"
1760   "vpickev.b\t%w0,%w2,%w1"
1761   [(set_attr "type" "simd_permute")
1762    (set_attr "mode" "V16QI")])
1764 (define_insn "lsx_vpickev_h"
1765 [(set (match_operand:V8HI 0 "register_operand" "=f")
1766       (vec_select:V8HI
1767         (vec_concat:V16HI
1768           (match_operand:V8HI 1 "register_operand" "f")
1769           (match_operand:V8HI 2 "register_operand" "f"))
1770         (parallel [(const_int 0) (const_int 2)
1771                    (const_int 4) (const_int 6)
1772                    (const_int 8) (const_int 10)
1773                    (const_int 12) (const_int 14)])))]
1774   "ISA_HAS_LSX"
1775   "vpickev.h\t%w0,%w2,%w1"
1776   [(set_attr "type" "simd_permute")
1777    (set_attr "mode" "V8HI")])
1779 (define_insn "lsx_vpickev_w"
1780 [(set (match_operand:V4SI 0 "register_operand" "=f")
1781       (vec_select:V4SI
1782         (vec_concat:V8SI
1783           (match_operand:V4SI 1 "register_operand" "f")
1784           (match_operand:V4SI 2 "register_operand" "f"))
1785         (parallel [(const_int 0) (const_int 2)
1786                    (const_int 4) (const_int 6)])))]
1787   "ISA_HAS_LSX"
1788   "vpickev.w\t%w0,%w2,%w1"
1789   [(set_attr "type" "simd_permute")
1790    (set_attr "mode" "V4SI")])
1792 (define_insn "lsx_vpickev_w_f"
1793 [(set (match_operand:V4SF 0 "register_operand" "=f")
1794       (vec_select:V4SF
1795         (vec_concat:V8SF
1796           (match_operand:V4SF 1 "register_operand" "f")
1797           (match_operand:V4SF 2 "register_operand" "f"))
1798         (parallel [(const_int 0) (const_int 2)
1799                    (const_int 4) (const_int 6)])))]
1800   "ISA_HAS_LSX"
1801   "vpickev.w\t%w0,%w2,%w1"
1802   [(set_attr "type" "simd_permute")
1803    (set_attr "mode" "V4SF")])
1805 (define_insn "lsx_vpickod_b"
1806 [(set (match_operand:V16QI 0 "register_operand" "=f")
1807       (vec_select:V16QI
1808         (vec_concat:V32QI
1809           (match_operand:V16QI 1 "register_operand" "f")
1810           (match_operand:V16QI 2 "register_operand" "f"))
1811         (parallel [(const_int 1) (const_int 3)
1812                    (const_int 5) (const_int 7)
1813                    (const_int 9) (const_int 11)
1814                    (const_int 13) (const_int 15)
1815                    (const_int 17) (const_int 19)
1816                    (const_int 21) (const_int 23)
1817                    (const_int 25) (const_int 27)
1818                    (const_int 29) (const_int 31)])))]
1819   "ISA_HAS_LSX"
1820   "vpickod.b\t%w0,%w2,%w1"
1821   [(set_attr "type" "simd_permute")
1822    (set_attr "mode" "V16QI")])
1824 (define_insn "lsx_vpickod_h"
1825 [(set (match_operand:V8HI 0 "register_operand" "=f")
1826       (vec_select:V8HI
1827         (vec_concat:V16HI
1828           (match_operand:V8HI 1 "register_operand" "f")
1829           (match_operand:V8HI 2 "register_operand" "f"))
1830         (parallel [(const_int 1) (const_int 3)
1831                    (const_int 5) (const_int 7)
1832                    (const_int 9) (const_int 11)
1833                    (const_int 13) (const_int 15)])))]
1834   "ISA_HAS_LSX"
1835   "vpickod.h\t%w0,%w2,%w1"
1836   [(set_attr "type" "simd_permute")
1837    (set_attr "mode" "V8HI")])
1839 (define_insn "lsx_vpickod_w"
1840 [(set (match_operand:V4SI 0 "register_operand" "=f")
1841       (vec_select:V4SI
1842         (vec_concat:V8SI
1843           (match_operand:V4SI 1 "register_operand" "f")
1844           (match_operand:V4SI 2 "register_operand" "f"))
1845         (parallel [(const_int 1) (const_int 3)
1846                    (const_int 5) (const_int 7)])))]
1847   "ISA_HAS_LSX"
1848   "vpickod.w\t%w0,%w2,%w1"
1849   [(set_attr "type" "simd_permute")
1850    (set_attr "mode" "V4SI")])
1852 (define_insn "lsx_vpickod_w_f"
1853 [(set (match_operand:V4SF 0 "register_operand" "=f")
1854       (vec_select:V4SF
1855         (vec_concat:V8SF
1856           (match_operand:V4SF 1 "register_operand" "f")
1857           (match_operand:V4SF 2 "register_operand" "f"))
1858         (parallel [(const_int 1) (const_int 3)
1859                    (const_int 5) (const_int 7)])))]
1860   "ISA_HAS_LSX"
1861   "vpickod.w\t%w0,%w2,%w1"
1862   [(set_attr "type" "simd_permute")
1863    (set_attr "mode" "V4SF")])
1865 (define_insn "popcount<mode>2"
1866   [(set (match_operand:ILSX 0 "register_operand" "=f")
1867         (popcount:ILSX (match_operand:ILSX 1 "register_operand" "f")))]
1868   "ISA_HAS_LSX"
1869   "vpcnt.<lsxfmt>\t%w0,%w1"
1870   [(set_attr "type" "simd_pcnt")
1871    (set_attr "mode" "<MODE>")])
1873 (define_insn "lsx_vsat_s_<lsxfmt>"
1874   [(set (match_operand:ILSX 0 "register_operand" "=f")
1875         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1876                       (match_operand 2 "const_<bitimm>_operand" "")]
1877                      UNSPEC_LSX_VSAT_S))]
1878   "ISA_HAS_LSX"
1879   "vsat.<lsxfmt>\t%w0,%w1,%2"
1880   [(set_attr "type" "simd_sat")
1881    (set_attr "mode" "<MODE>")])
1883 (define_insn "lsx_vsat_u_<lsxfmt_u>"
1884   [(set (match_operand:ILSX 0 "register_operand" "=f")
1885         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1886                       (match_operand 2 "const_<bitimm>_operand" "")]
1887                      UNSPEC_LSX_VSAT_U))]
1888   "ISA_HAS_LSX"
1889   "vsat.<lsxfmt_u>\t%w0,%w1,%2"
1890   [(set_attr "type" "simd_sat")
1891    (set_attr "mode" "<MODE>")])
1893 (define_insn "lsx_vshuf4i_<lsxfmt_f>"
1894   [(set (match_operand:LSX_WHB_W 0 "register_operand" "=f")
1895         (vec_select:LSX_WHB_W
1896           (match_operand:LSX_WHB_W 1 "register_operand" "f")
1897           (match_operand 2 "par_const_vector_shf_set_operand" "")))]
1898   "ISA_HAS_LSX"
1900   HOST_WIDE_INT val = 0;
1901   unsigned int i;
1903   /* We convert the selection to an immediate.  */
1904   for (i = 0; i < 4; i++)
1905     val |= INTVAL (XVECEXP (operands[2], 0, i)) << (2 * i);
1907   operands[2] = GEN_INT (val);
1908   return "vshuf4i.<lsxfmt>\t%w0,%w1,%X2";
1910   [(set_attr "type" "simd_shf")
1911    (set_attr "mode" "<MODE>")])
1913 (define_insn "lsx_vsrar_<lsxfmt>"
1914   [(set (match_operand:ILSX 0 "register_operand" "=f")
1915         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1916                       (match_operand:ILSX 2 "register_operand" "f")]
1917                      UNSPEC_LSX_VSRAR))]
1918   "ISA_HAS_LSX"
1919   "vsrar.<lsxfmt>\t%w0,%w1,%w2"
1920   [(set_attr "type" "simd_shift")
1921    (set_attr "mode" "<MODE>")])
1923 (define_insn "lsx_vsrari_<lsxfmt>"
1924   [(set (match_operand:ILSX 0 "register_operand" "=f")
1925         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1926                       (match_operand 2 "const_<bitimm>_operand" "")]
1927                      UNSPEC_LSX_VSRARI))]
1928   "ISA_HAS_LSX"
1929   "vsrari.<lsxfmt>\t%w0,%w1,%2"
1930   [(set_attr "type" "simd_shift")
1931    (set_attr "mode" "<MODE>")])
1933 (define_insn "lsx_vsrlr_<lsxfmt>"
1934   [(set (match_operand:ILSX 0 "register_operand" "=f")
1935         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1936                       (match_operand:ILSX 2 "register_operand" "f")]
1937                      UNSPEC_LSX_VSRLR))]
1938   "ISA_HAS_LSX"
1939   "vsrlr.<lsxfmt>\t%w0,%w1,%w2"
1940   [(set_attr "type" "simd_shift")
1941    (set_attr "mode" "<MODE>")])
1943 (define_insn "lsx_vsrlri_<lsxfmt>"
1944   [(set (match_operand:ILSX 0 "register_operand" "=f")
1945         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
1946                       (match_operand 2 "const_<bitimm>_operand" "")]
1947                      UNSPEC_LSX_VSRLRI))]
1948   "ISA_HAS_LSX"
1949   "vsrlri.<lsxfmt>\t%w0,%w1,%2"
1950   [(set_attr "type" "simd_shift")
1951    (set_attr "mode" "<MODE>")])
1953 (define_insn "lsx_vssub_s_<lsxfmt>"
1954   [(set (match_operand:ILSX 0 "register_operand" "=f")
1955         (ss_minus:ILSX (match_operand:ILSX 1 "register_operand" "f")
1956                       (match_operand:ILSX 2 "register_operand" "f")))]
1957   "ISA_HAS_LSX"
1958   "vssub.<lsxfmt>\t%w0,%w1,%w2"
1959   [(set_attr "type" "simd_int_arith")
1960    (set_attr "mode" "<MODE>")])
1962 (define_insn "lsx_vssub_u_<lsxfmt_u>"
1963   [(set (match_operand:ILSX 0 "register_operand" "=f")
1964         (us_minus:ILSX (match_operand:ILSX 1 "register_operand" "f")
1965                       (match_operand:ILSX 2 "register_operand" "f")))]
1966   "ISA_HAS_LSX"
1967   "vssub.<lsxfmt_u>\t%w0,%w1,%w2"
1968   [(set_attr "type" "simd_int_arith")
1969    (set_attr "mode" "<MODE>")])
1971 (define_insn "lsx_vreplve_<lsxfmt_f>"
1972   [(set (match_operand:LSX 0 "register_operand" "=f")
1973         (vec_duplicate:LSX
1974           (vec_select:<UNITMODE>
1975             (match_operand:LSX 1 "register_operand" "f")
1976             (parallel [(match_operand:SI 2 "register_operand" "r")]))))]
1977   "ISA_HAS_LSX"
1978   "vreplve.<lsxfmt>\t%w0,%w1,%z2"
1979   [(set_attr "type" "simd_splat")
1980    (set_attr "mode" "<MODE>")])
1982 (define_insn "lsx_vreplvei_mirror_<lsxfmt_f>"
1983   [(set (match_operand:LSX 0 "register_operand" "=f")
1984         (unspec: LSX [(match_operand:LSX 1 "register_operand" "f")
1985                                 (match_operand 2 "const_<indeximm>_operand" "")]
1986                                 UNSPEC_LSX_VREPLVEI_MIRROR))]
1987   "ISA_HAS_LSX"
1988   "vreplvei.d\t%w0,%w1,%2"
1989   [(set_attr "type" "simd_splat")
1990    (set_attr "mode" "<MODE>")])
1992 (define_insn "lsx_vreplvei_<lsxfmt_f>"
1993   [(set (match_operand:LSX 0 "register_operand" "=f")
1994         (vec_duplicate:LSX
1995           (vec_select:<UNITMODE>
1996             (match_operand:LSX 1 "register_operand" "f")
1997             (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))]
1998   "ISA_HAS_LSX"
1999   "vreplvei.<lsxfmt>\t%w0,%w1,%2"
2000   [(set_attr "type" "simd_splat")
2001    (set_attr "mode" "<MODE>")])
2003 (define_insn "lsx_vreplvei_<lsxfmt_f>_scalar"
2004   [(set (match_operand:LSX 0 "register_operand" "=f")
2005       (vec_duplicate:LSX
2006         (match_operand:<UNITMODE> 1 "register_operand" "f")))]
2007   "ISA_HAS_LSX"
2008   "vreplvei.<lsxfmt>\t%w0,%w1,0"
2009   [(set_attr "type" "simd_splat")
2010    (set_attr "mode" "<MODE>")])
2012 (define_insn "lsx_vfcvt_h_s"
2013   [(set (match_operand:V8HI 0 "register_operand" "=f")
2014         (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "f")
2015                       (match_operand:V4SF 2 "register_operand" "f")]
2016                      UNSPEC_LSX_VFCVT))]
2017   "ISA_HAS_LSX"
2018   "vfcvt.h.s\t%w0,%w1,%w2"
2019   [(set_attr "type" "simd_fcvt")
2020    (set_attr "mode" "V8HI")])
2022 (define_insn "lsx_vfcvt_s_d"
2023   [(set (match_operand:V4SF 0 "register_operand" "=f")
2024         (unspec:V4SF [(match_operand:V2DF 1 "register_operand" "f")
2025                       (match_operand:V2DF 2 "register_operand" "f")]
2026                      UNSPEC_LSX_VFCVT))]
2027   "ISA_HAS_LSX"
2028   "vfcvt.s.d\t%w0,%w1,%w2"
2029   [(set_attr "type" "simd_fcvt")
2030    (set_attr "mode" "V4SF")])
2032 (define_insn "vec_pack_trunc_v2df"
2033   [(set (match_operand:V4SF 0 "register_operand" "=f")
2034         (vec_concat:V4SF
2035           (float_truncate:V2SF (match_operand:V2DF 1 "register_operand" "f"))
2036           (float_truncate:V2SF (match_operand:V2DF 2 "register_operand" "f"))))]
2037   "ISA_HAS_LSX"
2038   "vfcvt.s.d\t%w0,%w2,%w1"
2039   [(set_attr "type" "simd_fcvt")
2040    (set_attr "mode" "V4SF")])
2042 (define_insn "lsx_vfcvth_s_h"
2043   [(set (match_operand:V4SF 0 "register_operand" "=f")
2044         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "f")]
2045                      UNSPEC_LSX_VFCVTH))]
2046   "ISA_HAS_LSX"
2047   "vfcvth.s.h\t%w0,%w1"
2048   [(set_attr "type" "simd_fcvt")
2049    (set_attr "mode" "V4SF")])
2051 (define_insn "vec_unpacks_hi_v4sf"
2052   [(set (match_operand:V2DF 0 "register_operand" "=f")
2053         (float_extend:V2DF
2054         (vec_select:V2SF
2055           (match_operand:V4SF 1 "register_operand" "f")
2056           (parallel [(const_int 2) (const_int 3)]))))]
2057   "ISA_HAS_LSX"
2058   "vfcvth.d.s\t%w0,%w1"
2059   [(set_attr "type" "simd_fcvt")
2060    (set_attr "mode" "V2DF")])
2062 (define_insn "lsx_vfcvtl_s_h"
2063   [(set (match_operand:V4SF 0 "register_operand" "=f")
2064         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "f")]
2065                      UNSPEC_LSX_VFCVTL))]
2066   "ISA_HAS_LSX"
2067   "vfcvtl.s.h\t%w0,%w1"
2068   [(set_attr "type" "simd_fcvt")
2069    (set_attr "mode" "V4SF")])
2071 (define_insn "vec_unpacks_lo_v4sf"
2072   [(set (match_operand:V2DF 0 "register_operand" "=f")
2073         (float_extend:V2DF
2074         (vec_select:V2SF
2075           (match_operand:V4SF 1 "register_operand" "f")
2076           (parallel [(const_int 0) (const_int 1)]))))]
2077   "ISA_HAS_LSX"
2078   "vfcvtl.d.s\t%w0,%w1"
2079   [(set_attr "type" "simd_fcvt")
2080    (set_attr "mode" "V2DF")])
2082 (define_code_attr lsxbr
2083   [(eq "bz")
2084    (ne "bnz")])
2086 (define_code_attr lsxeq_v
2087   [(eq "eqz")
2088    (ne "nez")])
2090 (define_code_attr lsxne_v
2091   [(eq "nez")
2092    (ne "eqz")])
2094 (define_code_attr lsxeq
2095   [(eq "anyeqz")
2096    (ne "allnez")])
2098 (define_code_attr lsxne
2099   [(eq "allnez")
2100    (ne "anyeqz")])
2102 (define_insn "lsx_<lsxbr>_<lsxfmt_f>"
2103  [(set (pc) (if_then_else
2104               (equality_op
2105                 (unspec:SI [(match_operand:LSX 1 "register_operand" "f")]
2106                             UNSPEC_LSX_BRANCH)
2107                   (match_operand:SI 2 "const_0_operand"))
2108                   (label_ref (match_operand 0))
2109                   (pc)))
2110       (clobber (match_scratch:FCC 3 "=z"))]
2111  "ISA_HAS_LSX"
2113   return loongarch_output_conditional_branch (insn, operands,
2114                                          "vset<lsxeq>.<lsxfmt>\t%Z3%w1\n\tbcnez\t%Z3%0",
2115                                          "vset<lsxne>.<lsxfmt>\t%Z3%w1\n\tbcnez\t%Z3%0");
2117  [(set_attr "type" "simd_branch")
2118   (set_attr "mode" "<MODE>")])
2120 (define_insn "lsx_<lsxbr>_v_<lsxfmt_f>"
2121  [(set (pc) (if_then_else
2122               (equality_op
2123                 (unspec:SI [(match_operand:LSX 1 "register_operand" "f")]
2124                             UNSPEC_LSX_BRANCH_V)
2125                   (match_operand:SI 2 "const_0_operand"))
2126                   (label_ref (match_operand 0))
2127                   (pc)))
2128       (clobber (match_scratch:FCC 3 "=z"))]
2129  "ISA_HAS_LSX"
2131   return loongarch_output_conditional_branch (insn, operands,
2132                                          "vset<lsxeq_v>.v\t%Z3%w1\n\tbcnez\t%Z3%0",
2133                                          "vset<lsxne_v>.v\t%Z3%w1\n\tbcnez\t%Z3%0");
2135  [(set_attr "type" "simd_branch")
2136   (set_attr "mode" "TI")])
2138 ;; vec_concate
2139 (define_expand "vec_concatv2di"
2140   [(set (match_operand:V2DI 0 "register_operand")
2141         (vec_concat:V2DI
2142           (match_operand:DI 1 "register_operand")
2143           (match_operand:DI 2 "register_operand")))]
2144   "ISA_HAS_LSX"
2146   emit_insn (gen_lsx_vinsgr2vr_d (operands[0], operands[1],
2147                                   operands[0], GEN_INT (0)));
2148   emit_insn (gen_lsx_vinsgr2vr_d (operands[0], operands[2],
2149                                   operands[0], GEN_INT (1)));
2150   DONE;
2153 ;; Implement vec_concatv2df by vilvl.d.
2154 (define_insn_and_split "vec_concatv2df"
2155   [(set (match_operand:V2DF 0 "register_operand" "=f")
2156         (vec_concat:V2DF
2157           (match_operand:DF 1 "register_operand" "f")
2158           (match_operand:DF 2 "register_operand" "f")))]
2159   "ISA_HAS_LSX"
2160   ""
2161   "&& reload_completed"
2162   [(const_int 0)]
2164   emit_insn (gen_lsx_vilvl_d_f (operands[0],
2165                                 gen_rtx_REG (V2DFmode, REGNO (operands[1])),
2166                                 gen_rtx_REG (V2DFmode, REGNO (operands[2]))));
2167   DONE;
2169   [(set_attr "mode" "V2DF")])
2171 ;; Implement vec_concatv4sf.
2172 ;; Optimize based on hardware register allocation of operands.
2173 (define_insn_and_split "vec_concatv4sf"
2174   [(set (match_operand:V4SF 0 "register_operand" "=f")
2175         (vec_concat:V4SF
2176           (vec_concat:V2SF
2177             (match_operand:SF 1 "register_operand" "f")
2178             (match_operand:SF 2 "register_operand" "f"))
2179           (vec_concat:V2SF
2180             (match_operand:SF 3 "register_operand" "f")
2181             (match_operand:SF 4 "register_operand" "f"))))]
2182   "ISA_HAS_LSX"
2183   ""
2184   "&& reload_completed"
2185   [(const_int 0)]
2187   operands[5] = GEN_INT (1);
2188   operands[6] = GEN_INT (2);
2189   operands[7] = GEN_INT (4);
2190   operands[8] = GEN_INT (8);
2192   /* If all input are same, use vreplvei.w to broadcast.  */
2193   if (REGNO (operands[1]) == REGNO (operands[2])
2194       && REGNO (operands[1]) == REGNO (operands[3])
2195       && REGNO (operands[1]) == REGNO (operands[4]))
2196     {
2197       emit_insn (gen_lsx_vreplvei_w_f_scalar (operands[0], operands[1]));
2198     }
2199   /* If op0 is equal to op3, use vreplvei.w to set each element of op0 as op3.
2200      If other input is different from op3, use vextrins.w to insert.  */
2201   else if (REGNO (operands[0]) == REGNO (operands[3]))
2202     {
2203       emit_insn (gen_lsx_vreplvei_w_f_scalar (operands[0], operands[3]));
2204       if (REGNO (operands[1]) != REGNO (operands[3]))
2205         emit_insn (gen_lsx_vextrins_w_f_scalar (operands[0], operands[1],
2206                                                 operands[0], operands[5]));
2207       if (REGNO (operands[2]) != REGNO (operands[3]))
2208         emit_insn (gen_lsx_vextrins_w_f_scalar (operands[0], operands[2],
2209                                                 operands[0], operands[6]));
2210       if (REGNO (operands[4]) != REGNO (operands[3]))
2211         emit_insn (gen_lsx_vextrins_w_f_scalar (operands[0], operands[4],
2212                                                 operands[0], operands[8]));
2213     }
2214   /* If op0 is equal to op4, use vreplvei.w to set each element of op0 as op4.
2215      If other input is different from op4, use vextrins.w to insert.  */
2216   else if (REGNO (operands[0]) == REGNO (operands[4]))
2217     {
2218       emit_insn (gen_lsx_vreplvei_w_f_scalar (operands[0], operands[4]));
2219       if (REGNO (operands[1]) != REGNO (operands[4]))
2220         emit_insn (gen_lsx_vextrins_w_f_scalar (operands[0], operands[1],
2221                                                 operands[0], operands[5]));
2222       if (REGNO (operands[2]) != REGNO (operands[4]))
2223         emit_insn (gen_lsx_vextrins_w_f_scalar (operands[0], operands[2],
2224                                                 operands[0], operands[6]));
2225       if (REGNO (operands[3]) != REGNO (operands[4]))
2226         emit_insn (gen_lsx_vextrins_w_f_scalar (operands[0], operands[3],
2227                                                 operands[0], operands[7]));
2228     }
2229   /* Otherwise, use vilvl.w to merge op1 and op2 first.
2230      If op3 is different from op1, use vextrins.w to insert.
2231      If op4 is different from op2, use vextrins.w to insert.  */
2232   else
2233     {
2234       emit_insn (
2235         gen_lsx_vilvl_w_f (operands[0],
2236                            gen_rtx_REG (V4SFmode, REGNO (operands[1])),
2237                            gen_rtx_REG (V4SFmode, REGNO (operands[2]))));
2238       emit_insn (gen_lsx_vextrins_w_f_scalar (operands[0], operands[3],
2239                                               operands[0], operands[7]));
2240       emit_insn (gen_lsx_vextrins_w_f_scalar (operands[0], operands[4],
2241                                               operands[0], operands[8]));
2242     }
2243   DONE;
2245   [(set_attr "mode" "V4SF")])
2247 (define_insn "andn<mode>3"
2248   [(set (match_operand:LSX 0 "register_operand" "=f")
2249         (and:LSX (not:LSX (match_operand:LSX 2 "register_operand" "f"))
2250                  (match_operand:LSX 1 "register_operand" "f")))]
2251   "ISA_HAS_LSX"
2252   "vandn.v\t%w0,%w2,%w1"
2253   [(set_attr "type" "simd_logic")
2254    (set_attr "mode" "<MODE>")])
2256 (define_insn "abs<mode>2"
2257   [(set (match_operand:ILSX 0 "register_operand" "=f")
2258         (abs:ILSX (match_operand:ILSX 1 "register_operand" "f")))]
2259   "ISA_HAS_LSX"
2260   "vsigncov.<lsxfmt>\t%w0,%w1,%w1"
2261   [(set_attr "type" "simd_logic")
2262    (set_attr "mode" "<MODE>")])
2264 (define_insn "vneg<mode>2"
2265   [(set (match_operand:ILSX 0 "register_operand" "=f")
2266         (neg:ILSX (match_operand:ILSX 1 "register_operand" "f")))]
2267   "ISA_HAS_LSX"
2268   "vneg.<lsxfmt>\t%w0,%w1"
2269   [(set_attr "type" "simd_logic")
2270    (set_attr "mode" "<MODE>")])
2272 (define_insn "lsx_vextw_s_d"
2273   [(set (match_operand:V2DI 0 "register_operand" "=f")
2274         (unspec:V2DI [(match_operand:V4SI 1 "register_operand" "f")]
2275                      UNSPEC_LSX_VEXTW_S))]
2276   "ISA_HAS_LSX"
2277   "vextw_s.d\t%w0,%w1"
2278   [(set_attr "type" "simd_fcvt")
2279    (set_attr "mode" "V4SI")])
2281 (define_insn "lsx_vextw_u_d"
2282   [(set (match_operand:V2DI 0 "register_operand" "=f")
2283         (unspec:V2DI [(match_operand:V4SI 1 "register_operand" "f")]
2284                      UNSPEC_LSX_VEXTW_U))]
2285   "ISA_HAS_LSX"
2286   "vextw_u.d\t%w0,%w1"
2287   [(set_attr "type" "simd_fcvt")
2288    (set_attr "mode" "V4SI")])
2290 (define_insn "lsx_vsllwil_s_<dlsxfmt>_<lsxfmt>"
2291   [(set (match_operand:<VDMODE> 0 "register_operand" "=f")
2292         (unspec:<VDMODE> [(match_operand:ILSX_WHB 1 "register_operand" "f")
2293                           (match_operand 2 "const_<bitimm>_operand" "")]
2294                          UNSPEC_LSX_VSLLWIL_S))]
2295   "ISA_HAS_LSX"
2296   "vsllwil.<dlsxfmt>.<lsxfmt>\t%w0,%w1,%2"
2297   [(set_attr "type" "simd_shift")
2298    (set_attr "mode" "<MODE>")])
2300 (define_insn "lsx_vsllwil_u_<dlsxfmt_u>_<lsxfmt_u>"
2301   [(set (match_operand:<VDMODE> 0 "register_operand" "=f")
2302         (unspec:<VDMODE> [(match_operand:ILSX_WHB 1 "register_operand" "f")
2303                           (match_operand 2 "const_<bitimm>_operand" "")]
2304                          UNSPEC_LSX_VSLLWIL_U))]
2305   "ISA_HAS_LSX"
2306   "vsllwil.<dlsxfmt_u>.<lsxfmt_u>\t%w0,%w1,%2"
2307   [(set_attr "type" "simd_shift")
2308    (set_attr "mode" "<MODE>")])
2310 (define_insn "lsx_vsran_<hlsxfmt>_<lsxfmt>"
2311   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2312         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2313                           (match_operand:ILSX_DWH 2 "register_operand" "f")]
2314                          UNSPEC_LSX_VSRAN))]
2315   "ISA_HAS_LSX"
2316   "vsran.<hlsxfmt>.<lsxfmt>\t%w0,%w1,%w2"
2317   [(set_attr "type" "simd_int_arith")
2318    (set_attr "mode" "<MODE>")])
2320 (define_insn "lsx_vssran_s_<hlsxfmt>_<lsxfmt>"
2321   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2322         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2323                           (match_operand:ILSX_DWH 2 "register_operand" "f")]
2324                          UNSPEC_LSX_VSSRAN_S))]
2325   "ISA_HAS_LSX"
2326   "vssran.<hlsxfmt>.<lsxfmt>\t%w0,%w1,%w2"
2327   [(set_attr "type" "simd_int_arith")
2328    (set_attr "mode" "<MODE>")])
2330 (define_insn "lsx_vssran_u_<hlsxfmt_u>_<lsxfmt>"
2331   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2332         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2333                           (match_operand:ILSX_DWH 2 "register_operand" "f")]
2334                          UNSPEC_LSX_VSSRAN_U))]
2335   "ISA_HAS_LSX"
2336   "vssran.<hlsxfmt_u>.<lsxfmt>\t%w0,%w1,%w2"
2337   [(set_attr "type" "simd_int_arith")
2338    (set_attr "mode" "<MODE>")])
2340 (define_insn "lsx_vsrain_<hlsxfmt>"
2341   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2342         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2343                           (match_operand 2 "const_<bitimm>_operand" "")]
2344                          UNSPEC_LSX_VSRAIN))]
2345   "ISA_HAS_LSX"
2346   "vsrain.<hlsxfmt>\t%w0,%w1,%2"
2347   [(set_attr "type" "simd_shift")
2348    (set_attr "mode" "<MODE>")])
2350 ;; FIXME: bitimm
2351 (define_insn "lsx_vsrains_s_<hlsxfmt>"
2352   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2353         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2354                           (match_operand 2 "const_<bitimm>_operand" "")]
2355                          UNSPEC_LSX_VSRAINS_S))]
2356   "ISA_HAS_LSX"
2357   "vsrains_s.<hlsxfmt>\t%w0,%w1,%2"
2358   [(set_attr "type" "simd_shift")
2359    (set_attr "mode" "<MODE>")])
2361 ;; FIXME: bitimm
2362 (define_insn "lsx_vsrains_u_<hlsxfmt>"
2363   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2364         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2365                           (match_operand 2 "const_<bitimm>_operand" "")]
2366                          UNSPEC_LSX_VSRAINS_U))]
2367   "ISA_HAS_LSX"
2368   "vsrains_u.<hlsxfmt>\t%w0,%w1,%2"
2369   [(set_attr "type" "simd_shift")
2370    (set_attr "mode" "<MODE>")])
2372 (define_insn "lsx_vsrarn_<hlsxfmt>_<lsxfmt>"
2373   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2374         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2375                           (match_operand:ILSX_DWH 2 "register_operand" "f")]
2376                          UNSPEC_LSX_VSRARN))]
2377   "ISA_HAS_LSX"
2378   "vsrarn.<hlsxfmt>.<lsxfmt>\t%w0,%w1,%w2"
2379   [(set_attr "type" "simd_int_arith")
2380    (set_attr "mode" "<MODE>")])
2382 (define_insn "lsx_vssrarn_s_<hlsxfmt>_<lsxfmt>"
2383   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2384         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2385                           (match_operand:ILSX_DWH 2 "register_operand" "f")]
2386                          UNSPEC_LSX_VSSRARN_S))]
2387   "ISA_HAS_LSX"
2388   "vssrarn.<hlsxfmt>.<lsxfmt>\t%w0,%w1,%w2"
2389   [(set_attr "type" "simd_int_arith")
2390    (set_attr "mode" "<MODE>")])
2392 (define_insn "lsx_vssrarn_u_<hlsxfmt_u>_<lsxfmt>"
2393   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2394         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2395                           (match_operand:ILSX_DWH 2 "register_operand" "f")]
2396                          UNSPEC_LSX_VSSRARN_U))]
2397   "ISA_HAS_LSX"
2398   "vssrarn.<hlsxfmt_u>.<lsxfmt>\t%w0,%w1,%w2"
2399   [(set_attr "type" "simd_int_arith")
2400    (set_attr "mode" "<MODE>")])
2402 (define_insn "lsx_vsrln_<hlsxfmt>_<lsxfmt>"
2403   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2404         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2405                           (match_operand:ILSX_DWH 2 "register_operand" "f")]
2406                          UNSPEC_LSX_VSRLN))]
2407   "ISA_HAS_LSX"
2408   "vsrln.<hlsxfmt>.<lsxfmt>\t%w0,%w1,%w2"
2409   [(set_attr "type" "simd_int_arith")
2410    (set_attr "mode" "<MODE>")])
2412 (define_insn "lsx_vssrln_u_<hlsxfmt_u>_<lsxfmt>"
2413   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2414         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2415                           (match_operand:ILSX_DWH 2 "register_operand" "f")]
2416                          UNSPEC_LSX_VSSRLN_U))]
2417   "ISA_HAS_LSX"
2418   "vssrln.<hlsxfmt_u>.<lsxfmt>\t%w0,%w1,%w2"
2419   [(set_attr "type" "simd_int_arith")
2420    (set_attr "mode" "<MODE>")])
2422 (define_insn "lsx_vsrlrn_<hlsxfmt>_<lsxfmt>"
2423   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2424         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2425                           (match_operand:ILSX_DWH 2 "register_operand" "f")]
2426                          UNSPEC_LSX_VSRLRN))]
2427   "ISA_HAS_LSX"
2428   "vsrlrn.<hlsxfmt>.<lsxfmt>\t%w0,%w1,%w2"
2429   [(set_attr "type" "simd_int_arith")
2430    (set_attr "mode" "<MODE>")])
2432 (define_insn "lsx_vssrlrn_u_<hlsxfmt_u>_<lsxfmt>"
2433   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2434         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2435                           (match_operand:ILSX_DWH 2 "register_operand" "f")]
2436                          UNSPEC_LSX_VSSRLRN_U))]
2437   "ISA_HAS_LSX"
2438   "vssrlrn.<hlsxfmt_u>.<lsxfmt>\t%w0,%w1,%w2"
2439   [(set_attr "type" "simd_int_arith")
2440    (set_attr "mode" "<MODE>")])
2442 (define_insn "lsx_vfrstpi_<lsxfmt>"
2443   [(set (match_operand:ILSX_HB 0 "register_operand" "=f")
2444         (unspec:ILSX_HB [(match_operand:ILSX_HB 1 "register_operand" "0")
2445                          (match_operand:ILSX_HB 2 "register_operand" "f")
2446                          (match_operand 3 "const_uimm5_operand" "")]
2447                         UNSPEC_LSX_VFRSTPI))]
2448   "ISA_HAS_LSX"
2449   "vfrstpi.<lsxfmt>\t%w0,%w2,%3"
2450   [(set_attr "type" "simd_shift")
2451    (set_attr "mode" "<MODE>")])
2453 (define_insn "lsx_vfrstp_<lsxfmt>"
2454   [(set (match_operand:ILSX_HB 0 "register_operand" "=f")
2455         (unspec:ILSX_HB [(match_operand:ILSX_HB 1 "register_operand" "0")
2456                          (match_operand:ILSX_HB 2 "register_operand" "f")
2457                          (match_operand:ILSX_HB 3 "register_operand" "f")]
2458                         UNSPEC_LSX_VFRSTP))]
2459   "ISA_HAS_LSX"
2460   "vfrstp.<lsxfmt>\t%w0,%w2,%w3"
2461   [(set_attr "type" "simd_int_arith")
2462    (set_attr "mode" "<MODE>")])
2464 (define_insn "lsx_vshuf4i_d"
2465   [(set (match_operand:V2DI 0 "register_operand" "=f")
2466         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
2467                       (match_operand:V2DI 2 "register_operand" "f")
2468                       (match_operand 3 "const_uimm8_operand")]
2469                      UNSPEC_LSX_VSHUF4I))]
2470   "ISA_HAS_LSX"
2471   "vshuf4i.d\t%w0,%w2,%3"
2472   [(set_attr "type" "simd_sld")
2473    (set_attr "mode" "V2DI")])
2475 (define_insn "lsx_vbsrl_<lsxfmt_f>"
2476   [(set (match_operand:LSX 0 "register_operand" "=f")
2477         (unspec:LSX [(match_operand:LSX 1 "register_operand" "f")
2478                      (match_operand 2 "const_uimm5_operand" "")]
2479                     UNSPEC_LSX_VBSRL_V))]
2480   "ISA_HAS_LSX"
2481   "vbsrl.v\t%w0,%w1,%2"
2482   [(set_attr "type" "simd_shift")
2483    (set_attr "mode" "<MODE>")])
2485 (define_insn "lsx_vbsll_<lsxfmt>"
2486   [(set (match_operand:ILSX 0 "register_operand" "=f")
2487         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
2488                       (match_operand 2 "const_uimm5_operand" "")]
2489                      UNSPEC_LSX_VBSLL_V))]
2490   "ISA_HAS_LSX"
2491   "vbsll.v\t%w0,%w1,%2"
2492   [(set_attr "type" "simd_shift")
2493    (set_attr "mode" "<MODE>")])
2495 (define_insn "lsx_vextrins_<lsxfmt>"
2496   [(set (match_operand:ILSX 0 "register_operand" "=f")
2497         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
2498                       (match_operand:ILSX 2 "register_operand" "f")
2499                       (match_operand 3 "const_uimm8_operand" "")]
2500                      UNSPEC_LSX_VEXTRINS))]
2501   "ISA_HAS_LSX"
2502   "vextrins.<lsxfmt>\t%w0,%w2,%3"
2503   [(set_attr "type" "simd_shift")
2504    (set_attr "mode" "<MODE>")])
2506 (define_insn "lsx_vmskltz_<lsxfmt>"
2507   [(set (match_operand:ILSX 0 "register_operand" "=f")
2508         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")]
2509                      UNSPEC_LSX_VMSKLTZ))]
2510   "ISA_HAS_LSX"
2511   "vmskltz.<lsxfmt>\t%w0,%w1"
2512   [(set_attr "type" "simd_shift")
2513    (set_attr "mode" "<MODE>")])
2515 (define_insn "lsx_vsigncov_<lsxfmt>"
2516   [(set (match_operand:ILSX 0 "register_operand" "=f")
2517         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "f")
2518                       (match_operand:ILSX 2 "register_operand" "f")]
2519                      UNSPEC_LSX_VSIGNCOV))]
2520   "ISA_HAS_LSX"
2521   "vsigncov.<lsxfmt>\t%w0,%w1,%w2"
2522   [(set_attr "type" "simd_int_arith")
2523    (set_attr "mode" "<MODE>")])
2525 (define_expand "copysign<mode>3"
2526   [(set (match_dup 4)
2527         (and:FLSX
2528           (not:FLSX (match_dup 3))
2529           (match_operand:FLSX 1 "register_operand")))
2530    (set (match_dup 5)
2531         (and:FLSX (match_dup 3)
2532                   (match_operand:FLSX 2 "reg_or_vector_same_val_operand")))
2533    (set (match_operand:FLSX 0 "register_operand")
2534         (ior:FLSX (match_dup 4) (match_dup 5)))]
2535   "ISA_HAS_LSX"
2537   /* copysign (x, -1) should instead be expanded as setting the sign
2538      bit.  */
2539   if (!REG_P (operands[2]))
2540     {
2541       rtx op2_elt = unwrap_const_vec_duplicate (operands[2]);
2542       if (GET_CODE (op2_elt) == CONST_DOUBLE
2543           && real_isneg (CONST_DOUBLE_REAL_VALUE (op2_elt)))
2544         {
2545           rtx n = GEN_INT (8 * GET_MODE_SIZE (<UNITMODE>mode) - 1);
2546           operands[0] = lowpart_subreg (<VIMODE>mode, operands[0],
2547                                         <MODE>mode);
2548           operands[1] = lowpart_subreg (<VIMODE>mode, operands[1],
2549                                         <MODE>mode);
2550           emit_insn (gen_lsx_vbitseti_<lsxfmt> (operands[0], operands[1],
2551                                                 n));
2552           DONE;
2553         }
2554     }
2556   operands[2] = force_reg (<MODE>mode, operands[2]);
2557   operands[3] = loongarch_build_signbit_mask (<MODE>mode, 1, 0);
2559   operands[4] = gen_reg_rtx (<MODE>mode);
2560   operands[5] = gen_reg_rtx (<MODE>mode);
2563 (define_expand "@xorsign<mode>3"
2564   [(set (match_dup 4)
2565     (and:FLSX (match_dup 3)
2566         (match_operand:FLSX 2 "register_operand")))
2567    (set (match_operand:FLSX 0 "register_operand")
2568     (xor:FLSX (match_dup 4)
2569          (match_operand:FLSX 1 "register_operand")))]
2570   "ISA_HAS_LSX"
2572   operands[3] = loongarch_build_signbit_mask (<MODE>mode, 1, 0);
2574   operands[4] = gen_reg_rtx (<MODE>mode);
2578 (define_insn "absv2df2"
2579   [(set (match_operand:V2DF 0 "register_operand" "=f")
2580         (abs:V2DF (match_operand:V2DF 1 "register_operand" "f")))]
2581   "ISA_HAS_LSX"
2582   "vbitclri.d\t%w0,%w1,63"
2583   [(set_attr "type" "simd_logic")
2584    (set_attr "mode" "V2DF")])
2586 (define_insn "absv4sf2"
2587   [(set (match_operand:V4SF 0 "register_operand" "=f")
2588         (abs:V4SF (match_operand:V4SF 1 "register_operand" "f")))]
2589   "ISA_HAS_LSX"
2590   "vbitclri.w\t%w0,%w1,31"
2591   [(set_attr "type" "simd_logic")
2592    (set_attr "mode" "V4SF")])
2594 (define_insn "vfmadd<mode>4"
2595   [(set (match_operand:FLSX 0 "register_operand" "=f")
2596         (fma:FLSX (match_operand:FLSX 1 "register_operand" "f")
2597                   (match_operand:FLSX 2 "register_operand" "f")
2598                   (match_operand:FLSX 3 "register_operand" "f")))]
2599   "ISA_HAS_LSX"
2600   "vfmadd.<flsxfmt>\t%w0,%w1,$w2,%w3"
2601   [(set_attr "type" "simd_fmadd")
2602    (set_attr "mode" "<MODE>")])
2604 (define_insn "fms<mode>4"
2605   [(set (match_operand:FLSX 0 "register_operand" "=f")
2606         (fma:FLSX (match_operand:FLSX 1 "register_operand" "f")
2607                   (match_operand:FLSX 2 "register_operand" "f")
2608                   (neg:FLSX (match_operand:FLSX 3 "register_operand" "f"))))]
2609   "ISA_HAS_LSX"
2610   "vfmsub.<flsxfmt>\t%w0,%w1,%w2,%w3"
2611   [(set_attr "type" "simd_fmadd")
2612    (set_attr "mode" "<MODE>")])
2614 (define_insn "vfnmsub<mode>4_nmsub4"
2615   [(set (match_operand:FLSX 0 "register_operand" "=f")
2616         (neg:FLSX
2617           (fma:FLSX
2618             (match_operand:FLSX 1 "register_operand" "f")
2619             (match_operand:FLSX 2 "register_operand" "f")
2620             (neg:FLSX (match_operand:FLSX 3 "register_operand" "f")))))]
2621   "ISA_HAS_LSX"
2622   "vfnmsub.<flsxfmt>\t%w0,%w1,%w2,%w3"
2623   [(set_attr "type" "simd_fmadd")
2624    (set_attr "mode" "<MODE>")])
2627 (define_insn "vfnmadd<mode>4_nmadd4"
2628   [(set (match_operand:FLSX 0 "register_operand" "=f")
2629         (neg:FLSX
2630           (fma:FLSX
2631             (match_operand:FLSX 1 "register_operand" "f")
2632             (match_operand:FLSX 2 "register_operand" "f")
2633             (match_operand:FLSX 3 "register_operand" "f"))))]
2634   "ISA_HAS_LSX"
2635   "vfnmadd.<flsxfmt>\t%w0,%w1,%w2,%w3"
2636   [(set_attr "type" "simd_fmadd")
2637    (set_attr "mode" "<MODE>")])
2639 (define_insn "lsx_vftint_w_d"
2640   [(set (match_operand:V4SI 0 "register_operand" "=f")
2641         (unspec:V4SI [(match_operand:V2DF 1 "register_operand" "f")
2642                       (match_operand:V2DF 2 "register_operand" "f")]
2643                      UNSPEC_LSX_VFTINT_W_D))]
2644   "ISA_HAS_LSX"
2645   "vftint.w.d\t%w0,%w1,%w2"
2646   [(set_attr "type" "simd_int_arith")
2647    (set_attr "mode" "V2DF")])
2649 (define_insn "vec_packs_float_v2di"
2650   [(set (match_operand:V4SF 0 "register_operand" "=f")
2651         (vec_concat:V4SF
2652           (float:V2SF (match_operand:V2DI 1 "register_operand" "f"))
2653           (float:V2SF (match_operand:V2DI 2 "register_operand" "f"))))]
2654   "ISA_HAS_LSX"
2655   "vffint.s.l\t%w0,%w2,%w1"
2656   [(set_attr "type" "simd_int_arith")
2657    (set_attr "mode" "V2DI")])
2659 (define_insn "vec_pack_sfix_trunc_v2df"
2660   [(set (match_operand:V4SI 0 "register_operand" "=f")
2661         (vec_concat:V4SI
2662           (fix:V2SI (match_operand:V2DF 1 "register_operand" "f"))
2663           (fix:V2SI (match_operand:V2DF 2 "register_operand" "f"))))]
2664   "ISA_HAS_LSX"
2665   "vftintrz.w.d\t%w0,%w2,%w1"
2666   [(set_attr "type" "simd_int_arith")
2667    (set_attr "mode" "V2DF")])
2669 (define_insn "lsx_vftintrp_w_d"
2670   [(set (match_operand:V4SI 0 "register_operand" "=f")
2671         (unspec:V4SI [(match_operand:V2DF 1 "register_operand" "f")
2672                       (match_operand:V2DF 2 "register_operand" "f")]
2673                      UNSPEC_LSX_VFTINTRP_W_D))]
2674   "ISA_HAS_LSX"
2675   "vftintrp.w.d\t%w0,%w1,%w2"
2676   [(set_attr "type" "simd_int_arith")
2677    (set_attr "mode" "V2DF")])
2679 (define_insn "lsx_vftintrm_w_d"
2680   [(set (match_operand:V4SI 0 "register_operand" "=f")
2681         (unspec:V4SI [(match_operand:V2DF 1 "register_operand" "f")
2682                       (match_operand:V2DF 2 "register_operand" "f")]
2683                      UNSPEC_LSX_VFTINTRM_W_D))]
2684   "ISA_HAS_LSX"
2685   "vftintrm.w.d\t%w0,%w1,%w2"
2686   [(set_attr "type" "simd_int_arith")
2687    (set_attr "mode" "V2DF")])
2689 (define_insn "lsx_vftintrne_w_d"
2690   [(set (match_operand:V4SI 0 "register_operand" "=f")
2691         (unspec:V4SI [(match_operand:V2DF 1 "register_operand" "f")
2692                       (match_operand:V2DF 2 "register_operand" "f")]
2693                      UNSPEC_LSX_VFTINTRNE_W_D))]
2694   "ISA_HAS_LSX"
2695   "vftintrne.w.d\t%w0,%w1,%w2"
2696   [(set_attr "type" "simd_int_arith")
2697    (set_attr "mode" "V2DF")])
2699 (define_insn "lsx_vftinth_l_s"
2700   [(set (match_operand:V2DI 0 "register_operand" "=f")
2701         (unspec:V2DI [(match_operand:V4SF 1 "register_operand" "f")]
2702                      UNSPEC_LSX_VFTINTH_L_H))]
2703   "ISA_HAS_LSX"
2704   "vftinth.l.s\t%w0,%w1"
2705   [(set_attr "type" "simd_shift")
2706    (set_attr "mode" "V4SF")])
2708 (define_insn "lsx_vftintl_l_s"
2709   [(set (match_operand:V2DI 0 "register_operand" "=f")
2710         (unspec:V2DI [(match_operand:V4SF 1 "register_operand" "f")]
2711                      UNSPEC_LSX_VFTINTL_L_S))]
2712   "ISA_HAS_LSX"
2713   "vftintl.l.s\t%w0,%w1"
2714   [(set_attr "type" "simd_shift")
2715    (set_attr "mode" "V4SF")])
2717 (define_insn "vec_unpacks_float_hi_v4si"
2718   [(set (match_operand:V2DF 0 "register_operand" "=f")
2719         (float:V2DF
2720           (vec_select:V2SI
2721             (match_operand:V4SI 1 "register_operand" "f")
2722             (parallel [(const_int 2) (const_int 3)]))))]
2723   "ISA_HAS_LSX"
2724   "vffinth.d.w\t%w0,%w1"
2725   [(set_attr "type" "simd_shift")
2726    (set_attr "mode" "V4SI")])
2728 (define_insn "vec_unpacks_float_lo_v4si"
2729   [(set (match_operand:V2DF 0 "register_operand" "=f")
2730         (float:V2DF
2731           (vec_select:V2SI
2732             (match_operand:V4SI 1 "register_operand" "f")
2733             (parallel [(const_int 0) (const_int 1)]))))]
2734   "ISA_HAS_LSX"
2735   "vffintl.d.w\t%w0,%w1"
2736   [(set_attr "type" "simd_shift")
2737    (set_attr "mode" "V4SI")])
2739 (define_insn "vec_unpack_sfix_trunc_hi_v4sf"
2740   [(set (match_operand:V2DI 0 "register_operand" "=f")
2741         (fix:V2DI
2742           (vec_select:V2SF
2743             (match_operand:V4SF 1 "register_operand" "f")
2744             (parallel [(const_int 2) (const_int 3)]))))]
2745   "ISA_HAS_LSX"
2746   "vftintrzh.l.s\t%w0,%w1"
2747   [(set_attr "type" "simd_shift")
2748    (set_attr "mode" "V4SF")])
2750 (define_insn "vec_unpack_sfix_trunc_lo_v4sf"
2751   [(set (match_operand:V2DI 0 "register_operand" "=f")
2752         (fix:V2DI
2753           (vec_select:V2SF
2754             (match_operand:V4SF 1 "register_operand" "f")
2755             (parallel [(const_int 0) (const_int 1)]))))]
2756   "ISA_HAS_LSX"
2757   "vftintrzl.l.s\t%w0,%w1"
2758   [(set_attr "type" "simd_shift")
2759    (set_attr "mode" "V4SF")])
2761 (define_insn "lsx_vftintrph_l_s"
2762   [(set (match_operand:V2DI 0 "register_operand" "=f")
2763         (unspec:V2DI [(match_operand:V4SF 1 "register_operand" "f")]
2764                      UNSPEC_LSX_VFTINTRPH_L_S))]
2765   "ISA_HAS_LSX"
2766   "vftintrph.l.s\t%w0,%w1"
2767   [(set_attr "type" "simd_shift")
2768    (set_attr "mode" "V4SF")])
2770 (define_insn "lsx_vftintrpl_l_s"
2771   [(set (match_operand:V2DI 0 "register_operand" "=f")
2772         (unspec:V2DI [(match_operand:V4SF 1 "register_operand" "f")]
2773                      UNSPEC_LSX_VFTINTRPL_L_S))]
2774   "ISA_HAS_LSX"
2775   "vftintrpl.l.s\t%w0,%w1"
2776   [(set_attr "type" "simd_shift")
2777    (set_attr "mode" "V4SF")])
2779 (define_insn "lsx_vftintrmh_l_s"
2780   [(set (match_operand:V2DI 0 "register_operand" "=f")
2781         (unspec:V2DI [(match_operand:V4SF 1 "register_operand" "f")]
2782                      UNSPEC_LSX_VFTINTRMH_L_S))]
2783   "ISA_HAS_LSX"
2784   "vftintrmh.l.s\t%w0,%w1"
2785   [(set_attr "type" "simd_shift")
2786    (set_attr "mode" "V4SF")])
2788 (define_insn "lsx_vftintrml_l_s"
2789   [(set (match_operand:V2DI 0 "register_operand" "=f")
2790         (unspec:V2DI [(match_operand:V4SF 1 "register_operand" "f")]
2791                      UNSPEC_LSX_VFTINTRML_L_S))]
2792   "ISA_HAS_LSX"
2793   "vftintrml.l.s\t%w0,%w1"
2794   [(set_attr "type" "simd_shift")
2795    (set_attr "mode" "V4SF")])
2797 (define_insn "lsx_vftintrneh_l_s"
2798   [(set (match_operand:V2DI 0 "register_operand" "=f")
2799         (unspec:V2DI [(match_operand:V4SF 1 "register_operand" "f")]
2800                      UNSPEC_LSX_VFTINTRNEH_L_S))]
2801   "ISA_HAS_LSX"
2802   "vftintrneh.l.s\t%w0,%w1"
2803   [(set_attr "type" "simd_shift")
2804    (set_attr "mode" "V4SF")])
2806 (define_insn "lsx_vftintrnel_l_s"
2807   [(set (match_operand:V2DI 0 "register_operand" "=f")
2808         (unspec:V2DI [(match_operand:V4SF 1 "register_operand" "f")]
2809                      UNSPEC_LSX_VFTINTRNEL_L_S))]
2810   "ISA_HAS_LSX"
2811   "vftintrnel.l.s\t%w0,%w1"
2812   [(set_attr "type" "simd_shift")
2813    (set_attr "mode" "V4SF")])
2815 ;; Offset load and broadcast
2816 (define_expand "lsx_vldrepl_<lsxfmt_f>"
2817   [(match_operand:LSX 0 "register_operand")
2818    (match_operand 1 "pmode_register_operand")
2819    (match_operand 2 "aq12<lsxfmt>_operand")]
2820   "ISA_HAS_LSX"
2822   emit_insn (gen_lsx_vldrepl_<lsxfmt_f>_insn
2823              (operands[0], operands[1], operands[2]));
2824   DONE;
2827 (define_insn "lsx_vldrepl_<lsxfmt_f>_insn"
2828   [(set (match_operand:LSX 0 "register_operand" "=f")
2829         (vec_duplicate:LSX
2830           (mem:<UNITMODE> (plus:DI (match_operand:DI 1 "register_operand" "r")
2831                                    (match_operand 2 "aq12<lsxfmt>_operand")))))]
2832   "ISA_HAS_LSX"
2834     return "vldrepl.<lsxfmt>\t%w0,%1,%2";
2836   [(set_attr "type" "simd_load")
2837    (set_attr "mode" "<MODE>")
2838    (set_attr "length" "4")])
2840 (define_insn "lsx_vldrepl_<lsxfmt_f>_insn_0"
2841   [(set (match_operand:LSX 0 "register_operand" "=f")
2842     (vec_duplicate:LSX
2843       (mem:<UNITMODE> (match_operand:DI 1 "register_operand" "r"))))]
2844   "ISA_HAS_LSX"
2846     return "vldrepl.<lsxfmt>\t%w0,%1,0";
2848   [(set_attr "type" "simd_load")
2849    (set_attr "mode" "<MODE>")
2850    (set_attr "length" "4")])
2852 ;; Offset store by sel
2853 (define_expand "lsx_vstelm_<lsxfmt_f>"
2854   [(match_operand:LSX 0 "register_operand")
2855    (match_operand 3 "const_<indeximm>_operand")
2856    (match_operand 2 "aq8<lsxfmt>_operand")
2857    (match_operand 1 "pmode_register_operand")]
2858   "ISA_HAS_LSX"
2860   emit_insn (gen_lsx_vstelm_<lsxfmt_f>_insn
2861              (operands[1], operands[2], operands[0], operands[3]));
2862   DONE;
2865 (define_insn "lsx_vstelm_<lsxfmt_f>_insn"
2866   [(set (mem:<UNITMODE> (plus:DI (match_operand:DI 0 "register_operand" "r")
2867                                  (match_operand 1 "aq8<lsxfmt>_operand")))
2868         (vec_select:<UNITMODE>
2869           (match_operand:LSX 2 "register_operand" "f")
2870           (parallel [(match_operand 3 "const_<indeximm>_operand" "")])))]
2872   "ISA_HAS_LSX"
2874   return "vstelm.<lsxfmt>\t%w2,%0,%1,%3";
2876   [(set_attr "type" "simd_store")
2877    (set_attr "mode" "<MODE>")
2878    (set_attr "length" "4")])
2880 ;; Offset is "0"
2881 (define_insn "lsx_vstelm_<lsxfmt_f>_insn_0"
2882   [(set (mem:<UNITMODE> (match_operand:DI 0 "register_operand" "r"))
2883     (vec_select:<UNITMODE>
2884       (match_operand:LSX 1 "register_operand" "f")
2885       (parallel [(match_operand:SI 2 "const_<indeximm>_operand")])))]
2886   "ISA_HAS_LSX"
2888     return "vstelm.<lsxfmt>\t%w1,%0,0,%2";
2890   [(set_attr "type" "simd_store")
2891    (set_attr "mode" "<MODE>")
2892    (set_attr "length" "4")])
2894 (define_expand "lsx_vld"
2895   [(match_operand:V16QI 0 "register_operand")
2896    (match_operand 1 "pmode_register_operand")
2897    (match_operand 2 "aq12b_operand")]
2898   "ISA_HAS_LSX"
2900   rtx addr = plus_constant (GET_MODE (operands[1]), operands[1],
2901                             INTVAL (operands[2]));
2902   loongarch_emit_move (operands[0], gen_rtx_MEM (V16QImode, addr));
2903   DONE;
2906 (define_expand "lsx_vst"
2907   [(match_operand:V16QI 0 "register_operand")
2908    (match_operand 1 "pmode_register_operand")
2909    (match_operand 2 "aq12b_operand")]
2910   "ISA_HAS_LSX"
2912   rtx addr = plus_constant (GET_MODE (operands[1]), operands[1],
2913                             INTVAL (operands[2]));
2914   loongarch_emit_move (gen_rtx_MEM (V16QImode, addr), operands[0]);
2915   DONE;
2918 (define_insn "lsx_vssrln_<hlsxfmt>_<lsxfmt>"
2919   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2920         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2921                           (match_operand:ILSX_DWH 2 "register_operand" "f")]
2922                          UNSPEC_LSX_VSSRLN))]
2923   "ISA_HAS_LSX"
2924   "vssrln.<hlsxfmt>.<lsxfmt>\t%w0,%w1,%w2"
2925   [(set_attr "type" "simd_int_arith")
2926    (set_attr "mode" "<MODE>")])
2929 (define_insn "lsx_vssrlrn_<hlsxfmt>_<lsxfmt>"
2930   [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
2931         (unspec:<VHMODE> [(match_operand:ILSX_DWH 1 "register_operand" "f")
2932                           (match_operand:ILSX_DWH 2 "register_operand" "f")]
2933                          UNSPEC_LSX_VSSRLRN))]
2934   "ISA_HAS_LSX"
2935   "vssrlrn.<hlsxfmt>.<lsxfmt>\t%w0,%w1,%w2"
2936   [(set_attr "type" "simd_int_arith")
2937    (set_attr "mode" "<MODE>")])
2939 (define_insn "iorn<mode>3"
2940   [(set (match_operand:ILSX 0 "register_operand" "=f")
2941         (ior:ILSX (not:ILSX (match_operand:ILSX 2 "register_operand" "f"))
2942                   (match_operand:ILSX 1 "register_operand" "f")))]
2943   "ISA_HAS_LSX"
2944   "vorn.v\t%w0,%w1,%w2"
2945   [(set_attr "type" "simd_logic")
2946    (set_attr "mode" "<MODE>")])
2948 (define_insn "lsx_vldi"
2949   [(set (match_operand:V2DI 0 "register_operand" "=f")
2950         (unspec:V2DI [(match_operand 1 "const_imm13_operand")]
2951                     UNSPEC_LSX_VLDI))]
2952   "ISA_HAS_LSX"
2954   HOST_WIDE_INT val = INTVAL (operands[1]);
2955   if (val < 0)
2956   {
2957     HOST_WIDE_INT modeVal = (val & 0xf00) >> 8;
2958     if (modeVal < 13)
2959       return  "vldi\t%w0,%1";
2960     else
2961       sorry ("imm13 only support 0000 ~ 1100 in bits 9 ~ 12 when bit '13' is 1");
2962     return "#";
2963   }
2964   else
2965     return "vldi\t%w0,%1";
2967   [(set_attr "type" "simd_load")
2968    (set_attr "mode" "V2DI")])
2970 (define_insn "lsx_vshuf_b"
2971   [(set (match_operand:V16QI 0 "register_operand" "=f")
2972         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "f")
2973                        (match_operand:V16QI 2 "register_operand" "f")
2974                        (match_operand:V16QI 3 "register_operand" "f")]
2975                       UNSPEC_LSX_VSHUF_B))]
2976   "ISA_HAS_LSX"
2977   "vshuf.b\t%w0,%w1,%w2,%w3"
2978   [(set_attr "type" "simd_shf")
2979    (set_attr "mode" "V16QI")])
2981 (define_insn "lsx_vldx"
2982   [(set (match_operand:V16QI 0 "register_operand" "=f")
2983         (unspec:V16QI [(match_operand:DI 1 "register_operand" "r")
2984                        (match_operand:DI 2 "reg_or_0_operand" "rJ")]
2985                       UNSPEC_LSX_VLDX))]
2986   "ISA_HAS_LSX"
2988   return "vldx\t%w0,%1,%z2";
2990   [(set_attr "type" "simd_load")
2991    (set_attr "mode" "V16QI")])
2993 (define_insn "lsx_vstx"
2994   [(set (mem:V16QI (plus:DI (match_operand:DI 1 "register_operand" "r")
2995                             (match_operand:DI 2 "reg_or_0_operand" "rJ")))
2996         (unspec: V16QI [(match_operand:V16QI 0 "register_operand" "f")]
2997                       UNSPEC_LSX_VSTX))]
2999   "ISA_HAS_LSX"
3001   return "vstx\t%w0,%1,%z2";
3003   [(set_attr "type" "simd_store")
3004    (set_attr "mode" "DI")])
3006 (define_insn "lsx_vextl_qu_du"
3007   [(set (match_operand:V2DI 0 "register_operand" "=f")
3008         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")]
3009                      UNSPEC_LSX_VEXTL_QU_DU))]
3010   "ISA_HAS_LSX"
3011   "vextl.qu.du\t%w0,%w1"
3012   [(set_attr "type" "simd_bit")
3013    (set_attr "mode" "V2DI")])
3015 (define_insn "lsx_vseteqz_v"
3016   [(set (match_operand:FCC 0 "register_operand" "=z")
3017         (eq:FCC
3018           (unspec:SI [(match_operand:V16QI 1 "register_operand" "f")]
3019                      UNSPEC_LSX_VSETEQZ_V)
3020           (match_operand:SI 2 "const_0_operand")))]
3021   "ISA_HAS_LSX"
3023   return "vseteqz.v\t%0,%1";
3025   [(set_attr "type" "simd_fcmp")
3026    (set_attr "mode" "FCC")])
3028 ;; Vector reduction operation
3029 (define_expand "reduc_plus_scal_v2di"
3030   [(match_operand:DI 0 "register_operand")
3031    (match_operand:V2DI 1 "register_operand")]
3032   "ISA_HAS_LSX"
3034   rtx tmp = gen_reg_rtx (V2DImode);
3035   emit_insn (gen_lsx_vhaddw_q_d (tmp, operands[1], operands[1]));
3036   emit_insn (gen_vec_extractv2didi (operands[0], tmp, const0_rtx));
3037   DONE;
3040 (define_expand "reduc_plus_scal_v4si"
3041   [(match_operand:SI 0 "register_operand")
3042    (match_operand:V4SI 1 "register_operand")]
3043   "ISA_HAS_LSX"
3045   rtx tmp = gen_reg_rtx (V2DImode);
3046   rtx tmp1 = gen_reg_rtx (V2DImode);
3047   emit_insn (gen_lsx_vhaddw_d_w (tmp, operands[1], operands[1]));
3048   emit_insn (gen_lsx_vhaddw_q_d (tmp1, tmp, tmp));
3049   emit_insn (gen_vec_extractv4sisi (operands[0], gen_lowpart (V4SImode,tmp1),
3050                                     const0_rtx));
3051   DONE;
3054 (define_expand "reduc_plus_scal_<mode>"
3055   [(match_operand:<UNITMODE> 0 "register_operand")
3056    (match_operand:FLSX 1 "register_operand")]
3057   "ISA_HAS_LSX"
3059   rtx tmp = gen_reg_rtx (<MODE>mode);
3060   loongarch_expand_vector_reduc (gen_add<mode>3, tmp, operands[1]);
3061   emit_insn (gen_vec_extract<mode><unitmode> (operands[0], tmp,
3062                                               const0_rtx));
3063   DONE;
3066 (define_expand "reduc_<optab>_scal_<mode>"
3067   [(any_bitwise:<UNITMODE>
3068       (match_operand:<UNITMODE> 0 "register_operand")
3069       (match_operand:ILSX 1 "register_operand"))]
3070   "ISA_HAS_LSX"
3072   rtx tmp = gen_reg_rtx (<MODE>mode);
3073   loongarch_expand_vector_reduc (gen_<optab><mode>3, tmp, operands[1]);
3074   emit_insn (gen_vec_extract<mode><unitmode> (operands[0], tmp,
3075                                               const0_rtx));
3076   DONE;
3079 (define_expand "reduc_smax_scal_<mode>"
3080   [(match_operand:<UNITMODE> 0 "register_operand")
3081    (match_operand:LSX 1 "register_operand")]
3082   "ISA_HAS_LSX"
3084   rtx tmp = gen_reg_rtx (<MODE>mode);
3085   loongarch_expand_vector_reduc (gen_smax<mode>3, tmp, operands[1]);
3086   emit_insn (gen_vec_extract<mode><unitmode> (operands[0], tmp,
3087                                               const0_rtx));
3088   DONE;
3091 (define_expand "reduc_smin_scal_<mode>"
3092   [(match_operand:<UNITMODE> 0 "register_operand")
3093    (match_operand:LSX 1 "register_operand")]
3094   "ISA_HAS_LSX"
3096   rtx tmp = gen_reg_rtx (<MODE>mode);
3097   loongarch_expand_vector_reduc (gen_smin<mode>3, tmp, operands[1]);
3098   emit_insn (gen_vec_extract<mode><unitmode> (operands[0], tmp,
3099                                               const0_rtx));
3100   DONE;
3103 (define_expand "reduc_umax_scal_<mode>"
3104   [(match_operand:<UNITMODE> 0 "register_operand")
3105    (match_operand:ILSX 1 "register_operand")]
3106   "ISA_HAS_LSX"
3108   rtx tmp = gen_reg_rtx (<MODE>mode);
3109   loongarch_expand_vector_reduc (gen_umax<mode>3, tmp, operands[1]);
3110   emit_insn (gen_vec_extract<mode><unitmode> (operands[0], tmp,
3111                                               const0_rtx));
3112   DONE;
3115 (define_expand "reduc_umin_scal_<mode>"
3116   [(match_operand:<UNITMODE> 0 "register_operand")
3117    (match_operand:ILSX 1 "register_operand")]
3118   "ISA_HAS_LSX"
3120   rtx tmp = gen_reg_rtx (<MODE>mode);
3121   loongarch_expand_vector_reduc (gen_umin<mode>3, tmp, operands[1]);
3122   emit_insn (gen_vec_extract<mode><unitmode> (operands[0], tmp,
3123                                               const0_rtx));
3124   DONE;
3127 (define_expand "avg<mode>3_ceil"
3128   [(match_operand:ILSX_WHB 0 "register_operand")
3129    (match_operand:ILSX_WHB 1 "register_operand")
3130    (match_operand:ILSX_WHB 2 "register_operand")]
3131   "ISA_HAS_LSX"
3133   emit_insn (gen_lsx_vavgr_s_<lsxfmt> (operands[0],
3134         operands[1], operands[2]));
3135   DONE;
3138 (define_expand "uavg<mode>3_ceil"
3139   [(match_operand:ILSX_WHB 0 "register_operand")
3140    (match_operand:ILSX_WHB 1 "register_operand")
3141    (match_operand:ILSX_WHB 2 "register_operand")]
3142   "ISA_HAS_LSX"
3144   emit_insn (gen_lsx_vavgr_u_<lsxfmt_u> (operands[0],
3145         operands[1], operands[2]));
3146   DONE;
3149 (define_expand "avg<mode>3_floor"
3150   [(match_operand:ILSX_WHB 0 "register_operand")
3151    (match_operand:ILSX_WHB 1 "register_operand")
3152    (match_operand:ILSX_WHB 2 "register_operand")]
3153   "ISA_HAS_LSX"
3155   emit_insn (gen_lsx_vavg_s_<lsxfmt> (operands[0],
3156         operands[1], operands[2]));
3157   DONE;
3160 (define_expand "uavg<mode>3_floor"
3161   [(match_operand:ILSX_WHB 0 "register_operand")
3162    (match_operand:ILSX_WHB 1 "register_operand")
3163    (match_operand:ILSX_WHB 2 "register_operand")]
3164   "ISA_HAS_LSX"
3166   emit_insn (gen_lsx_vavg_u_<lsxfmt_u> (operands[0],
3167         operands[1], operands[2]));
3168   DONE;
3171 (define_expand "usadv16qi"
3172   [(match_operand:V4SI 0 "register_operand")
3173    (match_operand:V16QI 1 "register_operand")
3174    (match_operand:V16QI 2 "register_operand")
3175    (match_operand:V4SI 3 "register_operand")]
3176   "ISA_HAS_LSX"
3178   rtx t1 = gen_reg_rtx (V16QImode);
3179   rtx t2 = gen_reg_rtx (V8HImode);
3180   rtx t3 = gen_reg_rtx (V4SImode);
3181   emit_insn (gen_uabdv16qi3 (t1, operands[1], operands[2]));
3182   emit_insn (gen_lsx_vhaddw_hu_bu (t2, t1, t1));
3183   emit_insn (gen_lsx_vhaddw_wu_hu (t3, t2, t2));
3184   emit_insn (gen_addv4si3 (operands[0], t3, operands[3]));
3185   DONE;
3188 (define_expand "ssadv16qi"
3189   [(match_operand:V4SI 0 "register_operand")
3190    (match_operand:V16QI 1 "register_operand")
3191    (match_operand:V16QI 2 "register_operand")
3192    (match_operand:V4SI 3 "register_operand")]
3193   "ISA_HAS_LSX"
3195   rtx t1 = gen_reg_rtx (V16QImode);
3196   rtx t2 = gen_reg_rtx (V8HImode);
3197   rtx t3 = gen_reg_rtx (V4SImode);
3198   emit_insn (gen_sabdv16qi3 (t1, operands[1], operands[2]));
3199   emit_insn (gen_lsx_vhaddw_hu_bu (t2, t1, t1));
3200   emit_insn (gen_lsx_vhaddw_wu_hu (t3, t2, t2));
3201   emit_insn (gen_addv4si3 (operands[0], t3, operands[3]));
3202   DONE;
3205 (define_insn "lsx_v<optab>wev_d_w<u>"
3206   [(set (match_operand:V2DI 0 "register_operand" "=f")
3207         (addsubmul:V2DI
3208           (any_extend:V2DI
3209             (vec_select:V2SI
3210               (match_operand:V4SI 1 "register_operand" "%f")
3211               (parallel [(const_int 0) (const_int 2)])))
3212           (any_extend:V2DI
3213             (vec_select:V2SI
3214               (match_operand:V4SI 2 "register_operand" "f")
3215               (parallel [(const_int 0) (const_int 2)])))))]
3216   "ISA_HAS_LSX"
3217   "v<optab>wev.d.w<u>\t%w0,%w1,%w2"
3218   [(set_attr "type" "simd_int_arith")
3219    (set_attr "mode" "V2DI")])
3221 (define_insn "lsx_v<optab>wev_w_h<u>"
3222   [(set (match_operand:V4SI 0 "register_operand" "=f")
3223         (addsubmul:V4SI
3224           (any_extend:V4SI
3225             (vec_select:V4HI
3226               (match_operand:V8HI 1 "register_operand" "%f")
3227               (parallel [(const_int 0) (const_int 2)
3228                          (const_int 4) (const_int 6)])))
3229           (any_extend:V4SI
3230             (vec_select:V4HI
3231               (match_operand:V8HI 2 "register_operand" "f")
3232               (parallel [(const_int 0) (const_int 2)
3233                          (const_int 4) (const_int 6)])))))]
3234   "ISA_HAS_LSX"
3235   "v<optab>wev.w.h<u>\t%w0,%w1,%w2"
3236   [(set_attr "type" "simd_int_arith")
3237    (set_attr "mode" "V4SI")])
3239 (define_insn "lsx_v<optab>wev_h_b<u>"
3240   [(set (match_operand:V8HI 0 "register_operand" "=f")
3241         (addsubmul:V8HI
3242           (any_extend:V8HI
3243             (vec_select:V8QI
3244               (match_operand:V16QI 1 "register_operand" "%f")
3245               (parallel [(const_int 0) (const_int 2)
3246                          (const_int 4) (const_int 6)
3247                          (const_int 8) (const_int 10)
3248                          (const_int 12) (const_int 14)])))
3249           (any_extend:V8HI
3250             (vec_select:V8QI
3251               (match_operand:V16QI 2 "register_operand" "f")
3252               (parallel [(const_int 0) (const_int 2)
3253                          (const_int 4) (const_int 6)
3254                          (const_int 8) (const_int 10)
3255                          (const_int 12) (const_int 14)])))))]
3256   "ISA_HAS_LSX"
3257   "v<optab>wev.h.b<u>\t%w0,%w1,%w2"
3258   [(set_attr "type" "simd_int_arith")
3259    (set_attr "mode" "V8HI")])
3261 (define_insn "lsx_v<optab>wod_d_w<u>"
3262   [(set (match_operand:V2DI 0 "register_operand" "=f")
3263         (addsubmul:V2DI
3264           (any_extend:V2DI
3265             (vec_select:V2SI
3266               (match_operand:V4SI 1 "register_operand" "%f")
3267               (parallel [(const_int 1) (const_int 3)])))
3268           (any_extend:V2DI
3269             (vec_select:V2SI
3270               (match_operand:V4SI 2 "register_operand" "f")
3271               (parallel [(const_int 1) (const_int 3)])))))]
3272   "ISA_HAS_LSX"
3273   "v<optab>wod.d.w<u>\t%w0,%w1,%w2"
3274   [(set_attr "type" "simd_int_arith")
3275    (set_attr "mode" "V2DI")])
3277 (define_insn "lsx_v<optab>wod_w_h<u>"
3278   [(set (match_operand:V4SI 0 "register_operand" "=f")
3279         (addsubmul:V4SI
3280           (any_extend:V4SI
3281             (vec_select:V4HI
3282               (match_operand:V8HI 1 "register_operand" "%f")
3283               (parallel [(const_int 1) (const_int 3)
3284                          (const_int 5) (const_int 7)])))
3285           (any_extend:V4SI
3286             (vec_select:V4HI
3287               (match_operand:V8HI 2 "register_operand" "f")
3288               (parallel [(const_int 1) (const_int 3)
3289                          (const_int 5) (const_int 7)])))))]
3290   "ISA_HAS_LSX"
3291   "v<optab>wod.w.h<u>\t%w0,%w1,%w2"
3292   [(set_attr "type" "simd_int_arith")
3293    (set_attr "mode" "V4SI")])
3295 (define_insn "lsx_v<optab>wod_h_b<u>"
3296   [(set (match_operand:V8HI 0 "register_operand" "=f")
3297         (addsubmul:V8HI
3298           (any_extend:V8HI
3299             (vec_select:V8QI
3300               (match_operand:V16QI 1 "register_operand" "%f")
3301               (parallel [(const_int 1) (const_int 3)
3302                          (const_int 5) (const_int 7)
3303                          (const_int 9) (const_int 11)
3304                          (const_int 13) (const_int 15)])))
3305           (any_extend:V8HI
3306             (vec_select:V8QI
3307               (match_operand:V16QI 2 "register_operand" "f")
3308               (parallel [(const_int 1) (const_int 3)
3309                          (const_int 5) (const_int 7)
3310                          (const_int 9) (const_int 11)
3311                          (const_int 13) (const_int 15)])))))]
3312   "ISA_HAS_LSX"
3313   "v<optab>wod.h.b<u>\t%w0,%w1,%w2"
3314   [(set_attr "type" "simd_int_arith")
3315    (set_attr "mode" "V8HI")])
3317 (define_insn "lsx_v<optab>wev_d_wu_w"
3318   [(set (match_operand:V2DI 0 "register_operand" "=f")
3319         (addmul:V2DI
3320           (zero_extend:V2DI
3321             (vec_select:V2SI
3322               (match_operand:V4SI 1 "register_operand" "%f")
3323               (parallel [(const_int 0) (const_int 2)])))
3324           (sign_extend:V2DI
3325             (vec_select:V2SI
3326               (match_operand:V4SI 2 "register_operand" "f")
3327               (parallel [(const_int 0) (const_int 2)])))))]
3328   "ISA_HAS_LSX"
3329   "v<optab>wev.d.wu.w\t%w0,%w1,%w2"
3330   [(set_attr "type" "simd_int_arith")
3331    (set_attr "mode" "V2DI")])
3333 (define_insn "lsx_v<optab>wev_w_hu_h"
3334   [(set (match_operand:V4SI 0 "register_operand" "=f")
3335         (addmul:V4SI
3336           (zero_extend:V4SI
3337             (vec_select:V4HI
3338               (match_operand:V8HI 1 "register_operand" "%f")
3339               (parallel [(const_int 0) (const_int 2)
3340                          (const_int 4) (const_int 6)])))
3341           (sign_extend:V4SI
3342             (vec_select:V4HI
3343               (match_operand:V8HI 2 "register_operand" "f")
3344               (parallel [(const_int 0) (const_int 2)
3345                          (const_int 4) (const_int 6)])))))]
3346   "ISA_HAS_LSX"
3347   "v<optab>wev.w.hu.h\t%w0,%w1,%w2"
3348   [(set_attr "type" "simd_int_arith")
3349    (set_attr "mode" "V4SI")])
3351 (define_insn "lsx_v<optab>wev_h_bu_b"
3352   [(set (match_operand:V8HI 0 "register_operand" "=f")
3353         (addmul:V8HI
3354           (zero_extend:V8HI
3355             (vec_select:V8QI
3356               (match_operand:V16QI 1 "register_operand" "%f")
3357               (parallel [(const_int 0) (const_int 2)
3358                          (const_int 4) (const_int 6)
3359                          (const_int 8) (const_int 10)
3360                          (const_int 12) (const_int 14)])))
3361           (sign_extend:V8HI
3362             (vec_select:V8QI
3363               (match_operand:V16QI 2 "register_operand" "f")
3364               (parallel [(const_int 0) (const_int 2)
3365                          (const_int 4) (const_int 6)
3366                          (const_int 8) (const_int 10)
3367                          (const_int 12) (const_int 14)])))))]
3368   "ISA_HAS_LSX"
3369   "v<optab>wev.h.bu.b\t%w0,%w1,%w2"
3370   [(set_attr "type" "simd_int_arith")
3371    (set_attr "mode" "V8HI")])
3373 (define_insn "lsx_v<optab>wod_d_wu_w"
3374   [(set (match_operand:V2DI 0 "register_operand" "=f")
3375         (addmul:V2DI
3376           (zero_extend:V2DI
3377             (vec_select:V2SI
3378               (match_operand:V4SI 1 "register_operand" "%f")
3379               (parallel [(const_int 1) (const_int 3)])))
3380           (sign_extend:V2DI
3381             (vec_select:V2SI
3382               (match_operand:V4SI 2 "register_operand" "f")
3383               (parallel [(const_int 1) (const_int 3)])))))]
3384   "ISA_HAS_LSX"
3385   "v<optab>wod.d.wu.w\t%w0,%w1,%w2"
3386   [(set_attr "type" "simd_int_arith")
3387    (set_attr "mode" "V2DI")])
3389 (define_insn "lsx_v<optab>wod_w_hu_h"
3390   [(set (match_operand:V4SI 0 "register_operand" "=f")
3391         (addmul:V4SI
3392           (zero_extend:V4SI
3393             (vec_select:V4HI
3394               (match_operand:V8HI 1 "register_operand" "%f")
3395               (parallel [(const_int 1) (const_int 3)
3396                          (const_int 5) (const_int 7)])))
3397           (sign_extend:V4SI
3398             (vec_select:V4HI
3399               (match_operand:V8HI 2 "register_operand" "f")
3400               (parallel [(const_int 1) (const_int 3)
3401                          (const_int 5) (const_int 7)])))))]
3402   "ISA_HAS_LSX"
3403   "v<optab>wod.w.hu.h\t%w0,%w1,%w2"
3404   [(set_attr "type" "simd_int_arith")
3405    (set_attr "mode" "V4SI")])
3407 (define_insn "lsx_v<optab>wod_h_bu_b"
3408   [(set (match_operand:V8HI 0 "register_operand" "=f")
3409         (addmul:V8HI
3410           (zero_extend:V8HI
3411             (vec_select:V8QI
3412               (match_operand:V16QI 1 "register_operand" "%f")
3413               (parallel [(const_int 1) (const_int 3)
3414                          (const_int 5) (const_int 7)
3415                          (const_int 9) (const_int 11)
3416                          (const_int 13) (const_int 15)])))
3417           (sign_extend:V8HI
3418             (vec_select:V8QI
3419               (match_operand:V16QI 2 "register_operand" "f")
3420               (parallel [(const_int 1) (const_int 3)
3421                          (const_int 5) (const_int 7)
3422                          (const_int 9) (const_int 11)
3423                          (const_int 13) (const_int 15)])))))]
3424   "ISA_HAS_LSX"
3425   "v<optab>wod.h.bu.b\t%w0,%w1,%w2"
3426   [(set_attr "type" "simd_int_arith")
3427    (set_attr "mode" "V8HI")])
3429 (define_insn "lsx_vaddwev_q_d"
3430   [(set (match_operand:V2DI 0 "register_operand" "=f")
3431         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3432                       (match_operand:V2DI 2 "register_operand" "f")]
3433                      UNSPEC_LSX_VADDWEV))]
3434   "ISA_HAS_LSX"
3435   "vaddwev.q.d\t%w0,%w1,%w2"
3436   [(set_attr "type" "simd_int_arith")
3437    (set_attr "mode" "V2DI")])
3439 (define_insn "lsx_vaddwev_q_du"
3440   [(set (match_operand:V2DI 0 "register_operand" "=f")
3441         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3442                       (match_operand:V2DI 2 "register_operand" "f")]
3443                      UNSPEC_LSX_VADDWEV2))]
3444   "ISA_HAS_LSX"
3445   "vaddwev.q.du\t%w0,%w1,%w2"
3446   [(set_attr "type" "simd_int_arith")
3447    (set_attr "mode" "V2DI")])
3449 (define_insn "lsx_vaddwod_q_d"
3450   [(set (match_operand:V2DI 0 "register_operand" "=f")
3451         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3452                       (match_operand:V2DI 2 "register_operand" "f")]
3453                      UNSPEC_LSX_VADDWOD))]
3454   "ISA_HAS_LSX"
3455   "vaddwod.q.d\t%w0,%w1,%w2"
3456   [(set_attr "type" "simd_int_arith")
3457    (set_attr "mode" "V2DI")])
3459 (define_insn "lsx_vaddwod_q_du"
3460   [(set (match_operand:V2DI 0 "register_operand" "=f")
3461         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3462                       (match_operand:V2DI 2 "register_operand" "f")]
3463                      UNSPEC_LSX_VADDWOD2))]
3464   "ISA_HAS_LSX"
3465   "vaddwod.q.du\t%w0,%w1,%w2"
3466   [(set_attr "type" "simd_int_arith")
3467    (set_attr "mode" "V2DI")])
3469 (define_insn "lsx_vsubwev_q_d"
3470   [(set (match_operand:V2DI 0 "register_operand" "=f")
3471         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3472                       (match_operand:V2DI 2 "register_operand" "f")]
3473                      UNSPEC_LSX_VSUBWEV))]
3474   "ISA_HAS_LSX"
3475   "vsubwev.q.d\t%w0,%w1,%w2"
3476   [(set_attr "type" "simd_int_arith")
3477    (set_attr "mode" "V2DI")])
3479 (define_insn "lsx_vsubwev_q_du"
3480   [(set (match_operand:V2DI 0 "register_operand" "=f")
3481         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3482                       (match_operand:V2DI 2 "register_operand" "f")]
3483                      UNSPEC_LSX_VSUBWEV2))]
3484   "ISA_HAS_LSX"
3485   "vsubwev.q.du\t%w0,%w1,%w2"
3486   [(set_attr "type" "simd_int_arith")
3487    (set_attr "mode" "V2DI")])
3489 (define_insn "lsx_vsubwod_q_d"
3490   [(set (match_operand:V2DI 0 "register_operand" "=f")
3491         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3492                       (match_operand:V2DI 2 "register_operand" "f")]
3493                      UNSPEC_LSX_VSUBWOD))]
3494   "ISA_HAS_LSX"
3495   "vsubwod.q.d\t%w0,%w1,%w2"
3496   [(set_attr "type" "simd_int_arith")
3497    (set_attr "mode" "V2DI")])
3499 (define_insn "lsx_vsubwod_q_du"
3500   [(set (match_operand:V2DI 0 "register_operand" "=f")
3501         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3502                       (match_operand:V2DI 2 "register_operand" "f")]
3503                      UNSPEC_LSX_VSUBWOD2))]
3504   "ISA_HAS_LSX"
3505   "vsubwod.q.du\t%w0,%w1,%w2"
3506   [(set_attr "type" "simd_int_arith")
3507    (set_attr "mode" "V2DI")])
3509 (define_insn "lsx_vaddwev_q_du_d"
3510   [(set (match_operand:V2DI 0 "register_operand" "=f")
3511         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3512                       (match_operand:V2DI 2 "register_operand" "f")]
3513                      UNSPEC_LSX_VADDWEV3))]
3514   "ISA_HAS_LSX"
3515   "vaddwev.q.du.d\t%w0,%w1,%w2"
3516   [(set_attr "type" "simd_int_arith")
3517    (set_attr "mode" "V2DI")])
3519 (define_insn "lsx_vaddwod_q_du_d"
3520   [(set (match_operand:V2DI 0 "register_operand" "=f")
3521         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3522                       (match_operand:V2DI 2 "register_operand" "f")]
3523                      UNSPEC_LSX_VADDWOD3))]
3524   "ISA_HAS_LSX"
3525   "vaddwod.q.du.d\t%w0,%w1,%w2"
3526   [(set_attr "type" "simd_int_arith")
3527    (set_attr "mode" "V2DI")])
3529 (define_insn "lsx_vmulwev_q_du_d"
3530   [(set (match_operand:V2DI 0 "register_operand" "=f")
3531         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3532                       (match_operand:V2DI 2 "register_operand" "f")]
3533                      UNSPEC_LSX_VMULWEV3))]
3534   "ISA_HAS_LSX"
3535   "vmulwev.q.du.d\t%w0,%w1,%w2"
3536   [(set_attr "type" "simd_int_arith")
3537    (set_attr "mode" "V2DI")])
3539 (define_insn "lsx_vmulwod_q_du_d"
3540   [(set (match_operand:V2DI 0 "register_operand" "=f")
3541         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3542                       (match_operand:V2DI 2 "register_operand" "f")]
3543                      UNSPEC_LSX_VMULWOD3))]
3544   "ISA_HAS_LSX"
3545   "vmulwod.q.du.d\t%w0,%w1,%w2"
3546   [(set_attr "type" "simd_int_arith")
3547    (set_attr "mode" "V2DI")])
3549 (define_insn "lsx_vmulwev_q_d"
3550   [(set (match_operand:V2DI 0 "register_operand" "=f")
3551         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3552                       (match_operand:V2DI 2 "register_operand" "f")]
3553                      UNSPEC_LSX_VMULWEV))]
3554   "ISA_HAS_LSX"
3555   "vmulwev.q.d\t%w0,%w1,%w2"
3556   [(set_attr "type" "simd_int_arith")
3557    (set_attr "mode" "V2DI")])
3559 (define_insn "lsx_vmulwev_q_du"
3560   [(set (match_operand:V2DI 0 "register_operand" "=f")
3561         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3562                       (match_operand:V2DI 2 "register_operand" "f")]
3563                      UNSPEC_LSX_VMULWEV2))]
3564   "ISA_HAS_LSX"
3565   "vmulwev.q.du\t%w0,%w1,%w2"
3566   [(set_attr "type" "simd_int_arith")
3567    (set_attr "mode" "V2DI")])
3569 (define_insn "lsx_vmulwod_q_d"
3570   [(set (match_operand:V2DI 0 "register_operand" "=f")
3571         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3572                       (match_operand:V2DI 2 "register_operand" "f")]
3573                      UNSPEC_LSX_VMULWOD))]
3574   "ISA_HAS_LSX"
3575   "vmulwod.q.d\t%w0,%w1,%w2"
3576   [(set_attr "type" "simd_int_arith")
3577    (set_attr "mode" "V2DI")])
3579 (define_insn "lsx_vmulwod_q_du"
3580   [(set (match_operand:V2DI 0 "register_operand" "=f")
3581         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3582                       (match_operand:V2DI 2 "register_operand" "f")]
3583                      UNSPEC_LSX_VMULWOD2))]
3584   "ISA_HAS_LSX"
3585   "vmulwod.q.du\t%w0,%w1,%w2"
3586   [(set_attr "type" "simd_int_arith")
3587    (set_attr "mode" "V2DI")])
3589 (define_insn "lsx_vhaddw_q_d"
3590   [(set (match_operand:V2DI 0 "register_operand" "=f")
3591         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3592                       (match_operand:V2DI 2 "register_operand" "f")]
3593                      UNSPEC_LSX_VHADDW_Q_D))]
3594   "ISA_HAS_LSX"
3595   "vhaddw.q.d\t%w0,%w1,%w2"
3596   [(set_attr "type" "simd_int_arith")
3597    (set_attr "mode" "V2DI")])
3599 (define_insn "lsx_vhaddw_qu_du"
3600   [(set (match_operand:V2DI 0 "register_operand" "=f")
3601         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3602                       (match_operand:V2DI 2 "register_operand" "f")]
3603                      UNSPEC_LSX_VHADDW_QU_DU))]
3604   "ISA_HAS_LSX"
3605   "vhaddw.qu.du\t%w0,%w1,%w2"
3606   [(set_attr "type" "simd_int_arith")
3607    (set_attr "mode" "V2DI")])
3609 (define_insn "lsx_vhsubw_q_d"
3610   [(set (match_operand:V2DI 0 "register_operand" "=f")
3611         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3612                       (match_operand:V2DI 2 "register_operand" "f")]
3613                      UNSPEC_LSX_VHSUBW_Q_D))]
3614   "ISA_HAS_LSX"
3615   "vhsubw.q.d\t%w0,%w1,%w2"
3616   [(set_attr "type" "simd_int_arith")
3617    (set_attr "mode" "V2DI")])
3619 (define_insn "lsx_vhsubw_qu_du"
3620   [(set (match_operand:V2DI 0 "register_operand" "=f")
3621         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3622                       (match_operand:V2DI 2 "register_operand" "f")]
3623                      UNSPEC_LSX_VHSUBW_QU_DU))]
3624   "ISA_HAS_LSX"
3625   "vhsubw.qu.du\t%w0,%w1,%w2"
3626   [(set_attr "type" "simd_int_arith")
3627    (set_attr "mode" "V2DI")])
3629 (define_insn "lsx_vmaddwev_d_w<u>"
3630   [(set (match_operand:V2DI 0 "register_operand" "=f")
3631         (plus:V2DI
3632           (match_operand:V2DI 1 "register_operand" "0")
3633           (mult:V2DI
3634             (any_extend:V2DI
3635               (vec_select:V2SI
3636                 (match_operand:V4SI 2 "register_operand" "%f")
3637                 (parallel [(const_int 0) (const_int 2)])))
3638             (any_extend:V2DI
3639               (vec_select:V2SI
3640                 (match_operand:V4SI 3 "register_operand" "f")
3641                 (parallel [(const_int 0) (const_int 2)]))))))]
3642   "ISA_HAS_LSX"
3643   "vmaddwev.d.w<u>\t%w0,%w2,%w3"
3644   [(set_attr "type" "simd_fmadd")
3645    (set_attr "mode" "V2DI")])
3647 (define_insn "lsx_vmaddwev_w_h<u>"
3648   [(set (match_operand:V4SI 0 "register_operand" "=f")
3649         (plus:V4SI
3650           (match_operand:V4SI 1 "register_operand" "0")
3651           (mult:V4SI
3652             (any_extend:V4SI
3653               (vec_select:V4HI
3654                 (match_operand:V8HI 2 "register_operand" "%f")
3655                 (parallel [(const_int 0) (const_int 2)
3656                            (const_int 4) (const_int 6)])))
3657             (any_extend:V4SI
3658               (vec_select:V4HI
3659                 (match_operand:V8HI 3 "register_operand" "f")
3660                 (parallel [(const_int 0) (const_int 2)
3661                            (const_int 4) (const_int 6)]))))))]
3662   "ISA_HAS_LSX"
3663   "vmaddwev.w.h<u>\t%w0,%w2,%w3"
3664   [(set_attr "type" "simd_fmadd")
3665    (set_attr "mode" "V4SI")])
3667 (define_insn "lsx_vmaddwev_h_b<u>"
3668   [(set (match_operand:V8HI 0 "register_operand" "=f")
3669         (plus:V8HI
3670           (match_operand:V8HI 1 "register_operand" "0")
3671           (mult:V8HI
3672             (any_extend:V8HI
3673               (vec_select:V8QI
3674                 (match_operand:V16QI 2 "register_operand" "%f")
3675                 (parallel [(const_int 0) (const_int 2)
3676                            (const_int 4) (const_int 6)
3677                            (const_int 8) (const_int 10)
3678                            (const_int 12) (const_int 14)])))
3679             (any_extend:V8HI
3680               (vec_select:V8QI
3681                 (match_operand:V16QI 3 "register_operand" "f")
3682                 (parallel [(const_int 0) (const_int 2)
3683                            (const_int 4) (const_int 6)
3684                            (const_int 8) (const_int 10)
3685                            (const_int 12) (const_int 14)]))))))]
3686   "ISA_HAS_LSX"
3687   "vmaddwev.h.b<u>\t%w0,%w2,%w3"
3688   [(set_attr "type" "simd_fmadd")
3689    (set_attr "mode" "V8HI")])
3691 (define_insn "lsx_vmaddwod_d_w<u>"
3692   [(set (match_operand:V2DI 0 "register_operand" "=f")
3693         (plus:V2DI
3694           (match_operand:V2DI 1 "register_operand" "0")
3695           (mult:V2DI
3696             (any_extend:V2DI
3697               (vec_select:V2SI
3698                 (match_operand:V4SI 2 "register_operand" "%f")
3699                 (parallel [(const_int 1) (const_int 3)])))
3700             (any_extend:V2DI
3701               (vec_select:V2SI
3702                 (match_operand:V4SI 3 "register_operand" "f")
3703                 (parallel [(const_int 1) (const_int 3)]))))))]
3704   "ISA_HAS_LSX"
3705   "vmaddwod.d.w<u>\t%w0,%w2,%w3"
3706   [(set_attr "type" "simd_fmadd")
3707    (set_attr "mode" "V2DI")])
3709 (define_insn "lsx_vmaddwod_w_h<u>"
3710   [(set (match_operand:V4SI 0 "register_operand" "=f")
3711         (plus:V4SI
3712           (match_operand:V4SI 1 "register_operand" "0")
3713           (mult:V4SI
3714             (any_extend:V4SI
3715               (vec_select:V4HI
3716                 (match_operand:V8HI 2 "register_operand" "%f")
3717                 (parallel [(const_int 1) (const_int 3)
3718                            (const_int 5) (const_int 7)])))
3719             (any_extend:V4SI
3720               (vec_select:V4HI
3721                 (match_operand:V8HI 3 "register_operand" "f")
3722                 (parallel [(const_int 1) (const_int 3)
3723                            (const_int 5) (const_int 7)]))))))]
3724   "ISA_HAS_LSX"
3725   "vmaddwod.w.h<u>\t%w0,%w2,%w3"
3726   [(set_attr "type" "simd_fmadd")
3727    (set_attr "mode" "V4SI")])
3729 (define_insn "lsx_vmaddwod_h_b<u>"
3730   [(set (match_operand:V8HI 0 "register_operand" "=f")
3731         (plus:V8HI
3732           (match_operand:V8HI 1 "register_operand" "0")
3733           (mult:V8HI
3734             (any_extend:V8HI
3735               (vec_select:V8QI
3736                 (match_operand:V16QI 2 "register_operand" "%f")
3737                 (parallel [(const_int 1) (const_int 3)
3738                            (const_int 5) (const_int 7)
3739                            (const_int 9) (const_int 11)
3740                            (const_int 13) (const_int 15)])))
3741             (any_extend:V8HI
3742               (vec_select:V8QI
3743                 (match_operand:V16QI 3 "register_operand" "f")
3744                 (parallel [(const_int 1) (const_int 3)
3745                            (const_int 5) (const_int 7)
3746                            (const_int 9) (const_int 11)
3747                            (const_int 13) (const_int 15)]))))))]
3748   "ISA_HAS_LSX"
3749   "vmaddwod.h.b<u>\t%w0,%w2,%w3"
3750   [(set_attr "type" "simd_fmadd")
3751    (set_attr "mode" "V8HI")])
3753 (define_insn "lsx_vmaddwev_d_wu_w"
3754   [(set (match_operand:V2DI 0 "register_operand" "=f")
3755         (plus:V2DI
3756           (match_operand:V2DI 1 "register_operand" "0")
3757           (mult:V2DI
3758             (zero_extend:V2DI
3759               (vec_select:V2SI
3760                 (match_operand:V4SI 2 "register_operand" "%f")
3761                 (parallel [(const_int 0) (const_int 2)])))
3762             (sign_extend:V2DI
3763               (vec_select:V2SI
3764                 (match_operand:V4SI 3 "register_operand" "f")
3765                 (parallel [(const_int 0) (const_int 2)]))))))]
3766   "ISA_HAS_LSX"
3767   "vmaddwev.d.wu.w\t%w0,%w2,%w3"
3768   [(set_attr "type" "simd_fmadd")
3769    (set_attr "mode" "V2DI")])
3771 (define_insn "lsx_vmaddwev_w_hu_h"
3772   [(set (match_operand:V4SI 0 "register_operand" "=f")
3773         (plus:V4SI
3774           (match_operand:V4SI 1 "register_operand" "0")
3775           (mult:V4SI
3776             (zero_extend:V4SI
3777               (vec_select:V4HI
3778                 (match_operand:V8HI 2 "register_operand" "%f")
3779                 (parallel [(const_int 0) (const_int 2)
3780                            (const_int 4) (const_int 6)])))
3781             (sign_extend:V4SI
3782               (vec_select:V4HI
3783                 (match_operand:V8HI 3 "register_operand" "f")
3784                 (parallel [(const_int 0) (const_int 2)
3785                            (const_int 4) (const_int 6)]))))))]
3786   "ISA_HAS_LSX"
3787   "vmaddwev.w.hu.h\t%w0,%w2,%w3"
3788   [(set_attr "type" "simd_fmadd")
3789    (set_attr "mode" "V4SI")])
3791 (define_insn "lsx_vmaddwev_h_bu_b"
3792   [(set (match_operand:V8HI 0 "register_operand" "=f")
3793         (plus:V8HI
3794           (match_operand:V8HI 1 "register_operand" "0")
3795           (mult:V8HI
3796             (zero_extend:V8HI
3797               (vec_select:V8QI
3798                 (match_operand:V16QI 2 "register_operand" "%f")
3799                 (parallel [(const_int 0) (const_int 2)
3800                            (const_int 4) (const_int 6)
3801                            (const_int 8) (const_int 10)
3802                            (const_int 12) (const_int 14)])))
3803             (sign_extend:V8HI
3804               (vec_select:V8QI
3805                 (match_operand:V16QI 3 "register_operand" "f")
3806                 (parallel [(const_int 0) (const_int 2)
3807                            (const_int 4) (const_int 6)
3808                            (const_int 8) (const_int 10)
3809                            (const_int 12) (const_int 14)]))))))]
3810   "ISA_HAS_LSX"
3811   "vmaddwev.h.bu.b\t%w0,%w2,%w3"
3812   [(set_attr "type" "simd_fmadd")
3813    (set_attr "mode" "V8HI")])
3815 (define_insn "lsx_vmaddwod_d_wu_w"
3816   [(set (match_operand:V2DI 0 "register_operand" "=f")
3817         (plus:V2DI
3818           (match_operand:V2DI 1 "register_operand" "0")
3819           (mult:V2DI
3820             (zero_extend:V2DI
3821               (vec_select:V2SI
3822                 (match_operand:V4SI 2 "register_operand" "%f")
3823                 (parallel [(const_int 1) (const_int 3)])))
3824             (sign_extend:V2DI
3825               (vec_select:V2SI
3826                 (match_operand:V4SI 3 "register_operand" "f")
3827                 (parallel [(const_int 1) (const_int 3)]))))))]
3828   "ISA_HAS_LSX"
3829   "vmaddwod.d.wu.w\t%w0,%w2,%w3"
3830   [(set_attr "type" "simd_fmadd")
3831    (set_attr "mode" "V2DI")])
3833 (define_insn "lsx_vmaddwod_w_hu_h"
3834   [(set (match_operand:V4SI 0 "register_operand" "=f")
3835         (plus:V4SI
3836           (match_operand:V4SI 1 "register_operand" "0")
3837           (mult:V4SI
3838             (zero_extend:V4SI
3839               (vec_select:V4HI
3840                 (match_operand:V8HI 2 "register_operand" "%f")
3841                 (parallel [(const_int 1) (const_int 3)
3842                            (const_int 5) (const_int 7)])))
3843             (sign_extend:V4SI
3844               (vec_select:V4HI
3845                 (match_operand:V8HI 3 "register_operand" "f")
3846                 (parallel [(const_int 1) (const_int 3)
3847                            (const_int 5) (const_int 7)]))))))]
3848   "ISA_HAS_LSX"
3849   "vmaddwod.w.hu.h\t%w0,%w2,%w3"
3850   [(set_attr "type" "simd_fmadd")
3851    (set_attr "mode" "V4SI")])
3853 (define_insn "lsx_vmaddwod_h_bu_b"
3854   [(set (match_operand:V8HI 0 "register_operand" "=f")
3855         (plus:V8HI
3856           (match_operand:V8HI 1 "register_operand" "0")
3857           (mult:V8HI
3858             (zero_extend:V8HI
3859               (vec_select:V8QI
3860                 (match_operand:V16QI 2 "register_operand" "%f")
3861                 (parallel [(const_int 1) (const_int 3)
3862                            (const_int 5) (const_int 7)
3863                            (const_int 9) (const_int 11)
3864                            (const_int 13) (const_int 15)])))
3865             (sign_extend:V8HI
3866               (vec_select:V8QI
3867                 (match_operand:V16QI 3 "register_operand" "f")
3868                 (parallel [(const_int 1) (const_int 3)
3869                            (const_int 5) (const_int 7)
3870                            (const_int 9) (const_int 11)
3871                            (const_int 13) (const_int 15)]))))))]
3872   "ISA_HAS_LSX"
3873   "vmaddwod.h.bu.b\t%w0,%w2,%w3"
3874   [(set_attr "type" "simd_fmadd")
3875    (set_attr "mode" "V8HI")])
3877 (define_insn "lsx_vmaddwev_q_d"
3878   [(set (match_operand:V2DI 0 "register_operand" "=f")
3879         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
3880                       (match_operand:V2DI 2 "register_operand" "f")
3881                       (match_operand:V2DI 3 "register_operand" "f")]
3882                      UNSPEC_LSX_VMADDWEV))]
3883   "ISA_HAS_LSX"
3884   "vmaddwev.q.d\t%w0,%w2,%w3"
3885   [(set_attr "type" "simd_int_arith")
3886    (set_attr "mode" "V2DI")])
3888 (define_insn "lsx_vmaddwod_q_d"
3889   [(set (match_operand:V2DI 0 "register_operand" "=f")
3890         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
3891                       (match_operand:V2DI 2 "register_operand" "f")
3892                       (match_operand:V2DI 3 "register_operand" "f")]
3893                      UNSPEC_LSX_VMADDWOD))]
3894   "ISA_HAS_LSX"
3895   "vmaddwod.q.d\t%w0,%w2,%w3"
3896   [(set_attr "type" "simd_int_arith")
3897    (set_attr "mode" "V2DI")])
3899 (define_insn "lsx_vmaddwev_q_du"
3900   [(set (match_operand:V2DI 0 "register_operand" "=f")
3901         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
3902                       (match_operand:V2DI 2 "register_operand" "f")
3903                       (match_operand:V2DI 3 "register_operand" "f")]
3904                      UNSPEC_LSX_VMADDWEV2))]
3905   "ISA_HAS_LSX"
3906   "vmaddwev.q.du\t%w0,%w2,%w3"
3907   [(set_attr "type" "simd_int_arith")
3908    (set_attr "mode" "V2DI")])
3910 (define_insn "lsx_vmaddwod_q_du"
3911   [(set (match_operand:V2DI 0 "register_operand" "=f")
3912         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
3913                       (match_operand:V2DI 2 "register_operand" "f")
3914                       (match_operand:V2DI 3 "register_operand" "f")]
3915                      UNSPEC_LSX_VMADDWOD2))]
3916   "ISA_HAS_LSX"
3917   "vmaddwod.q.du\t%w0,%w2,%w3"
3918   [(set_attr "type" "simd_int_arith")
3919    (set_attr "mode" "V2DI")])
3921 (define_insn "lsx_vmaddwev_q_du_d"
3922   [(set (match_operand:V2DI 0 "register_operand" "=f")
3923         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
3924                       (match_operand:V2DI 2 "register_operand" "f")
3925                       (match_operand:V2DI 3 "register_operand" "f")]
3926                      UNSPEC_LSX_VMADDWEV3))]
3927   "ISA_HAS_LSX"
3928   "vmaddwev.q.du.d\t%w0,%w2,%w3"
3929   [(set_attr "type" "simd_int_arith")
3930    (set_attr "mode" "V2DI")])
3932 (define_insn "lsx_vmaddwod_q_du_d"
3933   [(set (match_operand:V2DI 0 "register_operand" "=f")
3934         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
3935                       (match_operand:V2DI 2 "register_operand" "f")
3936                       (match_operand:V2DI 3 "register_operand" "f")]
3937                      UNSPEC_LSX_VMADDWOD3))]
3938   "ISA_HAS_LSX"
3939   "vmaddwod.q.du.d\t%w0,%w2,%w3"
3940   [(set_attr "type" "simd_int_arith")
3941    (set_attr "mode" "V2DI")])
3943 (define_insn "lsx_vadd_q"
3944   [(set (match_operand:V2DI 0 "register_operand" "=f")
3945         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3946                       (match_operand:V2DI 2 "register_operand" "f")]
3947                      UNSPEC_LSX_VADD_Q))]
3948   "ISA_HAS_LSX"
3949   "vadd.q\t%w0,%w1,%w2"
3950   [(set_attr "type" "simd_int_arith")
3951    (set_attr "mode" "V2DI")])
3953 (define_insn "lsx_vsub_q"
3954   [(set (match_operand:V2DI 0 "register_operand" "=f")
3955         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
3956                       (match_operand:V2DI 2 "register_operand" "f")]
3957                      UNSPEC_LSX_VSUB_Q))]
3958   "ISA_HAS_LSX"
3959   "vsub.q\t%w0,%w1,%w2"
3960   [(set_attr "type" "simd_int_arith")
3961    (set_attr "mode" "V2DI")])
3963 (define_insn "lsx_vmskgez_b"
3964   [(set (match_operand:V16QI 0 "register_operand" "=f")
3965         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "f")]
3966                       UNSPEC_LSX_VMSKGEZ))]
3967   "ISA_HAS_LSX"
3968   "vmskgez.b\t%w0,%w1"
3969   [(set_attr "type" "simd_bit")
3970    (set_attr "mode" "V16QI")])
3972 (define_insn "lsx_vmsknz_b"
3973   [(set (match_operand:V16QI 0 "register_operand" "=f")
3974         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "f")]
3975                       UNSPEC_LSX_VMSKNZ))]
3976   "ISA_HAS_LSX"
3977   "vmsknz.b\t%w0,%w1"
3978   [(set_attr "type" "simd_bit")
3979    (set_attr "mode" "V16QI")])
3981 (define_insn "vec_unpack<su>_hi_v16qi"
3982   [(set (match_operand:V8HI 0 "register_operand" "=f")
3983         (any_extend:V8HI
3984           (vec_select:V8QI
3985             (match_operand:V16QI 1 "register_operand" "f")
3986             (parallel [(const_int 8) (const_int 9)
3987                        (const_int 10) (const_int 11)
3988                        (const_int 12) (const_int 13)
3989                        (const_int 14) (const_int 15)]))))]
3990   "ISA_HAS_LSX"
3991   "vexth.h<u>.b<u>\t%w0,%w1"
3992   [(set_attr "type" "simd_fcvt")
3993    (set_attr "mode" "V8HI")])
3995 (define_insn "vec_unpack<su>_hi_v8hi"
3996   [(set (match_operand:V4SI 0 "register_operand" "=f")
3997         (any_extend:V4SI
3998           (vec_select:V4HI
3999             (match_operand:V8HI 1 "register_operand" "f")
4000             (parallel [(const_int 4) (const_int 5)
4001                        (const_int 6) (const_int 7)]))))]
4002   "ISA_HAS_LSX"
4003   "vexth.w<u>.h<u>\t%w0,%w1"
4004   [(set_attr "type" "simd_fcvt")
4005    (set_attr "mode" "V4SI")])
4007 (define_insn "vec_unpack<su>_hi_v4si"
4008   [(set (match_operand:V2DI 0 "register_operand" "=f")
4009         (any_extend:V2DI
4010           (vec_select:V2SI
4011             (match_operand:V4SI 1 "register_operand" "f")
4012             (parallel [(const_int 2) (const_int 3)]))))]
4013   "ISA_HAS_LSX"
4014   "vexth.d<u>.w<u>\t%w0,%w1"
4015   [(set_attr "type" "simd_fcvt")
4016    (set_attr "mode" "V2DI")])
4018 (define_insn "lsx_vexth_q_d"
4019   [(set (match_operand:V2DI 0 "register_operand" "=f")
4020         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")]
4021                      UNSPEC_LSX_VEXTH_Q_D))]
4022   "ISA_HAS_LSX"
4023   "vexth.q.d\t%w0,%w1"
4024   [(set_attr "type" "simd_fcvt")
4025    (set_attr "mode" "V2DI")])
4027 (define_insn "lsx_vexth_qu_du"
4028   [(set (match_operand:V2DI 0 "register_operand" "=f")
4029         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")]
4030                      UNSPEC_LSX_VEXTH_QU_DU))]
4031   "ISA_HAS_LSX"
4032   "vexth.qu.du\t%w0,%w1"
4033   [(set_attr "type" "simd_fcvt")
4034    (set_attr "mode" "V2DI")])
4036 (define_insn "lsx_vextl_q_d"
4037   [(set (match_operand:V2DI 0 "register_operand" "=f")
4038         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")]
4039                      UNSPEC_LSX_VEXTL_Q_D))]
4040   "ISA_HAS_LSX"
4041   "vextl.q.d\t%w0,%w1"
4042   [(set_attr "type" "simd_fcvt")
4043    (set_attr "mode" "V2DI")])
4045 (define_insn "lsx_vsrlni_<lsxfmt>_<dlsxfmt>"
4046   [(set (match_operand:ILSX 0 "register_operand" "=f")
4047         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
4048                       (match_operand:ILSX 2 "register_operand" "f")
4049                       (match_operand 3 "const_uimm8_operand" "")]
4050                      UNSPEC_LSX_VSRLNI))]
4051   "ISA_HAS_LSX"
4052   "vsrlni.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
4053   [(set_attr "type" "simd_shift")
4054    (set_attr "mode" "<MODE>")])
4056 (define_insn "lsx_vsrlrni_<lsxfmt>_<dlsxfmt>"
4057   [(set (match_operand:ILSX 0 "register_operand" "=f")
4058         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
4059                       (match_operand:ILSX 2 "register_operand" "f")
4060                       (match_operand 3 "const_uimm8_operand" "")]
4061                      UNSPEC_LSX_VSRLRNI))]
4062   "ISA_HAS_LSX"
4063   "vsrlrni.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
4064   [(set_attr "type" "simd_shift")
4065    (set_attr "mode" "<MODE>")])
4067 (define_insn "lsx_vssrlni_<lsxfmt>_<dlsxfmt>"
4068   [(set (match_operand:ILSX 0 "register_operand" "=f")
4069         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
4070                       (match_operand:ILSX 2 "register_operand" "f")
4071                       (match_operand 3 "const_uimm8_operand" "")]
4072                      UNSPEC_LSX_VSSRLNI))]
4073   "ISA_HAS_LSX"
4074   "vssrlni.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
4075   [(set_attr "type" "simd_shift")
4076    (set_attr "mode" "<MODE>")])
4078 (define_insn "lsx_vssrlni_<lsxfmt_u>_<dlsxfmt>"
4079   [(set (match_operand:ILSX 0 "register_operand" "=f")
4080         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
4081                       (match_operand:ILSX 2 "register_operand" "f")
4082                       (match_operand 3 "const_uimm8_operand" "")]
4083                      UNSPEC_LSX_VSSRLNI2))]
4084   "ISA_HAS_LSX"
4085   "vssrlni.<lsxfmt_u>.<dlsxfmt>\t%w0,%w2,%3"
4086   [(set_attr "type" "simd_shift")
4087    (set_attr "mode" "<MODE>")])
4089 (define_insn "lsx_vssrlrni_<lsxfmt>_<dlsxfmt>"
4090   [(set (match_operand:ILSX 0 "register_operand" "=f")
4091         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
4092                       (match_operand:ILSX 2 "register_operand" "f")
4093                       (match_operand 3 "const_uimm8_operand" "")]
4094                      UNSPEC_LSX_VSSRLRNI))]
4095   "ISA_HAS_LSX"
4096   "vssrlrni.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
4097   [(set_attr "type" "simd_shift")
4098    (set_attr "mode" "<MODE>")])
4100 (define_insn "lsx_vssrlrni_<lsxfmt_u>_<dlsxfmt>"
4101   [(set (match_operand:ILSX 0 "register_operand" "=f")
4102         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
4103                       (match_operand:ILSX 2 "register_operand" "f")
4104                       (match_operand 3 "const_uimm8_operand" "")]
4105                      UNSPEC_LSX_VSSRLRNI2))]
4106   "ISA_HAS_LSX"
4107   "vssrlrni.<lsxfmt_u>.<dlsxfmt>\t%w0,%w2,%3"
4108   [(set_attr "type" "simd_shift")
4109    (set_attr "mode" "<MODE>")])
4111 (define_insn "lsx_vsrani_<lsxfmt>_<dlsxfmt>"
4112   [(set (match_operand:ILSX 0 "register_operand" "=f")
4113         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
4114                       (match_operand:ILSX 2 "register_operand" "f")
4115                       (match_operand 3 "const_uimm8_operand" "")]
4116                      UNSPEC_LSX_VSRANI))]
4117   "ISA_HAS_LSX"
4118   "vsrani.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
4119   [(set_attr "type" "simd_shift")
4120    (set_attr "mode" "<MODE>")])
4122 (define_insn "lsx_vsrarni_<lsxfmt>_<dlsxfmt>"
4123   [(set (match_operand:ILSX 0 "register_operand" "=f")
4124         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
4125                       (match_operand:ILSX 2 "register_operand" "f")
4126                       (match_operand 3 "const_uimm8_operand" "")]
4127                      UNSPEC_LSX_VSRARNI))]
4128   "ISA_HAS_LSX"
4129   "vsrarni.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
4130   [(set_attr "type" "simd_shift")
4131    (set_attr "mode" "<MODE>")])
4133 (define_insn "lsx_vssrani_<lsxfmt>_<dlsxfmt>"
4134   [(set (match_operand:ILSX 0 "register_operand" "=f")
4135         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
4136                       (match_operand:ILSX 2 "register_operand" "f")
4137                       (match_operand 3 "const_uimm8_operand" "")]
4138                     UNSPEC_LSX_VSSRANI))]
4139   "ISA_HAS_LSX"
4140   "vssrani.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
4141   [(set_attr "type" "simd_shift")
4142    (set_attr "mode" "<MODE>")])
4144 (define_insn "lsx_vssrani_<lsxfmt_u>_<dlsxfmt>"
4145   [(set (match_operand:ILSX 0 "register_operand" "=f")
4146         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
4147                       (match_operand:ILSX 2 "register_operand" "f")
4148                       (match_operand 3 "const_uimm8_operand" "")]
4149                      UNSPEC_LSX_VSSRANI2))]
4150   "ISA_HAS_LSX"
4151   "vssrani.<lsxfmt_u>.<dlsxfmt>\t%w0,%w2,%3"
4152   [(set_attr "type" "simd_shift")
4153    (set_attr "mode" "<MODE>")])
4155 (define_insn "lsx_vssrarni_<lsxfmt>_<dlsxfmt>"
4156   [(set (match_operand:ILSX 0 "register_operand" "=f")
4157         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
4158                       (match_operand:ILSX 2 "register_operand" "f")
4159                       (match_operand 3 "const_uimm8_operand" "")]
4160                      UNSPEC_LSX_VSSRARNI))]
4161   "ISA_HAS_LSX"
4162   "vssrarni.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
4163   [(set_attr "type" "simd_shift")
4164    (set_attr "mode" "<MODE>")])
4166 (define_insn "lsx_vssrarni_<lsxfmt_u>_<dlsxfmt>"
4167   [(set (match_operand:ILSX 0 "register_operand" "=f")
4168         (unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
4169                       (match_operand:ILSX 2 "register_operand" "f")
4170                       (match_operand 3 "const_uimm8_operand" "")]
4171                      UNSPEC_LSX_VSSRARNI2))]
4172   "ISA_HAS_LSX"
4173   "vssrarni.<lsxfmt_u>.<dlsxfmt>\t%w0,%w2,%3"
4174   [(set_attr "type" "simd_shift")
4175    (set_attr "mode" "<MODE>")])
4177 (define_insn "lsx_vpermi_w"
4178   [(set (match_operand:V4SI 0 "register_operand" "=f")
4179         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
4180                       (match_operand:V4SI 2 "register_operand" "f")
4181                       (match_operand 3 "const_uimm8_operand" "")]
4182                      UNSPEC_LSX_VPERMI))]
4183   "ISA_HAS_LSX"
4184   "vpermi.w\t%w0,%w2,%3"
4185   [(set_attr "type" "simd_bit")
4186    (set_attr "mode" "V4SI")])
4188 ;; Delete one of two instructions that exactly play the same role.
4189 (define_peephole2
4190   [(set (match_operand:V2DI 0 "register_operand")
4191         (vec_duplicate:V2DI (match_operand:DI 1 "register_operand")))
4192    (set (match_operand:V2DI 2 "register_operand")
4193         (vec_merge:V2DI
4194           (vec_duplicate:V2DI (match_operand:DI 3 "register_operand"))
4195           (match_operand:V2DI 4 "register_operand")
4196           (match_operand 5 "const_int_operand")))]
4197   "operands[0] == operands[2] &&
4198    operands[1] == operands[3] &&
4199    operands[2] == operands[4] &&
4200    INTVAL (operands[5]) == 2"
4201   [(set (match_dup 0)
4202         (vec_duplicate:V2DI (match_dup 1)))]
4203   "")