* config/sh/sh.c (sh_expand_prologue): Remove unnecessary
[official-gcc.git] / gcc / config / mips / loongson.md
blob4f95c285ce5b000b653b4105657c366ed34eb337
1 ;; Machine description for ST Microelectronics Loongson-2E/2F.
2 ;; Copyright (C) 2008, 2009 Free Software Foundation, Inc.
3 ;; Contributed by CodeSourcery.
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/>.
21 (define_c_enum "unspec" [
22   UNSPEC_LOONGSON_PAVG
23   UNSPEC_LOONGSON_PCMPEQ
24   UNSPEC_LOONGSON_PCMPGT
25   UNSPEC_LOONGSON_PEXTR
26   UNSPEC_LOONGSON_PINSR_0
27   UNSPEC_LOONGSON_PINSR_1
28   UNSPEC_LOONGSON_PINSR_2
29   UNSPEC_LOONGSON_PINSR_3
30   UNSPEC_LOONGSON_PMADD
31   UNSPEC_LOONGSON_PMOVMSK
32   UNSPEC_LOONGSON_PMULHU
33   UNSPEC_LOONGSON_PMULH
34   UNSPEC_LOONGSON_PMULU
35   UNSPEC_LOONGSON_PASUBUB
36   UNSPEC_LOONGSON_BIADD
37   UNSPEC_LOONGSON_PSADBH
38   UNSPEC_LOONGSON_PSHUFH
39   UNSPEC_LOONGSON_PUNPCKH
40   UNSPEC_LOONGSON_PUNPCKL
41   UNSPEC_LOONGSON_PADDD
42   UNSPEC_LOONGSON_PSUBD
45 ;; Mode iterators and attributes.
47 ;; 64-bit vectors of bytes.
48 (define_mode_iterator VB [V8QI])
50 ;; 64-bit vectors of halfwords.
51 (define_mode_iterator VH [V4HI])
53 ;; 64-bit vectors of words.
54 (define_mode_iterator VW [V2SI])
56 ;; 64-bit vectors of halfwords and bytes.
57 (define_mode_iterator VHB [V4HI V8QI])
59 ;; 64-bit vectors of words and halfwords.
60 (define_mode_iterator VWH [V2SI V4HI])
62 ;; 64-bit vectors of words, halfwords and bytes.
63 (define_mode_iterator VWHB [V2SI V4HI V8QI])
65 ;; 64-bit vectors of words, halfwords and bytes; and DImode.
66 (define_mode_iterator VWHBDI [V2SI V4HI V8QI DI])
68 ;; The Loongson instruction suffixes corresponding to the modes in the
69 ;; VWHBDI iterator.
70 (define_mode_attr V_suffix [(V2SI "w") (V4HI "h") (V8QI "b") (DI "d")])
72 ;; Given a vector type T, the mode of a vector half the size of T
73 ;; and with the same number of elements.
74 (define_mode_attr V_squash [(V2SI "V2HI") (V4HI "V4QI")])
76 ;; Given a vector type T, the mode of a vector the same size as T
77 ;; but with half as many elements.
78 (define_mode_attr V_stretch_half [(V2SI "DI") (V4HI "V2SI") (V8QI "V4HI")])
80 ;; The Loongson instruction suffixes corresponding to the transformation
81 ;; expressed by V_stretch_half.
82 (define_mode_attr V_stretch_half_suffix [(V2SI "wd") (V4HI "hw") (V8QI "bh")])
84 ;; Given a vector type T, the mode of a vector the same size as T
85 ;; but with twice as many elements.
86 (define_mode_attr V_squash_double [(V2SI "V4HI") (V4HI "V8QI")])
88 ;; The Loongson instruction suffixes corresponding to the conversions
89 ;; specified by V_half_width.
90 (define_mode_attr V_squash_double_suffix [(V2SI "wh") (V4HI "hb")])
92 ;; Move patterns.
94 ;; Expander to legitimize moves involving values of vector modes.
95 (define_expand "mov<mode>"
96   [(set (match_operand:VWHB 0)
97         (match_operand:VWHB 1))]
98   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
100   if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
101     DONE;
104 ;; Handle legitimized moves between values of vector modes.
105 (define_insn "mov<mode>_internal"
106   [(set (match_operand:VWHB 0 "nonimmediate_operand" "=m,f,d,f,  d,  m,  d")
107         (match_operand:VWHB 1 "move_operand"          "f,m,f,dYG,dYG,dYG,m"))]
108   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
109   { return mips_output_move (operands[0], operands[1]); }
110   [(set_attr "move_type" "fpstore,fpload,mfc,mtc,move,store,load")
111    (set_attr "mode" "DI")])
113 ;; Initialization of a vector.
115 (define_expand "vec_init<mode>"
116   [(set (match_operand:VWHB 0 "register_operand")
117         (match_operand 1 ""))]
118   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
120   mips_expand_vector_init (operands[0], operands[1]);
121   DONE;
124 ;; Instruction patterns for SIMD instructions.
126 ;; Pack with signed saturation.
127 (define_insn "vec_pack_ssat_<mode>"
128   [(set (match_operand:<V_squash_double> 0 "register_operand" "=f")
129         (vec_concat:<V_squash_double>
130          (ss_truncate:<V_squash>
131           (match_operand:VWH 1 "register_operand" "f"))
132          (ss_truncate:<V_squash>
133           (match_operand:VWH 2 "register_operand" "f"))))]
134   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
135   "packss<V_squash_double_suffix>\t%0,%1,%2"
136   [(set_attr "type" "fmul")])
138 ;; Pack with unsigned saturation.
139 (define_insn "vec_pack_usat_<mode>"
140   [(set (match_operand:<V_squash_double> 0 "register_operand" "=f")
141         (vec_concat:<V_squash_double>
142          (us_truncate:<V_squash>
143           (match_operand:VH 1 "register_operand" "f"))
144          (us_truncate:<V_squash>
145           (match_operand:VH 2 "register_operand" "f"))))]
146   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
147   "packus<V_squash_double_suffix>\t%0,%1,%2"
148   [(set_attr "type" "fmul")])
150 ;; Addition, treating overflow by wraparound.
151 (define_insn "add<mode>3"
152   [(set (match_operand:VWHB 0 "register_operand" "=f")
153         (plus:VWHB (match_operand:VWHB 1 "register_operand" "f")
154                    (match_operand:VWHB 2 "register_operand" "f")))]
155   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
156   "padd<V_suffix>\t%0,%1,%2"
157   [(set_attr "type" "fadd")])
159 ;; Addition of doubleword integers stored in FP registers.
160 ;; Overflow is treated by wraparound.
161 ;; We use 'unspec' instead of 'plus' here to avoid clash with
162 ;; mips.md::add<mode>3.  If 'plus' was used, then such instruction
163 ;; would be recognized as adddi3 and reload would make it use
164 ;; GPRs instead of FPRs.
165 (define_insn "loongson_paddd"
166   [(set (match_operand:DI 0 "register_operand" "=f")
167         (unspec:DI [(match_operand:DI 1 "register_operand" "f")
168                     (match_operand:DI 2 "register_operand" "f")]
169                    UNSPEC_LOONGSON_PADDD))]
170   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
171   "paddd\t%0,%1,%2"
172   [(set_attr "type" "fadd")])
174 ;; Addition, treating overflow by signed saturation.
175 (define_insn "ssadd<mode>3"
176   [(set (match_operand:VHB 0 "register_operand" "=f")
177         (ss_plus:VHB (match_operand:VHB 1 "register_operand" "f")
178                      (match_operand:VHB 2 "register_operand" "f")))]
179   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
180   "padds<V_suffix>\t%0,%1,%2"
181   [(set_attr "type" "fadd")])
183 ;; Addition, treating overflow by unsigned saturation.
184 (define_insn "usadd<mode>3"
185   [(set (match_operand:VHB 0 "register_operand" "=f")
186         (us_plus:VHB (match_operand:VHB 1 "register_operand" "f")
187                      (match_operand:VHB 2 "register_operand" "f")))]
188   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
189   "paddus<V_suffix>\t%0,%1,%2"
190   [(set_attr "type" "fadd")])
192 ;; Logical AND NOT.
193 (define_insn "loongson_pandn_<V_suffix>"
194   [(set (match_operand:VWHBDI 0 "register_operand" "=f")
195         (and:VWHBDI
196          (not:VWHBDI (match_operand:VWHBDI 1 "register_operand" "f"))
197          (match_operand:VWHBDI 2 "register_operand" "f")))]
198   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
199   "pandn\t%0,%1,%2"
200   [(set_attr "type" "fmul")])
202 ;; Average.
203 (define_insn "loongson_pavg<V_suffix>"
204   [(set (match_operand:VHB 0 "register_operand" "=f")
205         (unspec:VHB [(match_operand:VHB 1 "register_operand" "f")
206                      (match_operand:VHB 2 "register_operand" "f")]
207                     UNSPEC_LOONGSON_PAVG))]
208   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
209   "pavg<V_suffix>\t%0,%1,%2"
210   [(set_attr "type" "fadd")])
212 ;; Equality test.
213 (define_insn "loongson_pcmpeq<V_suffix>"
214   [(set (match_operand:VWHB 0 "register_operand" "=f")
215         (unspec:VWHB [(match_operand:VWHB 1 "register_operand" "f")
216                       (match_operand:VWHB 2 "register_operand" "f")]
217                      UNSPEC_LOONGSON_PCMPEQ))]
218   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
219   "pcmpeq<V_suffix>\t%0,%1,%2"
220   [(set_attr "type" "fadd")])
222 ;; Greater-than test.
223 (define_insn "loongson_pcmpgt<V_suffix>"
224   [(set (match_operand:VWHB 0 "register_operand" "=f")
225         (unspec:VWHB [(match_operand:VWHB 1 "register_operand" "f")
226                       (match_operand:VWHB 2 "register_operand" "f")]
227                      UNSPEC_LOONGSON_PCMPGT))]
228   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
229   "pcmpgt<V_suffix>\t%0,%1,%2"
230   [(set_attr "type" "fadd")])
232 ;; Extract halfword.
233 (define_insn "loongson_pextr<V_suffix>"
234   [(set (match_operand:VH 0 "register_operand" "=f")
235         (unspec:VH [(match_operand:VH 1 "register_operand" "f")
236                     (match_operand:SI 2 "register_operand" "f")]
237                    UNSPEC_LOONGSON_PEXTR))]
238   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
239   "pextr<V_suffix>\t%0,%1,%2"
240   [(set_attr "type" "fmul")])
242 ;; Insert halfword.
243 (define_insn "loongson_pinsr<V_suffix>_0"
244   [(set (match_operand:VH 0 "register_operand" "=f")
245         (unspec:VH [(match_operand:VH 1 "register_operand" "f")
246                     (match_operand:VH 2 "register_operand" "f")]
247                    UNSPEC_LOONGSON_PINSR_0))]
248   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
249   "pinsr<V_suffix>_0\t%0,%1,%2"
250   [(set_attr "type" "fdiv")])
252 (define_insn "loongson_pinsr<V_suffix>_1"
253   [(set (match_operand:VH 0 "register_operand" "=f")
254         (unspec:VH [(match_operand:VH 1 "register_operand" "f")
255                     (match_operand:VH 2 "register_operand" "f")]
256                    UNSPEC_LOONGSON_PINSR_1))]
257   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
258   "pinsr<V_suffix>_1\t%0,%1,%2"
259   [(set_attr "type" "fdiv")])
261 (define_insn "loongson_pinsr<V_suffix>_2"
262   [(set (match_operand:VH 0 "register_operand" "=f")
263         (unspec:VH [(match_operand:VH 1 "register_operand" "f")
264                     (match_operand:VH 2 "register_operand" "f")]
265                    UNSPEC_LOONGSON_PINSR_2))]
266   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
267   "pinsr<V_suffix>_2\t%0,%1,%2"
268   [(set_attr "type" "fdiv")])
270 (define_insn "loongson_pinsr<V_suffix>_3"
271   [(set (match_operand:VH 0 "register_operand" "=f")
272         (unspec:VH [(match_operand:VH 1 "register_operand" "f")
273                     (match_operand:VH 2 "register_operand" "f")]
274                    UNSPEC_LOONGSON_PINSR_3))]
275   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
276   "pinsr<V_suffix>_3\t%0,%1,%2"
277   [(set_attr "type" "fdiv")])
279 ;; Multiply and add packed integers.
280 (define_insn "loongson_pmadd<V_stretch_half_suffix>"
281   [(set (match_operand:<V_stretch_half> 0 "register_operand" "=f")
282         (unspec:<V_stretch_half> [(match_operand:VH 1 "register_operand" "f")
283                                   (match_operand:VH 2 "register_operand" "f")]
284                                  UNSPEC_LOONGSON_PMADD))]
285   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
286   "pmadd<V_stretch_half_suffix>\t%0,%1,%2"
287   [(set_attr "type" "fmul")])
289 ;; Maximum of signed halfwords.
290 (define_insn "smax<mode>3"
291   [(set (match_operand:VH 0 "register_operand" "=f")
292         (smax:VH (match_operand:VH 1 "register_operand" "f")
293                  (match_operand:VH 2 "register_operand" "f")))]
294   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
295   "pmaxs<V_suffix>\t%0,%1,%2"
296   [(set_attr "type" "fadd")])
298 ;; Maximum of unsigned bytes.
299 (define_insn "umax<mode>3"
300   [(set (match_operand:VB 0 "register_operand" "=f")
301         (umax:VB (match_operand:VB 1 "register_operand" "f")
302                  (match_operand:VB 2 "register_operand" "f")))]
303   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
304   "pmaxu<V_suffix>\t%0,%1,%2"
305   [(set_attr "type" "fadd")])
307 ;; Minimum of signed halfwords.
308 (define_insn "smin<mode>3"
309   [(set (match_operand:VH 0 "register_operand" "=f")
310         (smin:VH (match_operand:VH 1 "register_operand" "f")
311                  (match_operand:VH 2 "register_operand" "f")))]
312   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
313   "pmins<V_suffix>\t%0,%1,%2"
314   [(set_attr "type" "fadd")])
316 ;; Minimum of unsigned bytes.
317 (define_insn "umin<mode>3"
318   [(set (match_operand:VB 0 "register_operand" "=f")
319         (umin:VB (match_operand:VB 1 "register_operand" "f")
320                  (match_operand:VB 2 "register_operand" "f")))]
321   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
322   "pminu<V_suffix>\t%0,%1,%2"
323   [(set_attr "type" "fadd")])
325 ;; Move byte mask.
326 (define_insn "loongson_pmovmsk<V_suffix>"
327   [(set (match_operand:VB 0 "register_operand" "=f")
328         (unspec:VB [(match_operand:VB 1 "register_operand" "f")]
329                    UNSPEC_LOONGSON_PMOVMSK))]
330   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
331   "pmovmsk<V_suffix>\t%0,%1"
332   [(set_attr "type" "fabs")])
334 ;; Multiply unsigned integers and store high result.
335 (define_insn "umul<mode>3_highpart"
336   [(set (match_operand:VH 0 "register_operand" "=f")
337         (unspec:VH [(match_operand:VH 1 "register_operand" "f")
338                     (match_operand:VH 2 "register_operand" "f")]
339                    UNSPEC_LOONGSON_PMULHU))]
340   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
341   "pmulhu<V_suffix>\t%0,%1,%2"
342   [(set_attr "type" "fmul")])
344 ;; Multiply signed integers and store high result.
345 (define_insn "smul<mode>3_highpart"
346   [(set (match_operand:VH 0 "register_operand" "=f")
347         (unspec:VH [(match_operand:VH 1 "register_operand" "f")
348                     (match_operand:VH 2 "register_operand" "f")]
349                    UNSPEC_LOONGSON_PMULH))]
350   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
351   "pmulh<V_suffix>\t%0,%1,%2"
352   [(set_attr "type" "fmul")])
354 ;; Multiply signed integers and store low result.
355 (define_insn "mul<mode>3"
356   [(set (match_operand:VH 0 "register_operand" "=f")
357         (mult:VH (match_operand:VH 1 "register_operand" "f")
358                  (match_operand:VH 2 "register_operand" "f")))]
359   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
360   "pmull<V_suffix>\t%0,%1,%2"
361   [(set_attr "type" "fmul")])
363 ;; Multiply unsigned word integers.
364 (define_insn "loongson_pmulu<V_suffix>"
365   [(set (match_operand:DI 0 "register_operand" "=f")
366         (unspec:DI [(match_operand:VW 1 "register_operand" "f")
367                     (match_operand:VW 2 "register_operand" "f")]
368                    UNSPEC_LOONGSON_PMULU))]
369   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
370   "pmulu<V_suffix>\t%0,%1,%2"
371   [(set_attr "type" "fmul")])
373 ;; Absolute difference.
374 (define_insn "loongson_pasubub"
375   [(set (match_operand:VB 0 "register_operand" "=f")
376         (unspec:VB [(match_operand:VB 1 "register_operand" "f")
377                     (match_operand:VB 2 "register_operand" "f")]
378                    UNSPEC_LOONGSON_PASUBUB))]
379   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
380   "pasubub\t%0,%1,%2"
381   [(set_attr "type" "fadd")])
383 ;; Sum of unsigned byte integers.
384 (define_insn "loongson_biadd"
385   [(set (match_operand:<V_stretch_half> 0 "register_operand" "=f")
386         (unspec:<V_stretch_half> [(match_operand:VB 1 "register_operand" "f")]
387                                  UNSPEC_LOONGSON_BIADD))]
388   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
389   "biadd\t%0,%1"
390   [(set_attr "type" "fabs")])
392 ;; Sum of absolute differences.
393 (define_insn "loongson_psadbh"
394   [(set (match_operand:<V_stretch_half> 0 "register_operand" "=f")
395         (unspec:<V_stretch_half> [(match_operand:VB 1 "register_operand" "f")
396                                   (match_operand:VB 2 "register_operand" "f")]
397                                  UNSPEC_LOONGSON_PSADBH))]
398   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
399   "pasubub\t%0,%1,%2;biadd\t%0,%0"
400   [(set_attr "type" "fadd")])
402 ;; Shuffle halfwords.
403 (define_insn "loongson_pshufh"
404   [(set (match_operand:VH 0 "register_operand" "=f")
405         (unspec:VH [(match_operand:VH 1 "register_operand" "0")
406                     (match_operand:VH 2 "register_operand" "f")
407                     (match_operand:SI 3 "register_operand" "f")]
408                    UNSPEC_LOONGSON_PSHUFH))]
409   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
410   "pshufh\t%0,%2,%3"
411   [(set_attr "type" "fmul")])
413 ;; Shift left logical.
414 (define_insn "ashl<mode>3"
415   [(set (match_operand:VWH 0 "register_operand" "=f")
416         (ashift:VWH (match_operand:VWH 1 "register_operand" "f")
417                     (match_operand:SI 2 "register_operand" "f")))]
418   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
419   "psll<V_suffix>\t%0,%1,%2"
420   [(set_attr "type" "fmul")])
422 ;; Shift right arithmetic.
423 (define_insn "ashr<mode>3"
424   [(set (match_operand:VWH 0 "register_operand" "=f")
425         (ashiftrt:VWH (match_operand:VWH 1 "register_operand" "f")
426                       (match_operand:SI 2 "register_operand" "f")))]
427   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
428   "psra<V_suffix>\t%0,%1,%2"
429   [(set_attr "type" "fdiv")])
431 ;; Shift right logical.
432 (define_insn "lshr<mode>3"
433   [(set (match_operand:VWH 0 "register_operand" "=f")
434         (lshiftrt:VWH (match_operand:VWH 1 "register_operand" "f")
435                       (match_operand:SI 2 "register_operand" "f")))]
436   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
437   "psrl<V_suffix>\t%0,%1,%2"
438   [(set_attr "type" "fdiv")])
440 ;; Subtraction, treating overflow by wraparound.
441 (define_insn "sub<mode>3"
442   [(set (match_operand:VWHB 0 "register_operand" "=f")
443         (minus:VWHB (match_operand:VWHB 1 "register_operand" "f")
444                     (match_operand:VWHB 2 "register_operand" "f")))]
445   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
446   "psub<V_suffix>\t%0,%1,%2"
447   [(set_attr "type" "fadd")])
449 ;; Subtraction of doubleword integers stored in FP registers.
450 ;; Overflow is treated by wraparound.
451 ;; See loongson_paddd for the reason we use 'unspec' rather than
452 ;; 'minus' here.
453 (define_insn "loongson_psubd"
454   [(set (match_operand:DI 0 "register_operand" "=f")
455         (unspec:DI [(match_operand:DI 1 "register_operand" "f")
456                     (match_operand:DI 2 "register_operand" "f")]
457                    UNSPEC_LOONGSON_PSUBD))]
458   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
459   "psubd\t%0,%1,%2"
460   [(set_attr "type" "fadd")])
462 ;; Subtraction, treating overflow by signed saturation.
463 (define_insn "sssub<mode>3"
464   [(set (match_operand:VHB 0 "register_operand" "=f")
465         (ss_minus:VHB (match_operand:VHB 1 "register_operand" "f")
466                       (match_operand:VHB 2 "register_operand" "f")))]
467   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
468   "psubs<V_suffix>\t%0,%1,%2"
469   [(set_attr "type" "fadd")])
471 ;; Subtraction, treating overflow by unsigned saturation.
472 (define_insn "ussub<mode>3"
473   [(set (match_operand:VHB 0 "register_operand" "=f")
474         (us_minus:VHB (match_operand:VHB 1 "register_operand" "f")
475                       (match_operand:VHB 2 "register_operand" "f")))]
476   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
477   "psubus<V_suffix>\t%0,%1,%2"
478   [(set_attr "type" "fadd")])
480 ;; Unpack high data.
481 (define_insn "vec_interleave_high<mode>"
482   [(set (match_operand:VWHB 0 "register_operand" "=f")
483         (unspec:VWHB [(match_operand:VWHB 1 "register_operand" "f")
484                       (match_operand:VWHB 2 "register_operand" "f")]
485                      UNSPEC_LOONGSON_PUNPCKH))]
486   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
487   "punpckh<V_stretch_half_suffix>\t%0,%1,%2"
488   [(set_attr "type" "fdiv")])
490 ;; Unpack low data.
491 (define_insn "vec_interleave_low<mode>"
492   [(set (match_operand:VWHB 0 "register_operand" "=f")
493         (unspec:VWHB [(match_operand:VWHB 1 "register_operand" "f")
494                       (match_operand:VWHB 2 "register_operand" "f")]
495                      UNSPEC_LOONGSON_PUNPCKL))]
496   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
497   "punpckl<V_stretch_half_suffix>\t%0,%1,%2"
498   [(set_attr "type" "fdiv")])
500 ;; Integer division and modulus.
502 (define_insn "<u>div<mode>3"
503   [(set (match_operand:GPR 0 "register_operand" "=&d")
504         (any_div:GPR (match_operand:GPR 1 "register_operand" "d")
505                      (match_operand:GPR 2 "register_operand" "d")))]
506   "TARGET_LOONGSON_2EF"
507   { return mips_output_division ("<d>div<u>.g\t%0,%1,%2", operands); }
508   [(set_attr "type" "idiv3")
509    (set_attr "mode" "<MODE>")])
511 (define_insn "<u>mod<mode>3"
512   [(set (match_operand:GPR 0 "register_operand" "=&d")
513         (any_mod:GPR (match_operand:GPR 1 "register_operand" "d")
514                      (match_operand:GPR 2 "register_operand" "d")))]
515   "TARGET_LOONGSON_2EF"
516   { return mips_output_division ("<d>mod<u>.g\t%0,%1,%2", operands); }
517   [(set_attr "type" "idiv3")
518    (set_attr "mode" "<MODE>")])