OSDN Git Service

* varasm.c (output_constant_def): Do not consult
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / mips.md
1 ;;  Mips.md          Machine Description for MIPS based processors
2 ;;  Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4 ;;  Contributed by   A. Lichnewsky, lich@inria.inria.fr
5 ;;  Changes by       Michael Meissner, meissner@osf.org
6 ;;  64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7 ;;  Brendan Eich, brendan@microunity.com.
8
9 ;; This file is part of GNU CC.
10
11 ;; GNU CC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
15
16 ;; GNU CC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU CC; see the file COPYING.  If not, write to
23 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
25
26 ;; ??? Currently does not have define_function_unit support for the R8000.
27 ;; Must include new entries for fmadd in addition to existing entries.
28
29 (define_constants
30   [(UNSPEC_ULW                   0)
31    (UNSPEC_USW                   1)
32    (UNSPEC_ULD                   2)
33    (UNSPEC_USD                   3)
34    (UNSPEC_GET_FNADDR            4)
35    (UNSPEC_HILO_DELAY            5)
36    (UNSPEC_BLOCKAGE              6)
37    (UNSPEC_LOADGP                7)
38    (UNSPEC_SETJMP                8)
39    (UNSPEC_LONGJMP               9)
40    (UNSPEC_EH_RECEIVER          10)
41    (UNSPEC_EH_RETURN            11)
42    (UNSPEC_CONSTTABLE_QI        12)
43    (UNSPEC_CONSTTABLE_HI        13)
44    (UNSPEC_CONSTTABLE_SI        14)
45    (UNSPEC_CONSTTABLE_DI        15)
46    (UNSPEC_CONSTTABLE_SF        16)
47    (UNSPEC_CONSTTABLE_DF        17)
48    (UNSPEC_ALIGN_2              18)
49    (UNSPEC_ALIGN_4              19)
50    (UNSPEC_ALIGN_8              20)])
51 \f
52
53 ;; ....................
54 ;;
55 ;;      Attributes
56 ;;
57 ;; ....................
58
59 ;; Classification of each insn.
60 ;; branch       conditional branch
61 ;; jump         unconditional jump
62 ;; call         unconditional call
63 ;; load         load instruction(s)
64 ;; store        store instruction(s)
65 ;; move         data movement within same register set
66 ;; xfer         transfer to/from coprocessor
67 ;; hilo         transfer of hi/lo registers
68 ;; arith        integer arithmetic instruction
69 ;; darith       double precision integer arithmetic instructions
70 ;; imul         integer multiply
71 ;; imadd        integer multiply-add
72 ;; idiv         integer divide
73 ;; icmp         integer compare
74 ;; fadd         floating point add/subtract
75 ;; fmul         floating point multiply
76 ;; fmadd        floating point multiply-add
77 ;; fdiv         floating point divide
78 ;; fabs         floating point absolute value
79 ;; fneg         floating point negation
80 ;; fcmp         floating point compare
81 ;; fcvt         floating point convert
82 ;; fsqrt        floating point square root
83 ;; frsqrt       floating point reciprocal square root
84 ;; multi        multiword sequence (or user asm statements)
85 ;; nop          no operation
86
87 (define_attr "type"
88   "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
89   (const_string "unknown"))
90
91 ;; Main data type used by the insn
92 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
93
94 ;; Length (in # of bytes).  A conditional branch is allowed only to a
95 ;; location within a signed 18-bit offset of the delay slot.  If that
96 ;; provides too smal a range, we use the `j' instruction.  This
97 ;; instruction takes a 28-bit value, but that value is not an offset.
98 ;; Instead, it's bitwise-ored with the high-order four bits of the
99 ;; instruction in the delay slot, which means it cannot be used to
100 ;; cross a 256MB boundary.  We could fall back back on the jr,
101 ;; instruction which allows full access to the entire address space,
102 ;; but we do not do so at present.
103
104 (define_attr "length" ""
105    (cond [(eq_attr "type" "branch")
106           (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
107                      (const_int 131072))
108                  (const_int 4)
109                  (ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
110                      (const_int 0))
111                  (const_int 24)
112                  ] (const_int 12))
113           ] (const_int 4)))
114
115 ;; Attribute describing the processor.  This attribute must match exactly
116 ;; with the processor_type enumeration in mips.h.
117
118 ;; Attribute describing the processor
119 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
120 ;;   (const
121 ;;    (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000"))   (const_string "r3000")
122 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000"))   (const_string "r4000")
123 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000"))   (const_string "r6000")]
124 ;;          (const_string "default"))))
125
126 ;; ??? Fix everything that tests this attribute.
127 (define_attr "cpu"
128   "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4300,r4600,r4650,r5000,r5400,r5500,r8000,sb1,sr71000"
129   (const (symbol_ref "mips_cpu_attr")))
130
131 ;; Does the instruction have a mandatory delay slot?
132 ;;   The 3900, is (mostly) mips1, but does not have a mandatory load delay
133 ;;   slot.
134 (define_attr "dslot" "no,yes"
135   (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp")
136                      (and (eq_attr "type" "load")
137                           (and (eq (symbol_ref "mips_isa") (const_int 1))
138                                (and (eq (symbol_ref "mips16") (const_int 0))
139                                     (eq_attr "cpu" "!r3900")))))
140                 (const_string "yes")
141                 (const_string "no")))
142
143 ;; Can the instruction be put into a delay slot?
144 (define_attr "can_delay" "no,yes"
145   (if_then_else (and (eq_attr "dslot" "no")
146                      ; ADJUST_INSN_LENGTH divides length by 2 on mips16,
147                      ; so cope with it here.
148                      (ior (and (eq (symbol_ref "mips16") (const_int 0))
149                                    (eq_attr "length" "4"))
150                           (and (ne (symbol_ref "mips16") (const_int 0))
151                                (eq_attr "length" "2"))))
152                 (const_string "yes")
153                 (const_string "no")))
154
155 ;; Attribute defining whether or not we can use the branch-likely instructions
156
157 (define_attr "branch_likely" "no,yes"
158   (const
159    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
160                  (const_string "yes")
161                  (const_string "no"))))
162
163
164 ;; Describe a user's asm statement.
165 (define_asm_attributes
166   [(set_attr "type" "multi")])
167
168 ;; whether or not generating calls to position independent functions
169 (define_attr "abicalls" "no,yes"
170   (const (symbol_ref "mips_abicalls_attr")))
171
172 \f
173
174 ;; .........................
175 ;;
176 ;;      Delay slots, can't describe load/fcmp/xfer delay slots here
177 ;;
178 ;; .........................
179
180 (define_delay (and (eq_attr "type" "branch")
181                    (eq (symbol_ref "mips16") (const_int 0)))
182   [(eq_attr "can_delay" "yes")
183    (nil)
184    (and (eq_attr "branch_likely" "yes")
185         (and (eq_attr "dslot" "no")
186              (eq_attr "length" "4")))])
187
188 (define_delay (eq_attr "type" "jump")
189   [(eq_attr "can_delay" "yes")
190    (nil)
191    (nil)])
192
193 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
194   [(eq_attr "can_delay" "yes")
195    (nil)
196    (nil)])
197
198 \f
199
200 ;; .........................
201 ;;
202 ;;      Functional units
203 ;;
204 ;; .........................
205
206 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
207 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
208
209 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
210
211 (define_function_unit "memory" 1 0
212   (and (eq_attr "type" "load")
213        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
214   3 0)
215
216 (define_function_unit "memory" 1 0
217   (and (eq_attr "type" "load")
218        (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
219   2 0)
220
221 (define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
222
223 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
224
225 (define_function_unit "imuldiv"  1 0
226   (eq_attr "type" "hilo")
227   1 3)
228
229 (define_function_unit "imuldiv"  1 0
230   (and (eq_attr "type" "imul,imadd")
231        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
232   17 17)
233
234 ;; On them mips16, we want to stronly discourage a mult from appearing
235 ;; after an mflo, since that requires explicit nop instructions.  We
236 ;; do this by pretending that mflo ties up the function unit for long
237 ;; enough that the scheduler will ignore load stalls and the like when
238 ;; selecting instructions to between the two instructions.
239
240 (define_function_unit "imuldiv" 1 0
241   (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
242   1 5)
243
244 (define_function_unit "imuldiv"  1 0
245   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r3000,r3900"))
246   12 12)
247
248 (define_function_unit "imuldiv"  1 0
249   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4000,r4600"))
250   10 10)
251
252 (define_function_unit "imuldiv"  1 0
253   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4650"))
254   4 4)
255
256 (define_function_unit "imuldiv"  1 0
257   (and (eq_attr "type" "imul,imadd")
258        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
259   1 1)
260
261 (define_function_unit "imuldiv"  1 0
262   (and (eq_attr "type" "imul,imadd")
263        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
264   4 4)
265
266 (define_function_unit "imuldiv"  1 0
267   (and (eq_attr "type" "imul,imadd")
268        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
269   5 5)
270
271 (define_function_unit "imuldiv"  1 0
272   (and (eq_attr "type" "imul,imadd")
273        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
274   8 8)
275
276 (define_function_unit "imuldiv"  1 0
277   (and (eq_attr "type" "imul,imadd")
278        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
279   9 9)
280
281 (define_function_unit "imuldiv"  1 0
282   (and (eq_attr "type" "idiv")
283        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
284   38 38)
285
286 (define_function_unit "imuldiv"  1 0
287   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
288   35 35)
289
290 (define_function_unit "imuldiv"  1 0
291   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
292   42 42)
293
294 (define_function_unit "imuldiv"  1 0
295   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
296   36 36)
297
298 (define_function_unit "imuldiv"  1 0
299   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
300   69 69)
301
302 (define_function_unit "imuldiv" 1 0
303   (and (eq_attr "type" "idiv")
304        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
305   35 35)
306
307 (define_function_unit "imuldiv" 1 0
308   (and (eq_attr "type" "idiv")
309        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
310   67 67)
311
312 (define_function_unit "imuldiv" 1 0
313   (and (eq_attr "type" "idiv")
314        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
315   37 37)
316
317 (define_function_unit "imuldiv" 1 0
318   (and (eq_attr "type" "idiv")
319        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
320   69 69)
321
322 (define_function_unit "imuldiv" 1 0
323   (and (eq_attr "type" "idiv")
324        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
325   36 36)
326
327 (define_function_unit "imuldiv" 1 0
328   (and (eq_attr "type" "idiv")
329        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
330   68 68)
331
332 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
333 ;; the FP hardware is part of the normal ALU circuitry.  This means FP
334 ;; instructions affect the pipe-line, and no functional unit
335 ;; parallelism can occur on R4300 processors.  To force GCC into coding
336 ;; for only a single functional unit, we force the R4300 FP
337 ;; instructions to be processed in the "imuldiv" unit.
338
339 (define_function_unit "adder" 1 1
340   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
341   3 0)
342
343 (define_function_unit "adder" 1 1
344   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
345   2 0)
346
347 (define_function_unit "adder" 1 1
348   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
349   1 0)
350
351 (define_function_unit "adder" 1 1
352   (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
353   4 0)
354
355 (define_function_unit "adder" 1 1
356   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
357   2 0)
358
359 (define_function_unit "adder" 1 1
360   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
361   3 0)
362
363 (define_function_unit "adder" 1 1
364   (and (eq_attr "type" "fabs,fneg")
365        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
366   2 0)
367
368 (define_function_unit "adder" 1 1
369   (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
370   1 0)
371
372 (define_function_unit "mult" 1 1
373   (and (eq_attr "type" "fmul")
374        (and (eq_attr "mode" "SF")
375             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
376   7 0)
377
378 (define_function_unit "mult" 1 1
379   (and (eq_attr "type" "fmul")
380        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
381   4 0)
382
383 (define_function_unit "mult" 1 1
384   (and (eq_attr "type" "fmul")
385        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
386   5 0)
387
388 (define_function_unit "mult" 1 1
389   (and (eq_attr "type" "fmul")
390        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
391   8 0)
392
393 (define_function_unit "mult" 1 1
394   (and (eq_attr "type" "fmul")
395        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
396   8 0)
397
398 (define_function_unit "mult" 1 1
399   (and (eq_attr "type" "fmul")
400        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
401   5 0)
402
403 (define_function_unit "mult" 1 1
404   (and (eq_attr "type" "fmul")
405        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
406   6 0)
407
408 (define_function_unit "divide" 1 1
409   (and (eq_attr "type" "fdiv")
410        (and (eq_attr "mode" "SF")
411             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
412   23 0)
413
414 (define_function_unit "divide" 1 1
415   (and (eq_attr "type" "fdiv")
416        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
417   12 0)
418
419 (define_function_unit "divide" 1 1
420   (and (eq_attr "type" "fdiv")
421        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
422   15 0)
423
424 (define_function_unit "divide" 1 1
425   (and (eq_attr "type" "fdiv")
426        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
427   32 0)
428
429 (define_function_unit "divide" 1 1
430   (and (eq_attr "type" "fdiv")
431        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
432   21 0)
433
434 (define_function_unit "divide" 1 1
435   (and (eq_attr "type" "fdiv")
436        (and (eq_attr "mode" "DF")
437             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
438   36 0)
439
440 (define_function_unit "divide" 1 1
441   (and (eq_attr "type" "fdiv")
442        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
443   19 0)
444
445 (define_function_unit "divide" 1 1
446   (and (eq_attr "type" "fdiv")
447        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
448   16 0)
449
450 (define_function_unit "divide" 1 1
451   (and (eq_attr "type" "fdiv")
452        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
453   61 0)
454
455 ;;; ??? Is this number right?
456 (define_function_unit "divide" 1 1
457   (and (eq_attr "type" "fsqrt,frsqrt")
458        (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
459   54 0)
460
461 (define_function_unit "divide" 1 1
462   (and (eq_attr "type" "fsqrt,frsqrt")
463        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
464   31 0)
465
466 (define_function_unit "divide" 1 1
467   (and (eq_attr "type" "fsqrt,frsqrt")
468        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
469   21 0)
470
471 ;;; ??? Is this number right?
472 (define_function_unit "divide" 1 1
473   (and (eq_attr "type" "fsqrt,frsqrt")
474        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
475   112 0)
476
477 (define_function_unit "divide" 1 1
478   (and (eq_attr "type" "fsqrt,frsqrt")
479        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
480   60 0)
481
482 (define_function_unit "divide" 1 1
483   (and (eq_attr "type" "fsqrt,frsqrt")
484        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
485   36 0)
486
487 ;; R4300 FP instruction classes treated as part of the "imuldiv"
488 ;; functional unit:
489
490 (define_function_unit "imuldiv" 1 0
491   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
492   3 3)
493
494 (define_function_unit "imuldiv" 1 0
495   (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
496   1 1)
497
498 (define_function_unit "imuldiv" 1 0
499   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
500   5 5)
501 (define_function_unit "imuldiv" 1 0
502   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
503   8 8)
504
505 (define_function_unit "imuldiv" 1 0
506   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
507        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
508   29 29)
509 (define_function_unit "imuldiv" 1 0
510   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
511        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
512   58 58)
513 \f
514 ;; The following functional units do not use the cpu type, and use
515 ;; much less memory in genattrtab.c.
516
517 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "load")                                3 0)
518 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "store")                               1 0)
519 ;;
520 ;; (define_function_unit "fp_comp"  1 0 (eq_attr "type" "fcmp")                                2 0)
521 ;;
522 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer")                                2 0)
523 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo")                                3 0)
524 ;;
525 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "imul")                               17 0)
526 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "idiv")                               38 0)
527 ;;
528 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fadd")                                4 0)
529 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fabs,fneg")                           2 0)
530 ;;
531 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF"))    7 0)
532 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF"))    8 0)
533 ;;
534 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF"))   23 0)
535 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF"))   36 0)
536 ;;
537 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF"))  54 0)
538 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
539 \f
540 ;; Include scheduling descriptions.
541
542 (include "5400.md")
543 (include "5500.md")
544 (include "sr71k.md")
545
546
547 ;;
548 ;;  ....................
549 ;;
550 ;;      CONDITIONAL TRAPS
551 ;;
552 ;;  ....................
553 ;;
554
555 (define_insn "trap"
556   [(trap_if (const_int 1) (const_int 0))]
557   ""
558   "*
559 {
560   if (ISA_HAS_COND_TRAP)
561     return \"teq\\t$0,$0\";
562   else if (TARGET_MIPS16)
563     return \"break 0\";
564   else
565     return \"break\";
566 }")
567
568 (define_expand "conditional_trap"
569   [(trap_if (match_operator 0 "cmp_op"
570                             [(match_dup 2) (match_dup 3)])
571             (match_operand 1 "const_int_operand" ""))]
572   "ISA_HAS_COND_TRAP"
573   "
574 {
575   mips_gen_conditional_trap (operands);
576   DONE;
577 }")
578
579 ;; Match a TRAP_IF with 2nd arg of 0.  The div_trap_* insns match a
580 ;; 2nd arg of any CONST_INT, so this insn must appear first.
581 ;; gen_div_trap always generates TRAP_IF with 2nd arg of 6 or 7.
582
583 (define_insn ""
584   [(trap_if (match_operator 0 "trap_cmp_op"
585                             [(match_operand:SI 1 "reg_or_0_operand" "d")
586                              (match_operand:SI 2 "nonmemory_operand" "dI")])
587             (const_int 0))]
588   "ISA_HAS_COND_TRAP"
589   "t%C0\\t%z1,%z2")
590 \f
591 ;;
592 ;;  ....................
593 ;;
594 ;;      ADDITION
595 ;;
596 ;;  ....................
597 ;;
598
599 (define_insn "adddf3"
600   [(set (match_operand:DF 0 "register_operand" "=f")
601         (plus:DF (match_operand:DF 1 "register_operand" "f")
602                  (match_operand:DF 2 "register_operand" "f")))]
603   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
604   "add.d\\t%0,%1,%2"
605   [(set_attr "type"     "fadd")
606    (set_attr "mode"     "DF")])
607
608 (define_insn "addsf3"
609   [(set (match_operand:SF 0 "register_operand" "=f")
610         (plus:SF (match_operand:SF 1 "register_operand" "f")
611                  (match_operand:SF 2 "register_operand" "f")))]
612   "TARGET_HARD_FLOAT"
613   "add.s\\t%0,%1,%2"
614   [(set_attr "type"     "fadd")
615    (set_attr "mode"     "SF")])
616
617 (define_expand "addsi3"
618   [(set (match_operand:SI 0 "register_operand" "=d")
619         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
620                  (match_operand:SI 2 "arith_operand" "dI")))]
621   ""
622   "
623 {
624   /* The mips16 assembler handles -32768 correctly, and so does gas,
625      but some other MIPS assemblers think that -32768 needs to be
626      loaded into a register before it can be added in.  */
627   if (! TARGET_MIPS16
628       && ! TARGET_GAS
629       && GET_CODE (operands[2]) == CONST_INT
630       && INTVAL (operands[2]) == -32768)
631     operands[2] = force_reg (SImode, operands[2]);
632
633   /* If a large stack adjustment was forced into a register, we may be
634      asked to generate rtx such as:
635
636         (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
637
638      but no such instruction is available in mips16.  Handle it by
639      using a temporary.  */
640   if (TARGET_MIPS16
641       && REGNO (operands[0]) == STACK_POINTER_REGNUM
642       && ((GET_CODE (operands[1]) == REG
643            && REGNO (operands[1]) != STACK_POINTER_REGNUM)
644           || GET_CODE (operands[2]) != CONST_INT))
645     {
646       rtx tmp = gen_reg_rtx (SImode);
647
648       emit_move_insn (tmp, operands[1]);
649       emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
650       emit_move_insn (operands[0], tmp);
651       DONE;
652     }
653 }")
654
655 (define_insn "addsi3_internal"
656   [(set (match_operand:SI 0 "register_operand" "=d")
657         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
658                  (match_operand:SI 2 "arith_operand" "dI")))]
659   "! TARGET_MIPS16
660    && (TARGET_GAS
661        || GET_CODE (operands[2]) != CONST_INT
662        || INTVAL (operands[2]) != -32768)"
663   "addu\\t%0,%z1,%2"
664   [(set_attr "type"     "arith")
665    (set_attr "mode"     "SI")])
666
667 ;; For the mips16, we need to recognize stack pointer additions
668 ;; explicitly, since we don't have a constraint for $sp.  These insns
669 ;; will be generated by the save_restore_insns functions.
670
671 (define_insn ""
672   [(set (reg:SI 29)
673         (plus:SI (reg:SI 29)
674                  (match_operand:SI 0 "small_int" "I")))]
675   "TARGET_MIPS16"
676   "addu\\t%$,%$,%0"
677   [(set_attr "type"     "arith")
678    (set_attr "mode"     "SI")
679    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
680                                       (const_int 4)
681                                       (const_int 8)))])
682
683 (define_insn ""
684   [(set (match_operand:SI 0 "register_operand" "=d")
685         (plus:SI (reg:SI 29)
686                  (match_operand:SI 1 "small_int" "I")))]
687   "TARGET_MIPS16"
688   "addu\\t%0,%$,%1"
689   [(set_attr "type"     "arith")
690    (set_attr "mode"     "SI")
691    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
692                                       (const_int 4)
693                                       (const_int 8)))])
694
695 (define_insn ""
696   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
697         (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
698                  (match_operand:SI 2 "arith_operand" "IQ,O,d")))]
699   "TARGET_MIPS16
700    && (GET_CODE (operands[1]) != REG
701        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
702        || M16_REG_P (REGNO (operands[1]))
703        || REGNO (operands[1]) == ARG_POINTER_REGNUM
704        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
705        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
706    && (GET_CODE (operands[2]) != REG
707        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
708        || M16_REG_P (REGNO (operands[2]))
709        || REGNO (operands[2]) == ARG_POINTER_REGNUM
710        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
711        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
712   "*
713 {
714   if (REGNO (operands[0]) == REGNO (operands[1]))
715     return \"addu\\t%0,%2\";
716   return \"addu\\t%0,%1,%2\";
717 }"
718   [(set_attr "type"     "arith")
719    (set_attr "mode"     "SI")
720    (set_attr_alternative "length"
721                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
722                                (const_int 4)
723                                (const_int 8))
724                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
725                                (const_int 4)
726                                (const_int 8))
727                  (const_int 4)])])
728
729
730 ;; On the mips16, we can sometimes split an add of a constant which is
731 ;; a 4 byte instruction into two adds which are both 2 byte
732 ;; instructions.  There are two cases: one where we are adding a
733 ;; constant plus a register to another register, and one where we are
734 ;; simply adding a constant to a register.
735
736 (define_split
737   [(set (match_operand:SI 0 "register_operand" "")
738         (plus:SI (match_dup 0)
739                  (match_operand:SI 1 "const_int_operand" "")))]
740   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
741    && GET_CODE (operands[0]) == REG
742    && M16_REG_P (REGNO (operands[0]))
743    && GET_CODE (operands[1]) == CONST_INT
744    && ((INTVAL (operands[1]) > 0x7f
745         && INTVAL (operands[1]) <= 0x7f + 0x7f)
746        || (INTVAL (operands[1]) < - 0x80
747            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
748   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
749    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
750   "
751 {
752   HOST_WIDE_INT val = INTVAL (operands[1]);
753
754   if (val >= 0)
755     {
756       operands[1] = GEN_INT (0x7f);
757       operands[2] = GEN_INT (val - 0x7f);
758     }
759   else
760     {
761       operands[1] = GEN_INT (- 0x80);
762       operands[2] = GEN_INT (val + 0x80);
763     }
764 }")
765
766 (define_split
767   [(set (match_operand:SI 0 "register_operand" "")
768         (plus:SI (match_operand:SI 1 "register_operand" "")
769                  (match_operand:SI 2 "const_int_operand" "")))]
770   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
771    && GET_CODE (operands[0]) == REG
772    && M16_REG_P (REGNO (operands[0]))
773    && GET_CODE (operands[1]) == REG
774    && M16_REG_P (REGNO (operands[1]))
775    && REGNO (operands[0]) != REGNO (operands[1])
776    && GET_CODE (operands[2]) == CONST_INT
777    && ((INTVAL (operands[2]) > 0x7
778         && INTVAL (operands[2]) <= 0x7 + 0x7f)
779        || (INTVAL (operands[2]) < - 0x8
780            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
781   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
782    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
783   "
784 {
785   HOST_WIDE_INT val = INTVAL (operands[2]);
786
787   if (val >= 0)
788     {
789       operands[2] = GEN_INT (0x7);
790       operands[3] = GEN_INT (val - 0x7);
791     }
792   else
793     {
794       operands[2] = GEN_INT (- 0x8);
795       operands[3] = GEN_INT (val + 0x8);
796     }
797 }")
798
799 (define_expand "adddi3"
800   [(parallel [(set (match_operand:DI 0 "register_operand" "")
801                    (plus:DI (match_operand:DI 1 "se_register_operand" "")
802                             (match_operand:DI 2 "se_arith_operand" "")))
803               (clobber (match_dup 3))])]
804   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
805   "
806 {
807   /* The mips16 assembler handles -32768 correctly, and so does gas,
808      but some other MIPS assemblers think that -32768 needs to be
809      loaded into a register before it can be added in.  */
810   if (! TARGET_MIPS16
811       && ! TARGET_GAS
812       && GET_CODE (operands[2]) == CONST_INT
813       && INTVAL (operands[2]) == -32768)
814     operands[2] = force_reg (DImode, operands[2]);
815
816   /* If a large stack adjustment was forced into a register, we may be
817      asked to generate rtx such as:
818
819         (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
820
821      but no such instruction is available in mips16.  Handle it by
822      using a temporary.  */
823   if (TARGET_MIPS16
824       && REGNO (operands[0]) == STACK_POINTER_REGNUM
825       && ((GET_CODE (operands[1]) == REG
826            && REGNO (operands[1]) != STACK_POINTER_REGNUM)
827           || GET_CODE (operands[2]) != CONST_INT))
828     {
829       rtx tmp = gen_reg_rtx (DImode);
830
831       emit_move_insn (tmp, operands[1]);
832       emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
833       emit_move_insn (operands[0], tmp);
834       DONE;
835     }
836
837   if (TARGET_64BIT)
838     {
839       emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
840                                         operands[2]));
841       DONE;
842     }
843
844   operands[3] = gen_reg_rtx (SImode);
845 }")
846
847 (define_insn "adddi3_internal_1"
848   [(set (match_operand:DI 0 "register_operand" "=d,&d")
849         (plus:DI (match_operand:DI 1 "register_operand" "0,d")
850                  (match_operand:DI 2 "register_operand" "d,d")))
851    (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
852   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
853   "*
854 {
855   return (REGNO (operands[0]) == REGNO (operands[1])
856           && REGNO (operands[0]) == REGNO (operands[2]))
857     ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
858     : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
859 }"
860   [(set_attr "type"     "darith")
861    (set_attr "mode"     "DI")
862    (set_attr "length"   "16")])
863
864 (define_split
865   [(set (match_operand:DI 0 "register_operand" "")
866         (plus:DI (match_operand:DI 1 "register_operand" "")
867                  (match_operand:DI 2 "register_operand" "")))
868    (clobber (match_operand:SI 3 "register_operand" ""))]
869   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
870    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
871    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
872    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
873    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
874    && (REGNO (operands[0]) != REGNO (operands[1])
875        || REGNO (operands[0]) != REGNO (operands[2]))"
876
877   [(set (subreg:SI (match_dup 0) 0)
878         (plus:SI (subreg:SI (match_dup 1) 0)
879                  (subreg:SI (match_dup 2) 0)))
880
881    (set (match_dup 3)
882         (ltu:SI (subreg:SI (match_dup 0) 0)
883                 (subreg:SI (match_dup 2) 0)))
884
885    (set (subreg:SI (match_dup 0) 4)
886         (plus:SI (subreg:SI (match_dup 1) 4)
887                  (subreg:SI (match_dup 2) 4)))
888
889    (set (subreg:SI (match_dup 0) 4)
890         (plus:SI (subreg:SI (match_dup 0) 4)
891                  (match_dup 3)))]
892   "")
893
894 (define_split
895   [(set (match_operand:DI 0 "register_operand" "")
896         (plus:DI (match_operand:DI 1 "register_operand" "")
897                  (match_operand:DI 2 "register_operand" "")))
898    (clobber (match_operand:SI 3 "register_operand" ""))]
899   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
900    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
901    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
902    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
903    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
904    && (REGNO (operands[0]) != REGNO (operands[1])
905        || REGNO (operands[0]) != REGNO (operands[2]))"
906
907   [(set (subreg:SI (match_dup 0) 4)
908         (plus:SI (subreg:SI (match_dup 1) 4)
909                  (subreg:SI (match_dup 2) 4)))
910
911    (set (match_dup 3)
912         (ltu:SI (subreg:SI (match_dup 0) 4)
913                 (subreg:SI (match_dup 2) 4)))
914
915    (set (subreg:SI (match_dup 0) 0)
916         (plus:SI (subreg:SI (match_dup 1) 0)
917                  (subreg:SI (match_dup 2) 0)))
918
919    (set (subreg:SI (match_dup 0) 0)
920         (plus:SI (subreg:SI (match_dup 0) 0)
921                  (match_dup 3)))]
922   "")
923
924 (define_insn "adddi3_internal_2"
925   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
926         (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
927                  (match_operand:DI 2 "small_int" "P,J,N")))
928    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
929   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
930    && (TARGET_GAS
931        || GET_CODE (operands[2]) != CONST_INT
932        || INTVAL (operands[2]) != -32768)"
933   "@
934    addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
935    move\\t%L0,%L1\;move\\t%M0,%M1
936    subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
937   [(set_attr "type"     "darith")
938    (set_attr "mode"     "DI")
939    (set_attr "length"   "12,8,16")])
940
941 (define_split
942   [(set (match_operand:DI 0 "register_operand" "")
943         (plus:DI (match_operand:DI 1 "register_operand" "")
944                  (match_operand:DI 2 "small_int" "")))
945    (clobber (match_operand:SI 3 "register_operand" ""))]
946   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
947    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
948    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
949    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
950    && INTVAL (operands[2]) > 0"
951
952   [(set (subreg:SI (match_dup 0) 0)
953         (plus:SI (subreg:SI (match_dup 1) 0)
954                  (match_dup 2)))
955
956    (set (match_dup 3)
957         (ltu:SI (subreg:SI (match_dup 0) 0)
958                 (match_dup 2)))
959
960    (set (subreg:SI (match_dup 0) 4)
961         (plus:SI (subreg:SI (match_dup 1) 4)
962                  (match_dup 3)))]
963   "")
964
965 (define_split
966   [(set (match_operand:DI 0 "register_operand" "")
967         (plus:DI (match_operand:DI 1 "register_operand" "")
968                  (match_operand:DI 2 "small_int" "")))
969    (clobber (match_operand:SI 3 "register_operand" ""))]
970   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
971    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
972    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
973    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
974    && INTVAL (operands[2]) > 0"
975
976   [(set (subreg:SI (match_dup 0) 4)
977         (plus:SI (subreg:SI (match_dup 1) 4)
978                  (match_dup 2)))
979
980    (set (match_dup 3)
981         (ltu:SI (subreg:SI (match_dup 0) 4)
982                 (match_dup 2)))
983
984    (set (subreg:SI (match_dup 0) 0)
985         (plus:SI (subreg:SI (match_dup 1) 0)
986                  (match_dup 3)))]
987   "")
988
989 (define_insn "adddi3_internal_3"
990   [(set (match_operand:DI 0 "register_operand" "=d")
991         (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
992                  (match_operand:DI 2 "se_arith_operand" "dI")))]
993   "TARGET_64BIT
994    && !TARGET_MIPS16
995    && (TARGET_GAS
996        || GET_CODE (operands[2]) != CONST_INT
997        || INTVAL (operands[2]) != -32768)"
998   "*
999 {
1000   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1001     ? \"dsubu\\t%0,%z1,%n2\"
1002     : \"daddu\\t%0,%z1,%2\";
1003 }"
1004   [(set_attr "type"     "darith")
1005    (set_attr "mode"     "DI")])
1006
1007 ;; For the mips16, we need to recognize stack pointer additions
1008 ;; explicitly, since we don't have a constraint for $sp.  These insns
1009 ;; will be generated by the save_restore_insns functions.
1010
1011 (define_insn ""
1012   [(set (reg:DI 29)
1013         (plus:DI (reg:DI 29)
1014                  (match_operand:DI 0 "small_int" "I")))]
1015   "TARGET_MIPS16 && TARGET_64BIT"
1016   "daddu\\t%$,%$,%0"
1017   [(set_attr "type"     "arith")
1018    (set_attr "mode"     "DI")
1019    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
1020                                       (const_int 4)
1021                                       (const_int 8)))])
1022
1023 (define_insn ""
1024   [(set (match_operand:DI 0 "register_operand" "=d")
1025         (plus:DI (reg:DI 29)
1026                  (match_operand:DI 1 "small_int" "I")))]
1027   "TARGET_MIPS16 && TARGET_64BIT"
1028   "daddu\\t%0,%$,%1"
1029   [(set_attr "type"     "arith")
1030    (set_attr "mode"     "DI")
1031    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
1032                                       (const_int 4)
1033                                       (const_int 8)))])
1034
1035 (define_insn ""
1036   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1037         (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1038                  (match_operand:DI 2 "arith_operand" "IQ,O,d")))]
1039   "TARGET_MIPS16 && TARGET_64BIT
1040    && (GET_CODE (operands[1]) != REG
1041        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
1042        || M16_REG_P (REGNO (operands[1]))
1043        || REGNO (operands[1]) == ARG_POINTER_REGNUM
1044        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
1045        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
1046    && (GET_CODE (operands[2]) != REG
1047        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
1048        || M16_REG_P (REGNO (operands[2]))
1049        || REGNO (operands[2]) == ARG_POINTER_REGNUM
1050        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
1051        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
1052   "*
1053 {
1054   if (REGNO (operands[0]) == REGNO (operands[1]))
1055     return \"daddu\\t%0,%2\";
1056   return \"daddu\\t%0,%1,%2\";
1057 }"
1058   [(set_attr "type"     "arith")
1059    (set_attr "mode"     "DI")
1060    (set_attr_alternative "length"
1061                 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
1062                                (const_int 4)
1063                                (const_int 8))
1064                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1065                                (const_int 4)
1066                                (const_int 8))
1067                  (const_int 4)])])
1068
1069
1070 ;; On the mips16, we can sometimes split an add of a constant which is
1071 ;; a 4 byte instruction into two adds which are both 2 byte
1072 ;; instructions.  There are two cases: one where we are adding a
1073 ;; constant plus a register to another register, and one where we are
1074 ;; simply adding a constant to a register.
1075
1076 (define_split
1077   [(set (match_operand:DI 0 "register_operand" "")
1078         (plus:DI (match_dup 0)
1079                  (match_operand:DI 1 "const_int_operand" "")))]
1080   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1081    && GET_CODE (operands[0]) == REG
1082    && M16_REG_P (REGNO (operands[0]))
1083    && GET_CODE (operands[1]) == CONST_INT
1084    && ((INTVAL (operands[1]) > 0xf
1085         && INTVAL (operands[1]) <= 0xf + 0xf)
1086        || (INTVAL (operands[1]) < - 0x10
1087            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1088   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1089    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1090   "
1091 {
1092   HOST_WIDE_INT val = INTVAL (operands[1]);
1093
1094   if (val >= 0)
1095     {
1096       operands[1] = GEN_INT (0xf);
1097       operands[2] = GEN_INT (val - 0xf);
1098     }
1099   else
1100     {
1101       operands[1] = GEN_INT (- 0x10);
1102       operands[2] = GEN_INT (val + 0x10);
1103     }
1104 }")
1105
1106 (define_split
1107   [(set (match_operand:DI 0 "register_operand" "")
1108         (plus:DI (match_operand:DI 1 "register_operand" "")
1109                  (match_operand:DI 2 "const_int_operand" "")))]
1110   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1111    && GET_CODE (operands[0]) == REG
1112    && M16_REG_P (REGNO (operands[0]))
1113    && GET_CODE (operands[1]) == REG
1114    && M16_REG_P (REGNO (operands[1]))
1115    && REGNO (operands[0]) != REGNO (operands[1])
1116    && GET_CODE (operands[2]) == CONST_INT
1117    && ((INTVAL (operands[2]) > 0x7
1118         && INTVAL (operands[2]) <= 0x7 + 0xf)
1119        || (INTVAL (operands[2]) < - 0x8
1120            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1121   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1122    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1123   "
1124 {
1125   HOST_WIDE_INT val = INTVAL (operands[2]);
1126
1127   if (val >= 0)
1128     {
1129       operands[2] = GEN_INT (0x7);
1130       operands[3] = GEN_INT (val - 0x7);
1131     }
1132   else
1133     {
1134       operands[2] = GEN_INT (- 0x8);
1135       operands[3] = GEN_INT (val + 0x8);
1136     }
1137 }")
1138
1139 (define_insn "addsi3_internal_2"
1140   [(set (match_operand:DI 0 "register_operand" "=d")
1141         (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1142                                  (match_operand:SI 2 "arith_operand" "dI"))))]
1143   "TARGET_64BIT
1144    && !TARGET_MIPS16
1145    && (TARGET_GAS
1146        || GET_CODE (operands[2]) != CONST_INT
1147        || INTVAL (operands[2]) != -32768)"
1148   "*
1149 {
1150   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1151     ? \"subu\\t%0,%z1,%n2\"
1152     : \"addu\\t%0,%z1,%2\";
1153 }"
1154   [(set_attr "type"     "arith")
1155    (set_attr "mode"     "SI")])
1156
1157 (define_insn ""
1158   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1159         (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1160                                  (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1161   "TARGET_MIPS16 && TARGET_64BIT"
1162   "*
1163 {
1164   if (REGNO (operands[0]) == REGNO (operands[1]))
1165     return \"addu\\t%0,%2\";
1166   return \"addu\\t%0,%1,%2\";
1167 }"
1168   [(set_attr "type"     "arith")
1169    (set_attr "mode"     "SI")
1170    (set_attr_alternative "length"
1171                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1172                                (const_int 4)
1173                                (const_int 8))
1174                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1175                                (const_int 4)
1176                                (const_int 8))
1177                  (const_int 4)])])
1178
1179 \f
1180 ;;
1181 ;;  ....................
1182 ;;
1183 ;;      SUBTRACTION
1184 ;;
1185 ;;  ....................
1186 ;;
1187
1188 (define_insn "subdf3"
1189   [(set (match_operand:DF 0 "register_operand" "=f")
1190         (minus:DF (match_operand:DF 1 "register_operand" "f")
1191                   (match_operand:DF 2 "register_operand" "f")))]
1192   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1193   "sub.d\\t%0,%1,%2"
1194   [(set_attr "type"     "fadd")
1195    (set_attr "mode"     "DF")])
1196
1197 (define_insn "subsf3"
1198   [(set (match_operand:SF 0 "register_operand" "=f")
1199         (minus:SF (match_operand:SF 1 "register_operand" "f")
1200                   (match_operand:SF 2 "register_operand" "f")))]
1201   "TARGET_HARD_FLOAT"
1202   "sub.s\\t%0,%1,%2"
1203   [(set_attr "type"     "fadd")
1204    (set_attr "mode"     "SF")])
1205
1206 (define_expand "subsi3"
1207   [(set (match_operand:SI 0 "register_operand" "=d")
1208         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1209                   (match_operand:SI 2 "arith_operand" "dI")))]
1210   ""
1211   "
1212 {
1213   if (GET_CODE (operands[2]) == CONST_INT
1214       && (INTVAL (operands[2]) == -32768
1215           || (TARGET_MIPS16
1216               && INTVAL (operands[2]) == -0x4000)))
1217     operands[2] = force_reg (SImode, operands[2]);
1218 }")
1219
1220 (define_insn "subsi3_internal"
1221   [(set (match_operand:SI 0 "register_operand" "=d")
1222         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1223                   (match_operand:SI 2 "arith_operand" "dI")))]
1224   "!TARGET_MIPS16
1225    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1226   "subu\\t%0,%z1,%2"
1227   [(set_attr "type"     "arith")
1228    (set_attr "mode"     "SI")])
1229
1230 ;; For the mips16, we need to recognize stack pointer subtractions
1231 ;; explicitly, since we don't have a constraint for $sp.  These insns
1232 ;; will be generated by the save_restore_insns functions.
1233
1234 (define_insn ""
1235   [(set (reg:SI 29)
1236         (minus:SI (reg:SI 29)
1237                   (match_operand:SI 0 "small_int" "I")))]
1238   "TARGET_MIPS16
1239    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1240   "addu\\t%$,%$,%n0"
1241   [(set_attr "type"     "arith")
1242    (set_attr "mode"     "SI")
1243    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1244                                       (const_int 4)
1245                                       (const_int 8)))])
1246
1247 (define_insn ""
1248   [(set (match_operand:SI 0 "register_operand" "=d")
1249         (minus:SI (reg:SI 29)
1250                   (match_operand:SI 1 "small_int" "I")))]
1251   "TARGET_MIPS16
1252    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1253   "addu\\t%0,%$,%n1"
1254   [(set_attr "type"     "arith")
1255    (set_attr "mode"     "SI")
1256    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
1257                                       (const_int 4)
1258                                       (const_int 8)))])
1259
1260
1261 (define_insn ""
1262   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1263         (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1264                   (match_operand:SI 2 "arith_operand" "I,O,d")))]
1265   "TARGET_MIPS16
1266    && (GET_CODE (operands[2]) != CONST_INT
1267        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1268   "*
1269 {
1270   if (REGNO (operands[0]) == REGNO (operands[1]))
1271     return \"subu\\t%0,%2\";
1272   return \"subu\\t%0,%1,%2\";
1273 }"
1274   [(set_attr "type"     "arith")
1275    (set_attr "mode"     "SI")
1276    (set_attr_alternative "length"
1277                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1278                                (const_int 4)
1279                                (const_int 8))
1280                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1281                                (const_int 4)
1282                                (const_int 8))
1283                  (const_int 4)])])
1284
1285 ;; On the mips16, we can sometimes split a subtract of a constant
1286 ;; which is a 4 byte instruction into two adds which are both 2 byte
1287 ;; instructions.  There are two cases: one where we are setting a
1288 ;; register to a register minus a constant, and one where we are
1289 ;; simply subtracting a constant from a register.
1290
1291 (define_split
1292   [(set (match_operand:SI 0 "register_operand" "")
1293         (minus:SI (match_dup 0)
1294                   (match_operand:SI 1 "const_int_operand" "")))]
1295   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1296    && GET_CODE (operands[0]) == REG
1297    && M16_REG_P (REGNO (operands[0]))
1298    && GET_CODE (operands[1]) == CONST_INT
1299    && ((INTVAL (operands[1]) > 0x80
1300         && INTVAL (operands[1]) <= 0x80 + 0x80)
1301        || (INTVAL (operands[1]) < - 0x7f
1302            && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1303   [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1304    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1305   "
1306 {
1307   HOST_WIDE_INT val = INTVAL (operands[1]);
1308
1309   if (val >= 0)
1310     {
1311       operands[1] = GEN_INT (0x80);
1312       operands[2] = GEN_INT (val - 0x80);
1313     }
1314   else
1315     {
1316       operands[1] = GEN_INT (- 0x7f);
1317       operands[2] = GEN_INT (val + 0x7f);
1318     }
1319 }")
1320
1321 (define_split
1322   [(set (match_operand:SI 0 "register_operand" "")
1323         (minus:SI (match_operand:SI 1 "register_operand" "")
1324                   (match_operand:SI 2 "const_int_operand" "")))]
1325   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1326    && GET_CODE (operands[0]) == REG
1327    && M16_REG_P (REGNO (operands[0]))
1328    && GET_CODE (operands[1]) == REG
1329    && M16_REG_P (REGNO (operands[1]))
1330    && REGNO (operands[0]) != REGNO (operands[1])
1331    && GET_CODE (operands[2]) == CONST_INT
1332    && ((INTVAL (operands[2]) > 0x8
1333         && INTVAL (operands[2]) <= 0x8 + 0x80)
1334        || (INTVAL (operands[2]) < - 0x7
1335            && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1336   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1337    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1338   "
1339 {
1340   HOST_WIDE_INT val = INTVAL (operands[2]);
1341
1342   if (val >= 0)
1343     {
1344       operands[2] = GEN_INT (0x8);
1345       operands[3] = GEN_INT (val - 0x8);
1346     }
1347   else
1348     {
1349       operands[2] = GEN_INT (- 0x7);
1350       operands[3] = GEN_INT (val + 0x7);
1351     }
1352 }")
1353
1354 (define_expand "subdi3"
1355   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1356                    (minus:DI (match_operand:DI 1 "se_register_operand" "d")
1357                              (match_operand:DI 2 "se_register_operand" "d")))
1358               (clobber (match_dup 3))])]
1359   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1360   "
1361 {
1362   if (TARGET_64BIT)
1363     {
1364       emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1365                                         operands[2]));
1366       DONE;
1367     }
1368
1369   operands[3] = gen_reg_rtx (SImode);
1370 }")
1371
1372 (define_insn "subdi3_internal"
1373   [(set (match_operand:DI 0 "register_operand" "=d")
1374         (minus:DI (match_operand:DI 1 "register_operand" "d")
1375                   (match_operand:DI 2 "register_operand" "d")))
1376    (clobber (match_operand:SI 3 "register_operand" "=d"))]
1377   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1378   "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1379   [(set_attr "type"     "darith")
1380    (set_attr "mode"     "DI")
1381    (set_attr "length"   "16")])
1382
1383 (define_split
1384   [(set (match_operand:DI 0 "register_operand" "")
1385         (minus:DI (match_operand:DI 1 "register_operand" "")
1386                   (match_operand:DI 2 "register_operand" "")))
1387    (clobber (match_operand:SI 3 "register_operand" ""))]
1388   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1389    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1390    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1391    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1392    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1393
1394   [(set (match_dup 3)
1395         (ltu:SI (subreg:SI (match_dup 1) 0)
1396                 (subreg:SI (match_dup 2) 0)))
1397
1398    (set (subreg:SI (match_dup 0) 0)
1399         (minus:SI (subreg:SI (match_dup 1) 0)
1400                   (subreg:SI (match_dup 2) 0)))
1401
1402    (set (subreg:SI (match_dup 0) 4)
1403         (minus:SI (subreg:SI (match_dup 1) 4)
1404                   (subreg:SI (match_dup 2) 4)))
1405
1406    (set (subreg:SI (match_dup 0) 4)
1407         (minus:SI (subreg:SI (match_dup 0) 4)
1408                   (match_dup 3)))]
1409   "")
1410
1411 (define_split
1412   [(set (match_operand:DI 0 "register_operand" "")
1413         (minus:DI (match_operand:DI 1 "register_operand" "")
1414                   (match_operand:DI 2 "register_operand" "")))
1415    (clobber (match_operand:SI 3 "register_operand" ""))]
1416   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1417    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1418    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1419    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1420    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1421
1422   [(set (match_dup 3)
1423         (ltu:SI (subreg:SI (match_dup 1) 4)
1424                 (subreg:SI (match_dup 2) 4)))
1425
1426    (set (subreg:SI (match_dup 0) 4)
1427         (minus:SI (subreg:SI (match_dup 1) 4)
1428                   (subreg:SI (match_dup 2) 4)))
1429
1430    (set (subreg:SI (match_dup 0) 0)
1431         (minus:SI (subreg:SI (match_dup 1) 0)
1432                   (subreg:SI (match_dup 2) 0)))
1433
1434    (set (subreg:SI (match_dup 0) 0)
1435         (minus:SI (subreg:SI (match_dup 0) 0)
1436                   (match_dup 3)))]
1437   "")
1438
1439 (define_insn "subdi3_internal_2"
1440   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1441         (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1442                   (match_operand:DI 2 "small_int" "P,J,N")))
1443    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1444   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1445    && INTVAL (operands[2]) != -32768"
1446   "@
1447    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1448    move\\t%L0,%L1\;move\\t%M0,%M1
1449    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1450   [(set_attr "type"     "darith")
1451    (set_attr "mode"     "DI")
1452    (set_attr "length"   "12,8,16")])
1453
1454 (define_split
1455   [(set (match_operand:DI 0 "register_operand" "")
1456         (minus:DI (match_operand:DI 1 "register_operand" "")
1457                   (match_operand:DI 2 "small_int" "")))
1458    (clobber (match_operand:SI 3 "register_operand" ""))]
1459   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1460    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1461    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1462    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1463    && INTVAL (operands[2]) > 0"
1464
1465   [(set (match_dup 3)
1466         (ltu:SI (subreg:SI (match_dup 1) 0)
1467                 (match_dup 2)))
1468
1469    (set (subreg:SI (match_dup 0) 0)
1470         (minus:SI (subreg:SI (match_dup 1) 0)
1471                   (match_dup 2)))
1472
1473    (set (subreg:SI (match_dup 0) 4)
1474         (minus:SI (subreg:SI (match_dup 1) 4)
1475                   (match_dup 3)))]
1476   "")
1477
1478 (define_split
1479   [(set (match_operand:DI 0 "register_operand" "")
1480         (minus:DI (match_operand:DI 1 "register_operand" "")
1481                   (match_operand:DI 2 "small_int" "")))
1482    (clobber (match_operand:SI 3 "register_operand" ""))]
1483   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1484    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1485    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1486    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1487    && INTVAL (operands[2]) > 0"
1488
1489   [(set (match_dup 3)
1490         (ltu:SI (subreg:SI (match_dup 1) 4)
1491                 (match_dup 2)))
1492
1493    (set (subreg:SI (match_dup 0) 4)
1494         (minus:SI (subreg:SI (match_dup 1) 4)
1495                   (match_dup 2)))
1496
1497    (set (subreg:SI (match_dup 0) 0)
1498         (minus:SI (subreg:SI (match_dup 1) 0)
1499                   (match_dup 3)))]
1500   "")
1501
1502 (define_insn "subdi3_internal_3"
1503   [(set (match_operand:DI 0 "register_operand" "=d")
1504         (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
1505                   (match_operand:DI 2 "se_arith_operand" "dI")))]
1506   "TARGET_64BIT && !TARGET_MIPS16
1507    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1508   "*
1509 {
1510   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1511     ? \"daddu\\t%0,%z1,%n2\"
1512     : \"dsubu\\t%0,%z1,%2\";
1513 }"
1514   [(set_attr "type"     "darith")
1515    (set_attr "mode"     "DI")])
1516
1517 ;; For the mips16, we need to recognize stack pointer subtractions
1518 ;; explicitly, since we don't have a constraint for $sp.  These insns
1519 ;; will be generated by the save_restore_insns functions.
1520
1521 (define_insn ""
1522   [(set (reg:DI 29)
1523         (minus:DI (reg:DI 29)
1524                   (match_operand:DI 0 "small_int" "I")))]
1525   "TARGET_MIPS16
1526    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1527   "daddu\\t%$,%$,%n0"
1528   [(set_attr "type"     "arith")
1529    (set_attr "mode"     "DI")
1530    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1531                                       (const_int 4)
1532                                       (const_int 8)))])
1533
1534 (define_insn ""
1535   [(set (match_operand:DI 0 "register_operand" "=d")
1536         (minus:DI (reg:DI 29)
1537                   (match_operand:DI 1 "small_int" "I")))]
1538   "TARGET_MIPS16
1539    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1540   "daddu\\t%0,%$,%n1"
1541   [(set_attr "type"     "arith")
1542    (set_attr "mode"     "DI")
1543    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
1544                                       (const_int 4)
1545                                       (const_int 8)))])
1546
1547 (define_insn ""
1548   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1549         (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1550                   (match_operand:DI 2 "arith_operand" "I,O,d")))]
1551   "TARGET_MIPS16
1552    && (GET_CODE (operands[2]) != CONST_INT
1553        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1554   "*
1555 {
1556   if (REGNO (operands[0]) == REGNO (operands[1]))
1557     return \"dsubu\\t%0,%2\";
1558   return \"dsubu\\t%0,%1,%2\";
1559 }"
1560   [(set_attr "type"     "arith")
1561    (set_attr "mode"     "DI")
1562    (set_attr_alternative "length"
1563                 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
1564                                (const_int 4)
1565                                (const_int 8))
1566                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1567                                (const_int 4)
1568                                (const_int 8))
1569                  (const_int 4)])])
1570
1571 ;; On the mips16, we can sometimes split an add of a constant which is
1572 ;; a 4 byte instruction into two adds which are both 2 byte
1573 ;; instructions.  There are two cases: one where we are adding a
1574 ;; constant plus a register to another register, and one where we are
1575 ;; simply adding a constant to a register.
1576
1577 (define_split
1578   [(set (match_operand:DI 0 "register_operand" "")
1579         (minus:DI (match_dup 0)
1580                   (match_operand:DI 1 "const_int_operand" "")))]
1581   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1582    && GET_CODE (operands[0]) == REG
1583    && M16_REG_P (REGNO (operands[0]))
1584    && GET_CODE (operands[1]) == CONST_INT
1585    && ((INTVAL (operands[1]) > 0x10
1586         && INTVAL (operands[1]) <= 0x10 + 0x10)
1587        || (INTVAL (operands[1]) < - 0xf
1588            && INTVAL (operands[1]) >= - 0xf - 0xf))"
1589   [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1590    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1591   "
1592 {
1593   HOST_WIDE_INT val = INTVAL (operands[1]);
1594
1595   if (val >= 0)
1596     {
1597       operands[1] = GEN_INT (0xf);
1598       operands[2] = GEN_INT (val - 0xf);
1599     }
1600   else
1601     {
1602       operands[1] = GEN_INT (- 0x10);
1603       operands[2] = GEN_INT (val + 0x10);
1604     }
1605 }")
1606
1607 (define_split
1608   [(set (match_operand:DI 0 "register_operand" "")
1609         (minus:DI (match_operand:DI 1 "register_operand" "")
1610                   (match_operand:DI 2 "const_int_operand" "")))]
1611   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1612    && GET_CODE (operands[0]) == REG
1613    && M16_REG_P (REGNO (operands[0]))
1614    && GET_CODE (operands[1]) == REG
1615    && M16_REG_P (REGNO (operands[1]))
1616    && REGNO (operands[0]) != REGNO (operands[1])
1617    && GET_CODE (operands[2]) == CONST_INT
1618    && ((INTVAL (operands[2]) > 0x8
1619         && INTVAL (operands[2]) <= 0x8 + 0x10)
1620        || (INTVAL (operands[2]) < - 0x7
1621            && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1622   [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1623    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1624   "
1625 {
1626   HOST_WIDE_INT val = INTVAL (operands[2]);
1627
1628   if (val >= 0)
1629     {
1630       operands[2] = GEN_INT (0x8);
1631       operands[3] = GEN_INT (val - 0x8);
1632     }
1633   else
1634     {
1635       operands[2] = GEN_INT (- 0x7);
1636       operands[3] = GEN_INT (val + 0x7);
1637     }
1638 }")
1639
1640 (define_insn "subsi3_internal_2"
1641   [(set (match_operand:DI 0 "register_operand" "=d")
1642         (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1643                                   (match_operand:SI 2 "arith_operand" "dI"))))]
1644   "TARGET_64BIT && !TARGET_MIPS16
1645    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1646   "*
1647 {
1648   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1649     ? \"addu\\t%0,%z1,%n2\"
1650     : \"subu\\t%0,%z1,%2\";
1651 }"
1652   [(set_attr "type"     "arith")
1653    (set_attr "mode"     "DI")])
1654
1655 (define_insn ""
1656   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1657         (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1658                                   (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1659   "TARGET_64BIT && TARGET_MIPS16
1660    && (GET_CODE (operands[2]) != CONST_INT
1661        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1662   "*
1663 {
1664   if (REGNO (operands[0]) == REGNO (operands[1]))
1665     return \"subu\\t%0,%2\";
1666   return \"subu\\t%0,%1,%2\";
1667 }"
1668   [(set_attr "type"     "arith")
1669    (set_attr "mode"     "SI")
1670    (set_attr_alternative "length"
1671                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1672                                (const_int 4)
1673                                (const_int 8))
1674                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1675                                (const_int 4)
1676                                (const_int 8))
1677                  (const_int 4)])])
1678
1679
1680 \f
1681 ;;
1682 ;;  ....................
1683 ;;
1684 ;;      MULTIPLICATION
1685 ;;
1686 ;;  ....................
1687 ;;
1688
1689 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1690 ;; operands may corrupt immediately following multiplies. This is a
1691 ;; simple fix to insert NOPs.
1692
1693 (define_expand "muldf3"
1694   [(set (match_operand:DF 0 "register_operand" "=f")
1695         (mult:DF (match_operand:DF 1 "register_operand" "f")
1696                  (match_operand:DF 2 "register_operand" "f")))]
1697   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1698   "
1699 {
1700   if (!TARGET_MIPS4300)
1701     emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1702   else
1703     emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1704   DONE;
1705 }")
1706
1707 (define_insn "muldf3_internal"
1708   [(set (match_operand:DF 0 "register_operand" "=f")
1709         (mult:DF (match_operand:DF 1 "register_operand" "f")
1710                  (match_operand:DF 2 "register_operand" "f")))]
1711   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_MIPS4300"
1712   "mul.d\\t%0,%1,%2"
1713   [(set_attr "type"     "fmul")
1714    (set_attr "mode"     "DF")])
1715
1716 (define_insn "muldf3_r4300"
1717   [(set (match_operand:DF 0 "register_operand" "=f")
1718         (mult:DF (match_operand:DF 1 "register_operand" "f")
1719                  (match_operand:DF 2 "register_operand" "f")))]
1720   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_MIPS4300"
1721   "*
1722 {
1723   output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1724   if (TARGET_4300_MUL_FIX)
1725     output_asm_insn (\"nop\", operands);
1726   return \"\";
1727 }"
1728   [(set_attr "type"     "fmul")
1729    (set_attr "mode"     "DF")
1730    (set_attr "length"   "8")])  ;; mul.d + nop
1731
1732 (define_expand "mulsf3"
1733   [(set (match_operand:SF 0 "register_operand" "=f")
1734         (mult:SF (match_operand:SF 1 "register_operand" "f")
1735                  (match_operand:SF 2 "register_operand" "f")))]
1736   "TARGET_HARD_FLOAT"
1737   "
1738 {
1739   if (!TARGET_MIPS4300)
1740     emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1741   else
1742     emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1743   DONE;
1744 }")
1745
1746 (define_insn "mulsf3_internal"
1747   [(set (match_operand:SF 0 "register_operand" "=f")
1748         (mult:SF (match_operand:SF 1 "register_operand" "f")
1749                  (match_operand:SF 2 "register_operand" "f")))]
1750   "TARGET_HARD_FLOAT && !TARGET_MIPS4300"
1751   "mul.s\\t%0,%1,%2"
1752   [(set_attr "type"     "fmul")
1753    (set_attr "mode"     "SF")])
1754
1755 (define_insn "mulsf3_r4300"
1756   [(set (match_operand:SF 0 "register_operand" "=f")
1757         (mult:SF (match_operand:SF 1 "register_operand" "f")
1758                  (match_operand:SF 2 "register_operand" "f")))]
1759   "TARGET_HARD_FLOAT && TARGET_MIPS4300"
1760   "*
1761 {
1762   output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1763   if (TARGET_4300_MUL_FIX)
1764     output_asm_insn (\"nop\", operands);
1765   return \"\";
1766 }"
1767   [(set_attr "type"     "fmul")
1768    (set_attr "mode"     "SF")
1769    (set_attr "length"   "8")])  ;; mul.s + nop
1770
1771
1772 ;; ??? The R4000 (only) has a cpu bug.  If a double-word shift executes while
1773 ;; a multiply is in progress, it may give an incorrect result.  Avoid
1774 ;; this by keeping the mflo with the mult on the R4000.
1775
1776 (define_expand "mulsi3"
1777   [(set (match_operand:SI 0 "register_operand" "=l")
1778         (mult:SI (match_operand:SI 1 "register_operand" "d")
1779                  (match_operand:SI 2 "register_operand" "d")))
1780    (clobber (match_scratch:SI 3 "=h"))
1781    (clobber (match_scratch:SI 4 "=a"))]
1782   ""
1783   "
1784 {
1785   if (GENERATE_MULT3_SI || TARGET_MAD)
1786     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1787   else if (!TARGET_MIPS4000 || TARGET_MIPS16)
1788     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1789   else
1790     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1791   DONE;
1792 }")
1793
1794 (define_insn "mulsi3_mult3"
1795   [(set (match_operand:SI 0 "register_operand" "=d,l")
1796         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1797                  (match_operand:SI 2 "register_operand" "d,d")))
1798    (clobber (match_scratch:SI 3 "=h,h"))
1799    (clobber (match_scratch:SI 4 "=l,X"))
1800    (clobber (match_scratch:SI 5 "=a,a"))]
1801   "GENERATE_MULT3_SI
1802    || TARGET_MAD"
1803   "*
1804 {
1805   if (which_alternative == 1)
1806     return \"mult\\t%1,%2\";
1807   if (TARGET_MAD
1808       || TARGET_MIPS5400
1809       || TARGET_MIPS5500
1810       || ISA_MIPS32
1811       || ISA_MIPS32R2
1812       || ISA_MIPS64)
1813     return \"mul\\t%0,%1,%2\";
1814   return \"mult\\t%0,%1,%2\";
1815 }"
1816   [(set_attr "type"     "imul")
1817    (set_attr "mode"     "SI")])
1818
1819 (define_insn "mulsi3_internal"
1820   [(set (match_operand:SI 0 "register_operand" "=l")
1821         (mult:SI (match_operand:SI 1 "register_operand" "d")
1822                  (match_operand:SI 2 "register_operand" "d")))
1823    (clobber (match_scratch:SI 3 "=h"))
1824    (clobber (match_scratch:SI 4 "=a"))]
1825   "!TARGET_MIPS4000 || TARGET_MIPS16"
1826   "mult\\t%1,%2"
1827   [(set_attr "type"     "imul")
1828    (set_attr "mode"     "SI")])
1829
1830 (define_insn "mulsi3_r4000"
1831   [(set (match_operand:SI 0 "register_operand" "=d")
1832         (mult:SI (match_operand:SI 1 "register_operand" "d")
1833                  (match_operand:SI 2 "register_operand" "d")))
1834    (clobber (match_scratch:SI 3 "=h"))
1835    (clobber (match_scratch:SI 4 "=l"))
1836    (clobber (match_scratch:SI 5 "=a"))]
1837   "TARGET_MIPS4000 && !TARGET_MIPS16"
1838   "*
1839 {
1840   rtx xoperands[10];
1841
1842   xoperands[0] = operands[0];
1843   xoperands[1] = gen_rtx_REG (SImode, LO_REGNUM);
1844
1845   output_asm_insn (\"mult\\t%1,%2\", operands);
1846   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1847   return \"\";
1848 }"
1849   [(set_attr "type"     "imul")
1850    (set_attr "mode"     "SI")
1851    (set_attr "length"   "12")])         ;; mult + mflo + delay
1852
1853 ;; Multiply-accumulate patterns
1854
1855 ;; For processors that can copy the output to a general register:
1856 ;;
1857 ;; The all-d alternative is needed because the combiner will find this
1858 ;; pattern and then register alloc/reload will move registers around to
1859 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1860 ;;
1861 ;; The last alternative should be made slightly less desirable, but adding
1862 ;; "?" to the constraint is too strong, and causes values to be loaded into
1863 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1864 ;; trick.
1865 (define_insn "*mul_acc_si"
1866   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1867         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1868                           (match_operand:SI 2 "register_operand" "d,d,d"))
1869                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1870    (clobber (match_scratch:SI 4 "=h,h,h"))
1871    (clobber (match_scratch:SI 5 "=X,3,l"))
1872    (clobber (match_scratch:SI 6 "=a,a,a"))
1873    (clobber (match_scratch:SI 7 "=X,X,d"))]
1874   "(TARGET_MIPS3900
1875    || TARGET_MIPS5400
1876    || TARGET_MIPS5500
1877    || ISA_HAS_MADD_MSUB)
1878    && !TARGET_MIPS16"
1879   "*
1880 {
1881   static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
1882   static const char *const macc[] = { \"macc\\t$0,%1,%2\", \"macc\\t%0,%1,%2\" };
1883   if (which_alternative == 2)
1884     return \"#\";
1885   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1886     return \"#\";
1887
1888   if (TARGET_MIPS5400)
1889     return macc[which_alternative];
1890
1891   if (TARGET_MIPS5500)
1892     {
1893       if (which_alternative == 0)
1894         return madd[0];
1895       else
1896         return macc[which_alternative];
1897     }
1898
1899   return madd[which_alternative];
1900 }"
1901   [(set_attr "type"     "imadd,imadd,multi")
1902    (set_attr "mode"     "SI")
1903    (set_attr "length"   "4,4,8")])
1904
1905 ;; Split the above insn if we failed to get LO allocated.
1906 (define_split
1907   [(set (match_operand:SI 0 "register_operand" "")
1908         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1909                           (match_operand:SI 2 "register_operand" ""))
1910                  (match_operand:SI 3 "register_operand" "")))
1911    (clobber (match_scratch:SI 4 ""))
1912    (clobber (match_scratch:SI 5 ""))
1913    (clobber (match_scratch:SI 6 ""))
1914    (clobber (match_scratch:SI 7 ""))]
1915   "reload_completed && !TARGET_DEBUG_D_MODE
1916    && GP_REG_P (true_regnum (operands[0]))
1917    && GP_REG_P (true_regnum (operands[3]))"
1918   [(parallel [(set (match_dup 7)
1919                    (mult:SI (match_dup 1) (match_dup 2)))
1920               (clobber (match_dup 4))
1921               (clobber (match_dup 5))
1922               (clobber (match_dup 6))])
1923    (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
1924   "")
1925
1926 ;; Splitter to copy result of MADD to a general register
1927 (define_split
1928   [(set (match_operand:SI                   0 "register_operand" "")
1929         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1930                           (match_operand:SI 2 "register_operand" ""))
1931                  (match_operand:SI          3 "register_operand" "")))
1932    (clobber (match_scratch:SI               4 ""))
1933    (clobber (match_scratch:SI               5 ""))
1934    (clobber (match_scratch:SI               6 ""))
1935    (clobber (match_scratch:SI               7 ""))]
1936   "reload_completed && !TARGET_DEBUG_D_MODE
1937    && GP_REG_P (true_regnum (operands[0]))
1938    && true_regnum (operands[3]) == LO_REGNUM"
1939   [(parallel [(set (match_dup 3)
1940                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1941                             (match_dup 3)))
1942               (clobber (match_dup 4))
1943               (clobber (match_dup 5))
1944               (clobber (match_dup 6))
1945               (clobber (match_dup 7))])
1946    (set (match_dup 0) (match_dup 3))]
1947   "")
1948
1949 (define_insn "*mul_sub_si"
1950   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1951         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1952                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1953                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1954    (clobber (match_scratch:SI 4 "=h,h,h"))
1955    (clobber (match_scratch:SI 5 "=X,3,l"))
1956    (clobber (match_scratch:SI 6 "=a,a,a"))
1957    (clobber (match_scratch:SI 7 "=X,X,d"))]
1958   "ISA_HAS_MADD_MSUB"
1959   "*
1960 {
1961   if (which_alternative != 0)
1962     return \"#\";
1963   return \"msub\\t%2,%3\";
1964 }"
1965   [(set_attr "type"     "imadd,multi,multi")
1966    (set_attr "mode"     "SI")
1967    (set_attr "length"   "4,8,8")])
1968
1969 ;; Split the above insn if we failed to get LO allocated.
1970 (define_split
1971   [(set (match_operand:SI 0 "register_operand" "")
1972         (minus:SI (match_operand:SI 1 "register_operand" "")
1973                   (mult:SI (match_operand:SI 2 "register_operand" "")
1974                            (match_operand:SI 3 "register_operand" ""))))
1975    (clobber (match_scratch:SI 4 ""))
1976    (clobber (match_scratch:SI 5 ""))
1977    (clobber (match_scratch:SI 6 ""))
1978    (clobber (match_scratch:SI 7 ""))]
1979   "reload_completed && !TARGET_DEBUG_D_MODE
1980    && GP_REG_P (true_regnum (operands[0]))
1981    && GP_REG_P (true_regnum (operands[1]))"
1982   [(parallel [(set (match_dup 7)
1983                    (mult:SI (match_dup 2) (match_dup 3)))
1984               (clobber (match_dup 4))
1985               (clobber (match_dup 5))
1986               (clobber (match_dup 6))])
1987    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
1988   "")
1989
1990 ;; Splitter to copy result of MSUB to a general register
1991 (define_split
1992   [(set (match_operand:SI 0 "register_operand" "")
1993         (minus:SI (match_operand:SI 1 "register_operand" "")
1994                   (mult:SI (match_operand:SI 2 "register_operand" "")
1995                            (match_operand:SI 3 "register_operand" ""))))
1996    (clobber (match_scratch:SI 4 ""))
1997    (clobber (match_scratch:SI 5 ""))
1998    (clobber (match_scratch:SI 6 ""))
1999    (clobber (match_scratch:SI 7 ""))]
2000   "reload_completed && !TARGET_DEBUG_D_MODE
2001    && GP_REG_P (true_regnum (operands[0]))
2002    && true_regnum (operands[1]) == LO_REGNUM"
2003   [(parallel [(set (match_dup 1)
2004                    (minus:SI (match_dup 1)
2005                              (mult:SI (match_dup 2) (match_dup 3))))
2006               (clobber (match_dup 4))
2007               (clobber (match_dup 5))
2008               (clobber (match_dup 6))
2009               (clobber (match_dup 7))])
2010    (set (match_dup 0) (match_dup 1))]
2011   "")
2012
2013 (define_insn "*muls"
2014   [(set (match_operand:SI                  0 "register_operand" "=l,d")
2015         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
2016                          (match_operand:SI 2 "register_operand" "d,d"))))
2017    (clobber (match_scratch:SI              3                    "=h,h"))
2018    (clobber (match_scratch:SI              4                    "=a,a"))
2019    (clobber (match_scratch:SI              5                    "=X,l"))]
2020   "ISA_HAS_MULS && TARGET_64BIT"
2021   "@
2022    muls\\t$0,%1,%2
2023    muls\\t%0,%1,%2"
2024   [(set_attr "type"     "imul")
2025    (set_attr "mode"     "SI")])
2026
2027 ;; See comments above for mul_acc_si.
2028 (define_insn "*msac"
2029   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
2030         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
2031                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
2032                            (match_operand:SI 3 "register_operand" "d,d,d"))))
2033    (clobber (match_scratch:SI 4 "=h,h,h"))
2034    (clobber (match_scratch:SI 5 "=X,1,l"))
2035    (clobber (match_scratch:SI 6 "=a,a,a"))
2036    (clobber (match_scratch:SI 7 "=X,X,d"))]
2037   "ISA_HAS_MSAC && TARGET_64BIT"
2038   "@
2039    msac\\t$0,%2,%3
2040    msac\\t%0,%2,%3
2041    #"
2042   [(set_attr "type"     "imadd,imadd,multi")
2043    (set_attr "mode"     "SI")
2044    (set_attr "length"   "4,4,8")])
2045
2046 (define_split
2047   [(set (match_operand:SI 0 "register_operand" "")
2048         (minus:SI (match_operand:SI 1 "register_operand" "")
2049                   (mult:SI (match_operand:SI 2 "register_operand" "")
2050                            (match_operand:SI 3 "register_operand" ""))))
2051    (clobber (match_scratch:SI 4 ""))
2052    (clobber (match_scratch:SI 5 ""))
2053    (clobber (match_scratch:SI 6 ""))
2054    (clobber (match_scratch:SI 7 ""))]
2055   "reload_completed && !TARGET_DEBUG_D_MODE
2056    && GP_REG_P (true_regnum (operands[0]))
2057    && GP_REG_P (true_regnum (operands[1]))"
2058   [(parallel [(set (match_dup 7)
2059                    (mult:SI (match_dup 2) (match_dup 3)))
2060               (clobber (match_dup 4))
2061               (clobber (match_dup 5))
2062               (clobber (match_dup 6))])
2063    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
2064   "")
2065
2066 (define_expand "muldi3"
2067   [(set (match_operand:DI 0 "register_operand" "=l")
2068         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
2069                  (match_operand:DI 2 "register_operand" "d")))
2070    (clobber (match_scratch:DI 3 "=h"))
2071    (clobber (match_scratch:DI 4 "=a"))]
2072   "TARGET_64BIT"
2073
2074   "
2075 {
2076   if (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)
2077     emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
2078   else
2079     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
2080   DONE;
2081 }")
2082
2083 ;; Don't accept both operands using se_register_operand, because if
2084 ;; both operands are sign extended we would prefer to use mult in the
2085 ;; mulsidi3 pattern.  Commutativity should permit either operand to be
2086 ;; sign extended.
2087
2088 (define_insn "muldi3_internal"
2089   [(set (match_operand:DI 0 "register_operand" "=l")
2090         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
2091                  (match_operand:DI 2 "register_operand" "d")))
2092    (clobber (match_scratch:DI 3 "=h"))
2093    (clobber (match_scratch:DI 4 "=a"))]
2094   "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16"
2095   "dmult\\t%1,%2"
2096   [(set_attr "type"     "imul")
2097    (set_attr "mode"     "DI")])
2098
2099 (define_insn "muldi3_internal2"
2100   [(set (match_operand:DI 0 "register_operand" "=d")
2101         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
2102                  (match_operand:DI 2 "register_operand" "d")))
2103    (clobber (match_scratch:DI 3 "=h"))
2104    (clobber (match_scratch:DI 4 "=l"))
2105    (clobber (match_scratch:DI 5 "=a"))]
2106   "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)"
2107   "*
2108 {
2109   if (GENERATE_MULT3_DI)
2110     output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
2111   else
2112     {
2113       rtx xoperands[10];
2114
2115       xoperands[0] = operands[0];
2116       xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM);
2117
2118       output_asm_insn (\"dmult\\t%1,%2\", operands);
2119       output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2120     }
2121   return \"\";
2122 }"
2123   [(set_attr "type"     "imul")
2124    (set_attr "mode"     "DI")
2125    (set (attr "length")
2126         (if_then_else (ne (symbol_ref "GENERATE_MULT3_DI") (const_int 0))
2127                        (const_int 4)
2128                        (const_int 12)))])       ;; mult + mflo + delay
2129
2130 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
2131
2132 (define_expand "mulsidi3"
2133   [(set (match_operand:DI 0 "register_operand" "=x")
2134         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2135                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2136   ""
2137   "
2138 {
2139   rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
2140   if (TARGET_64BIT)
2141     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
2142                                    dummy, dummy));
2143   else
2144     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
2145                                       dummy, dummy));
2146   DONE;
2147 }")
2148
2149 (define_expand "umulsidi3"
2150   [(set (match_operand:DI 0 "register_operand" "=x")
2151         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2152                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2153   ""
2154   "
2155 {
2156   rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
2157   if (TARGET_64BIT)
2158     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
2159                                    dummy, dummy));
2160   else
2161     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
2162                                       dummy, dummy));
2163   DONE;
2164 }")
2165
2166 (define_insn "mulsidi3_internal"
2167   [(set (match_operand:DI 0 "register_operand" "=x")
2168         (mult:DI (match_operator:DI 3 "extend_operator"
2169                                     [(match_operand:SI 1 "register_operand" "d")])
2170                  (match_operator:DI 4 "extend_operator"
2171                                     [(match_operand:SI 2 "register_operand" "d")])))
2172    (clobber (match_scratch:SI 5 "=a"))]
2173   "!TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2174   "*
2175 {
2176   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2177     return \"mult\\t%1,%2\";
2178   return \"multu\\t%1,%2\";
2179 }"
2180   [(set_attr "type"     "imul")
2181    (set_attr "mode"     "SI")])
2182
2183 (define_insn "mulsidi3_64bit"
2184   [(set (match_operand:DI 0 "register_operand" "=a")
2185         (mult:DI (match_operator:DI 3 "extend_operator"
2186                                     [(match_operand:SI 1 "register_operand" "d")])
2187                  (match_operator:DI 4 "extend_operator"
2188                                     [(match_operand:SI 2 "register_operand" "d")])))
2189    (clobber (match_scratch:DI 5 "=l"))
2190    (clobber (match_scratch:DI 6 "=h"))]
2191   "TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2192   "*
2193 {
2194   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2195     return \"mult\\t%1,%2\";
2196   return \"multu\\t%1,%2\";
2197 }"
2198   [(set_attr "type"     "imul")
2199    (set_attr "mode"     "SI")])
2200
2201 ;; widening multiply with accumulator and/or negation
2202 ;; These don't match yet for zero-extending; too complex for combine?
2203 ;; Possible additions we should have:
2204 ;;  "=x" variants for when !TARGET_64BIT ?
2205 ;;  all-d alternatives with splits like pure SImode versions
2206 (define_insn "*muls_di"
2207   [(set (match_operand:DI 0 "register_operand" "=a")
2208         (neg:DI
2209          (mult:DI (match_operator:DI 3 "extend_operator"
2210                                      [(match_operand:SI 1 "register_operand" "d")])
2211                   (match_operator:DI 4 "extend_operator"
2212                                      [(match_operand:SI 2 "register_operand" "d")]))))
2213    (clobber (match_scratch:SI 5 "=h"))
2214    (clobber (match_scratch:SI 6 "=l"))]
2215   "TARGET_64BIT
2216    && ISA_HAS_MULS
2217    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2218   "*
2219 {
2220   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2221     return \"muls\\t$0,%1,%2\";
2222   else
2223     return \"mulsu\\t$0,%1,%2\";
2224 }"
2225   [(set_attr "type"     "imul")
2226    (set_attr "length"   "4")
2227    (set_attr "mode"     "SI")])
2228
2229 (define_insn "*msac_di"
2230   [(set (match_operand:DI 0 "register_operand" "=a")
2231         (minus:DI (match_operand:DI 3 "register_operand" "0")
2232                   (mult:DI (match_operator:DI 4 "extend_operator"
2233                                               [(match_operand:SI 1 "register_operand" "d")])
2234                            (match_operator:DI 5 "extend_operator"
2235                                               [(match_operand:SI 2 "register_operand" "d")]))))
2236    (clobber (match_scratch:SI 6 "=h"))
2237    (clobber (match_scratch:SI 7 "=l"))]
2238   "TARGET_64BIT
2239    && ISA_HAS_MSAC
2240    && GET_CODE (operands[4]) == GET_CODE (operands[5])"
2241   "*
2242 {
2243   if (GET_CODE (operands[4]) == SIGN_EXTEND)
2244      {
2245        if (TARGET_MIPS5500)
2246          return \"msub\\t%1,%2\";
2247        else
2248     return \"msac\\t$0,%1,%2\";
2249     }
2250   else
2251      {
2252        if (TARGET_MIPS5500)
2253          return \"msubu\\t%1,%2\";
2254        else
2255     return \"msacu\\t$0,%1,%2\";
2256     }
2257 }"
2258   [(set_attr "type"     "imadd")
2259    (set_attr "length"   "4")
2260    (set_attr "mode"     "SI")])
2261
2262 ;; _highpart patterns
2263 (define_expand "smulsi3_highpart"
2264   [(set (match_operand:SI 0 "register_operand" "=h")
2265         (truncate:SI
2266          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2267                                (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2268                       (const_int 32))))]
2269   ""
2270   "
2271 {
2272   rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
2273   rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
2274 #ifndef NO_MD_PROTOTYPES
2275   rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
2276 #else
2277   rtx (*genfn) ();
2278 #endif
2279  if (ISA_HAS_MULHI && TARGET_64BIT)
2280     genfn = gen_xmulsi3_highpart_mulhi;
2281  else
2282     genfn = gen_xmulsi3_highpart_internal;
2283   emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2284                        dummy, dummy2));
2285   DONE;
2286 }")
2287
2288 (define_expand "umulsi3_highpart"
2289   [(set (match_operand:SI 0 "register_operand" "=h")
2290         (truncate:SI
2291          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2292                                (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2293                       (const_int 32))))]
2294   ""
2295   "
2296 {
2297   rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
2298   rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
2299 #ifndef NO_MD_PROTOTYPES
2300   rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
2301 #else
2302   rtx (*genfn) ();
2303 #endif
2304   if (ISA_HAS_MULHI && TARGET_64BIT)
2305     genfn = gen_xmulsi3_highpart_mulhi;
2306   else
2307     genfn = gen_xmulsi3_highpart_internal;
2308   emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2309                        dummy, dummy2));
2310   DONE;
2311 }")
2312
2313 (define_insn "xmulsi3_highpart_internal"
2314   [(set (match_operand:SI 0 "register_operand" "=h")
2315         (truncate:SI
2316          (match_operator:DI 5 "highpart_shift_operator"
2317                             [(mult:DI (match_operator:DI 3 "extend_operator"
2318                                                          [(match_operand:SI 1 "register_operand" "d")])
2319                                       (match_operator:DI 4 "extend_operator"
2320                                                          [(match_operand:SI 2 "register_operand" "d")]))
2321                              (const_int 32)])))
2322    (clobber (match_scratch:SI 6 "=l"))
2323    (clobber (match_scratch:SI 7 "=a"))]
2324   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
2325   "*
2326 {
2327   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2328     return \"mult\\t%1,%2\";
2329   else
2330     return \"multu\\t%1,%2\";
2331 }"
2332   [(set_attr "type"     "imul")
2333    (set_attr "mode"     "SI")])
2334
2335 (define_insn "xmulsi3_highpart_mulhi"
2336   [(set (match_operand:SI 0 "register_operand" "=h,d")
2337         (truncate:SI
2338          (match_operator:DI 5 "highpart_shift_operator"
2339                             [(mult:DI (match_operator:DI 3 "extend_operator"
2340                                                          [(match_operand:SI 1 "register_operand" "d,d")])
2341                                       (match_operator:DI 4 "extend_operator"
2342                                                          [(match_operand:SI 2 "register_operand" "d,d")]))
2343                              (const_int 32)])))
2344    (clobber (match_scratch:SI 6 "=l,l"))
2345    (clobber (match_scratch:SI 7 "=a,a"))
2346    (clobber (match_scratch:SI 8 "=X,h"))]
2347   "ISA_HAS_MULHI
2348    && TARGET_64BIT
2349    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2350   "*
2351 {
2352   static char const *const sign[] = { \"mult\\t%1,%2\",  \"mulhi\\t%0,%1,%2\"  };
2353   static char const *const zero[] = { \"multu\\t%1,%2\", \"mulhiu\\t%0,%1,%2\" };
2354   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2355     return sign[which_alternative];
2356   else
2357     return zero[which_alternative];
2358 }"
2359   [(set_attr "type"     "imul")
2360    (set_attr "mode"     "SI")
2361    (set_attr "length"   "4")])
2362
2363 (define_insn "*xmulsi3_neg_highpart_mulhi"
2364   [(set (match_operand:SI 0 "register_operand" "=h,d")
2365         (truncate:SI
2366          (match_operator:DI 5 "highpart_shift_operator"
2367                             [(neg:DI
2368                               (mult:DI (match_operator:DI 3 "extend_operator"
2369                                                           [(match_operand:SI 1 "register_operand" "d,d")])
2370                                        (match_operator:DI 4 "extend_operator"
2371                                                           [(match_operand:SI 2 "register_operand" "d,d")])))
2372                              (const_int 32)])))
2373    (clobber (match_scratch:SI 6 "=l,l"))
2374    (clobber (match_scratch:SI 7 "=a,a"))
2375    (clobber (match_scratch:SI 8 "=X,h"))]
2376   "ISA_HAS_MULHI
2377    && TARGET_64BIT
2378    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2379   "*
2380 {
2381   static char const *const sign[] = { \"mulshi\\t$0,%1,%2\",  \"mulshi\\t%0,%1,%2\"  };
2382   static char const *const zero[] = { \"mulshiu\\t$0,%1,%2\", \"mulshiu\\t%0,%1,%2\" };
2383   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2384     return sign[which_alternative];
2385   else
2386     return zero[which_alternative];
2387 }"
2388   [(set_attr "type"     "imul")
2389    (set_attr "mode"     "SI")
2390    (set_attr "length"   "4")])
2391
2392
2393 (define_insn "smuldi3_highpart"
2394   [(set (match_operand:DI 0 "register_operand" "=h")
2395         (truncate:DI
2396          (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2397                                (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2398                       (const_int 64))))
2399    (clobber (match_scratch:DI 3 "=l"))
2400    (clobber (match_scratch:DI 4 "=a"))]
2401   "TARGET_64BIT"
2402   "dmult\\t%1,%2"
2403   [(set_attr "type"     "imul")
2404    (set_attr "mode"     "DI")])
2405
2406 (define_insn "umuldi3_highpart"
2407   [(set (match_operand:DI 0 "register_operand" "=h")
2408         (truncate:DI
2409          (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2410                                (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2411                       (const_int 64))))
2412    (clobber (match_scratch:DI 3 "=l"))
2413    (clobber (match_scratch:DI 4 "=a"))]
2414   "TARGET_64BIT"
2415   "dmultu\\t%1,%2"
2416   [(set_attr "type"     "imul")
2417    (set_attr "mode"     "DI")])
2418
2419 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2420 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
2421
2422 (define_insn "madsi"
2423   [(set (match_operand:SI 0 "register_operand" "+l")
2424         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2425                           (match_operand:SI 2 "register_operand" "d"))
2426                  (match_dup 0)))
2427    (clobber (match_scratch:SI 3 "=h"))
2428    (clobber (match_scratch:SI 4 "=a"))]
2429   "TARGET_MAD"
2430   "mad\\t%1,%2"
2431   [(set_attr "type"     "imadd")
2432    (set_attr "mode"     "SI")])
2433
2434 (define_insn "*mul_acc_di"
2435   [(set (match_operand:DI 0 "register_operand" "+x")
2436         (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2437                            [(match_operand:SI 1 "register_operand" "d")])
2438                           (match_operator:DI 4 "extend_operator"
2439                            [(match_operand:SI 2 "register_operand" "d")]))
2440                  (match_dup 0)))
2441    (clobber (match_scratch:SI 5 "=a"))]
2442   "TARGET_MAD
2443    && ! TARGET_64BIT
2444    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2445   "*
2446 {
2447   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2448     return \"mad\\t%1,%2\";
2449   else
2450     return \"madu\\t%1,%2\";
2451 }"
2452   [(set_attr "type"     "imadd")
2453    (set_attr "mode"     "SI")])
2454
2455 (define_insn "*mul_acc_64bit_di"
2456   [(set (match_operand:DI 0 "register_operand" "+a")
2457         (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2458                            [(match_operand:SI 1 "register_operand" "d")])
2459                           (match_operator:DI 4 "extend_operator"
2460                            [(match_operand:SI 2 "register_operand" "d")]))
2461                  (match_dup 0)))
2462    (clobber (match_scratch:SI 5 "=h"))
2463    (clobber (match_scratch:SI 6 "=l"))]
2464   "TARGET_MAD
2465    && TARGET_64BIT
2466    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2467   "*
2468 {
2469   if (TARGET_MAD)
2470     {
2471       if (GET_CODE (operands[3]) == SIGN_EXTEND)
2472         return \"mad\\t%1,%2\";
2473       else
2474         return \"madu\\t%1,%2\";
2475     }
2476   else if (ISA_HAS_MACC)
2477     {
2478       if (GET_CODE (operands[3]) == SIGN_EXTEND)
2479         {
2480           if (TARGET_MIPS5500)
2481             return \"madd\\t%1,%2\";
2482           else
2483         return \"macc\\t$0,%1,%2\";
2484         }
2485       else
2486         {
2487           if (TARGET_MIPS5500)
2488             return \"maddu\\t%1,%2\";
2489           else
2490         return \"maccu\\t$0,%1,%2\";
2491         }
2492     }
2493   else
2494     abort ();
2495
2496 }"
2497   [(set_attr "type"     "imadd")
2498    (set_attr "mode"     "SI")])
2499
2500 ;; Floating point multiply accumulate instructions.
2501
2502 (define_insn ""
2503   [(set (match_operand:DF 0 "register_operand" "=f")
2504         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2505                           (match_operand:DF 2 "register_operand" "f"))
2506                  (match_operand:DF 3 "register_operand" "f")))]
2507   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2508   "madd.d\\t%0,%3,%1,%2"
2509   [(set_attr "type"     "fmadd")
2510    (set_attr "mode"     "DF")])
2511
2512 (define_insn ""
2513   [(set (match_operand:SF 0 "register_operand" "=f")
2514         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2515                           (match_operand:SF 2 "register_operand" "f"))
2516                  (match_operand:SF 3 "register_operand" "f")))]
2517   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2518   "madd.s\\t%0,%3,%1,%2"
2519   [(set_attr "type"     "fmadd")
2520    (set_attr "mode"     "SF")])
2521
2522 (define_insn ""
2523   [(set (match_operand:DF 0 "register_operand" "=f")
2524         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2525                            (match_operand:DF 2 "register_operand" "f"))
2526                   (match_operand:DF 3 "register_operand" "f")))]
2527   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2528   "msub.d\\t%0,%3,%1,%2"
2529   [(set_attr "type"     "fmadd")
2530    (set_attr "mode"     "DF")])
2531
2532 (define_insn ""
2533   [(set (match_operand:SF 0 "register_operand" "=f")
2534         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2535                            (match_operand:SF 2 "register_operand" "f"))
2536                   (match_operand:SF 3 "register_operand" "f")))]
2537
2538   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2539   "msub.s\\t%0,%3,%1,%2"
2540   [(set_attr "type"     "fmadd")
2541    (set_attr "mode"     "SF")])
2542
2543 (define_insn ""
2544   [(set (match_operand:DF 0 "register_operand" "=f")
2545         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2546                                   (match_operand:DF 2 "register_operand" "f"))
2547                          (match_operand:DF 3 "register_operand" "f"))))]
2548   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2549   "nmadd.d\\t%0,%3,%1,%2"
2550   [(set_attr "type"     "fmadd")
2551    (set_attr "mode"     "DF")])
2552
2553 (define_insn ""
2554   [(set (match_operand:SF 0 "register_operand" "=f")
2555         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2556                                   (match_operand:SF 2 "register_operand" "f"))
2557                          (match_operand:SF 3 "register_operand" "f"))))]
2558   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2559   "nmadd.s\\t%0,%3,%1,%2"
2560   [(set_attr "type"     "fmadd")
2561    (set_attr "mode"     "SF")])
2562
2563 (define_insn ""
2564   [(set (match_operand:DF 0 "register_operand" "=f")
2565         (minus:DF (match_operand:DF 1 "register_operand" "f")
2566                   (mult:DF (match_operand:DF 2 "register_operand" "f")
2567                            (match_operand:DF 3 "register_operand" "f"))))]
2568   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2569   "nmsub.d\\t%0,%1,%2,%3"
2570   [(set_attr "type"     "fmadd")
2571    (set_attr "mode"     "DF")])
2572
2573 (define_insn ""
2574   [(set (match_operand:SF 0 "register_operand" "=f")
2575         (minus:SF (match_operand:SF 1 "register_operand" "f")
2576                   (mult:SF (match_operand:SF 2 "register_operand" "f")
2577                            (match_operand:SF 3 "register_operand" "f"))))]
2578   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2579   "nmsub.s\\t%0,%1,%2,%3"
2580   [(set_attr "type"     "fmadd")
2581    (set_attr "mode"     "SF")])
2582 \f
2583 ;;
2584 ;;  ....................
2585 ;;
2586 ;;      DIVISION and REMAINDER
2587 ;;
2588 ;;  ....................
2589 ;;
2590
2591 (define_insn "divdf3"
2592   [(set (match_operand:DF 0 "register_operand" "=f")
2593         (div:DF (match_operand:DF 1 "register_operand" "f")
2594                 (match_operand:DF 2 "register_operand" "f")))]
2595   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2596   "div.d\\t%0,%1,%2"
2597   [(set_attr "type"     "fdiv")
2598    (set_attr "mode"     "DF")])
2599
2600 (define_insn "divsf3"
2601   [(set (match_operand:SF 0 "register_operand" "=f")
2602         (div:SF (match_operand:SF 1 "register_operand" "f")
2603                 (match_operand:SF 2 "register_operand" "f")))]
2604   "TARGET_HARD_FLOAT"
2605   "div.s\\t%0,%1,%2"
2606   [(set_attr "type"     "fdiv")
2607    (set_attr "mode"     "SF")])
2608
2609 (define_insn ""
2610   [(set (match_operand:DF 0 "register_operand" "=f")
2611         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2612                 (match_operand:DF 2 "register_operand" "f")))]
2613   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2614   "recip.d\\t%0,%2"
2615   [(set_attr "type"     "fdiv")
2616    (set_attr "mode"     "DF")])
2617
2618 (define_insn ""
2619   [(set (match_operand:SF 0 "register_operand" "=f")
2620         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2621                 (match_operand:SF 2 "register_operand" "f")))]
2622   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2623   "recip.s\\t%0,%2"
2624   [(set_attr "type"     "fdiv")
2625    (set_attr "mode"     "SF")])
2626
2627 ;; If optimizing, prefer the divmod functions over separate div and
2628 ;; mod functions, since this will allow using one instruction for both
2629 ;; the quotient and remainder.  At present, the divmod is not moved out
2630 ;; of loops if it is constant within the loop, so allow -mdebugc to
2631 ;; use the old method of doing things.
2632
2633 ;; 64 is the multiply/divide hi register
2634 ;; 65 is the multiply/divide lo register
2635
2636 ;; ??? We can't accept constants here, because the MIPS assembler will replace
2637 ;; a divide by power of 2 with a shift, and then the remainder is no longer
2638 ;; available.
2639
2640 (define_expand "divmodsi4"
2641   [(set (match_operand:SI 0 "register_operand" "=d")
2642         (div:SI (match_operand:SI 1 "register_operand" "d")
2643                 (match_operand:SI 2 "register_operand" "d")))
2644    (set (match_operand:SI 3 "register_operand" "=d")
2645         (mod:SI (match_dup 1)
2646                 (match_dup 2)))
2647    (clobber (match_scratch:SI 4 "=l"))
2648    (clobber (match_scratch:SI 5 "=h"))
2649    (clobber (match_scratch:SI 6 "=a"))]
2650   "optimize"
2651   "
2652 {
2653   emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
2654              operands[3]));
2655   if (!TARGET_NO_CHECK_ZERO_DIV)
2656     {
2657       emit_insn (gen_div_trap (operands[2],
2658                                GEN_INT (0),
2659                                GEN_INT (0x7)));
2660     }
2661   if (TARGET_CHECK_RANGE_DIV)
2662     {
2663       emit_insn (gen_div_trap (operands[2],
2664                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2665                                GEN_INT (0x6)));
2666       emit_insn (gen_div_trap (operands[2],
2667                                copy_to_mode_reg (SImode,
2668                                                  GEN_INT
2669                                                  (trunc_int_for_mode
2670                                                   (BITMASK_HIGH, SImode))),
2671                                GEN_INT (0x6)));
2672     }
2673
2674   DONE;
2675 }")
2676
2677 (define_insn "divmodsi4_internal"
2678   [(set (match_operand:SI 0 "register_operand" "=l")
2679         (div:SI (match_operand:SI 1 "register_operand" "d")
2680                 (match_operand:SI 2 "register_operand" "d")))
2681    (set (match_operand:SI 3 "register_operand" "=h")
2682         (mod:SI (match_dup 1)
2683                 (match_dup 2)))
2684    (clobber (match_scratch:SI 4 "=a"))]
2685   "optimize"
2686   "div\\t$0,%1,%2"
2687   [(set_attr "type"     "idiv")
2688    (set_attr "mode"     "SI")])
2689
2690 (define_expand "divmoddi4"
2691   [(set (match_operand:DI 0 "register_operand" "=d")
2692         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2693                 (match_operand:DI 2 "se_register_operand" "d")))
2694    (set (match_operand:DI 3 "register_operand" "=d")
2695         (mod:DI (match_dup 1)
2696                 (match_dup 2)))
2697    (clobber (match_scratch:DI 4 "=l"))
2698    (clobber (match_scratch:DI 5 "=h"))
2699    (clobber (match_scratch:DI 6 "=a"))]
2700   "TARGET_64BIT && optimize"
2701   "
2702 {
2703   emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
2704              operands[3]));
2705   if (!TARGET_NO_CHECK_ZERO_DIV)
2706     {
2707       emit_insn (gen_div_trap (operands[2],
2708                                GEN_INT (0),
2709                                GEN_INT (0x7)));
2710     }
2711   if (TARGET_CHECK_RANGE_DIV)
2712     {
2713       emit_insn (gen_div_trap (operands[2],
2714                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2715                                GEN_INT (0x6)));
2716       emit_insn (gen_div_trap (operands[2],
2717                                copy_to_mode_reg (DImode,
2718                                                  GEN_INT (BITMASK_HIGH)),
2719                                GEN_INT (0x6)));
2720     }
2721
2722   DONE;
2723 }")
2724
2725 (define_insn "divmoddi4_internal"
2726   [(set (match_operand:DI 0 "register_operand" "=l")
2727         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2728                 (match_operand:DI 2 "se_register_operand" "d")))
2729    (set (match_operand:DI 3 "register_operand" "=h")
2730         (mod:DI (match_dup 1)
2731                 (match_dup 2)))
2732    (clobber (match_scratch:DI 4 "=a"))]
2733   "TARGET_64BIT && optimize"
2734   "ddiv\\t$0,%1,%2"
2735   [(set_attr "type"     "idiv")
2736    (set_attr "mode"     "SI")])
2737
2738 (define_expand "udivmodsi4"
2739   [(set (match_operand:SI 0 "register_operand" "=d")
2740         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2741                  (match_operand:SI 2 "register_operand" "d")))
2742    (set (match_operand:SI 3 "register_operand" "=d")
2743         (umod:SI (match_dup 1)
2744                  (match_dup 2)))
2745    (clobber (match_scratch:SI 4 "=l"))
2746    (clobber (match_scratch:SI 5 "=h"))
2747    (clobber (match_scratch:SI 6 "=a"))]
2748   "optimize"
2749   "
2750 {
2751   emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
2752                                       operands[3]));
2753   if (!TARGET_NO_CHECK_ZERO_DIV)
2754     {
2755       emit_insn (gen_div_trap (operands[2],
2756                                GEN_INT (0),
2757                                GEN_INT (0x7)));
2758     }
2759
2760   DONE;
2761 }")
2762
2763 (define_insn "udivmodsi4_internal"
2764   [(set (match_operand:SI 0 "register_operand" "=l")
2765         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2766                  (match_operand:SI 2 "register_operand" "d")))
2767    (set (match_operand:SI 3 "register_operand" "=h")
2768         (umod:SI (match_dup 1)
2769                  (match_dup 2)))
2770    (clobber (match_scratch:SI 4 "=a"))]
2771   "optimize"
2772   "divu\\t$0,%1,%2"
2773   [(set_attr "type"     "idiv")
2774    (set_attr "mode"     "SI")])
2775
2776 (define_expand "udivmoddi4"
2777   [(set (match_operand:DI 0 "register_operand" "=d")
2778         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2779                  (match_operand:DI 2 "se_register_operand" "d")))
2780    (set (match_operand:DI 3 "register_operand" "=d")
2781         (umod:DI (match_dup 1)
2782                  (match_dup 2)))
2783    (clobber (match_scratch:DI 4 "=l"))
2784    (clobber (match_scratch:DI 5 "=h"))
2785    (clobber (match_scratch:DI 6 "=a"))]
2786   "TARGET_64BIT && optimize"
2787   "
2788 {
2789   emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
2790                                       operands[3]));
2791   if (!TARGET_NO_CHECK_ZERO_DIV)
2792     {
2793       emit_insn (gen_div_trap (operands[2],
2794                                GEN_INT (0),
2795                                GEN_INT (0x7)));
2796     }
2797
2798   DONE;
2799 }")
2800
2801 (define_insn "udivmoddi4_internal"
2802   [(set (match_operand:DI 0 "register_operand" "=l")
2803         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2804                  (match_operand:DI 2 "se_register_operand" "d")))
2805    (set (match_operand:DI 3 "register_operand" "=h")
2806         (umod:DI (match_dup 1)
2807                  (match_dup 2)))
2808    (clobber (match_scratch:DI 4 "=a"))]
2809   "TARGET_64BIT && optimize"
2810   "ddivu\\t$0,%1,%2"
2811   [(set_attr "type"     "idiv")
2812    (set_attr "mode"     "SI")])
2813
2814 ;; Division trap
2815
2816 (define_expand "div_trap"
2817   [(trap_if (eq (match_operand 0 "register_operand" "d")
2818                 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2819             (match_operand 2 "immediate_operand" ""))]
2820   ""
2821   "
2822 {
2823   if (TARGET_MIPS16)
2824     emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
2825   else
2826     emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
2827   DONE;
2828 }")
2829
2830 (define_insn "div_trap_normal"
2831   [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2832                 (match_operand 1 "true_reg_or_0_operand" "d,J"))
2833             (match_operand 2 "immediate_operand" ""))]
2834   "!TARGET_MIPS16"
2835   "*
2836 {
2837   rtx link;
2838   int have_dep_anti = 0;
2839
2840   /* For divmod if one division is not needed then we don't need an extra
2841      divide by zero trap, which is anti dependent on previous trap */
2842   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2843
2844     if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2845         && GET_CODE (XEXP (link, 0)) == INSN
2846         && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2847         && which_alternative == 1)
2848       have_dep_anti = 1;
2849   if (! have_dep_anti)
2850     {
2851       if (GENERATE_BRANCHLIKELY)
2852         {
2853           if (which_alternative == 1)
2854             return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2855           else
2856             return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2857         }
2858       else
2859         {
2860           if (which_alternative == 1)
2861             return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2862           else
2863             return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2864         }
2865     }
2866   return \"\";
2867 }"
2868   [(set_attr "type" "unknown")
2869    (set_attr "length" "12")])
2870
2871
2872 ;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
2873
2874 (define_insn "div_trap_mips16"
2875   [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2876                 (match_operand 1 "true_reg_or_0_operand" "d,J"))
2877             (match_operand 2 "immediate_operand" ""))
2878    (clobber (reg:SI 24))]
2879   "TARGET_MIPS16"
2880   "*
2881 {
2882   rtx link;
2883   int have_dep_anti = 0;
2884
2885   /* For divmod if one division is not needed then we don't need an extra
2886      divide by zero trap, which is anti dependent on previous trap */
2887   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2888
2889     if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2890         && GET_CODE (XEXP (link, 0)) == INSN
2891         && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2892         && which_alternative == 1)
2893       have_dep_anti = 1;
2894   if (! have_dep_anti)
2895     {
2896       /* No branch delay slots on mips16.  */
2897       if (which_alternative == 1)
2898         return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2899       else
2900         return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2901     }
2902   return \"\";
2903 }"
2904   [(set_attr "type" "unknown")
2905    (set_attr "length" "12")])
2906
2907 (define_expand "divsi3"
2908   [(set (match_operand:SI 0 "register_operand" "=l")
2909         (div:SI (match_operand:SI 1 "register_operand" "d")
2910                 (match_operand:SI 2 "register_operand" "d")))
2911    (clobber (match_scratch:SI 3 "=h"))
2912    (clobber (match_scratch:SI 4 "=a"))]
2913   "!optimize"
2914   "
2915 {
2916   emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
2917   if (!TARGET_NO_CHECK_ZERO_DIV)
2918     {
2919       emit_insn (gen_div_trap (operands[2],
2920                                GEN_INT (0),
2921                                GEN_INT (0x7)));
2922     }
2923   if (TARGET_CHECK_RANGE_DIV)
2924     {
2925       emit_insn (gen_div_trap (operands[2],
2926                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2927                                GEN_INT (0x6)));
2928       emit_insn (gen_div_trap (operands[2],
2929                                copy_to_mode_reg (SImode,
2930                                                  GEN_INT
2931                                                  (trunc_int_for_mode
2932                                                   (BITMASK_HIGH, SImode))),
2933                                GEN_INT (0x6)));
2934     }
2935
2936   DONE;
2937 }")
2938
2939 (define_insn "divsi3_internal"
2940   [(set (match_operand:SI 0 "register_operand" "=l")
2941         (div:SI (match_operand:SI 1 "register_operand" "d")
2942                 (match_operand:SI 2 "nonmemory_operand" "di")))
2943    (clobber (match_scratch:SI 3 "=h"))
2944    (clobber (match_scratch:SI 4 "=a"))]
2945   "!optimize"
2946   "div\\t$0,%1,%2"
2947   [(set_attr "type"     "idiv")
2948    (set_attr "mode"     "SI")])
2949
2950 (define_expand "divdi3"
2951   [(set (match_operand:DI 0 "register_operand" "=l")
2952         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2953                 (match_operand:DI 2 "se_register_operand" "d")))
2954    (clobber (match_scratch:DI 3 "=h"))
2955    (clobber (match_scratch:DI 4 "=a"))]
2956   "TARGET_64BIT && !optimize"
2957   "
2958 {
2959   emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
2960   if (!TARGET_NO_CHECK_ZERO_DIV)
2961     {
2962       emit_insn (gen_div_trap (operands[2],
2963                                GEN_INT (0),
2964                                GEN_INT (0x7)));
2965     }
2966   if (TARGET_CHECK_RANGE_DIV)
2967     {
2968       emit_insn (gen_div_trap (operands[2],
2969                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2970                                GEN_INT (0x6)));
2971       emit_insn (gen_div_trap (operands[2],
2972                                copy_to_mode_reg (DImode,
2973                                                  GEN_INT (BITMASK_HIGH)),
2974                                GEN_INT (0x6)));
2975     }
2976
2977   DONE;
2978 }")
2979
2980 (define_insn "divdi3_internal"
2981   [(set (match_operand:DI 0 "register_operand" "=l")
2982         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2983                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2984    (clobber (match_scratch:SI 3 "=h"))
2985    (clobber (match_scratch:SI 4 "=a"))]
2986   "TARGET_64BIT && !optimize"
2987   "ddiv\\t$0,%1,%2"
2988   [(set_attr "type"     "idiv")
2989    (set_attr "mode"     "DI")])
2990
2991 (define_expand "modsi3"
2992   [(set (match_operand:SI 0 "register_operand" "=h")
2993         (mod:SI (match_operand:SI 1 "register_operand" "d")
2994                 (match_operand:SI 2 "register_operand" "d")))
2995    (clobber (match_scratch:SI 3 "=l"))
2996    (clobber (match_scratch:SI 4 "=a"))]
2997   "!optimize"
2998   "
2999 {
3000   emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
3001   if (!TARGET_NO_CHECK_ZERO_DIV)
3002     {
3003       emit_insn (gen_div_trap (operands[2],
3004                                GEN_INT (0),
3005                                GEN_INT (0x7)));
3006     }
3007   if (TARGET_CHECK_RANGE_DIV)
3008     {
3009       emit_insn (gen_div_trap (operands[2],
3010                                copy_to_mode_reg (SImode, GEN_INT (-1)),
3011                                GEN_INT (0x6)));
3012       emit_insn (gen_div_trap (operands[2],
3013                                copy_to_mode_reg (SImode,
3014                                                  GEN_INT
3015                                                  (trunc_int_for_mode
3016                                                   (BITMASK_HIGH, SImode))),
3017                                GEN_INT (0x6)));
3018     }
3019
3020   DONE;
3021 }")
3022
3023 (define_insn "modsi3_internal"
3024   [(set (match_operand:SI 0 "register_operand" "=h")
3025         (mod:SI (match_operand:SI 1 "register_operand" "d")
3026                 (match_operand:SI 2 "nonmemory_operand" "di")))
3027    (clobber (match_scratch:SI 3 "=l"))
3028    (clobber (match_scratch:SI 4 "=a"))]
3029   "!optimize"
3030   "div\\t$0,%1,%2"
3031   [(set_attr "type"     "idiv")
3032    (set_attr "mode"     "SI")])
3033
3034 (define_expand "moddi3"
3035   [(set (match_operand:DI 0 "register_operand" "=h")
3036         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
3037                 (match_operand:DI 2 "se_register_operand" "d")))
3038    (clobber (match_scratch:DI 3 "=l"))
3039    (clobber (match_scratch:DI 4 "=a"))]
3040   "TARGET_64BIT && !optimize"
3041   "
3042 {
3043   emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
3044   if (!TARGET_NO_CHECK_ZERO_DIV)
3045     {
3046       emit_insn (gen_div_trap (operands[2],
3047                                GEN_INT (0),
3048                                GEN_INT (0x7)));
3049     }
3050   if (TARGET_CHECK_RANGE_DIV)
3051     {
3052       emit_insn (gen_div_trap (operands[2],
3053                                copy_to_mode_reg (DImode, GEN_INT (-1)),
3054                                GEN_INT (0x6)));
3055       emit_insn (gen_div_trap (operands[2],
3056                                copy_to_mode_reg (DImode,
3057                                                  GEN_INT (BITMASK_HIGH)),
3058                                GEN_INT (0x6)));
3059     }
3060
3061   DONE;
3062 }")
3063
3064 (define_insn "moddi3_internal"
3065   [(set (match_operand:DI 0 "register_operand" "=h")
3066         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
3067                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
3068    (clobber (match_scratch:SI 3 "=l"))
3069    (clobber (match_scratch:SI 4 "=a"))]
3070   "TARGET_64BIT && !optimize"
3071   "ddiv\\t$0,%1,%2"
3072   [(set_attr "type"     "idiv")
3073    (set_attr "mode"     "DI")])
3074
3075 (define_expand "udivsi3"
3076   [(set (match_operand:SI 0 "register_operand" "=l")
3077         (udiv:SI (match_operand:SI 1 "register_operand" "d")
3078                  (match_operand:SI 2 "register_operand" "d")))
3079    (clobber (match_scratch:SI 3 "=h"))
3080    (clobber (match_scratch:SI 4 "=a"))]
3081   "!optimize"
3082   "
3083 {
3084   emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
3085   if (!TARGET_NO_CHECK_ZERO_DIV)
3086     {
3087       emit_insn (gen_div_trap (operands[2],
3088                                GEN_INT (0),
3089                                GEN_INT (0x7)));
3090     }
3091
3092   DONE;
3093 }")
3094
3095 (define_insn "udivsi3_internal"
3096   [(set (match_operand:SI 0 "register_operand" "=l")
3097         (udiv:SI (match_operand:SI 1 "register_operand" "d")
3098                  (match_operand:SI 2 "nonmemory_operand" "di")))
3099    (clobber (match_scratch:SI 3 "=h"))
3100    (clobber (match_scratch:SI 4 "=a"))]
3101   "!optimize"
3102   "divu\\t$0,%1,%2"
3103   [(set_attr "type"     "idiv")
3104    (set_attr "mode"     "SI")])
3105
3106 (define_expand "udivdi3"
3107   [(set (match_operand:DI 0 "register_operand" "=l")
3108         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
3109                  (match_operand:DI 2 "se_register_operand" "di")))
3110    (clobber (match_scratch:DI 3 "=h"))
3111    (clobber (match_scratch:DI 4 "=a"))]
3112   "TARGET_64BIT && !optimize"
3113   "
3114 {
3115   emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
3116   if (!TARGET_NO_CHECK_ZERO_DIV)
3117     {
3118       emit_insn (gen_div_trap (operands[2],
3119                                GEN_INT (0),
3120                                GEN_INT (0x7)));
3121     }
3122
3123   DONE;
3124 }")
3125
3126 (define_insn "udivdi3_internal"
3127   [(set (match_operand:DI 0 "register_operand" "=l")
3128         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
3129                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
3130    (clobber (match_scratch:SI 3 "=h"))
3131    (clobber (match_scratch:SI 4 "=a"))]
3132   "TARGET_64BIT && !optimize"
3133   "ddivu\\t$0,%1,%2"
3134   [(set_attr "type"     "idiv")
3135    (set_attr "mode"     "DI")])
3136
3137 (define_expand "umodsi3"
3138   [(set (match_operand:SI 0 "register_operand" "=h")
3139         (umod:SI (match_operand:SI 1 "register_operand" "d")
3140                  (match_operand:SI 2 "register_operand" "d")))
3141    (clobber (match_scratch:SI 3 "=l"))
3142    (clobber (match_scratch:SI 4 "=a"))]
3143   "!optimize"
3144   "
3145 {
3146   emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
3147   if (!TARGET_NO_CHECK_ZERO_DIV)
3148     {
3149       emit_insn (gen_div_trap (operands[2],
3150                                GEN_INT (0),
3151                                GEN_INT (0x7)));
3152     }
3153
3154   DONE;
3155 }")
3156
3157 (define_insn "umodsi3_internal"
3158   [(set (match_operand:SI 0 "register_operand" "=h")
3159         (umod:SI (match_operand:SI 1 "register_operand" "d")
3160                  (match_operand:SI 2 "nonmemory_operand" "di")))
3161    (clobber (match_scratch:SI 3 "=l"))
3162    (clobber (match_scratch:SI 4 "=a"))]
3163   "!optimize"
3164   "divu\\t$0,%1,%2"
3165   [(set_attr "type"     "idiv")
3166    (set_attr "mode"     "SI")])
3167
3168 (define_expand "umoddi3"
3169   [(set (match_operand:DI 0 "register_operand" "=h")
3170         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
3171                  (match_operand:DI 2 "se_register_operand" "di")))
3172    (clobber (match_scratch:DI 3 "=l"))
3173    (clobber (match_scratch:DI 4 "=a"))]
3174   "TARGET_64BIT && !optimize"
3175   "
3176 {
3177   emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
3178   if (!TARGET_NO_CHECK_ZERO_DIV)
3179     {
3180       emit_insn (gen_div_trap (operands[2],
3181                                GEN_INT (0),
3182                                GEN_INT (0x7)));
3183     }
3184
3185   DONE;
3186 }")
3187
3188 (define_insn "umoddi3_internal"
3189   [(set (match_operand:DI 0 "register_operand" "=h")
3190         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
3191                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
3192    (clobber (match_scratch:SI 3 "=l"))
3193    (clobber (match_scratch:SI 4 "=a"))]
3194   "TARGET_64BIT && !optimize"
3195   "ddivu\\t$0,%1,%2"
3196   [(set_attr "type"     "idiv")
3197    (set_attr "mode"     "DI")])
3198 \f
3199 ;;
3200 ;;  ....................
3201 ;;
3202 ;;      SQUARE ROOT
3203 ;;
3204 ;;  ....................
3205
3206 (define_insn "sqrtdf2"
3207   [(set (match_operand:DF 0 "register_operand" "=f")
3208         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
3209   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
3210   "sqrt.d\\t%0,%1"
3211   [(set_attr "type"     "fsqrt")
3212    (set_attr "mode"     "DF")])
3213
3214 (define_insn "sqrtsf2"
3215   [(set (match_operand:SF 0 "register_operand" "=f")
3216         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
3217   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
3218   "sqrt.s\\t%0,%1"
3219   [(set_attr "type"     "fsqrt")
3220    (set_attr "mode"     "SF")])
3221
3222 (define_insn ""
3223   [(set (match_operand:DF 0 "register_operand" "=f")
3224         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
3225                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
3226   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
3227   "rsqrt.d\\t%0,%2"
3228   [(set_attr "type"     "frsqrt")
3229    (set_attr "mode"     "DF")])
3230
3231 (define_insn ""
3232   [(set (match_operand:SF 0 "register_operand" "=f")
3233         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
3234                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
3235   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
3236   "rsqrt.s\\t%0,%2"
3237   [(set_attr "type"     "frsqrt")
3238    (set_attr "mode"     "SF")])
3239
3240 \f
3241 ;;
3242 ;;  ....................
3243 ;;
3244 ;;      ABSOLUTE VALUE
3245 ;;
3246 ;;  ....................
3247
3248 ;; Do not use the integer abs macro instruction, since that signals an
3249 ;; exception on -2147483648 (sigh).
3250
3251 (define_insn "abssi2"
3252   [(set (match_operand:SI 0 "register_operand" "=d")
3253         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
3254   "!TARGET_MIPS16"
3255   "*
3256 {
3257   dslots_jump_total++;
3258   dslots_jump_filled++;
3259   operands[2] = const0_rtx;
3260
3261   if (REGNO (operands[0]) == REGNO (operands[1]))
3262     {
3263       if (GENERATE_BRANCHLIKELY)
3264         return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
3265       else
3266         return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
3267     }
3268   else
3269     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
3270 }"
3271   [(set_attr "type"     "multi")
3272    (set_attr "mode"     "SI")
3273    (set_attr "length"   "12")])
3274
3275 (define_insn "absdi2"
3276   [(set (match_operand:DI 0 "register_operand" "=d")
3277         (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
3278   "TARGET_64BIT && !TARGET_MIPS16"
3279   "*
3280 {
3281   unsigned int regno1;
3282   dslots_jump_total++;
3283   dslots_jump_filled++;
3284   operands[2] = const0_rtx;
3285
3286   if (GET_CODE (operands[1]) == REG)
3287     regno1 = REGNO (operands[1]);
3288   else
3289     regno1 = REGNO (XEXP (operands[1], 0));
3290
3291   if (REGNO (operands[0]) == regno1)
3292     return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3293   else
3294     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3295 }"
3296   [(set_attr "type"     "multi")
3297    (set_attr "mode"     "DI")
3298    (set_attr "length"   "12")])
3299
3300 (define_insn "absdf2"
3301   [(set (match_operand:DF 0 "register_operand" "=f")
3302         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
3303   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3304   "abs.d\\t%0,%1"
3305   [(set_attr "type"     "fabs")
3306    (set_attr "mode"     "DF")])
3307
3308 (define_insn "abssf2"
3309   [(set (match_operand:SF 0 "register_operand" "=f")
3310         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
3311   "TARGET_HARD_FLOAT"
3312   "abs.s\\t%0,%1"
3313   [(set_attr "type"     "fabs")
3314    (set_attr "mode"     "SF")])
3315
3316 \f
3317 ;;
3318 ;;  ....................
3319 ;;
3320 ;;      FIND FIRST BIT INSTRUCTION
3321 ;;
3322 ;;  ....................
3323 ;;
3324
3325 (define_insn "ffssi2"
3326   [(set (match_operand:SI 0 "register_operand" "=&d")
3327         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
3328    (clobber (match_scratch:SI 2 "=&d"))
3329    (clobber (match_scratch:SI 3 "=&d"))]
3330   "!TARGET_MIPS16"
3331   "*
3332 {
3333   dslots_jump_total += 2;
3334   dslots_jump_filled += 2;
3335   operands[4] = const0_rtx;
3336
3337   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3338     return \"%(\\
3339 move\\t%0,%z4\\n\\
3340 \\tbeq\\t%1,%z4,2f\\n\\
3341 %~1:\\tand\\t%2,%1,0x0001\\n\\
3342 \\taddu\\t%0,%0,1\\n\\
3343 \\tbeq\\t%2,%z4,1b\\n\\
3344 \\tsrl\\t%1,%1,1\\n\\
3345 %~2:%)\";
3346
3347   return \"%(\\
3348 move\\t%0,%z4\\n\\
3349 \\tmove\\t%3,%1\\n\\
3350 \\tbeq\\t%3,%z4,2f\\n\\
3351 %~1:\\tand\\t%2,%3,0x0001\\n\\
3352 \\taddu\\t%0,%0,1\\n\\
3353 \\tbeq\\t%2,%z4,1b\\n\\
3354 \\tsrl\\t%3,%3,1\\n\\
3355 %~2:%)\";
3356 }"
3357   [(set_attr "type"     "multi")
3358    (set_attr "mode"     "SI")
3359    (set_attr "length"   "12")])
3360
3361 (define_insn "ffsdi2"
3362   [(set (match_operand:DI 0 "register_operand" "=&d")
3363         (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
3364    (clobber (match_scratch:DI 2 "=&d"))
3365    (clobber (match_scratch:DI 3 "=&d"))]
3366   "TARGET_64BIT && !TARGET_MIPS16"
3367   "*
3368 {
3369   dslots_jump_total += 2;
3370   dslots_jump_filled += 2;
3371   operands[4] = const0_rtx;
3372
3373   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3374     return \"%(\\
3375 move\\t%0,%z4\\n\\
3376 \\tbeq\\t%1,%z4,2f\\n\\
3377 %~1:\\tand\\t%2,%1,0x0001\\n\\
3378 \\tdaddu\\t%0,%0,1\\n\\
3379 \\tbeq\\t%2,%z4,1b\\n\\
3380 \\tdsrl\\t%1,%1,1\\n\\
3381 %~2:%)\";
3382
3383   return \"%(\\
3384 move\\t%0,%z4\\n\\
3385 \\tmove\\t%3,%1\\n\\
3386 \\tbeq\\t%3,%z4,2f\\n\\
3387 %~1:\\tand\\t%2,%3,0x0001\\n\\
3388 \\tdaddu\\t%0,%0,1\\n\\
3389 \\tbeq\\t%2,%z4,1b\\n\\
3390 \\tdsrl\\t%3,%3,1\\n\\
3391 %~2:%)\";
3392 }"
3393   [(set_attr "type"     "multi")
3394    (set_attr "mode"     "DI")
3395    (set_attr "length"   "24")])
3396
3397 \f
3398 ;;
3399 ;;  ....................
3400 ;;
3401 ;;      NEGATION and ONE'S COMPLEMENT
3402 ;;
3403 ;;  ....................
3404
3405 (define_insn "negsi2"
3406   [(set (match_operand:SI 0 "register_operand" "=d")
3407         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
3408   ""
3409   "*
3410 {
3411   if (TARGET_MIPS16)
3412     return \"neg\\t%0,%1\";
3413   operands[2] = const0_rtx;
3414   return \"subu\\t%0,%z2,%1\";
3415 }"
3416   [(set_attr "type"     "arith")
3417    (set_attr "mode"     "SI")])
3418
3419 (define_expand "negdi2"
3420   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
3421                    (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
3422               (clobber (match_dup 2))])]
3423   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3424   "
3425 {
3426   if (TARGET_64BIT)
3427     {
3428       emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
3429       DONE;
3430     }
3431
3432   operands[2] = gen_reg_rtx (SImode);
3433 }")
3434
3435 (define_insn "negdi2_internal"
3436   [(set (match_operand:DI 0 "register_operand" "=d")
3437         (neg:DI (match_operand:DI 1 "register_operand" "d")))
3438    (clobber (match_operand:SI 2 "register_operand" "=d"))]
3439   "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
3440   "*
3441 {
3442   operands[3] = const0_rtx;
3443   return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
3444 }"
3445   [(set_attr "type"     "darith")
3446    (set_attr "mode"     "DI")
3447    (set_attr "length"   "16")])
3448
3449 (define_insn "negdi2_internal_2"
3450   [(set (match_operand:DI 0 "register_operand" "=d")
3451         (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
3452   "TARGET_64BIT && !TARGET_MIPS16"
3453   "*
3454 {
3455   operands[2] = const0_rtx;
3456   return \"dsubu\\t%0,%z2,%1\";
3457 }"
3458   [(set_attr "type"     "arith")
3459    (set_attr "mode"     "DI")])
3460
3461 (define_insn "negdf2"
3462   [(set (match_operand:DF 0 "register_operand" "=f")
3463         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3464   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3465   "neg.d\\t%0,%1"
3466   [(set_attr "type"     "fneg")
3467    (set_attr "mode"     "DF")])
3468
3469 (define_insn "negsf2"
3470   [(set (match_operand:SF 0 "register_operand" "=f")
3471         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3472   "TARGET_HARD_FLOAT"
3473   "neg.s\\t%0,%1"
3474   [(set_attr "type"     "fneg")
3475    (set_attr "mode"     "SF")])
3476
3477 (define_insn "one_cmplsi2"
3478   [(set (match_operand:SI 0 "register_operand" "=d")
3479         (not:SI (match_operand:SI 1 "register_operand" "d")))]
3480   ""
3481   "*
3482 {
3483   if (TARGET_MIPS16)
3484     return \"not\\t%0,%1\";
3485   operands[2] = const0_rtx;
3486   return \"nor\\t%0,%z2,%1\";
3487 }"
3488   [(set_attr "type"     "arith")
3489    (set_attr "mode"     "SI")])
3490
3491 (define_insn "one_cmpldi2"
3492   [(set (match_operand:DI 0 "register_operand" "=d")
3493         (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
3494   ""
3495   "*
3496 {
3497   if (TARGET_MIPS16)
3498     {
3499       if (TARGET_64BIT)
3500         return \"not\\t%0,%1\";
3501       return \"not\\t%M0,%M1\;not\\t%L0,%L1\";
3502     }
3503   operands[2] = const0_rtx;
3504   if (TARGET_64BIT)
3505     return \"nor\\t%0,%z2,%1\";
3506   return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
3507 }"
3508   [(set_attr "type"     "darith")
3509    (set_attr "mode"     "DI")
3510    (set (attr "length")
3511         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3512                        (const_int 4)
3513                        (const_int 8)))])
3514
3515 (define_split
3516   [(set (match_operand:DI 0 "register_operand" "")
3517         (not:DI (match_operand:DI 1 "register_operand" "")))]
3518   "reload_completed && !TARGET_64BIT
3519    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3520    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3521    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3522
3523   [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
3524    (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))]
3525   "")
3526
3527 \f
3528 ;;
3529 ;;  ....................
3530 ;;
3531 ;;      LOGICAL
3532 ;;
3533 ;;  ....................
3534 ;;
3535
3536 ;; Many of these instructions uses trivial define_expands, because we
3537 ;; want to use a different set of constraints when TARGET_MIPS16.
3538
3539 (define_expand "andsi3"
3540   [(set (match_operand:SI 0 "register_operand" "=d,d")
3541         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3542                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3543   ""
3544   "
3545 {
3546   if (TARGET_MIPS16)
3547     {
3548       operands[1] = force_reg (SImode, operands[1]);
3549       operands[2] = force_reg (SImode, operands[2]);
3550     }
3551 }")
3552
3553 (define_insn ""
3554   [(set (match_operand:SI 0 "register_operand" "=d,d")
3555         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3556                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3557   "!TARGET_MIPS16"
3558   "@
3559    and\\t%0,%1,%2
3560    andi\\t%0,%1,%x2"
3561   [(set_attr "type"     "arith")
3562    (set_attr "mode"     "SI")])
3563
3564 (define_insn ""
3565   [(set (match_operand:SI 0 "register_operand" "=d")
3566         (and:SI (match_operand:SI 1 "register_operand" "%0")
3567                 (match_operand:SI 2 "register_operand" "d")))]
3568   "TARGET_MIPS16"
3569   "and\\t%0,%2"
3570   [(set_attr "type"     "arith")
3571    (set_attr "mode"     "SI")])
3572
3573 (define_expand "anddi3"
3574   [(set (match_operand:DI 0 "register_operand" "=d")
3575         (and:DI (match_operand:DI 1 "se_register_operand" "d")
3576                 (match_operand:DI 2 "se_register_operand" "d")))]
3577   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3578   "
3579 {
3580   if (TARGET_MIPS16)
3581     {
3582       operands[1] = force_reg (DImode, operands[1]);
3583       operands[2] = force_reg (DImode, operands[2]);
3584     }
3585 }")
3586
3587 (define_insn ""
3588   [(set (match_operand:DI 0 "register_operand" "=d")
3589         (and:DI (match_operand:DI 1 "se_register_operand" "d")
3590                 (match_operand:DI 2 "se_register_operand" "d")))]
3591   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3592   "*
3593 {
3594   if (TARGET_64BIT)
3595     return \"and\\t%0,%1,%2\";
3596   return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
3597 }"
3598   [(set_attr "type"     "darith")
3599    (set_attr "mode"     "DI")
3600    (set (attr "length")
3601         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3602                        (const_int 4)
3603                        (const_int 8)))])
3604
3605 (define_insn ""
3606   [(set (match_operand:DI 0 "register_operand" "=d")
3607         (and:DI (match_operand:DI 1 "se_register_operand" "0")
3608                 (match_operand:DI 2 "se_register_operand" "d")))]
3609   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3610   "*
3611 {
3612   if (TARGET_64BIT)
3613     return \"and\\t%0,%2\";
3614   return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
3615 }"
3616   [(set_attr "type"     "darith")
3617    (set_attr "mode"     "DI")
3618    (set (attr "length")
3619         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3620                        (const_int 4)
3621                        (const_int 8)))])
3622
3623 (define_split
3624   [(set (match_operand:DI 0 "register_operand" "")
3625         (and:DI (match_operand:DI 1 "register_operand" "")
3626                 (match_operand:DI 2 "register_operand" "")))]
3627   "reload_completed && !TARGET_64BIT
3628    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3629    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3630    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3631    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3632
3633   [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3634    (set (subreg:SI (match_dup 0) 4) (and:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3635   "")
3636
3637 (define_insn "anddi3_internal1"
3638   [(set (match_operand:DI 0 "register_operand" "=d,d")
3639         (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
3640                 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
3641   "TARGET_64BIT && !TARGET_MIPS16"
3642   "@
3643    and\\t%0,%1,%2
3644    andi\\t%0,%1,%x2"
3645   [(set_attr "type"     "arith")
3646    (set_attr "mode"     "DI")])
3647
3648 (define_expand "iorsi3"
3649   [(set (match_operand:SI 0 "register_operand" "=d,d")
3650         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3651                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3652   ""
3653   "
3654 {
3655   if (TARGET_MIPS16)
3656     {
3657       operands[1] = force_reg (SImode, operands[1]);
3658       operands[2] = force_reg (SImode, operands[2]);
3659     }
3660 }")
3661
3662 (define_insn ""
3663   [(set (match_operand:SI 0 "register_operand" "=d,d")
3664         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3665                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3666   "!TARGET_MIPS16"
3667   "@
3668    or\\t%0,%1,%2
3669    ori\\t%0,%1,%x2"
3670   [(set_attr "type"     "arith")
3671    (set_attr "mode"     "SI")])
3672
3673 (define_insn ""
3674   [(set (match_operand:SI 0 "register_operand" "=d")
3675         (ior:SI (match_operand:SI 1 "register_operand" "%0")
3676                 (match_operand:SI 2 "register_operand" "d")))]
3677   "TARGET_MIPS16"
3678   "or\\t%0,%2"
3679   [(set_attr "type"     "arith")
3680    (set_attr "mode"     "SI")])
3681
3682 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
3683 ;;; TARGET_64BIT
3684
3685 (define_expand "iordi3"
3686   [(set (match_operand:DI 0 "register_operand" "=d")
3687         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3688                 (match_operand:DI 2 "se_register_operand" "d")))]
3689   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3690   "")
3691
3692 (define_insn ""
3693   [(set (match_operand:DI 0 "register_operand" "=d")
3694         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3695                 (match_operand:DI 2 "se_register_operand" "d")))]
3696   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3697   "*
3698 {
3699   if (TARGET_64BIT)
3700     return \"or\\t%0,%1,%2\";
3701   return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
3702 }"
3703   [(set_attr "type"     "darith")
3704    (set_attr "mode"     "DI")
3705    (set (attr "length")
3706         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3707                        (const_int 4)
3708                        (const_int 8)))])
3709
3710 (define_insn ""
3711   [(set (match_operand:DI 0 "register_operand" "=d")
3712         (ior:DI (match_operand:DI 1 "se_register_operand" "0")
3713                 (match_operand:DI 2 "se_register_operand" "d")))]
3714   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3715   "*
3716 {
3717   if (TARGET_64BIT)
3718     return \"or\\t%0,%2\";
3719   return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
3720 }"
3721   [(set_attr "type"     "darith")
3722    (set_attr "mode"     "DI")
3723    (set (attr "length")
3724         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3725                        (const_int 4)
3726                        (const_int 8)))])
3727
3728 (define_split
3729   [(set (match_operand:DI 0 "register_operand" "")
3730         (ior:DI (match_operand:DI 1 "register_operand" "")
3731                 (match_operand:DI 2 "register_operand" "")))]
3732   "reload_completed && !TARGET_64BIT
3733    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3734    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3735    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3736    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3737
3738   [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3739    (set (subreg:SI (match_dup 0) 4) (ior:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3740   "")
3741
3742 (define_expand "xorsi3"
3743   [(set (match_operand:SI 0 "register_operand" "=d,d")
3744         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3745                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3746   ""
3747   "")
3748
3749 (define_insn ""
3750   [(set (match_operand:SI 0 "register_operand" "=d,d")
3751         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3752                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3753   "!TARGET_MIPS16"
3754   "@
3755    xor\\t%0,%1,%2
3756    xori\\t%0,%1,%x2"
3757   [(set_attr "type"     "arith")
3758    (set_attr "mode"     "SI")])
3759
3760 (define_insn ""
3761   [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3762         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3763                 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3764   "TARGET_MIPS16"
3765   "@
3766    xor\\t%0,%2
3767    cmpi\\t%1,%2
3768    cmp\\t%1,%2"
3769   [(set_attr "type"     "arith")
3770    (set_attr "mode"     "SI")
3771    (set_attr_alternative "length"
3772                 [(const_int 4)
3773                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3774                                (const_int 4)
3775                                (const_int 8))
3776                  (const_int 4)])])
3777
3778 ;; ??? If delete the 32-bit long long patterns, then could merge this with
3779 ;; the following xordi3_internal pattern.
3780 (define_expand "xordi3"
3781   [(set (match_operand:DI 0 "register_operand" "=d")
3782         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3783                 (match_operand:DI 2 "se_register_operand" "d")))]
3784   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3785   "")
3786
3787 (define_insn ""
3788   [(set (match_operand:DI 0 "register_operand" "=d")
3789         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3790                 (match_operand:DI 2 "se_register_operand" "d")))]
3791   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3792   "*
3793 {
3794   if (TARGET_64BIT)
3795     return \"xor\\t%0,%1,%2\";
3796   return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
3797 }"
3798   [(set_attr "type"     "darith")
3799    (set_attr "mode"     "DI")
3800    (set (attr "length")
3801         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3802                        (const_int 4)
3803                        (const_int 8)))])
3804
3805 (define_insn ""
3806   [(set (match_operand:DI 0 "register_operand" "=d")
3807         (xor:DI (match_operand:DI 1 "se_register_operand" "0")
3808                 (match_operand:DI 2 "se_register_operand" "d")))]
3809   "!TARGET_64BIT && TARGET_MIPS16"
3810   "xor\\t%M0,%M2\;xor\\t%L0,%L2"
3811   [(set_attr "type"     "darith")
3812    (set_attr "mode"     "DI")
3813    (set_attr "length"   "8")])
3814
3815 (define_insn ""
3816   [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3817         (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
3818                 (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
3819   "TARGET_64BIT && TARGET_MIPS16"
3820   "@
3821    xor\\t%0,%2
3822    cmpi\\t%1,%2
3823    cmp\\t%1,%2"
3824   [(set_attr "type"     "arith")
3825    (set_attr "mode"     "DI")
3826    (set_attr_alternative "length"
3827                 [(const_int 4)
3828                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3829                                (const_int 4)
3830                                (const_int 8))
3831                  (const_int 4)])])
3832
3833 (define_split
3834   [(set (match_operand:DI 0 "register_operand" "")
3835         (xor:DI (match_operand:DI 1 "register_operand" "")
3836                 (match_operand:DI 2 "register_operand" "")))]
3837   "reload_completed && !TARGET_64BIT
3838    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3839    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3840    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3841    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3842
3843   [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3844    (set (subreg:SI (match_dup 0) 4) (xor:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3845   "")
3846
3847 (define_insn "xordi3_immed"
3848   [(set (match_operand:DI 0 "register_operand" "=d")
3849         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3850                 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
3851   "TARGET_64BIT && !TARGET_MIPS16"
3852   "xori\\t%0,%1,%x2"
3853   [(set_attr "type"     "arith")
3854    (set_attr "mode"     "DI")])
3855
3856 (define_insn "*norsi3"
3857   [(set (match_operand:SI 0 "register_operand" "=d")
3858         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3859                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3860   "!TARGET_MIPS16"
3861   "nor\\t%0,%z1,%z2"
3862   [(set_attr "type"     "arith")
3863    (set_attr "mode"     "SI")])
3864
3865 (define_insn "*nordi3"
3866   [(set (match_operand:DI 0 "register_operand" "=d")
3867         (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
3868                 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
3869   "!TARGET_MIPS16"
3870   "*
3871 {
3872   if (TARGET_64BIT)
3873     return \"nor\\t%0,%z1,%z2\";
3874   return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
3875 }"
3876   [(set_attr "type"     "darith")
3877    (set_attr "mode"     "DI")
3878    (set (attr "length")
3879         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3880                        (const_int 4)
3881                        (const_int 8)))])
3882
3883 (define_split
3884   [(set (match_operand:DI 0 "register_operand" "")
3885         (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
3886                 (not:DI (match_operand:DI 2 "register_operand" ""))))]
3887   "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT
3888    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3889    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3890    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3891    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3892
3893   [(set (subreg:SI (match_dup 0) 0) (and:SI (not:SI (subreg:SI (match_dup 1) 0)) (not:SI (subreg:SI (match_dup 2) 0))))
3894    (set (subreg:SI (match_dup 0) 4) (and:SI (not:SI (subreg:SI (match_dup 1) 4)) (not:SI (subreg:SI (match_dup 2) 4))))]
3895   "")
3896 \f
3897 ;;
3898 ;;  ....................
3899 ;;
3900 ;;      TRUNCATION
3901 ;;
3902 ;;  ....................
3903
3904 (define_insn "truncdfsf2"
3905   [(set (match_operand:SF 0 "register_operand" "=f")
3906         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3907   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3908   "cvt.s.d\\t%0,%1"
3909   [(set_attr "type"     "fcvt")
3910    (set_attr "mode"     "SF")])
3911
3912 (define_insn "truncdisi2"
3913   [(set (match_operand:SI 0 "register_operand" "=d")
3914         (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
3915   "TARGET_64BIT"
3916   "*
3917 {
3918   if (TARGET_MIPS16)
3919     return \"dsll\\t%0,%1,32\;dsra\\t%0,32\";
3920   return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
3921 }"
3922   [(set_attr "type"     "darith")
3923    (set_attr "mode"     "SI")
3924    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3925                                       (const_int 8)
3926                                       (const_int 16)))])
3927
3928 (define_insn "truncdihi2"
3929   [(set (match_operand:HI 0 "register_operand" "=d")
3930         (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
3931   "TARGET_64BIT"
3932   "*
3933 {
3934   if (TARGET_MIPS16)
3935     return \"dsll\\t%0,%1,48\;dsra\\t%0,48\";
3936   return \"andi\\t%0,%1,0xffff\";
3937 }"
3938   [(set_attr "type"     "darith")
3939    (set_attr "mode"     "HI")
3940    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3941                                       (const_int 4)
3942                                       (const_int 16)))])
3943 (define_insn "truncdiqi2"
3944   [(set (match_operand:QI 0 "register_operand" "=d")
3945         (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
3946   "TARGET_64BIT"
3947   "*
3948 {
3949   if (TARGET_MIPS16)
3950     return \"dsll\\t%0,%1,56\;dsra\\t%0,56\";
3951   return \"andi\\t%0,%1,0x00ff\";
3952 }"
3953   [(set_attr "type"     "darith")
3954    (set_attr "mode"     "QI")
3955    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3956                                       (const_int 4)
3957                                       (const_int 16)))])
3958
3959 ;; Combiner patterns to optimize shift/truncate combinations.
3960 (define_insn ""
3961   [(set (match_operand:SI 0 "register_operand" "=d")
3962         (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3963                                   (match_operand:DI 2 "small_int" "I"))))]
3964   "TARGET_64BIT && !TARGET_MIPS16"
3965   "*
3966 {
3967   int shift_amt = INTVAL (operands[2]) & 0x3f;
3968
3969   if (shift_amt < 32)
3970     {
3971       operands[2] = GEN_INT (32 - shift_amt);
3972       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3973     }
3974   else
3975     {
3976       operands[2] = GEN_INT (shift_amt);
3977       return \"dsra\\t%0,%1,%2\";
3978     }
3979 }"
3980   [(set_attr "type"     "darith")
3981    (set_attr "mode"     "SI")
3982    (set_attr "length"   "8")])
3983
3984 (define_insn ""
3985   [(set (match_operand:SI 0 "register_operand" "=d")
3986         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3987                                   (match_operand:DI 2 "small_int" "I"))))]
3988   "TARGET_64BIT && !TARGET_MIPS16"
3989   "*
3990 {
3991   int shift_amt = INTVAL (operands[2]) & 0x3f;
3992
3993   if (shift_amt < 32)
3994     {
3995       operands[2] = GEN_INT (32 - shift_amt);
3996       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3997     }
3998   else if (shift_amt == 32)
3999     return \"dsra\\t%0,%1,32\";
4000   else
4001     {
4002       operands[2] = GEN_INT (shift_amt);
4003       return \"dsrl\\t%0,%1,%2\";
4004     }
4005 }"
4006   [(set_attr "type"     "darith")
4007    (set_attr "mode"     "SI")
4008    (set_attr "length"   "8")])
4009
4010 (define_insn ""
4011   [(set (match_operand:SI 0 "register_operand" "=d")
4012         (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
4013                                 (match_operand:DI 2 "small_int" "I"))))]
4014   "TARGET_64BIT"
4015   "*
4016 {
4017   int shift_amt = INTVAL (operands[2]) & 0x3f;
4018
4019   if (shift_amt < 32)
4020     {
4021       operands[2] = GEN_INT (32 + shift_amt);
4022       if (TARGET_MIPS16)
4023         return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\";
4024       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
4025     }
4026   else
4027     return \"move\\t%0,%.\";
4028 }"
4029   [(set_attr "type"     "darith")
4030    (set_attr "mode"     "SI")
4031    (set_attr "length"   "8")])
4032
4033 ;; Combiner patterns to optimize truncate/zero_extend combinations.
4034
4035 (define_insn ""
4036   [(set (match_operand:SI 0 "register_operand" "=d")
4037         (zero_extend:SI (truncate:HI
4038                          (match_operand:DI 1 "se_register_operand" "d"))))]
4039   "TARGET_64BIT && !TARGET_MIPS16"
4040   "andi\\t%0,%1,0xffff"
4041   [(set_attr "type"     "darith")
4042    (set_attr "mode"     "SI")])
4043
4044 (define_insn ""
4045   [(set (match_operand:SI 0 "register_operand" "=d")
4046         (zero_extend:SI (truncate:QI
4047                          (match_operand:DI 1 "se_register_operand" "d"))))]
4048   "TARGET_64BIT && !TARGET_MIPS16"
4049   "andi\\t%0,%1,0xff"
4050   [(set_attr "type"     "darith")
4051    (set_attr "mode"     "SI")])
4052
4053 (define_insn ""
4054   [(set (match_operand:HI 0 "register_operand" "=d")
4055         (zero_extend:HI (truncate:QI
4056                          (match_operand:DI 1 "se_register_operand" "d"))))]
4057   "TARGET_64BIT && !TARGET_MIPS16"
4058   "andi\\t%0,%1,0xff"
4059   [(set_attr "type"     "darith")
4060    (set_attr "mode"     "HI")])
4061 \f
4062 ;;
4063 ;;  ....................
4064 ;;
4065 ;;      ZERO EXTENSION
4066 ;;
4067 ;;  ....................
4068
4069 ;; Extension insns.
4070 ;; Those for integer source operand are ordered widest source type first.
4071
4072 (define_expand "zero_extendsidi2"
4073   [(set (match_operand:DI 0 "register_operand" "")
4074         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4075   "TARGET_64BIT"
4076   "
4077 {
4078   if ((optimize || TARGET_MIPS16) && GET_CODE (operands[1]) == MEM)
4079     operands[1] = force_not_mem (operands[1]);
4080
4081   if (GET_CODE (operands[1]) != MEM)
4082     {
4083       rtx op1   = gen_lowpart (DImode, operands[1]);
4084       rtx temp  = gen_reg_rtx (DImode);
4085       rtx shift = GEN_INT (32);
4086
4087       emit_insn (gen_ashldi3 (temp, op1, shift));
4088       emit_insn (gen_lshrdi3 (operands[0], temp, shift));
4089       DONE;
4090     }
4091 }")
4092
4093 (define_insn "zero_extendsidi2_internal"
4094   [(set (match_operand:DI 0 "register_operand" "=d,d")
4095         (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
4096   "TARGET_64BIT && !TARGET_MIPS16"
4097   "* return mips_move_1word (operands, insn, TRUE);"
4098   [(set_attr "type"     "load")
4099    (set_attr "mode"     "DI")
4100    (set_attr "length"   "4,8")])
4101
4102 (define_expand "zero_extendhisi2"
4103   [(set (match_operand:SI 0 "register_operand" "")
4104         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4105   ""
4106   "
4107 {
4108   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4109     {
4110       rtx op = gen_lowpart (SImode, operands[1]);
4111       rtx temp = force_reg (SImode, GEN_INT (0xffff));
4112
4113       emit_insn (gen_andsi3 (operands[0], op, temp));
4114       DONE;
4115     }
4116 }")
4117
4118 (define_insn ""
4119   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
4120         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
4121   "!TARGET_MIPS16"
4122   "*
4123 {
4124   if (which_alternative == 0)
4125     return \"andi\\t%0,%1,0xffff\";
4126   else
4127     return mips_move_1word (operands, insn, TRUE);
4128 }"
4129   [(set_attr "type"     "arith,load,load")
4130    (set_attr "mode"     "SI")
4131    (set_attr "length"   "4,4,8")])
4132
4133 (define_insn ""
4134   [(set (match_operand:SI 0 "register_operand" "=d,d")
4135         (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
4136   "TARGET_MIPS16"
4137   "* return mips_move_1word (operands, insn, TRUE);"
4138   [(set_attr "type"     "load,load")
4139    (set_attr "mode"     "SI")
4140    (set_attr "length"   "4,8")])
4141
4142 (define_expand "zero_extendhidi2"
4143   [(set (match_operand:DI 0 "register_operand" "")
4144         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
4145   "TARGET_64BIT"
4146   "
4147 {
4148   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4149     {
4150       rtx op = gen_lowpart (DImode, operands[1]);
4151       rtx temp = force_reg (DImode, GEN_INT (0xffff));
4152
4153       emit_insn (gen_anddi3 (operands[0], op, temp));
4154       DONE;
4155     }
4156 }")
4157
4158 (define_insn ""
4159   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4160         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
4161   "TARGET_64BIT && !TARGET_MIPS16"
4162   "*
4163 {
4164   if (which_alternative == 0)
4165     return \"andi\\t%0,%1,0xffff\";
4166   else
4167     return mips_move_1word (operands, insn, TRUE);
4168 }"
4169   [(set_attr "type"     "arith,load,load")
4170    (set_attr "mode"     "DI")
4171    (set_attr "length"   "4,4,8")])
4172
4173 (define_insn ""
4174   [(set (match_operand:DI 0 "register_operand" "=d,d")
4175         (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
4176   "TARGET_64BIT && TARGET_MIPS16"
4177   "* return mips_move_1word (operands, insn, TRUE);"
4178   [(set_attr "type"     "load,load")
4179    (set_attr "mode"     "DI")
4180    (set_attr "length"   "4,8")])
4181
4182 (define_expand "zero_extendqihi2"
4183   [(set (match_operand:HI 0 "register_operand" "")
4184         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
4185   ""
4186   "
4187 {
4188   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4189     {
4190       rtx op0 = gen_lowpart (SImode, operands[0]);
4191       rtx op1 = gen_lowpart (SImode, operands[1]);
4192       rtx temp = force_reg (SImode, GEN_INT (0xff));
4193
4194       emit_insn (gen_andsi3 (op0, op1, temp));
4195       DONE;
4196     }
4197 }")
4198
4199 (define_insn ""
4200   [(set (match_operand:HI 0 "register_operand" "=d,d,d")
4201         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
4202   "!TARGET_MIPS16"
4203   "*
4204 {
4205   if (which_alternative == 0)
4206     return \"andi\\t%0,%1,0x00ff\";
4207   else
4208     return mips_move_1word (operands, insn, TRUE);
4209 }"
4210   [(set_attr "type"     "arith,load,load")
4211    (set_attr "mode"     "HI")
4212    (set_attr "length"   "4,4,8")])
4213
4214 (define_insn ""
4215   [(set (match_operand:HI 0 "register_operand" "=d,d")
4216         (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
4217   "TARGET_MIPS16"
4218   "* return mips_move_1word (operands, insn, TRUE);"
4219   [(set_attr "type"     "load,load")
4220    (set_attr "mode"     "HI")
4221    (set_attr "length"   "4,8")])
4222
4223 (define_expand "zero_extendqisi2"
4224   [(set (match_operand:SI 0 "register_operand" "")
4225         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4226   ""
4227   "
4228 {
4229   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4230     {
4231       rtx op = gen_lowpart (SImode, operands[1]);
4232       rtx temp = force_reg (SImode, GEN_INT (0xff));
4233
4234       emit_insn (gen_andsi3 (operands[0], op, temp));
4235       DONE;
4236     }
4237 }")
4238
4239 (define_insn ""
4240   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
4241         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
4242   "!TARGET_MIPS16"
4243   "*
4244 {
4245   if (which_alternative == 0)
4246     return \"andi\\t%0,%1,0x00ff\";
4247   else
4248     return mips_move_1word (operands, insn, TRUE);
4249 }"
4250   [(set_attr "type"     "arith,load,load")
4251    (set_attr "mode"     "SI")
4252    (set_attr "length"   "4,4,8")])
4253
4254 (define_insn ""
4255   [(set (match_operand:SI 0 "register_operand" "=d,d")
4256         (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4257   "TARGET_MIPS16"
4258   "* return mips_move_1word (operands, insn, TRUE);"
4259   [(set_attr "type"     "load,load")
4260    (set_attr "mode"     "SI")
4261    (set_attr "length"   "4,8")])
4262
4263 (define_expand "zero_extendqidi2"
4264   [(set (match_operand:DI 0 "register_operand" "")
4265         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4266   "TARGET_64BIT"
4267   "
4268 {
4269   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4270     {
4271       rtx op = gen_lowpart (DImode, operands[1]);
4272       rtx temp = force_reg (DImode, GEN_INT (0xff));
4273
4274       emit_insn (gen_anddi3 (operands[0], op, temp));
4275       DONE;
4276     }
4277 }")
4278
4279 (define_insn ""
4280   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4281         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
4282   "TARGET_64BIT && !TARGET_MIPS16"
4283   "*
4284 {
4285   if (which_alternative == 0)
4286     return \"andi\\t%0,%1,0x00ff\";
4287   else
4288     return mips_move_1word (operands, insn, TRUE);
4289 }"
4290   [(set_attr "type"     "arith,load,load")
4291    (set_attr "mode"     "DI")
4292    (set_attr "length"   "4,4,8")])
4293
4294 ;; These can be created when a paradoxical subreg operand with an implicit
4295 ;; sign_extend operator is reloaded.  Because of the subreg, this is really
4296 ;; a zero extend.
4297 ;; ??? It might be possible to eliminate the need for these patterns by adding
4298 ;; more support to reload for implicit sign_extend operators.
4299 (define_insn "*paradoxical_extendhidi2"
4300   [(set (match_operand:DI 0 "register_operand" "=d,d")
4301         (sign_extend:DI
4302          (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
4303   "TARGET_64BIT"
4304   "*
4305 {
4306   return mips_move_1word (operands, insn, TRUE);
4307 }"
4308   [(set_attr "type"     "load,load")
4309    (set_attr "mode"     "DI")
4310    (set_attr "length"   "4,8")])
4311
4312 (define_insn ""
4313   [(set (match_operand:DI 0 "register_operand" "=d,d")
4314         (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4315   "TARGET_64BIT && TARGET_MIPS16"
4316   "* return mips_move_1word (operands, insn, TRUE);"
4317   [(set_attr "type"     "load,load")
4318    (set_attr "mode"     "DI")
4319    (set_attr "length"   "4,8")])
4320 \f
4321 ;;
4322 ;;  ....................
4323 ;;
4324 ;;      SIGN EXTENSION
4325 ;;
4326 ;;  ....................
4327
4328 ;; Extension insns.
4329 ;; Those for integer source operand are ordered widest source type first.
4330
4331 ;; In 64 bit mode, 32 bit values in general registers are always
4332 ;; correctly sign extended.  That means that if the target is a
4333 ;; general register, we can sign extend from SImode to DImode just by
4334 ;; doing a move.  The matching define_insns are *movdi_internal2_extend
4335 ;; and *movdi_internal2_mips16.
4336
4337 (define_expand "extendsidi2"
4338   [(set (match_operand:DI 0 "register_operand" "")
4339         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4340   "TARGET_64BIT"
4341   "")
4342
4343 ;; These patterns originally accepted general_operands, however, slightly
4344 ;; better code is generated by only accepting register_operands, and then
4345 ;; letting combine generate the lh and lb insns.
4346
4347 (define_expand "extendhidi2"
4348   [(set (match_operand:DI 0 "register_operand" "")
4349         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
4350   "TARGET_64BIT"
4351   "
4352 {
4353   if (optimize && GET_CODE (operands[1]) == MEM)
4354     operands[1] = force_not_mem (operands[1]);
4355
4356   if (GET_CODE (operands[1]) != MEM)
4357     {
4358       rtx op1   = gen_lowpart (DImode, operands[1]);
4359       rtx temp  = gen_reg_rtx (DImode);
4360       rtx shift = GEN_INT (48);
4361
4362       emit_insn (gen_ashldi3 (temp, op1, shift));
4363       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4364       DONE;
4365     }
4366 }")
4367
4368 (define_insn "extendhidi2_internal"
4369   [(set (match_operand:DI 0 "register_operand" "=d,d")
4370         (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
4371   "TARGET_64BIT"
4372   "* return mips_move_1word (operands, insn, FALSE);"
4373   [(set_attr "type"     "load")
4374    (set_attr "mode"     "DI")
4375    (set_attr "length"   "4,8")])
4376
4377 (define_expand "extendhisi2"
4378   [(set (match_operand:SI 0 "register_operand" "")
4379         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4380   ""
4381   "
4382 {
4383   if (ISA_HAS_SEB_SEH)
4384     {
4385       emit_insn (gen_extendhisi2_hw (operands[0],
4386                                      force_reg (HImode, operands[1]))); 
4387       DONE;
4388     }
4389
4390   if (optimize && GET_CODE (operands[1]) == MEM)
4391     operands[1] = force_not_mem (operands[1]);
4392
4393   if (GET_CODE (operands[1]) != MEM)
4394     {
4395       rtx op1   = gen_lowpart (SImode, operands[1]);
4396       rtx temp  = gen_reg_rtx (SImode);
4397       rtx shift = GEN_INT (16);
4398
4399       emit_insn (gen_ashlsi3 (temp, op1, shift));
4400       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4401       DONE;
4402     }
4403 }")
4404
4405 (define_insn "extendhisi2_hw" 
4406   [(set (match_operand:SI 0 "register_operand" "=r")
4407         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
4408   "ISA_HAS_SEB_SEH"     
4409   "seh\\t%0,%1"
4410   [(set_attr "type" "arith")
4411    (set_attr "mode" "SI")])
4412
4413 (define_insn "extendhisi2_internal"
4414   [(set (match_operand:SI 0 "register_operand" "=d,d")
4415         (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
4416   ""
4417   "* return mips_move_1word (operands, insn, FALSE);"
4418   [(set_attr "type"     "load")
4419    (set_attr "mode"     "SI")
4420    (set_attr "length"   "4,8")])
4421
4422 (define_expand "extendqihi2"
4423   [(set (match_operand:HI 0 "register_operand" "")
4424         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
4425   ""
4426   "
4427 {
4428   if (optimize && GET_CODE (operands[1]) == MEM)
4429     operands[1] = force_not_mem (operands[1]);
4430
4431   if (GET_CODE (operands[1]) != MEM)
4432     {
4433       rtx op0   = gen_lowpart (SImode, operands[0]);
4434       rtx op1   = gen_lowpart (SImode, operands[1]);
4435       rtx temp  = gen_reg_rtx (SImode);
4436       rtx shift = GEN_INT (24);
4437
4438       emit_insn (gen_ashlsi3 (temp, op1, shift));
4439       emit_insn (gen_ashrsi3 (op0, temp, shift));
4440       DONE;
4441     }
4442 }")
4443
4444 (define_insn "extendqihi2_internal"
4445   [(set (match_operand:HI 0 "register_operand" "=d,d")
4446         (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
4447   ""
4448   "* return mips_move_1word (operands, insn, FALSE);"
4449   [(set_attr "type"     "load")
4450    (set_attr "mode"     "SI")
4451    (set_attr "length"   "4,8")])
4452
4453
4454 (define_expand "extendqisi2"
4455   [(set (match_operand:SI 0 "register_operand" "")
4456         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4457   ""
4458   "
4459 {
4460   if (ISA_HAS_SEB_SEH)
4461     {
4462       emit_insn (gen_extendqisi2_hw (operands[0],
4463                                      force_reg (QImode, operands[1]))); 
4464       DONE;
4465     }
4466   if (optimize && GET_CODE (operands[1]) == MEM)
4467     operands[1] = force_not_mem (operands[1]);
4468
4469   if (GET_CODE (operands[1]) != MEM)
4470     {
4471       rtx op1   = gen_lowpart (SImode, operands[1]);
4472       rtx temp  = gen_reg_rtx (SImode);
4473       rtx shift = GEN_INT (24);
4474
4475       emit_insn (gen_ashlsi3 (temp, op1, shift));
4476       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4477       DONE;
4478     }
4479 }")
4480
4481 (define_insn "extendqisi2_hw" 
4482   [(set (match_operand:SI 0 "register_operand" "=r")
4483         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
4484   "ISA_HAS_SEB_SEH"     
4485   "seb\\t%0,%1"
4486   [(set_attr "type" "arith")
4487    (set_attr "mode" "SI")])
4488
4489 (define_insn "extendqisi2_insn"
4490   [(set (match_operand:SI 0 "register_operand" "=d,d")
4491         (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4492   ""
4493   "* return mips_move_1word (operands, insn, FALSE);"
4494   [(set_attr "type"     "load")
4495    (set_attr "mode"     "SI")
4496    (set_attr "length"   "4,8")])
4497
4498 (define_expand "extendqidi2"
4499   [(set (match_operand:DI 0 "register_operand" "")
4500         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4501   "TARGET_64BIT"
4502   "
4503 {
4504   if (optimize && GET_CODE (operands[1]) == MEM)
4505     operands[1] = force_not_mem (operands[1]);
4506
4507   if (GET_CODE (operands[1]) != MEM)
4508     {
4509       rtx op1   = gen_lowpart (DImode, operands[1]);
4510       rtx temp  = gen_reg_rtx (DImode);
4511       rtx shift = GEN_INT (56);
4512
4513       emit_insn (gen_ashldi3 (temp, op1, shift));
4514       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4515       DONE;
4516     }
4517 }")
4518
4519 (define_insn "extendqidi2_insn"
4520   [(set (match_operand:DI 0 "register_operand" "=d,d")
4521         (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4522   "TARGET_64BIT"
4523   "* return mips_move_1word (operands, insn, FALSE);"
4524   [(set_attr "type"     "load")
4525    (set_attr "mode"     "DI")
4526    (set_attr "length"   "4,8")])
4527
4528
4529 (define_insn "extendsfdf2"
4530   [(set (match_operand:DF 0 "register_operand" "=f")
4531         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
4532   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4533   "cvt.d.s\\t%0,%1"
4534   [(set_attr "type"     "fcvt")
4535    (set_attr "mode"     "DF")])
4536
4537 \f
4538
4539 ;;
4540 ;;  ....................
4541 ;;
4542 ;;      CONVERSIONS
4543 ;;
4544 ;;  ....................
4545
4546 (define_expand "fix_truncdfsi2"
4547   [(set (match_operand:SI 0 "register_operand" "=f")
4548         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
4549   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4550 {
4551   if (!ISA_HAS_TRUNC_W)
4552     {
4553       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
4554       DONE;
4555     }
4556 })
4557
4558 (define_insn "fix_truncdfsi2_insn"
4559   [(set (match_operand:SI 0 "register_operand" "=f")
4560         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
4561   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
4562   "trunc.w.d %0,%1"
4563   [(set_attr "type"     "fcvt")
4564    (set_attr "mode"     "DF")
4565    (set_attr "length"   "4")])
4566
4567 (define_insn "fix_truncdfsi2_macro"
4568   [(set (match_operand:SI 0 "register_operand" "=f")
4569         (fix:SI (match_operand:DF 1 "register_operand" "f")))
4570    (clobber (match_scratch:DF 2 "=d"))]
4571   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
4572   "trunc.w.d %0,%1,%2"
4573   [(set_attr "type"     "fcvt")
4574    (set_attr "mode"     "DF")
4575    (set_attr "length"   "36")])
4576
4577 (define_expand "fix_truncsfsi2"
4578   [(set (match_operand:SI 0 "register_operand" "=f")
4579         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
4580   "TARGET_HARD_FLOAT"
4581 {
4582   if (!ISA_HAS_TRUNC_W)
4583     {
4584       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
4585       DONE;
4586     }
4587 })
4588
4589 (define_insn "fix_truncsfsi2_insn"
4590   [(set (match_operand:SI 0 "register_operand" "=f")
4591         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
4592   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
4593   "trunc.w.s %0,%1"
4594   [(set_attr "type"     "fcvt")
4595    (set_attr "mode"     "DF")
4596    (set_attr "length"   "4")])
4597
4598 (define_insn "fix_truncsfsi2_macro"
4599   [(set (match_operand:SI 0 "register_operand" "=f")
4600         (fix:SI (match_operand:SF 1 "register_operand" "f")))
4601    (clobber (match_scratch:SF 2 "=d"))]
4602   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
4603   "trunc.w.s %0,%1,%2"
4604   [(set_attr "type"     "fcvt")
4605    (set_attr "mode"     "DF")
4606    (set_attr "length"   "36")])
4607
4608 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
4609 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
4610 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
4611
4612 ;;; Deleting this means that we now need two libgcc2.a libraries.  One for
4613 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
4614
4615 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
4616
4617 (define_insn "fix_truncdfdi2"
4618   [(set (match_operand:DI 0 "register_operand" "=f")
4619         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
4620   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4621   "trunc.l.d %0,%1"
4622   [(set_attr "type"     "fcvt")
4623    (set_attr "mode"     "DF")
4624    (set_attr "length"   "4")])
4625
4626
4627 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
4628 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
4629 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
4630 (define_insn "fix_truncsfdi2"
4631   [(set (match_operand:DI 0 "register_operand" "=f")
4632         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
4633   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4634   "trunc.l.s %0,%1"
4635   [(set_attr "type"     "fcvt")
4636    (set_attr "mode"     "SF")
4637    (set_attr "length"   "4")])
4638
4639
4640 (define_insn "floatsidf2"
4641   [(set (match_operand:DF 0 "register_operand" "=f")
4642         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4643   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4644   "cvt.d.w\\t%0,%1"
4645   [(set_attr "type"     "fcvt")
4646    (set_attr "mode"     "DF")
4647    (set_attr "length"   "4")])
4648
4649
4650 (define_insn "floatdidf2"
4651   [(set (match_operand:DF 0 "register_operand" "=f")
4652         (float:DF (match_operand:DI 1 "register_operand" "f")))]
4653   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4654   "cvt.d.l\\t%0,%1"
4655   [(set_attr "type"     "fcvt")
4656    (set_attr "mode"     "DF")
4657    (set_attr "length"   "4")])
4658
4659
4660 (define_insn "floatsisf2"
4661   [(set (match_operand:SF 0 "register_operand" "=f")
4662         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4663   "TARGET_HARD_FLOAT"
4664   "cvt.s.w\\t%0,%1"
4665   [(set_attr "type"     "fcvt")
4666    (set_attr "mode"     "SF")
4667    (set_attr "length"   "4")])
4668
4669
4670 (define_insn "floatdisf2"
4671   [(set (match_operand:SF 0 "register_operand" "=f")
4672         (float:SF (match_operand:DI 1 "register_operand" "f")))]
4673   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4674   "cvt.s.l\\t%0,%1"
4675   [(set_attr "type"     "fcvt")
4676    (set_attr "mode"     "SF")
4677    (set_attr "length"   "4")])
4678
4679
4680 (define_expand "fixuns_truncdfsi2"
4681   [(set (match_operand:SI 0 "register_operand" "")
4682         (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
4683   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4684   "
4685 {
4686   rtx reg1 = gen_reg_rtx (DFmode);
4687   rtx reg2 = gen_reg_rtx (DFmode);
4688   rtx reg3 = gen_reg_rtx (SImode);
4689   rtx label1 = gen_label_rtx ();
4690   rtx label2 = gen_label_rtx ();
4691   REAL_VALUE_TYPE offset;
4692
4693   real_2expN (&offset, 31);
4694
4695   if (reg1)                     /* turn off complaints about unreached code */
4696     {
4697       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
4698       do_pending_stack_adjust ();
4699
4700       emit_insn (gen_cmpdf (operands[1], reg1));
4701       emit_jump_insn (gen_bge (label1));
4702
4703       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
4704       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4705                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4706       emit_barrier ();
4707
4708       emit_label (label1);
4709       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4710       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4711                                      (BITMASK_HIGH, SImode)));
4712
4713       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4714       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4715
4716       emit_label (label2);
4717
4718       /* allow REG_NOTES to be set on last insn (labels don't have enough
4719          fields, and can't be used for REG_NOTES anyway).  */
4720       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4721       DONE;
4722     }
4723 }")
4724
4725
4726 (define_expand "fixuns_truncdfdi2"
4727   [(set (match_operand:DI 0 "register_operand" "")
4728         (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
4729   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4730   "
4731 {
4732   rtx reg1 = gen_reg_rtx (DFmode);
4733   rtx reg2 = gen_reg_rtx (DFmode);
4734   rtx reg3 = gen_reg_rtx (DImode);
4735   rtx label1 = gen_label_rtx ();
4736   rtx label2 = gen_label_rtx ();
4737   REAL_VALUE_TYPE offset;
4738
4739   real_2expN (&offset, 63);
4740
4741   if (reg1)                     /* turn off complaints about unreached code */
4742     {
4743       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
4744       do_pending_stack_adjust ();
4745
4746       emit_insn (gen_cmpdf (operands[1], reg1));
4747       emit_jump_insn (gen_bge (label1));
4748
4749       emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
4750       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4751                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4752       emit_barrier ();
4753
4754       emit_label (label1);
4755       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4756       emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4757       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4758
4759       emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4760       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4761
4762       emit_label (label2);
4763
4764       /* allow REG_NOTES to be set on last insn (labels don't have enough
4765          fields, and can't be used for REG_NOTES anyway).  */
4766       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4767       DONE;
4768     }
4769 }")
4770
4771
4772 (define_expand "fixuns_truncsfsi2"
4773   [(set (match_operand:SI 0 "register_operand" "")
4774         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4775   "TARGET_HARD_FLOAT"
4776   "
4777 {
4778   rtx reg1 = gen_reg_rtx (SFmode);
4779   rtx reg2 = gen_reg_rtx (SFmode);
4780   rtx reg3 = gen_reg_rtx (SImode);
4781   rtx label1 = gen_label_rtx ();
4782   rtx label2 = gen_label_rtx ();
4783   REAL_VALUE_TYPE offset;
4784
4785   real_2expN (&offset, 31);
4786
4787   if (reg1)                     /* turn off complaints about unreached code */
4788     {
4789       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
4790       do_pending_stack_adjust ();
4791
4792       emit_insn (gen_cmpsf (operands[1], reg1));
4793       emit_jump_insn (gen_bge (label1));
4794
4795       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4796       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4797                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4798       emit_barrier ();
4799
4800       emit_label (label1);
4801       emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4802       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4803                                      (BITMASK_HIGH, SImode)));
4804
4805       emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4806       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4807
4808       emit_label (label2);
4809
4810       /* allow REG_NOTES to be set on last insn (labels don't have enough
4811          fields, and can't be used for REG_NOTES anyway).  */
4812       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4813       DONE;
4814     }
4815 }")
4816
4817
4818 (define_expand "fixuns_truncsfdi2"
4819   [(set (match_operand:DI 0 "register_operand" "")
4820         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4821   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4822   "
4823 {
4824   rtx reg1 = gen_reg_rtx (SFmode);
4825   rtx reg2 = gen_reg_rtx (SFmode);
4826   rtx reg3 = gen_reg_rtx (DImode);
4827   rtx label1 = gen_label_rtx ();
4828   rtx label2 = gen_label_rtx ();
4829   REAL_VALUE_TYPE offset;
4830
4831   real_2expN (&offset, 63);
4832
4833   if (reg1)                     /* turn off complaints about unreached code */
4834     {
4835       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
4836       do_pending_stack_adjust ();
4837
4838       emit_insn (gen_cmpsf (operands[1], reg1));
4839       emit_jump_insn (gen_bge (label1));
4840
4841       emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4842       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4843                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4844       emit_barrier ();
4845
4846       emit_label (label1);
4847       emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4848       emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4849       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4850
4851       emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4852       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4853
4854       emit_label (label2);
4855
4856       /* allow REG_NOTES to be set on last insn (labels don't have enough
4857          fields, and can't be used for REG_NOTES anyway).  */
4858       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4859       DONE;
4860     }
4861 }")
4862
4863 \f
4864 ;;
4865 ;;  ....................
4866 ;;
4867 ;;      DATA MOVEMENT
4868 ;;
4869 ;;  ....................
4870
4871 ;; Bit field extract patterns which use lwl/lwr.
4872
4873 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4874 ;; It isn't clear whether this will give better code.
4875
4876 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4877 (define_expand "extv"
4878   [(set (match_operand 0 "register_operand" "")
4879         (sign_extract (match_operand:QI 1 "memory_operand" "")
4880                       (match_operand 2 "immediate_operand" "")
4881                       (match_operand 3 "immediate_operand" "")))]
4882   "!TARGET_MIPS16"
4883   "
4884 {
4885   /* If the field does not start on a byte boundary, then fail.  */
4886   if (INTVAL (operands[3]) % 8 != 0)
4887     FAIL;
4888
4889   /* MIPS I and MIPS II can only handle a 32bit field.  */
4890   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4891     FAIL;
4892
4893   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4894   if (TARGET_64BIT
4895       && INTVAL (operands[2]) != 64
4896       && INTVAL (operands[2]) != 32)
4897     FAIL;
4898
4899   /* This can happen for a 64 bit target, when extracting a value from
4900      a 64 bit union member.  extract_bit_field doesn't verify that our
4901      source matches the predicate, so we force it to be a MEM here.  */
4902   if (GET_CODE (operands[1]) != MEM)
4903     FAIL;
4904
4905   /* Change the mode to BLKmode for aliasing purposes.  */
4906   operands[1] = adjust_address (operands[1], BLKmode, 0);
4907   set_mem_size (operands[1], GEN_INT (INTVAL (operands[2]) / BITS_PER_UNIT));
4908
4909   /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value.  */
4910   if (INTVAL (operands[2]) == 64)
4911     emit_insn (gen_movdi_uld (operands[0], operands[1]));
4912   else
4913     {
4914       if (TARGET_64BIT)
4915         {
4916           operands[0] = gen_lowpart (SImode, operands[0]);
4917           if (operands[0] == NULL_RTX)
4918             FAIL;
4919         }
4920       emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4921     }
4922   DONE;
4923 }")
4924
4925 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4926 (define_expand "extzv"
4927   [(set (match_operand 0 "register_operand" "")
4928         (zero_extract (match_operand:QI 1 "memory_operand" "")
4929                       (match_operand 2 "immediate_operand" "")
4930                       (match_operand 3 "immediate_operand" "")))]
4931   "!TARGET_MIPS16"
4932   "
4933 {
4934   /* If the field does not start on a byte boundary, then fail.  */
4935   if (INTVAL (operands[3]) % 8 != 0)
4936     FAIL;
4937
4938   /* MIPS I and MIPS II can only handle a 32bit field.  */
4939   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4940     FAIL;
4941
4942   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4943   if (TARGET_64BIT
4944       && INTVAL (operands[2]) != 64
4945       && INTVAL (operands[2]) != 32)
4946     FAIL;
4947
4948   /* This can happen for a 64 bit target, when extracting a value from
4949      a 64 bit union member.  extract_bit_field doesn't verify that our
4950      source matches the predicate, so we force it to be a MEM here.  */
4951   if (GET_CODE (operands[1]) != MEM)
4952     FAIL;
4953
4954   /* Change the mode to BLKmode for aliasing purposes.  */
4955   operands[1] = adjust_address (operands[1], BLKmode, 0);
4956   set_mem_size (operands[1], GEN_INT (INTVAL (operands[2]) / BITS_PER_UNIT));
4957
4958   /* Otherwise, emit a lwl/lwr pair to load the value.  */
4959   if (INTVAL (operands[2]) == 64)
4960     emit_insn (gen_movdi_uld (operands[0], operands[1]));
4961   else
4962     {
4963       if (TARGET_64BIT)
4964         {
4965           operands[0] = gen_lowpart (SImode, operands[0]);
4966           if (operands[0] == NULL_RTX)
4967             FAIL;
4968         }
4969       emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4970     }
4971   DONE;
4972 }")
4973
4974 ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
4975 (define_expand "insv"
4976   [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4977                       (match_operand 1 "immediate_operand" "")
4978                       (match_operand 2 "immediate_operand" ""))
4979         (match_operand 3 "register_operand" ""))]
4980   "!TARGET_MIPS16"
4981   "
4982 {
4983   /* If the field does not start on a byte boundary, then fail.  */
4984   if (INTVAL (operands[2]) % 8 != 0)
4985     FAIL;
4986
4987   /* MIPS I and MIPS II can only handle a 32bit field.  */
4988   if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
4989     FAIL;
4990
4991   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4992   if (TARGET_64BIT
4993       && INTVAL (operands[1]) != 64
4994       && INTVAL (operands[1]) != 32)
4995     FAIL;
4996
4997   /* This can happen for a 64 bit target, when storing into a 32 bit union
4998      member.  store_bit_field doesn't verify that our target matches the
4999      predicate, so we force it to be a MEM here.  */
5000   if (GET_CODE (operands[0]) != MEM)
5001     FAIL;
5002
5003   /* Change the mode to BLKmode for aliasing purposes.  */
5004   operands[0] = adjust_address (operands[0], BLKmode, 0);
5005   set_mem_size (operands[0], GEN_INT (INTVAL (operands[1]) / BITS_PER_UNIT));
5006
5007   /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value.  */
5008   if (INTVAL (operands[1]) == 64)
5009     emit_insn (gen_movdi_usd (operands[0], operands[3]));
5010   else
5011     {
5012       if (TARGET_64BIT)
5013         {
5014           operands[3] = gen_lowpart (SImode, operands[3]);
5015           if (operands[3] == NULL_RTX)
5016             FAIL;
5017         }
5018       emit_insn (gen_movsi_usw (operands[0], operands[3]));
5019     }
5020   DONE;
5021 }")
5022
5023 ;; unaligned word moves generated by the bit field patterns
5024
5025 (define_insn "movsi_ulw"
5026   [(set (match_operand:SI 0 "register_operand" "=&d,&d")
5027         (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")]
5028                    UNSPEC_ULW))]
5029   "!TARGET_MIPS16"
5030   "*
5031 {
5032   rtx offset = const0_rtx;
5033   rtx addr = XEXP (operands[1], 0);
5034   rtx mem_addr = eliminate_constant_term (addr, &offset);
5035   const char *ret;
5036
5037   if (TARGET_STATS)
5038     mips_count_memory_refs (operands[1], 2);
5039
5040   /* The stack/frame pointers are always aligned, so we can convert
5041      to the faster lw if we are referencing an aligned stack location.  */
5042
5043   if ((INTVAL (offset) & 3) == 0
5044       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
5045     ret = \"lw\\t%0,%1\";
5046   else
5047     ret = \"ulw\\t%0,%1\";
5048
5049   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
5050 }"
5051   [(set_attr "type"     "load,load")
5052    (set_attr "mode"     "SI")
5053    (set_attr "length"   "8,16")])
5054
5055 (define_insn "movsi_usw"
5056   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
5057         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")]
5058                     UNSPEC_USW))]
5059   "!TARGET_MIPS16"
5060   "*
5061 {
5062   rtx offset = const0_rtx;
5063   rtx addr = XEXP (operands[0], 0);
5064   rtx mem_addr = eliminate_constant_term (addr, &offset);
5065
5066   if (TARGET_STATS)
5067     mips_count_memory_refs (operands[0], 2);
5068
5069   /* The stack/frame pointers are always aligned, so we can convert
5070      to the faster sw if we are referencing an aligned stack location.  */
5071
5072   if ((INTVAL (offset) & 3) == 0
5073       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
5074     return \"sw\\t%z1,%0\";
5075
5076   return \"usw\\t%z1,%0\";
5077 }"
5078   [(set_attr "type"     "store")
5079    (set_attr "mode"     "SI")
5080    (set_attr "length"   "8,16")])
5081
5082 ;; Bit field extract patterns which use ldl/ldr.
5083
5084 ;; unaligned double word moves generated by the bit field patterns
5085
5086 (define_insn "movdi_uld"
5087   [(set (match_operand:DI 0 "register_operand" "=&d,&d")
5088         (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")]
5089                    UNSPEC_ULD))]
5090   ""
5091   "*
5092 {
5093   rtx offset = const0_rtx;
5094   rtx addr = XEXP (operands[1], 0);
5095   rtx mem_addr = eliminate_constant_term (addr, &offset);
5096   const char *ret;
5097
5098   if (TARGET_STATS)
5099     mips_count_memory_refs (operands[1], 2);
5100
5101   /* The stack/frame pointers are always aligned, so we can convert
5102      to the faster lw if we are referencing an aligned stack location.  */
5103
5104   if ((INTVAL (offset) & 7) == 0
5105       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
5106     ret = \"ld\\t%0,%1\";
5107   else
5108     ret = \"uld\\t%0,%1\";
5109
5110   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
5111 }"
5112   [(set_attr "type"     "load,load")
5113    (set_attr "mode"     "SI")
5114    (set_attr "length"   "8,16")])
5115
5116 (define_insn "movdi_usd"
5117   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
5118         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")]
5119                     UNSPEC_USD))]
5120   ""
5121   "*
5122 {
5123   rtx offset = const0_rtx;
5124   rtx addr = XEXP (operands[0], 0);
5125   rtx mem_addr = eliminate_constant_term (addr, &offset);
5126
5127   if (TARGET_STATS)
5128     mips_count_memory_refs (operands[0], 2);
5129
5130   /* The stack/frame pointers are always aligned, so we can convert
5131      to the faster sw if we are referencing an aligned stack location.  */
5132
5133   if ((INTVAL (offset) & 7) == 0
5134       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
5135     return \"sd\\t%z1,%0\";
5136
5137   return \"usd\\t%z1,%0\";
5138 }"
5139   [(set_attr "type"     "store")
5140    (set_attr "mode"     "SI")
5141    (set_attr "length"   "8,16")])
5142
5143 ;; These two patterns support loading addresses with two instructions instead
5144 ;; of using the macro instruction la.
5145
5146 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
5147 ;; unnecessary.
5148
5149 (define_insn "high"
5150   [(set (match_operand:SI 0 "register_operand" "=r")
5151         (high:SI (match_operand:SI 1 "immediate_operand" "")))]
5152   "mips_split_addresses && !TARGET_MIPS16"
5153   "lui\\t%0,%%hi(%1) # high"
5154   [(set_attr "type"     "move")])
5155
5156 (define_insn "low"
5157   [(set (match_operand:SI 0 "register_operand" "=r")
5158         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
5159                    (match_operand:SI 2 "immediate_operand" "")))]
5160   "mips_split_addresses && !TARGET_MIPS16"
5161   "addiu\\t%0,%1,%%lo(%2) # low"
5162   [(set_attr "type"     "arith")
5163    (set_attr "mode"     "SI")])
5164
5165 ;; 64-bit integer moves
5166
5167 ;; Unlike most other insns, the move insns can't be split with
5168 ;; different predicates, because register spilling and other parts of
5169 ;; the compiler, have memoized the insn number already.
5170
5171 (define_expand "movdi"
5172   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5173         (match_operand:DI 1 "general_operand" ""))]
5174   ""
5175   "
5176 {
5177   if (mips_split_addresses && mips_check_split (operands[1], DImode))
5178     {
5179       enum machine_mode mode = GET_MODE (operands[0]);
5180       rtx tem = ((reload_in_progress | reload_completed)
5181                  ? operands[0] : gen_reg_rtx (mode));
5182
5183       emit_insn (gen_rtx_SET (VOIDmode, tem,
5184                               gen_rtx_HIGH (mode, operands[1])));
5185
5186       operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
5187     }
5188
5189   /* If we are generating embedded PIC code, and we are referring to a
5190      symbol in the .text section, we must use an offset from the start
5191      of the function.  */
5192   if (TARGET_EMBEDDED_PIC
5193       && (GET_CODE (operands[1]) == LABEL_REF
5194           || (GET_CODE (operands[1]) == SYMBOL_REF
5195               && ! SYMBOL_REF_FLAG (operands[1]))))
5196     {
5197       rtx temp;
5198
5199       temp = embedded_pic_offset (operands[1]);
5200       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
5201                            force_reg (DImode, temp));
5202       emit_move_insn (operands[0], force_reg (DImode, temp));
5203       DONE;
5204     }
5205
5206   /* If operands[1] is a constant address illegal for pic, then we need to
5207      handle it just like LEGITIMIZE_ADDRESS does.  */
5208   if (flag_pic && pic_address_needs_scratch (operands[1]))
5209     {
5210       rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
5211       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5212
5213       if (! SMALL_INT (temp2))
5214         temp2 = force_reg (DImode, temp2);
5215
5216       emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
5217       DONE;
5218     }
5219
5220   /* On the mips16, we can handle a GP relative reference by adding in
5221      $gp.  We need to check the name to see whether this is a string
5222      constant.  */
5223   if (TARGET_MIPS16
5224       && register_operand (operands[0], DImode)
5225       && GET_CODE (operands[1]) == SYMBOL_REF
5226       && SYMBOL_REF_FLAG (operands[1]))
5227     {
5228       const char *name = XSTR (operands[1], 0);
5229
5230       if (name[0] != '*'
5231           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5232                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5233         {
5234           rtx base_reg;
5235
5236           if (reload_in_progress || reload_completed)
5237             {
5238               /* In movsi we use the constant table here.  However, in
5239                  this case, we're better off copying $28 into a
5240                  register and adding, because the constant table entry
5241                  would be 8 bytes.  */
5242               base_reg = operands[0];
5243               emit_move_insn (base_reg,
5244                               gen_rtx (CONST, DImode,
5245                                        gen_rtx (REG, DImode,
5246                                                 GP_REG_FIRST + 28)));
5247             }
5248           else
5249             {
5250               base_reg = gen_reg_rtx (Pmode);
5251               emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5252             }
5253
5254           emit_move_insn (operands[0],
5255                           gen_rtx (PLUS, Pmode, base_reg,
5256                                    mips16_gp_offset (operands[1])));
5257           DONE;
5258         }
5259     }
5260
5261   if ((reload_in_progress | reload_completed) == 0
5262       && !register_operand (operands[0], DImode)
5263       && !register_operand (operands[1], DImode)
5264       && (TARGET_MIPS16
5265           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5266                && operands[1] != CONST0_RTX (DImode))))
5267     {
5268       rtx temp = force_reg (DImode, operands[1]);
5269       emit_move_insn (operands[0], temp);
5270       DONE;
5271     }
5272 }")
5273
5274 ;; For mips16, we need a special case to handle storing $31 into
5275 ;; memory, since we don't have a constraint to match $31.  This
5276 ;; instruction can be generated by save_restore_insns.
5277
5278 (define_insn ""
5279   [(set (match_operand:DI 0 "memory_operand" "=R,m")
5280         (reg:DI 31))]
5281   "TARGET_MIPS16 && TARGET_64BIT"
5282   "*
5283 {
5284   operands[1] = gen_rtx (REG, DImode, 31);
5285   return mips_move_2words (operands, insn);
5286 }"
5287   [(set_attr "type"     "store")
5288    (set_attr "mode"     "DI")
5289    (set_attr "length"   "4,8")])
5290
5291 (define_insn "movdi_internal"
5292   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5293         (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5294   "!TARGET_64BIT && !TARGET_MIPS16
5295    && (register_operand (operands[0], DImode)
5296        || register_operand (operands[1], DImode)
5297        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5298        || operands[1] == CONST0_RTX (DImode))"
5299   "* return mips_move_2words (operands, insn); "
5300   [(set_attr "type"     "move,arith,load,load,store,store,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5301    (set_attr "mode"     "DI")
5302    (set_attr "length"   "8,16,8,16,8,16,8,8,8,8,8,8,8,8,8")])
5303
5304 (define_insn ""
5305   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
5306         (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
5307   "!TARGET_64BIT && TARGET_MIPS16
5308    && (register_operand (operands[0], DImode)
5309        || register_operand (operands[1], DImode))"
5310   "* return mips_move_2words (operands, insn);"
5311   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
5312    (set_attr "mode"     "DI")
5313    (set_attr "length"   "8,8,8,8,12,8,16,8,16,8")])
5314
5315 (define_split
5316   [(set (match_operand:DI 0 "register_operand" "")
5317         (match_operand:DI 1 "register_operand" ""))]
5318   "reload_completed && !TARGET_64BIT
5319    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5320    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
5321    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
5322
5323   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
5324    (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
5325   "")
5326
5327 (define_insn "movdi_internal2"
5328   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*f,*f,*f,*f,*d,*R,*m,*x,*d,*x,*a,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5329         (match_operand:DI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f,*d*J,*R,*m,*f,*f,*f,*J,*x,*d,*J,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5330   "TARGET_64BIT && !TARGET_MIPS16
5331    && (register_operand (operands[0], DImode)
5332        || register_operand (operands[1], DImode)
5333        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5334        || operands[1] == CONST0_RTX (DImode))"
5335   "* return mips_move_2words (operands, insn); "
5336   [(set_attr "type"     "move,arith,arith,load,load,store,store,move,xfer,load,load,xfer,store,store,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5337    (set_attr "mode"     "DI")
5338    (set_attr "length"   "4,4,8,4,8,4,8,4,4,4,8,4,4,8,4,4,4,8,8,8,8,8,8,8")])
5339
5340 ;; Sign-extended operands are reloaded using this instruction, so the
5341 ;; constraints must handle every SImode source operand X and destination
5342 ;; register R for which:
5343 ;;
5344 ;;     mips_secondary_reload_class (CLASS_OF (R), DImode, true,
5345 ;;                                  gen_rtx_SIGN_EXTEND (DImode, X))
5346 ;;
5347 ;; returns NO_REGS.  Also handle memory destinations, where allowed.
5348 ;;
5349 ;; This pattern is essentially a trimmed-down version of movdi_internal2.
5350 ;; The main difference is that dJ -> f and f -> d are the only constraints
5351 ;; involving float registers.  See mips_secondary_reload_class for details.
5352 (define_insn "*movdi_internal2_extend"
5353   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*d,*f,*x,*d,*x,*a,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5354         (sign_extend:DI (match_operand:SI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f,*d*J,*J,*x,*d,*J,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D")))]
5355   "TARGET_64BIT && !TARGET_MIPS16
5356    && (register_operand (operands[0], DImode)
5357        || register_operand (operands[1], DImode)
5358        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5359        || operands[1] == CONST0_RTX (DImode))"
5360   "* return mips_sign_extend (insn, operands[0], operands[1]);"
5361   [(set_attr "type"     "move,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5362    (set_attr "mode"     "DI")
5363    (set_attr "length"   "4,4,8,4,8,4,8,4,4,4,4,4,8,8,8,8,8,8,8")])
5364
5365 (define_insn "*movdi_internal2_mips16"
5366   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
5367         (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
5368   "TARGET_64BIT && TARGET_MIPS16
5369    && (register_operand (operands[0], DImode)
5370        || se_register_operand (operands[1], DImode))"
5371   "* return mips_move_2words (operands, insn);"
5372   [(set_attr "type"     "move,move,move,arith,arith,arith,load,load,store,store,hilo")
5373    (set_attr "mode"     "DI")
5374    (set_attr_alternative "length"
5375                 [(const_int 4)
5376                  (const_int 4)
5377                  (const_int 4)
5378                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5379                                (const_int 4)
5380                                (const_int 8))
5381                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5382                                (const_int 8)
5383                                (const_int 12))
5384                  (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
5385                                (const_int 4)
5386                                (const_int 8))
5387                  (const_int 4)
5388                  (const_int 8)
5389                  (const_int 4)
5390                  (const_int 8)
5391                  (const_int 4)])])
5392
5393 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
5394 ;; when the original load is a 4 byte instruction but the add and the
5395 ;; load are 2 2 byte instructions.
5396
5397 (define_split
5398   [(set (match_operand:DI 0 "register_operand" "")
5399         (mem:DI (plus:DI (match_dup 0)
5400                          (match_operand:DI 1 "const_int_operand" ""))))]
5401   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
5402    && !TARGET_DEBUG_D_MODE
5403    && GET_CODE (operands[0]) == REG
5404    && M16_REG_P (REGNO (operands[0]))
5405    && GET_CODE (operands[1]) == CONST_INT
5406    && ((INTVAL (operands[1]) < 0
5407         && INTVAL (operands[1]) >= -0x10)
5408        || (INTVAL (operands[1]) >= 32 * 8
5409            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
5410        || (INTVAL (operands[1]) >= 0
5411            && INTVAL (operands[1]) < 32 * 8
5412            && (INTVAL (operands[1]) & 7) != 0))"
5413   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
5414    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
5415   "
5416 {
5417   HOST_WIDE_INT val = INTVAL (operands[1]);
5418
5419   if (val < 0)
5420     operands[2] = GEN_INT (0);
5421   else if (val >= 32 * 8)
5422     {
5423       int off = val & 7;
5424
5425       operands[1] = GEN_INT (0x8 + off);
5426       operands[2] = GEN_INT (val - off - 0x8);
5427     }
5428   else
5429     {
5430       int off = val & 7;
5431
5432       operands[1] = GEN_INT (off);
5433       operands[2] = GEN_INT (val - off);
5434     }
5435 }")
5436
5437 ;; Handle input reloads in DImode.
5438 ;; This is mainly to handle reloading HILO_REGNUM.  Note that we may
5439 ;; see it as the source or the destination, depending upon which way
5440 ;; reload handles the instruction.
5441 ;; Making the second operand TImode is a trick.  The compiler may
5442 ;; reuse the same register for operand 0 and operand 2.  Using TImode
5443 ;; gives us two registers, so we can always use the one which is not
5444 ;; used.
5445
5446 (define_expand "reload_indi"
5447   [(set (match_operand:DI 0 "register_operand" "=b")
5448         (match_operand:DI 1 "" "b"))
5449    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5450   "TARGET_64BIT"
5451   "
5452 {
5453   rtx scratch = gen_rtx_REG (DImode,
5454                              (REGNO (operands[0]) == REGNO (operands[2])
5455                               ? REGNO (operands[2]) + 1
5456                               : REGNO (operands[2])));
5457
5458   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5459     {
5460       if (GET_CODE (operands[1]) == MEM)
5461         {
5462           rtx memword, offword, hi_word, lo_word;
5463           rtx addr = find_replacement (&XEXP (operands[1], 0));
5464           rtx op1 = replace_equiv_address (operands[1], addr);
5465
5466           scratch = gen_rtx_REG (SImode, REGNO (scratch));
5467           memword = adjust_address (op1, SImode, 0);
5468           offword = adjust_address (op1, SImode, 4);
5469
5470           if (BYTES_BIG_ENDIAN)
5471             {
5472               hi_word = memword;
5473               lo_word = offword;
5474             }
5475           else
5476             {
5477               hi_word = offword;
5478               lo_word = memword;
5479             }
5480           emit_move_insn (scratch, hi_word);
5481           emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
5482           emit_move_insn (scratch, lo_word);
5483           emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
5484           emit_insn (gen_hilo_delay (operands[0]));
5485         }
5486       else
5487         {
5488           emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5489           emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
5490           emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5491           emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5492           emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5493           emit_insn (gen_hilo_delay (operands[0]));
5494         }
5495       DONE;
5496     }
5497   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5498     {
5499       emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
5500       emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5501       emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5502       emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
5503       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5504       emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5505       emit_insn (gen_hilo_delay (operands[1]));
5506       DONE;
5507     }
5508   /* This handles moves between a float register and HI/LO.  */
5509   emit_move_insn (scratch, operands[1]);
5510   emit_move_insn (operands[0], scratch);
5511   DONE;
5512 }")
5513
5514 ;; Handle output reloads in DImode.
5515
5516 ;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5517 ;; use a TImode scratch reg.
5518
5519 (define_expand "reload_outdi"
5520   [(set (match_operand:DI 0 "general_operand" "=b")
5521         (match_operand:DI 1 "se_register_operand" "b"))
5522    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5523   "TARGET_64BIT"
5524   "
5525 {
5526   rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5527
5528   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5529     {
5530       emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5531       emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5532       emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5533       emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5534       emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5535       emit_insn (gen_hilo_delay (operands[0]));
5536       DONE;
5537     }
5538   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5539     {
5540       if (GET_CODE (operands[0]) == MEM)
5541         {
5542           rtx scratch, memword, offword, hi_word, lo_word;
5543           rtx addr = find_replacement (&XEXP (operands[0], 0));
5544           rtx op0 = replace_equiv_address (operands[0], addr);
5545
5546           scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
5547           memword = adjust_address (op0, SImode, 0);
5548           offword = adjust_address (op0, SImode, 4);
5549
5550           if (BYTES_BIG_ENDIAN)
5551             {
5552               hi_word = memword;
5553               lo_word = offword;
5554             }
5555           else
5556             {
5557               hi_word = offword;
5558               lo_word = memword;
5559             }
5560           emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
5561           emit_move_insn (hi_word, scratch);
5562           emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
5563           emit_move_insn (lo_word, scratch);
5564           emit_insn (gen_hilo_delay (operands[1]));
5565         }
5566       else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
5567         {
5568           /* Handle the case where operand[0] is not a 'd' register,
5569              and hence we can not directly move from the HILO register
5570              into it.  */
5571           rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5572           emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5573           emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5574           emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5575           emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
5576           emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
5577           emit_insn (gen_iordi3 (scratch, scratch, scratch2));
5578           emit_insn (gen_movdi (operands[0], scratch));
5579           emit_insn (gen_hilo_delay (operands[1]));
5580         }
5581       else
5582         {
5583           emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5584           emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5585           emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5586           emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5587           emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5588           emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5589           emit_insn (gen_hilo_delay (operands[1]));
5590         }
5591       DONE;
5592     }
5593   /* This handles moves between a float register and HI/LO.  */
5594   emit_move_insn (scratch, operands[1]);
5595   emit_move_insn (operands[0], scratch);
5596   DONE;
5597 }")
5598
5599 ;; 32-bit Integer moves
5600
5601 (define_split
5602   [(set (match_operand:SI 0 "register_operand" "")
5603         (match_operand:SI 1 "large_int" ""))]
5604   "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
5605   [(set (match_dup 0)
5606         (match_dup 2))
5607    (set (match_dup 0)
5608         (ior:SI (match_dup 0)
5609                 (match_dup 3)))]
5610   "
5611 {
5612   operands[2] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
5613                                              & BITMASK_UPPER16,
5614                                              SImode));
5615   operands[3] = GEN_INT (INTVAL (operands[1]) & BITMASK_LOWER16);
5616 }")
5617
5618 ;; Unlike most other insns, the move insns can't be split with
5619 ;; different predicates, because register spilling and other parts of
5620 ;; the compiler, have memoized the insn number already.
5621
5622 (define_expand "movsi"
5623   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5624         (match_operand:SI 1 "general_operand" ""))]
5625   ""
5626   "
5627 {
5628   if (mips_split_addresses && mips_check_split (operands[1], SImode))
5629     {
5630       enum machine_mode mode = GET_MODE (operands[0]);
5631       rtx tem = ((reload_in_progress | reload_completed)
5632                  ? operands[0] : gen_reg_rtx (mode));
5633
5634       emit_insn (gen_rtx_SET (VOIDmode, tem,
5635                               gen_rtx_HIGH (mode, operands[1])));
5636
5637       operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
5638     }
5639
5640   /* If we are generating embedded PIC code, and we are referring to a
5641      symbol in the .text section, we must use an offset from the start
5642      of the function.  */
5643   if (TARGET_EMBEDDED_PIC
5644       && (GET_CODE (operands[1]) == LABEL_REF
5645           || (GET_CODE (operands[1]) == SYMBOL_REF
5646               && ! SYMBOL_REF_FLAG (operands[1]))))
5647     {
5648       rtx temp;
5649
5650       temp = embedded_pic_offset (operands[1]);
5651       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
5652                            force_reg (SImode, temp));
5653       emit_move_insn (operands[0], force_reg (SImode, temp));
5654       DONE;
5655     }
5656
5657   /* If operands[1] is a constant address invalid for pic, then we need to
5658      handle it just like LEGITIMIZE_ADDRESS does.  */
5659   if (flag_pic && pic_address_needs_scratch (operands[1]))
5660     {
5661       rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
5662       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5663
5664       if (! SMALL_INT (temp2))
5665         temp2 = force_reg (SImode, temp2);
5666
5667       emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, temp2));
5668       DONE;
5669     }
5670
5671   /* On the mips16, we can handle a GP relative reference by adding in
5672      $gp.  We need to check the name to see whether this is a string
5673      constant.  */
5674   if (TARGET_MIPS16
5675       && register_operand (operands[0], SImode)
5676       && GET_CODE (operands[1]) == SYMBOL_REF
5677       && SYMBOL_REF_FLAG (operands[1]))
5678     {
5679       const char *name = XSTR (operands[1], 0);
5680
5681       if (name[0] != '*'
5682           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5683                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5684         {
5685           rtx base_reg;
5686
5687           if (reload_in_progress || reload_completed)
5688             {
5689               /* We need to reload this address.  In this case we
5690                  aren't going to have a chance to combine loading the
5691                  address with the load or store.  That means that we
5692                  can either generate a 2 byte move followed by a 4
5693                  byte addition, or a 2 byte load with a 4 byte entry
5694                  in the constant table.  Since the entry in the
5695                  constant table might be shared, we're better off, on
5696                  average, loading the address from the constant table.  */
5697               emit_move_insn (operands[0],
5698                               force_const_mem (SImode, operands[1]));
5699               DONE;
5700             }
5701
5702           base_reg = gen_reg_rtx (Pmode);
5703           emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5704
5705           emit_move_insn (operands[0],
5706                           gen_rtx (PLUS, Pmode, base_reg,
5707                                    mips16_gp_offset (operands[1])));
5708           DONE;
5709         }
5710     }
5711
5712   if ((reload_in_progress | reload_completed) == 0
5713       && !register_operand (operands[0], SImode)
5714       && !register_operand (operands[1], SImode)
5715       && (TARGET_MIPS16
5716           || GET_CODE (operands[1]) != CONST_INT
5717           || INTVAL (operands[1]) != 0))
5718     {
5719       rtx temp = force_reg (SImode, operands[1]);
5720       emit_move_insn (operands[0], temp);
5721       DONE;
5722     }
5723 }")
5724
5725 ;; We can only store $ra directly into a small sp offset.  Should the
5726 ;; offset be too wide, non-constant or not sp-based, leave it up to
5727 ;; reload to choose a scratch register.
5728
5729 (define_insn ""
5730   [(set (mem:SI (plus:SI (reg:SI 29)
5731                          (match_operand:SI 0 "small_int" "n")))
5732         (reg:SI 31))]
5733   "TARGET_MIPS16"
5734   "sw\\t$31,%0($sp)"
5735   [(set_attr "type"     "store")
5736    (set_attr "mode"     "SI")
5737    (set_attr_alternative
5738     "length"
5739     [(if_then_else
5740       (lt (symbol_ref "(unsigned HOST_WIDE_INT) INTVAL (operands[0])")
5741           (const_int 1024))
5742       (const_int 4)
5743       (const_int 8))])])
5744
5745 ;; The difference between these two is whether or not ints are allowed
5746 ;; in FP registers (off by default, use -mdebugh to enable).
5747
5748 (define_insn "movsi_internal"
5749   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*f,*f,*f,?*f,*d,*R,*m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5750         (match_operand:SI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f,*d*J,*R,*m,*f,*f,*f,*z,*d,J,*x,*d,*a,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5751   "!TARGET_MIPS16
5752    && (register_operand (operands[0], SImode)
5753        || register_operand (operands[1], SImode)
5754        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5755   "* return mips_move_1word (operands, insn, FALSE);"
5756   [(set_attr "type"     "move,arith,arith,load,load,store,store,move,xfer,load,load,xfer,store,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5757    (set_attr "mode"     "SI")
5758    (set_attr "length"   "4,4,8,4,8,4,8,4,4,4,8,4,4,8,4,4,4,4,4,4,4,4,8,4,4,8")])
5759
5760 ;; This is the mips16 movsi instruction.  We accept a small integer as
5761 ;; the source if the destination is a GP memory reference.  This is
5762 ;; because we want the combine pass to turn adding a GP reference to a
5763 ;; register into a direct GP reference, but the combine pass will pass
5764 ;; in the source as a constant if it finds an equivalent one.  If the
5765 ;; instruction is recognized, reload will force the constant back out
5766 ;; into a register.
5767
5768 (define_insn ""
5769   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d,*d")
5770         (match_operand:SI 1 "move_operand" "d,d,y,K,N,s,R,m,d,d,*x,*a"))]
5771   "TARGET_MIPS16
5772    && (register_operand (operands[0], SImode)
5773        || register_operand (operands[1], SImode)
5774        || (GET_CODE (operands[0]) == MEM
5775            && GET_CODE (XEXP (operands[0], 0)) == PLUS
5776            && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
5777            && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
5778            && GET_CODE (operands[1]) == CONST_INT
5779            && (SMALL_INT (operands[1])
5780                || SMALL_INT_UNSIGNED (operands[1]))))"
5781   "* return mips_move_1word (operands, insn, FALSE);"
5782   [(set_attr "type"     "move,move,move,arith,arith,arith,load,load,store,store,hilo,hilo")
5783    (set_attr "mode"     "SI")
5784    (set_attr_alternative "length"
5785                 [(const_int 4)
5786                  (const_int 4)
5787                  (const_int 4)
5788                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5789                                (const_int 4)
5790                                (const_int 8))
5791                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5792                                (const_int 8)
5793                                (const_int 12))
5794                  (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
5795                                (const_int 4)
5796                                (const_int 8))
5797                  (const_int 4)
5798                  (const_int 8)
5799                  (const_int 4)
5800                  (const_int 8)
5801                  (const_int 4)
5802                  (const_int 4)])])
5803
5804 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
5805 ;; when the original load is a 4 byte instruction but the add and the
5806 ;; load are 2 2 byte instructions.
5807
5808 (define_split
5809   [(set (match_operand:SI 0 "register_operand" "")
5810         (mem:SI (plus:SI (match_dup 0)
5811                          (match_operand:SI 1 "const_int_operand" ""))))]
5812   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5813    && GET_CODE (operands[0]) == REG
5814    && M16_REG_P (REGNO (operands[0]))
5815    && GET_CODE (operands[1]) == CONST_INT
5816    && ((INTVAL (operands[1]) < 0
5817         && INTVAL (operands[1]) >= -0x80)
5818        || (INTVAL (operands[1]) >= 32 * 4
5819            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5820        || (INTVAL (operands[1]) >= 0
5821            && INTVAL (operands[1]) < 32 * 4
5822            && (INTVAL (operands[1]) & 3) != 0))"
5823   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5824    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
5825   "
5826 {
5827   HOST_WIDE_INT val = INTVAL (operands[1]);
5828
5829   if (val < 0)
5830     operands[2] = GEN_INT (0);
5831   else if (val >= 32 * 4)
5832     {
5833       int off = val & 3;
5834
5835       operands[1] = GEN_INT (0x7c + off);
5836       operands[2] = GEN_INT (val - off - 0x7c);
5837     }
5838   else
5839     {
5840       int off = val & 3;
5841
5842       operands[1] = GEN_INT (off);
5843       operands[2] = GEN_INT (val - off);
5844     }
5845 }")
5846
5847 ;; On the mips16, we can split a load of certain constants into a load
5848 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
5849 ;; instructions.
5850
5851 (define_split
5852   [(set (match_operand:SI 0 "register_operand" "")
5853         (match_operand:SI 1 "const_int_operand" ""))]
5854   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5855    && GET_CODE (operands[0]) == REG
5856    && M16_REG_P (REGNO (operands[0]))
5857    && GET_CODE (operands[1]) == CONST_INT
5858    && INTVAL (operands[1]) >= 0x100
5859    && INTVAL (operands[1]) <= 0xff + 0x7f"
5860   [(set (match_dup 0) (match_dup 1))
5861    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5862   "
5863 {
5864   int val = INTVAL (operands[1]);
5865
5866   operands[1] = GEN_INT (0xff);
5867   operands[2] = GEN_INT (val - 0xff);
5868 }")
5869
5870 ;; On the mips16, we can split a load of a negative constant into a
5871 ;; load and a neg.  That's what mips_move_1word will generate anyhow.
5872
5873 (define_split
5874   [(set (match_operand:SI 0 "register_operand" "")
5875         (match_operand:SI 1 "const_int_operand" ""))]
5876   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5877    && GET_CODE (operands[0]) == REG
5878    && M16_REG_P (REGNO (operands[0]))
5879    && GET_CODE (operands[1]) == CONST_INT
5880    && INTVAL (operands[1]) < 0
5881    && INTVAL (operands[1]) > - 0x8000"
5882   [(set (match_dup 0) (match_dup 1))
5883    (set (match_dup 0) (neg:SI (match_dup 0)))]
5884   "
5885 {
5886   operands[1] = GEN_INT (- INTVAL (operands[1]));
5887 }")
5888
5889 ;; Reload HILO_REGNUM in SI mode.  This needs a scratch register in
5890 ;; order to set the sign bit correctly in the HI register.
5891
5892 (define_expand "reload_outsi"
5893   [(set (match_operand:SI 0 "general_operand" "=b")
5894         (match_operand:SI 1 "register_operand" "b"))
5895    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5896   "TARGET_64BIT || TARGET_MIPS16"
5897   "
5898 {
5899   if (TARGET_64BIT
5900       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5901     {
5902       emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
5903       emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5904       emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
5905       emit_insn (gen_hilo_delay (operands[0]));
5906       DONE;
5907     }
5908   /* Use a mult to reload LO on mips16.  ??? This is hideous.  */
5909   if (TARGET_MIPS16
5910       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5911     {
5912       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5913       /* This is gen_mulsi3_internal, but we need to fill in the
5914          scratch registers.  */
5915       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5916                           gen_rtvec (3,
5917                                      gen_rtx (SET, VOIDmode,
5918                                               operands[0],
5919                                               gen_rtx (MULT, SImode,
5920                                                        operands[1],
5921                                                        operands[2])),
5922                                      gen_rtx (CLOBBER, VOIDmode,
5923                                               gen_rtx (REG, SImode, 64)),
5924                                      gen_rtx (CLOBBER, VOIDmode,
5925                                               gen_rtx (REG, SImode, 66)))));
5926       DONE;
5927     }
5928   /* FIXME: I don't know how to get a value into the HI register.  */
5929   if (GET_CODE (operands[0]) == REG
5930       && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5931           : GP_REG_P (REGNO (operands[0]))))
5932     {
5933       emit_move_insn (operands[0], operands[1]);
5934       DONE;
5935     }
5936   /* This handles moves between a float register and HI/LO.  */
5937   emit_move_insn (operands[2], operands[1]);
5938   emit_move_insn (operands[0], operands[2]);
5939   DONE;
5940 }")
5941
5942 ;; Reload a value into HI or LO.  There is no mthi or mtlo on mips16,
5943 ;; so we use a mult.  ??? This is hideous, and we ought to figure out
5944 ;; something better.
5945
5946 ;; We use no predicate for operand1, because it may be a PLUS, and there
5947 ;; is no convenient predicate for that.
5948
5949 (define_expand "reload_insi"
5950   [(set (match_operand:SI 0 "register_operand" "=b")
5951         (match_operand:SI 1 "" "b"))
5952    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5953   "TARGET_MIPS16"
5954   "
5955 {
5956   if (TARGET_MIPS16
5957       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5958     {
5959       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5960       /* This is gen_mulsi3_internal, but we need to fill in the
5961          scratch registers.  */
5962       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5963                           gen_rtvec (3,
5964                                      gen_rtx (SET, VOIDmode,
5965                                               operands[0],
5966                                               gen_rtx (MULT, SImode,
5967                                                        operands[1],
5968                                                        operands[2])),
5969                                      gen_rtx (CLOBBER, VOIDmode,
5970                                               gen_rtx (REG, SImode, 64)),
5971                                      gen_rtx (CLOBBER, VOIDmode,
5972                                               gen_rtx (REG, SImode, 66)))));
5973       DONE;
5974     }
5975
5976   /* If this is a plus, then this must be an add of the stack pointer against
5977      either a hard register or a pseudo.  */
5978   if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5979     {
5980       rtx plus_op;
5981
5982       if (XEXP (operands[1], 0) == stack_pointer_rtx)
5983         plus_op = XEXP (operands[1], 1);
5984       else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5985         plus_op = XEXP (operands[1], 0);
5986       else
5987         abort ();
5988
5989       /* We should have a register now.  */
5990       if (GET_CODE (plus_op) != REG)
5991         abort ();
5992
5993       if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5994         {
5995           /* We have to have at least one temporary register which is not
5996              overlapping plus_op.  */
5997           if (! rtx_equal_p (plus_op, operands[0]))
5998             {
5999               emit_move_insn (operands[0], stack_pointer_rtx);
6000               emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
6001             }
6002           else if (! rtx_equal_p (plus_op, operands[2]))
6003             {
6004               emit_move_insn (operands[2], stack_pointer_rtx);
6005               emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
6006             }
6007           else
6008             abort ();
6009         }
6010       else
6011         {
6012           /* We need two registers in this case.  */
6013           if (! rtx_equal_p (operands[0], operands[2]))
6014             {
6015               emit_move_insn (operands[0], stack_pointer_rtx);
6016               emit_move_insn (operands[2], plus_op);
6017               emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
6018             }
6019           else
6020             abort ();
6021         }
6022       DONE;
6023     }
6024
6025   /* FIXME: I don't know how to get a value into the HI register.  */
6026   emit_move_insn (operands[0], operands[1]);
6027   DONE;
6028 }")
6029
6030 ;; This insn is for the unspec delay for HILO.
6031
6032 (define_insn "hilo_delay"
6033   [(unspec [(match_operand 0 "register_operand" "=b")] UNSPEC_HILO_DELAY)]
6034   ""
6035   ""
6036   [(set_attr "type" "nop")
6037    (set_attr "mode" "none")
6038    (set_attr "can_delay" "no")])
6039
6040 ;; This insn handles moving CCmode values.  It's really just a
6041 ;; slightly simplified copy of movsi_internal2, with additional cases
6042 ;; to move a condition register to a general register and to move
6043 ;; between the general registers and the floating point registers.
6044
6045 (define_insn "movcc"
6046   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
6047         (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
6048   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
6049   "* return mips_move_1word (operands, insn, FALSE);"
6050   [(set_attr "type"     "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
6051    (set_attr "mode"     "SI")
6052    (set_attr "length"   "8,4,4,8,4,8,4,4,4,4,8,4,8")])
6053
6054 ;; Reload condition code registers.  reload_incc and reload_outcc
6055 ;; both handle moves from arbitrary operands into condition code
6056 ;; registers.  reload_incc handles the more common case in which
6057 ;; a source operand is constrained to be in a condition-code
6058 ;; register, but has not been allocated to one.
6059 ;;
6060 ;; Sometimes, such as in movcc, we have a CCmode destination whose
6061 ;; constraints do not include 'z'.  reload_outcc handles the case
6062 ;; when such an operand is allocated to a condition-code register.
6063 ;;
6064 ;; Note that reloads from a condition code register to some
6065 ;; other location can be done using ordinary moves.  Moving
6066 ;; into a GPR takes a single movcc, moving elsewhere takes
6067 ;; two.  We can leave these cases to the generic reload code.
6068 (define_expand "reload_incc"
6069   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
6070         (match_operand:CC 1 "general_operand" ""))
6071    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
6072   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
6073   "
6074 {
6075   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
6076   DONE;
6077 }")
6078
6079 (define_expand "reload_outcc"
6080   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
6081         (match_operand:CC 1 "register_operand" ""))
6082    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
6083   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
6084   "
6085 {
6086   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
6087   DONE;
6088 }")
6089
6090 ;; MIPS4 supports loading and storing a floating point register from
6091 ;; the sum of two general registers.  We use two versions for each of
6092 ;; these four instructions: one where the two general registers are
6093 ;; SImode, and one where they are DImode.  This is because general
6094 ;; registers will be in SImode when they hold 32 bit values, but,
6095 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
6096 ;; instructions will still work correctly.
6097
6098 ;; ??? Perhaps it would be better to support these instructions by
6099 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
6100 ;; these instructions can only be used to load and store floating
6101 ;; point registers, that would probably cause trouble in reload.
6102
6103 (define_insn ""
6104   [(set (match_operand:SF 0 "register_operand" "=f")
6105         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
6106                          (match_operand:SI 2 "register_operand" "d"))))]
6107   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
6108   "lwxc1\\t%0,%1(%2)"
6109   [(set_attr "type"     "load")
6110    (set_attr "mode"     "SF")])
6111
6112 (define_insn ""
6113   [(set (match_operand:SF 0 "register_operand" "=f")
6114         (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
6115                          (match_operand:DI 2 "se_register_operand" "d"))))]
6116   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
6117   "lwxc1\\t%0,%1(%2)"
6118   [(set_attr "type"     "load")
6119    (set_attr "mode"     "SF")])
6120
6121 (define_insn ""
6122   [(set (match_operand:DF 0 "register_operand" "=f")
6123         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
6124                          (match_operand:SI 2 "register_operand" "d"))))]
6125   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6126   "ldxc1\\t%0,%1(%2)"
6127   [(set_attr "type"     "load")
6128    (set_attr "mode"     "DF")])
6129
6130 (define_insn ""
6131   [(set (match_operand:DF 0 "register_operand" "=f")
6132         (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
6133                          (match_operand:DI 2 "se_register_operand" "d"))))]
6134   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6135   "ldxc1\\t%0,%1(%2)"
6136   [(set_attr "type"     "load")
6137    (set_attr "mode"     "DF")])
6138
6139 (define_insn ""
6140   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
6141                          (match_operand:SI 2 "register_operand" "d")))
6142         (match_operand:SF 0 "register_operand" "f"))]
6143   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
6144   "swxc1\\t%0,%1(%2)"
6145   [(set_attr "type"     "store")
6146    (set_attr "mode"     "SF")])
6147
6148 (define_insn ""
6149   [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
6150                          (match_operand:DI 2 "se_register_operand" "d")))
6151         (match_operand:SF 0 "register_operand" "f"))]
6152   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
6153   "swxc1\\t%0,%1(%2)"
6154   [(set_attr "type"     "store")
6155    (set_attr "mode"     "SF")])
6156
6157 (define_insn ""
6158   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
6159                          (match_operand:SI 2 "register_operand" "d")))
6160         (match_operand:DF 0 "register_operand" "f"))]
6161   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6162   "sdxc1\\t%0,%1(%2)"
6163   [(set_attr "type"     "store")
6164    (set_attr "mode"     "DF")])
6165
6166 (define_insn ""
6167   [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
6168                          (match_operand:DI 2 "se_register_operand" "d")))
6169         (match_operand:DF 0 "register_operand" "f"))]
6170   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6171   "sdxc1\\t%0,%1(%2)"
6172   [(set_attr "type"     "store")
6173    (set_attr "mode"     "DF")])
6174
6175 ;; 16-bit Integer moves
6176
6177 ;; Unlike most other insns, the move insns can't be split with
6178 ;; different predicates, because register spilling and other parts of
6179 ;; the compiler, have memoized the insn number already.
6180 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6181
6182 (define_expand "movhi"
6183   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6184         (match_operand:HI 1 "general_operand" ""))]
6185   ""
6186   "
6187 {
6188   if ((reload_in_progress | reload_completed) == 0
6189       && !register_operand (operands[0], HImode)
6190       && !register_operand (operands[1], HImode)
6191       && (TARGET_MIPS16
6192           || (GET_CODE (operands[1]) != CONST_INT
6193           || INTVAL (operands[1]) != 0)))
6194     {
6195       rtx temp = force_reg (HImode, operands[1]);
6196       emit_move_insn (operands[0], temp);
6197       DONE;
6198     }
6199 }")
6200
6201 ;; The difference between these two is whether or not ints are allowed
6202 ;; in FP registers (off by default, use -mdebugh to enable).
6203
6204 (define_insn "movhi_internal"
6205   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
6206         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6207   "!TARGET_MIPS16
6208    && (register_operand (operands[0], HImode)
6209        || register_operand (operands[1], HImode)
6210        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6211   "* return mips_move_1word (operands, insn, TRUE);"
6212   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6213    (set_attr "mode"     "HI")
6214    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,4")])
6215
6216 (define_insn ""
6217   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6218         (match_operand:HI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
6219   "TARGET_MIPS16
6220    && (register_operand (operands[0], HImode)
6221        || register_operand (operands[1], HImode))"
6222   "* return mips_move_1word (operands, insn, TRUE);"
6223   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
6224    (set_attr "mode"     "HI")
6225    (set_attr_alternative "length"
6226                 [(const_int 4)
6227                  (const_int 4)
6228                  (const_int 4)
6229                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6230                                (const_int 4)
6231                                (const_int 8))
6232                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6233                                (const_int 8)
6234                                (const_int 12))
6235                  (const_int 4)
6236                  (const_int 8)
6237                  (const_int 4)
6238                  (const_int 8)
6239                  (const_int 4)])])
6240
6241
6242 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
6243 ;; when the original load is a 4 byte instruction but the add and the
6244 ;; load are 2 2 byte instructions.
6245
6246 (define_split
6247   [(set (match_operand:HI 0 "register_operand" "")
6248         (mem:HI (plus:SI (match_dup 0)
6249                          (match_operand:SI 1 "const_int_operand" ""))))]
6250   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6251    && GET_CODE (operands[0]) == REG
6252    && M16_REG_P (REGNO (operands[0]))
6253    && GET_CODE (operands[1]) == CONST_INT
6254    && ((INTVAL (operands[1]) < 0
6255         && INTVAL (operands[1]) >= -0x80)
6256        || (INTVAL (operands[1]) >= 32 * 2
6257            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
6258        || (INTVAL (operands[1]) >= 0
6259            && INTVAL (operands[1]) < 32 * 2
6260            && (INTVAL (operands[1]) & 1) != 0))"
6261   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6262    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
6263   "
6264 {
6265   HOST_WIDE_INT val = INTVAL (operands[1]);
6266
6267   if (val < 0)
6268     operands[2] = GEN_INT (0);
6269   else if (val >= 32 * 2)
6270     {
6271       int off = val & 1;
6272
6273       operands[1] = GEN_INT (0x7e + off);
6274       operands[2] = GEN_INT (val - off - 0x7e);
6275     }
6276   else
6277     {
6278       int off = val & 1;
6279
6280       operands[1] = GEN_INT (off);
6281       operands[2] = GEN_INT (val - off);
6282     }
6283 }")
6284
6285 ;; 8-bit Integer moves
6286
6287 ;; Unlike most other insns, the move insns can't be split with
6288 ;; different predicates, because register spilling and other parts of
6289 ;; the compiler, have memoized the insn number already.
6290 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6291
6292 (define_expand "movqi"
6293   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6294         (match_operand:QI 1 "general_operand" ""))]
6295   ""
6296   "
6297 {
6298   if ((reload_in_progress | reload_completed) == 0
6299       && !register_operand (operands[0], QImode)
6300       && !register_operand (operands[1], QImode)
6301       && (TARGET_MIPS16
6302           || (GET_CODE (operands[1]) != CONST_INT
6303           || INTVAL (operands[1]) != 0)))
6304     {
6305       rtx temp = force_reg (QImode, operands[1]);
6306       emit_move_insn (operands[0], temp);
6307       DONE;
6308     }
6309 }")
6310
6311 ;; The difference between these two is whether or not ints are allowed
6312 ;; in FP registers (off by default, use -mdebugh to enable).
6313
6314 (define_insn "movqi_internal"
6315   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
6316         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6317   "!TARGET_MIPS16
6318    && (register_operand (operands[0], QImode)
6319        || register_operand (operands[1], QImode)
6320        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6321   "* return mips_move_1word (operands, insn, TRUE);"
6322   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6323    (set_attr "mode"     "QI")
6324    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,4")])
6325
6326 (define_insn ""
6327   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6328         (match_operand:QI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
6329   "TARGET_MIPS16
6330    && (register_operand (operands[0], QImode)
6331        || register_operand (operands[1], QImode))"
6332   "* return mips_move_1word (operands, insn, TRUE);"
6333   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
6334    (set_attr "mode"     "QI")
6335    (set_attr_alternative "length"
6336                 [(const_int 4)
6337                  (const_int 4)
6338                  (const_int 4)
6339                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6340                                (const_int 4)
6341                                (const_int 8))
6342                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6343                                (const_int 8)
6344                                (const_int 12))
6345                  (const_int 4)
6346                  (const_int 8)
6347                  (const_int 4)
6348                  (const_int 8)
6349                  (const_int 4)])])
6350
6351
6352 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
6353 ;; when the original load is a 4 byte instruction but the add and the
6354 ;; load are 2 2 byte instructions.
6355
6356 (define_split
6357   [(set (match_operand:QI 0 "register_operand" "")
6358         (mem:QI (plus:SI (match_dup 0)
6359                          (match_operand:SI 1 "const_int_operand" ""))))]
6360   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6361    && GET_CODE (operands[0]) == REG
6362    && M16_REG_P (REGNO (operands[0]))
6363    && GET_CODE (operands[1]) == CONST_INT
6364    && ((INTVAL (operands[1]) < 0
6365         && INTVAL (operands[1]) >= -0x80)
6366        || (INTVAL (operands[1]) >= 32
6367            && INTVAL (operands[1]) <= 31 + 0x7f))"
6368   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6369    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
6370   "
6371 {
6372   HOST_WIDE_INT val = INTVAL (operands[1]);
6373
6374   if (val < 0)
6375     operands[2] = GEN_INT (0);
6376   else
6377     {
6378       operands[1] = GEN_INT (0x7f);
6379       operands[2] = GEN_INT (val - 0x7f);
6380     }
6381 }")
6382
6383 ;; 32-bit floating point moves
6384
6385 (define_expand "movsf"
6386   [(set (match_operand:SF 0 "nonimmediate_operand" "")
6387         (match_operand:SF 1 "general_operand" ""))]
6388   ""
6389   "
6390 {
6391   if ((reload_in_progress | reload_completed) == 0
6392       && !register_operand (operands[0], SFmode)
6393       && !nonmemory_operand (operands[1], SFmode))
6394     operands[1] = force_reg (SFmode, operands[1]);
6395 }")
6396
6397 (define_insn "movsf_internal1"
6398   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
6399         (match_operand:SF 1 "general_operand" "f,G,R,m,fG,fG,*d,*f,*G*d,*R,*m,*d,*d"))]
6400   "TARGET_HARD_FLOAT
6401    && (register_operand (operands[0], SFmode)
6402        || nonmemory_operand (operands[1], SFmode))"
6403   "* return mips_move_1word (operands, insn, FALSE);"
6404   [(set_attr "type"     "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
6405    (set_attr "mode"     "SF")
6406    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,8,4,8")])
6407
6408 (define_insn "movsf_internal2"
6409   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
6410         (match_operand:SF 1 "general_operand" "      Gd,R,m,d,d"))]
6411   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
6412    && (register_operand (operands[0], SFmode)
6413        || nonmemory_operand (operands[1], SFmode))"
6414   "* return mips_move_1word (operands, insn, FALSE);"
6415   [(set_attr "type"     "move,load,load,store,store")
6416    (set_attr "mode"     "SF")
6417    (set_attr "length"   "4,4,8,4,8")])
6418
6419 (define_insn ""
6420   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
6421         (match_operand:SF 1 "nonimmediate_operand" "d,d,y,R,m,d,d"))]
6422   "TARGET_MIPS16
6423    && (register_operand (operands[0], SFmode)
6424        || register_operand (operands[1], SFmode))"
6425   "* return mips_move_1word (operands, insn, FALSE);"
6426   [(set_attr "type"     "move,move,move,load,load,store,store")
6427    (set_attr "mode"     "SF")
6428    (set_attr "length"   "4,4,4,4,8,4,8")])
6429
6430
6431 ;; 64-bit floating point moves
6432
6433 (define_expand "movdf"
6434   [(set (match_operand:DF 0 "nonimmediate_operand" "")
6435         (match_operand:DF 1 "general_operand" ""))]
6436   ""
6437   "
6438 {
6439   if ((reload_in_progress | reload_completed) == 0
6440       && !register_operand (operands[0], DFmode)
6441       && !nonmemory_operand (operands[1], DFmode))
6442     operands[1] = force_reg (DFmode, operands[1]);
6443 }")
6444
6445 (define_insn "movdf_internal1"
6446   [(set (match_operand:DF 0 "nonimmediate_operand"  "=f,f,f,f,R,To,*f,*d,*d,*d,*d,*R,*T")
6447        (match_operand:DF 1 "general_operand"  "f,G,R,To,fG,fG,*d,*f,*d*G,*R,*T,*d,*d"))]
6448   "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
6449    && TARGET_DOUBLE_FLOAT
6450    && (register_operand (operands[0], DFmode)
6451        || nonmemory_operand (operands[1], DFmode))"
6452   "* return mips_move_2words (operands, insn); "
6453   [(set_attr "type"    "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
6454    (set_attr "mode"    "DF")
6455    (set_attr "length"  "4,8,8,16,8,16,8,8,8,8,16,8,16")])
6456
6457 (define_insn "movdf_internal1a"
6458   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,*d,*d,*To,*R,*d")
6459         (match_operand:DF 1 "general_operand"      " f,To,f,G,f,G,*To,*R,*d,*d,*d"))]
6460   "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
6461    && TARGET_DOUBLE_FLOAT
6462    && (register_operand (operands[0], DFmode)
6463        || nonmemory_operand (operands[1], DFmode))"
6464   "* return mips_move_2words (operands, insn); "
6465   [(set_attr "type"     "move,load,store,store,store,store,load,load,store,store,move")
6466    (set_attr "mode"     "DF")
6467    (set_attr "length"   "4,8,4,4,8,8,8,4,8,4,4")])
6468
6469 (define_insn "movdf_internal2"
6470   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To,d,f,f")
6471         (match_operand:DF 1 "general_operand" "dG,R,To,d,d,f,d,f"))]
6472   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
6473    && (register_operand (operands[0], DFmode)
6474        || nonmemory_operand (operands[1], DFmode))"
6475   "* return mips_move_2words (operands, insn); "
6476   [(set_attr "type"     "move,load,load,store,store,xfer,load,move")
6477    (set_attr "mode"     "DF")
6478    (set_attr "length"   "8,8,16,8,16,8,8,4")])
6479
6480 (define_insn ""
6481   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
6482         (match_operand:DF 1 "nonimmediate_operand" "d,d,y,R,To,d,d"))]
6483   "TARGET_MIPS16
6484    && (register_operand (operands[0], DFmode)
6485        || register_operand (operands[1], DFmode))"
6486   "* return mips_move_2words (operands, insn);"
6487   [(set_attr "type"     "move,move,move,load,load,store,store")
6488    (set_attr "mode"     "DF")
6489    (set_attr "length"   "8,8,8,8,16,8,16")])
6490
6491 (define_split
6492   [(set (match_operand:DF 0 "register_operand" "")
6493         (match_operand:DF 1 "register_operand" ""))]
6494   "reload_completed && !TARGET_64BIT
6495    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6496    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6497    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
6498   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
6499    (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
6500   "")
6501
6502 ;; Instructions to load the global pointer register.
6503 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
6504 ;; uses in front of it.  All symbol_refs implicitly use the gp reg.
6505
6506 (define_insn "loadgp"
6507   [(set (reg:DI 28)
6508         (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
6509                              (match_operand:DI 1 "register_operand" "")]
6510                             UNSPEC_LOADGP))
6511    (clobber (reg:DI 1))]
6512   ""
6513   "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
6514   [(set_attr "type"     "move")
6515    (set_attr "mode"     "DI")
6516    (set_attr "length"   "12")])
6517 \f
6518 ;; Block moves, see mips.c for more details.
6519 ;; Argument 0 is the destination
6520 ;; Argument 1 is the source
6521 ;; Argument 2 is the length
6522 ;; Argument 3 is the alignment
6523
6524 (define_expand "movstrsi"
6525   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6526                    (match_operand:BLK 1 "general_operand" ""))
6527               (use (match_operand:SI 2 "arith32_operand" ""))
6528               (use (match_operand:SI 3 "immediate_operand" ""))])]
6529   "!TARGET_MIPS16"
6530   "
6531 {
6532   if (operands[0])              /* avoid unused code messages */
6533     {
6534       expand_block_move (operands);
6535       DONE;
6536     }
6537 }")
6538
6539 ;; Insn generated by block moves
6540
6541 (define_insn "movstrsi_internal"
6542   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6543         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6544    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6545    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6546    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6547    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6548    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6549    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6550    (use (const_int 0))]                                 ;; normal block move
6551   ""
6552   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6553   [(set_attr "type"     "store")
6554    (set_attr "mode"     "none")
6555    (set_attr "length"   "80")])
6556
6557 ;; We need mips16 versions, because an offset from the stack pointer
6558 ;; is not offsettable, since the stack pointer can only handle 4 and 8
6559 ;; byte loads.
6560
6561 (define_insn ""
6562   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6563         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6564    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6565    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6566    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6567    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6568    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6569    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6570    (use (const_int 0))]                                 ;; normal block move
6571   "TARGET_MIPS16"
6572   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6573   [(set_attr "type"     "multi")
6574    (set_attr "mode"     "none")
6575    (set_attr "length"   "80")])
6576
6577 ;; Split a block move into 2 parts, the first part is everything
6578 ;; except for the last move, and the second part is just the last
6579 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
6580 ;; fill a delay slot.  This also prevents a bug in delayed branches
6581 ;; from showing up, which reuses one of the registers in our clobbers.
6582
6583 ;; ??? Disabled because it doesn't preserve alias information for
6584 ;; operands 0 and 1.  Also, the rtl for the second insn doesn't mention
6585 ;; that it uses the registers clobbered by the first.
6586 ;;
6587 ;; It would probably be better to split the block into individual
6588 ;; instructions instead.
6589 (define_split
6590   [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6591         (mem:BLK (match_operand:SI 1 "register_operand" "")))
6592    (clobber (match_operand:SI 4 "register_operand" ""))
6593    (clobber (match_operand:SI 5 "register_operand" ""))
6594    (clobber (match_operand:SI 6 "register_operand" ""))
6595    (clobber (match_operand:SI 7 "register_operand" ""))
6596    (use (match_operand:SI 2 "small_int" ""))
6597    (use (match_operand:SI 3 "small_int" ""))
6598    (use (const_int 0))]
6599
6600   "reload_completed && 0 && INTVAL (operands[2]) > 0"
6601
6602   ;; All but the last move
6603   [(parallel [(set (mem:BLK (match_dup 0))
6604                    (mem:BLK (match_dup 1)))
6605               (clobber (match_dup 4))
6606               (clobber (match_dup 5))
6607               (clobber (match_dup 6))
6608               (clobber (match_dup 7))
6609               (use (match_dup 2))
6610               (use (match_dup 3))
6611               (use (const_int 1))])
6612
6613    ;; The last store, so it can fill a delay slot
6614    (parallel [(set (mem:BLK (match_dup 0))
6615                    (mem:BLK (match_dup 1)))
6616               (clobber (match_dup 4))
6617               (clobber (match_dup 5))
6618               (clobber (match_dup 6))
6619               (clobber (match_dup 7))
6620               (use (match_dup 2))
6621               (use (match_dup 3))
6622               (use (const_int 2))])]
6623
6624   "")
6625
6626 (define_insn "movstrsi_internal2"
6627   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6628         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6629    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6630    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6631    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6632    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6633    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6634    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6635    (use (const_int 1))]                                 ;; all but last store
6636   ""
6637   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6638   [(set_attr "type"     "store")
6639    (set_attr "mode"     "none")
6640    (set_attr "length"   "80")])
6641
6642 (define_insn ""
6643   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6644         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6645    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6646    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6647    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6648    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6649    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6650    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6651    (use (const_int 1))]                                 ;; all but last store
6652   "TARGET_MIPS16"
6653   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6654   [(set_attr "type"     "multi")
6655    (set_attr "mode"     "none")
6656    (set_attr "length"   "80")])
6657
6658 (define_insn "movstrsi_internal3"
6659   [(set (match_operand:BLK 0 "memory_operand" "=Ro")    ;; destination
6660         (match_operand:BLK 1 "memory_operand" "Ro"))    ;; source
6661    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6662    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6663    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6664    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6665    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6666    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6667    (use (const_int 2))]                                 ;; just last store of block move
6668   ""
6669   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6670   [(set_attr "type"     "store")
6671    (set_attr "mode"     "none")])
6672 \f
6673 ;;
6674 ;;  ....................
6675 ;;
6676 ;;      SHIFTS
6677 ;;
6678 ;;  ....................
6679
6680 ;; Many of these instructions uses trivial define_expands, because we
6681 ;; want to use a different set of constraints when TARGET_MIPS16.
6682
6683 (define_expand "ashlsi3"
6684   [(set (match_operand:SI 0 "register_operand" "=d")
6685         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6686                    (match_operand:SI 2 "arith_operand" "dI")))]
6687   ""
6688   "
6689 {
6690   /* On the mips16, a shift of more than 8 is a four byte instruction,
6691      so, for a shift between 8 and 16, it is just as fast to do two
6692      shifts of 8 or less.  If there is a lot of shifting going on, we
6693      may win in CSE.  Otherwise combine will put the shifts back
6694      together again.  This can be called by function_arg, so we must
6695      be careful not to allocate a new register if we've reached the
6696      reload pass.  */
6697   if (TARGET_MIPS16
6698       && optimize
6699       && GET_CODE (operands[2]) == CONST_INT
6700       && INTVAL (operands[2]) > 8
6701       && INTVAL (operands[2]) <= 16
6702       && ! reload_in_progress
6703       && ! reload_completed)
6704     {
6705       rtx temp = gen_reg_rtx (SImode);
6706
6707       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6708       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6709                                         GEN_INT (INTVAL (operands[2]) - 8)));
6710       DONE;
6711     }
6712 }")
6713
6714 (define_insn "ashlsi3_internal1"
6715   [(set (match_operand:SI 0 "register_operand" "=d")
6716         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6717                    (match_operand:SI 2 "arith_operand" "dI")))]
6718   "!TARGET_MIPS16"
6719   "*
6720 {
6721   if (GET_CODE (operands[2]) == CONST_INT)
6722     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6723
6724   return \"sll\\t%0,%1,%2\";
6725 }"
6726   [(set_attr "type"     "arith")
6727    (set_attr "mode"     "SI")])
6728
6729 (define_insn "ashlsi3_internal2"
6730   [(set (match_operand:SI 0 "register_operand" "=d,d")
6731         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6732                    (match_operand:SI 2 "arith_operand" "d,I")))]
6733   "TARGET_MIPS16"
6734   "*
6735 {
6736   if (which_alternative == 0)
6737     return \"sll\\t%0,%2\";
6738
6739   if (GET_CODE (operands[2]) == CONST_INT)
6740     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6741
6742   return \"sll\\t%0,%1,%2\";
6743 }"
6744   [(set_attr "type"     "arith")
6745    (set_attr "mode"     "SI")
6746    (set_attr_alternative "length"
6747                 [(const_int 4)
6748                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6749                                (const_int 4)
6750                                (const_int 8))])])
6751
6752 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6753
6754 (define_split
6755   [(set (match_operand:SI 0 "register_operand" "")
6756         (ashift:SI (match_operand:SI 1 "register_operand" "")
6757                    (match_operand:SI 2 "const_int_operand" "")))]
6758   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6759    && GET_CODE (operands[2]) == CONST_INT
6760    && INTVAL (operands[2]) > 8
6761    && INTVAL (operands[2]) <= 16"
6762   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6763    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6764 "
6765 {
6766   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6767 }")
6768
6769 (define_expand "ashldi3"
6770   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6771                    (ashift:DI (match_operand:DI 1 "se_register_operand" "")
6772                               (match_operand:SI 2 "arith_operand" "")))
6773               (clobber (match_dup  3))])]
6774   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6775   "
6776 {
6777   if (TARGET_64BIT)
6778     {
6779       /* On the mips16, a shift of more than 8 is a four byte
6780          instruction, so, for a shift between 8 and 16, it is just as
6781          fast to do two shifts of 8 or less.  If there is a lot of
6782          shifting going on, we may win in CSE.  Otherwise combine will
6783          put the shifts back together again.  This can be called by
6784          function_arg, so we must be careful not to allocate a new
6785          register if we've reached the reload pass.  */
6786       if (TARGET_MIPS16
6787           && optimize
6788           && GET_CODE (operands[2]) == CONST_INT
6789           && INTVAL (operands[2]) > 8
6790           && INTVAL (operands[2]) <= 16
6791           && ! reload_in_progress
6792           && ! reload_completed)
6793         {
6794           rtx temp = gen_reg_rtx (DImode);
6795
6796           emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6797           emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6798                                             GEN_INT (INTVAL (operands[2]) - 8)));
6799           DONE;
6800         }
6801
6802       emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6803                                         operands[2]));
6804       DONE;
6805     }
6806
6807   operands[3] = gen_reg_rtx (SImode);
6808 }")
6809
6810
6811 (define_insn "ashldi3_internal"
6812   [(set (match_operand:DI 0 "register_operand" "=&d")
6813         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6814                    (match_operand:SI 2 "register_operand" "d")))
6815    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6816   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6817   "*
6818 {
6819   operands[4] = const0_rtx;
6820   dslots_jump_total += 3;
6821   dslots_jump_filled += 2;
6822
6823   return \"sll\\t%3,%2,26\\n\\
6824 \\tbgez\\t%3,1f\\n\\
6825 \\tsll\\t%M0,%L1,%2\\n\\
6826 \\t%(b\\t3f\\n\\
6827 \\tmove\\t%L0,%z4%)\\n\\
6828 \\n\\
6829 %~1:\\n\\
6830 \\t%(beq\\t%3,%z4,2f\\n\\
6831 \\tsll\\t%M0,%M1,%2%)\\n\\
6832 \\n\\
6833 \\tsubu\\t%3,%z4,%2\\n\\
6834 \\tsrl\\t%3,%L1,%3\\n\\
6835 \\tor\\t%M0,%M0,%3\\n\\
6836 %~2:\\n\\
6837 \\tsll\\t%L0,%L1,%2\\n\\
6838 %~3:\";
6839 }"
6840   [(set_attr "type"     "darith")
6841    (set_attr "mode"     "SI")
6842    (set_attr "length"   "48")])
6843
6844
6845 (define_insn "ashldi3_internal2"
6846   [(set (match_operand:DI 0 "register_operand" "=d")
6847         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6848                    (match_operand:SI 2 "small_int" "IJK")))
6849    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6850   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6851    && (INTVAL (operands[2]) & 32) != 0"
6852   "*
6853 {
6854   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6855   operands[4] = const0_rtx;
6856   return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6857 }"
6858   [(set_attr "type"     "darith")
6859    (set_attr "mode"     "DI")
6860    (set_attr "length"   "8")])
6861
6862
6863 (define_split
6864   [(set (match_operand:DI 0 "register_operand" "")
6865         (ashift:DI (match_operand:DI 1 "register_operand" "")
6866                    (match_operand:SI 2 "small_int" "")))
6867    (clobber (match_operand:SI 3 "register_operand" ""))]
6868   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6869    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6870    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6871    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6872    && (INTVAL (operands[2]) & 32) != 0"
6873
6874   [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6875    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6876
6877   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6878
6879
6880 (define_split
6881   [(set (match_operand:DI 0 "register_operand" "")
6882         (ashift:DI (match_operand:DI 1 "register_operand" "")
6883                    (match_operand:SI 2 "small_int" "")))
6884    (clobber (match_operand:SI 3 "register_operand" ""))]
6885   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6886    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6887    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6888    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6889    && (INTVAL (operands[2]) & 32) != 0"
6890
6891   [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6892    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
6893
6894   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6895
6896
6897 (define_insn "ashldi3_internal3"
6898   [(set (match_operand:DI 0 "register_operand" "=d")
6899         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6900                    (match_operand:SI 2 "small_int" "IJK")))
6901    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6902   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6903    && (INTVAL (operands[2]) & 63) < 32
6904    && (INTVAL (operands[2]) & 63) != 0"
6905   "*
6906 {
6907   int amount = INTVAL (operands[2]);
6908
6909   operands[2] = GEN_INT (amount & 31);
6910   operands[4] = const0_rtx;
6911   operands[5] = GEN_INT ((-amount) & 31);
6912
6913   return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6914 }"
6915   [(set_attr "type"     "darith")
6916    (set_attr "mode"     "DI")
6917    (set_attr "length"   "16")])
6918
6919
6920 (define_split
6921   [(set (match_operand:DI 0 "register_operand" "")
6922         (ashift:DI (match_operand:DI 1 "register_operand" "")
6923                    (match_operand:SI 2 "small_int" "")))
6924    (clobber (match_operand:SI 3 "register_operand" ""))]
6925   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6926    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6927    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6928    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6929    && (INTVAL (operands[2]) & 63) < 32
6930    && (INTVAL (operands[2]) & 63) != 0"
6931
6932   [(set (subreg:SI (match_dup 0) 4)
6933         (ashift:SI (subreg:SI (match_dup 1) 4)
6934                    (match_dup 2)))
6935
6936    (set (match_dup 3)
6937         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6938                      (match_dup 4)))
6939
6940    (set (subreg:SI (match_dup 0) 4)
6941         (ior:SI (subreg:SI (match_dup 0) 4)
6942                 (match_dup 3)))
6943
6944    (set (subreg:SI (match_dup 0) 0)
6945         (ashift:SI (subreg:SI (match_dup 1) 0)
6946                    (match_dup 2)))]
6947   "
6948 {
6949   int amount = INTVAL (operands[2]);
6950   operands[2] = GEN_INT (amount & 31);
6951   operands[4] = GEN_INT ((-amount) & 31);
6952 }")
6953
6954
6955 (define_split
6956   [(set (match_operand:DI 0 "register_operand" "")
6957         (ashift:DI (match_operand:DI 1 "register_operand" "")
6958                    (match_operand:SI 2 "small_int" "")))
6959    (clobber (match_operand:SI 3 "register_operand" ""))]
6960   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6961    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6962    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6963    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6964    && (INTVAL (operands[2]) & 63) < 32
6965    && (INTVAL (operands[2]) & 63) != 0"
6966
6967   [(set (subreg:SI (match_dup 0) 0)
6968         (ashift:SI (subreg:SI (match_dup 1) 0)
6969                    (match_dup 2)))
6970
6971    (set (match_dup 3)
6972         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6973                      (match_dup 4)))
6974
6975    (set (subreg:SI (match_dup 0) 0)
6976         (ior:SI (subreg:SI (match_dup 0) 0)
6977                 (match_dup 3)))
6978
6979    (set (subreg:SI (match_dup 0) 4)
6980         (ashift:SI (subreg:SI (match_dup 1) 4)
6981                    (match_dup 2)))]
6982   "
6983 {
6984   int amount = INTVAL (operands[2]);
6985   operands[2] = GEN_INT (amount & 31);
6986   operands[4] = GEN_INT ((-amount) & 31);
6987 }")
6988
6989
6990 (define_insn "ashldi3_internal4"
6991   [(set (match_operand:DI 0 "register_operand" "=d")
6992         (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6993                    (match_operand:SI 2 "arith_operand" "dI")))]
6994   "TARGET_64BIT && !TARGET_MIPS16"
6995   "*
6996 {
6997   if (GET_CODE (operands[2]) == CONST_INT)
6998     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6999
7000   return \"dsll\\t%0,%1,%2\";
7001 }"
7002   [(set_attr "type"     "arith")
7003    (set_attr "mode"     "DI")])
7004
7005 (define_insn ""
7006   [(set (match_operand:DI 0 "register_operand" "=d,d")
7007         (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
7008                    (match_operand:SI 2 "arith_operand" "d,I")))]
7009   "TARGET_64BIT && TARGET_MIPS16"
7010   "*
7011 {
7012   if (which_alternative == 0)
7013     return \"dsll\\t%0,%2\";
7014
7015   if (GET_CODE (operands[2]) == CONST_INT)
7016     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7017
7018   return \"dsll\\t%0,%1,%2\";
7019 }"
7020   [(set_attr "type"     "arith")
7021    (set_attr "mode"     "DI")
7022    (set_attr_alternative "length"
7023                 [(const_int 4)
7024                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7025                                (const_int 4)
7026                                (const_int 8))])])
7027
7028
7029 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7030
7031 (define_split
7032   [(set (match_operand:DI 0 "register_operand" "")
7033         (ashift:DI (match_operand:DI 1 "register_operand" "")
7034                    (match_operand:SI 2 "const_int_operand" "")))]
7035   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
7036    && reload_completed
7037    && GET_CODE (operands[2]) == CONST_INT
7038    && INTVAL (operands[2]) > 8
7039    && INTVAL (operands[2]) <= 16"
7040   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
7041    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
7042 "
7043 {
7044   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7045 }")
7046
7047 (define_expand "ashrsi3"
7048   [(set (match_operand:SI 0 "register_operand" "=d")
7049         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
7050                      (match_operand:SI 2 "arith_operand" "dI")))]
7051   ""
7052   "
7053 {
7054   /* On the mips16, a shift of more than 8 is a four byte instruction,
7055      so, for a shift between 8 and 16, it is just as fast to do two
7056      shifts of 8 or less.  If there is a lot of shifting going on, we
7057      may win in CSE.  Otherwise combine will put the shifts back
7058      together again.  */
7059   if (TARGET_MIPS16
7060       && optimize
7061       && GET_CODE (operands[2]) == CONST_INT
7062       && INTVAL (operands[2]) > 8
7063       && INTVAL (operands[2]) <= 16)
7064     {
7065       rtx temp = gen_reg_rtx (SImode);
7066
7067       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7068       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
7069                                         GEN_INT (INTVAL (operands[2]) - 8)));
7070       DONE;
7071     }
7072 }")
7073
7074 (define_insn "ashrsi3_internal1"
7075   [(set (match_operand:SI 0 "register_operand" "=d")
7076         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
7077                      (match_operand:SI 2 "arith_operand" "dI")))]
7078   "!TARGET_MIPS16"
7079   "*
7080 {
7081   if (GET_CODE (operands[2]) == CONST_INT)
7082     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7083
7084   return \"sra\\t%0,%1,%2\";
7085 }"
7086   [(set_attr "type"     "arith")
7087    (set_attr "mode"     "SI")])
7088
7089 (define_insn "ashrsi3_internal2"
7090   [(set (match_operand:SI 0 "register_operand" "=d,d")
7091         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7092                      (match_operand:SI 2 "arith_operand" "d,I")))]
7093   "TARGET_MIPS16"
7094   "*
7095 {
7096   if (which_alternative == 0)
7097     return \"sra\\t%0,%2\";
7098
7099   if (GET_CODE (operands[2]) == CONST_INT)
7100     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7101
7102   return \"sra\\t%0,%1,%2\";
7103 }"
7104   [(set_attr "type"     "arith")
7105    (set_attr "mode"     "SI")
7106    (set_attr_alternative "length"
7107                 [(const_int 4)
7108                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7109                                (const_int 4)
7110                                (const_int 8))])])
7111
7112
7113 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7114
7115 (define_split
7116   [(set (match_operand:SI 0 "register_operand" "")
7117         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
7118                      (match_operand:SI 2 "const_int_operand" "")))]
7119   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7120    && GET_CODE (operands[2]) == CONST_INT
7121    && INTVAL (operands[2]) > 8
7122    && INTVAL (operands[2]) <= 16"
7123   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
7124    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
7125 "
7126 {
7127   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7128 }")
7129
7130 (define_expand "ashrdi3"
7131   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7132                    (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7133                                 (match_operand:SI 2 "arith_operand" "")))
7134               (clobber (match_dup  3))])]
7135   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7136   "
7137 {
7138   if (TARGET_64BIT)
7139     {
7140       /* On the mips16, a shift of more than 8 is a four byte
7141          instruction, so, for a shift between 8 and 16, it is just as
7142          fast to do two shifts of 8 or less.  If there is a lot of
7143          shifting going on, we may win in CSE.  Otherwise combine will
7144          put the shifts back together again.  */
7145       if (TARGET_MIPS16
7146           && optimize
7147           && GET_CODE (operands[2]) == CONST_INT
7148           && INTVAL (operands[2]) > 8
7149           && INTVAL (operands[2]) <= 16)
7150         {
7151           rtx temp = gen_reg_rtx (DImode);
7152
7153           emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7154           emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
7155                                             GEN_INT (INTVAL (operands[2]) - 8)));
7156           DONE;
7157         }
7158
7159       emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
7160                                         operands[2]));
7161       DONE;
7162     }
7163
7164   operands[3] = gen_reg_rtx (SImode);
7165 }")
7166
7167
7168 (define_insn "ashrdi3_internal"
7169   [(set (match_operand:DI 0 "register_operand" "=&d")
7170         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7171                      (match_operand:SI 2 "register_operand" "d")))
7172    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7173   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7174   "*
7175 {
7176   operands[4] = const0_rtx;
7177   dslots_jump_total += 3;
7178   dslots_jump_filled += 2;
7179
7180   return \"sll\\t%3,%2,26\\n\\
7181 \\tbgez\\t%3,1f\\n\\
7182 \\tsra\\t%L0,%M1,%2\\n\\
7183 \\t%(b\\t3f\\n\\
7184 \\tsra\\t%M0,%M1,31%)\\n\\
7185 \\n\\
7186 %~1:\\n\\
7187 \\t%(beq\\t%3,%z4,2f\\n\\
7188 \\tsrl\\t%L0,%L1,%2%)\\n\\
7189 \\n\\
7190 \\tsubu\\t%3,%z4,%2\\n\\
7191 \\tsll\\t%3,%M1,%3\\n\\
7192 \\tor\\t%L0,%L0,%3\\n\\
7193 %~2:\\n\\
7194 \\tsra\\t%M0,%M1,%2\\n\\
7195 %~3:\";
7196 }"
7197   [(set_attr "type"     "darith")
7198    (set_attr "mode"     "DI")
7199    (set_attr "length"   "48")])
7200
7201
7202 (define_insn "ashrdi3_internal2"
7203   [(set (match_operand:DI 0 "register_operand" "=d")
7204         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7205                      (match_operand:SI 2 "small_int" "IJK")))
7206    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7207   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
7208   "*
7209 {
7210   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7211   return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
7212 }"
7213   [(set_attr "type"     "darith")
7214    (set_attr "mode"     "DI")
7215    (set_attr "length"   "8")])
7216
7217
7218 (define_split
7219   [(set (match_operand:DI 0 "register_operand" "")
7220         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7221                      (match_operand:SI 2 "small_int" "")))
7222    (clobber (match_operand:SI 3 "register_operand" ""))]
7223   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7224    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7225    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7226    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7227    && (INTVAL (operands[2]) & 32) != 0"
7228
7229   [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7230    (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
7231
7232   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7233
7234
7235 (define_split
7236   [(set (match_operand:DI 0 "register_operand" "")
7237         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7238                      (match_operand:SI 2 "small_int" "")))
7239    (clobber (match_operand:SI 3 "register_operand" ""))]
7240   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7241    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7242    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7243    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7244    && (INTVAL (operands[2]) & 32) != 0"
7245
7246   [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7247    (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
7248
7249   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7250
7251
7252 (define_insn "ashrdi3_internal3"
7253   [(set (match_operand:DI 0 "register_operand" "=d")
7254         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7255                      (match_operand:SI 2 "small_int" "IJK")))
7256    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7257   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7258    && (INTVAL (operands[2]) & 63) < 32
7259    && (INTVAL (operands[2]) & 63) != 0"
7260   "*
7261 {
7262   int amount = INTVAL (operands[2]);
7263
7264   operands[2] = GEN_INT (amount & 31);
7265   operands[4] = GEN_INT ((-amount) & 31);
7266
7267   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
7268 }"
7269   [(set_attr "type"     "darith")
7270    (set_attr "mode"     "DI")
7271    (set_attr "length"   "16")])
7272
7273
7274 (define_split
7275   [(set (match_operand:DI 0 "register_operand" "")
7276         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7277                      (match_operand:SI 2 "small_int" "")))
7278    (clobber (match_operand:SI 3 "register_operand" ""))]
7279   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7280    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7281    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7282    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7283    && (INTVAL (operands[2]) & 63) < 32
7284    && (INTVAL (operands[2]) & 63) != 0"
7285
7286   [(set (subreg:SI (match_dup 0) 0)
7287         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7288                      (match_dup 2)))
7289
7290    (set (match_dup 3)
7291         (ashift:SI (subreg:SI (match_dup 1) 4)
7292                    (match_dup 4)))
7293
7294    (set (subreg:SI (match_dup 0) 0)
7295         (ior:SI (subreg:SI (match_dup 0) 0)
7296                 (match_dup 3)))
7297
7298    (set (subreg:SI (match_dup 0) 4)
7299         (ashiftrt:SI (subreg:SI (match_dup 1) 4)
7300                      (match_dup 2)))]
7301   "
7302 {
7303   int amount = INTVAL (operands[2]);
7304   operands[2] = GEN_INT (amount & 31);
7305   operands[4] = GEN_INT ((-amount) & 31);
7306 }")
7307
7308
7309 (define_split
7310   [(set (match_operand:DI 0 "register_operand" "")
7311         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7312                      (match_operand:SI 2 "small_int" "")))
7313    (clobber (match_operand:SI 3 "register_operand" ""))]
7314   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7315    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7316    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7317    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7318    && (INTVAL (operands[2]) & 63) < 32
7319    && (INTVAL (operands[2]) & 63) != 0"
7320
7321   [(set (subreg:SI (match_dup 0) 4)
7322         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7323                      (match_dup 2)))
7324
7325    (set (match_dup 3)
7326         (ashift:SI (subreg:SI (match_dup 1) 0)
7327                    (match_dup 4)))
7328
7329    (set (subreg:SI (match_dup 0) 4)
7330         (ior:SI (subreg:SI (match_dup 0) 4)
7331                 (match_dup 3)))
7332
7333    (set (subreg:SI (match_dup 0) 0)
7334         (ashiftrt:SI (subreg:SI (match_dup 1) 0)
7335                      (match_dup 2)))]
7336   "
7337 {
7338   int amount = INTVAL (operands[2]);
7339   operands[2] = GEN_INT (amount & 31);
7340   operands[4] = GEN_INT ((-amount) & 31);
7341 }")
7342
7343
7344 (define_insn "ashrdi3_internal4"
7345   [(set (match_operand:DI 0 "register_operand" "=d")
7346         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7347                      (match_operand:SI 2 "arith_operand" "dI")))]
7348   "TARGET_64BIT && !TARGET_MIPS16"
7349   "*
7350 {
7351   if (GET_CODE (operands[2]) == CONST_INT)
7352     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7353
7354   return \"dsra\\t%0,%1,%2\";
7355 }"
7356   [(set_attr "type"     "arith")
7357    (set_attr "mode"     "DI")])
7358
7359 (define_insn ""
7360   [(set (match_operand:DI 0 "register_operand" "=d,d")
7361         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7362                      (match_operand:SI 2 "arith_operand" "d,I")))]
7363   "TARGET_64BIT && TARGET_MIPS16"
7364   "*
7365 {
7366   if (GET_CODE (operands[2]) == CONST_INT)
7367     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7368
7369   return \"dsra\\t%0,%2\";
7370 }"
7371   [(set_attr "type"     "arith")
7372    (set_attr "mode"     "DI")
7373    (set_attr_alternative "length"
7374                 [(const_int 4)
7375                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7376                                (const_int 4)
7377                                (const_int 8))])])
7378
7379 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7380
7381 (define_split
7382   [(set (match_operand:DI 0 "register_operand" "")
7383         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7384                      (match_operand:SI 2 "const_int_operand" "")))]
7385   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
7386    && reload_completed
7387    && GET_CODE (operands[2]) == CONST_INT
7388    && INTVAL (operands[2]) > 8
7389    && INTVAL (operands[2]) <= 16"
7390   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7391    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7392 "
7393 {
7394   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7395 }")
7396
7397 (define_expand "lshrsi3"
7398   [(set (match_operand:SI 0 "register_operand" "=d")
7399         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7400                      (match_operand:SI 2 "arith_operand" "dI")))]
7401   ""
7402   "
7403 {
7404   /* On the mips16, a shift of more than 8 is a four byte instruction,
7405      so, for a shift between 8 and 16, it is just as fast to do two
7406      shifts of 8 or less.  If there is a lot of shifting going on, we
7407      may win in CSE.  Otherwise combine will put the shifts back
7408      together again.  */
7409   if (TARGET_MIPS16
7410       && optimize
7411       && GET_CODE (operands[2]) == CONST_INT
7412       && INTVAL (operands[2]) > 8
7413       && INTVAL (operands[2]) <= 16)
7414     {
7415       rtx temp = gen_reg_rtx (SImode);
7416
7417       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7418       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7419                                         GEN_INT (INTVAL (operands[2]) - 8)));
7420       DONE;
7421     }
7422 }")
7423
7424 (define_insn "lshrsi3_internal1"
7425   [(set (match_operand:SI 0 "register_operand" "=d")
7426         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7427                      (match_operand:SI 2 "arith_operand" "dI")))]
7428   "!TARGET_MIPS16"
7429   "*
7430 {
7431   if (GET_CODE (operands[2]) == CONST_INT)
7432     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7433
7434   return \"srl\\t%0,%1,%2\";
7435 }"
7436   [(set_attr "type"     "arith")
7437    (set_attr "mode"     "SI")])
7438
7439 (define_insn "lshrsi3_internal2"
7440   [(set (match_operand:SI 0 "register_operand" "=d,d")
7441         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7442                      (match_operand:SI 2 "arith_operand" "d,I")))]
7443   "TARGET_MIPS16"
7444   "*
7445 {
7446   if (which_alternative == 0)
7447     return \"srl\\t%0,%2\";
7448
7449   if (GET_CODE (operands[2]) == CONST_INT)
7450     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7451
7452   return \"srl\\t%0,%1,%2\";
7453 }"
7454   [(set_attr "type"     "arith")
7455    (set_attr "mode"     "SI")
7456    (set_attr_alternative "length"
7457                 [(const_int 4)
7458                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7459                                (const_int 4)
7460                                (const_int 8))])])
7461
7462
7463 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7464
7465 (define_split
7466   [(set (match_operand:SI 0 "register_operand" "")
7467         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7468                      (match_operand:SI 2 "const_int_operand" "")))]
7469   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7470    && GET_CODE (operands[2]) == CONST_INT
7471    && INTVAL (operands[2]) > 8
7472    && INTVAL (operands[2]) <= 16"
7473   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7474    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7475 "
7476 {
7477   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7478 }")
7479
7480 ;; If we load a byte on the mips16 as a bitfield, the resulting
7481 ;; sequence of instructions is too complicated for combine, because it
7482 ;; involves four instructions: a load, a shift, a constant load into a
7483 ;; register, and an and (the key problem here is that the mips16 does
7484 ;; not have and immediate).  We recognize a shift of a load in order
7485 ;; to make it simple enough for combine to understand.
7486
7487 (define_insn ""
7488   [(set (match_operand:SI 0 "register_operand" "=d,d")
7489         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
7490                      (match_operand:SI 2 "immediate_operand" "I,I")))]
7491   "TARGET_MIPS16"
7492   "lw\\t%0,%1\;srl\\t%0,%2"
7493   [(set_attr "type"     "load")
7494    (set_attr "mode"     "SI")
7495    (set_attr_alternative "length"
7496                 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7497                                (const_int 8)
7498                                (const_int 12))
7499                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7500                                (const_int 12)
7501                                (const_int 16))])])
7502
7503 (define_split
7504   [(set (match_operand:SI 0 "register_operand" "")
7505         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7506                      (match_operand:SI 2 "immediate_operand" "")))]
7507   "TARGET_MIPS16 && !TARGET_DEBUG_D_MODE"
7508   [(set (match_dup 0) (match_dup 1))
7509    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7510   "")
7511
7512 (define_expand "lshrdi3"
7513   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7514                    (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7515                                 (match_operand:SI 2 "arith_operand" "")))
7516               (clobber (match_dup  3))])]
7517   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7518   "
7519 {
7520   if (TARGET_64BIT)
7521     {
7522       /* On the mips16, a shift of more than 8 is a four byte
7523          instruction, so, for a shift between 8 and 16, it is just as
7524          fast to do two shifts of 8 or less.  If there is a lot of
7525          shifting going on, we may win in CSE.  Otherwise combine will
7526          put the shifts back together again.  */
7527       if (TARGET_MIPS16
7528           && optimize
7529           && GET_CODE (operands[2]) == CONST_INT
7530           && INTVAL (operands[2]) > 8
7531           && INTVAL (operands[2]) <= 16)
7532         {
7533           rtx temp = gen_reg_rtx (DImode);
7534
7535           emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7536           emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7537                                             GEN_INT (INTVAL (operands[2]) - 8)));
7538           DONE;
7539         }
7540
7541       emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7542                                         operands[2]));
7543       DONE;
7544     }
7545
7546   operands[3] = gen_reg_rtx (SImode);
7547 }")
7548
7549
7550 (define_insn "lshrdi3_internal"
7551   [(set (match_operand:DI 0 "register_operand" "=&d")
7552         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7553                      (match_operand:SI 2 "register_operand" "d")))
7554    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7555   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7556   "*
7557 {
7558   operands[4] = const0_rtx;
7559   dslots_jump_total += 3;
7560   dslots_jump_filled += 2;
7561
7562   return \"sll\\t%3,%2,26\\n\\
7563 \\tbgez\\t%3,1f\\n\\
7564 \\tsrl\\t%L0,%M1,%2\\n\\
7565 \\t%(b\\t3f\\n\\
7566 \\tmove\\t%M0,%z4%)\\n\\
7567 \\n\\
7568 %~1:\\n\\
7569 \\t%(beq\\t%3,%z4,2f\\n\\
7570 \\tsrl\\t%L0,%L1,%2%)\\n\\
7571 \\n\\
7572 \\tsubu\\t%3,%z4,%2\\n\\
7573 \\tsll\\t%3,%M1,%3\\n\\
7574 \\tor\\t%L0,%L0,%3\\n\\
7575 %~2:\\n\\
7576 \\tsrl\\t%M0,%M1,%2\\n\\
7577 %~3:\";
7578 }"
7579   [(set_attr "type"     "darith")
7580    (set_attr "mode"     "DI")
7581    (set_attr "length"   "48")])
7582
7583
7584 (define_insn "lshrdi3_internal2"
7585   [(set (match_operand:DI 0 "register_operand" "=d")
7586         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7587                      (match_operand:SI 2 "small_int" "IJK")))
7588    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7589   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7590    && (INTVAL (operands[2]) & 32) != 0"
7591   "*
7592 {
7593   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7594   operands[4] = const0_rtx;
7595   return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7596 }"
7597   [(set_attr "type"     "darith")
7598    (set_attr "mode"     "DI")
7599    (set_attr "length"   "8")])
7600
7601
7602 (define_split
7603   [(set (match_operand:DI 0 "register_operand" "")
7604         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7605                      (match_operand:SI 2 "small_int" "")))
7606    (clobber (match_operand:SI 3 "register_operand" ""))]
7607   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7608    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7609    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7610    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7611    && (INTVAL (operands[2]) & 32) != 0"
7612
7613   [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7614    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
7615
7616   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7617
7618
7619 (define_split
7620   [(set (match_operand:DI 0 "register_operand" "")
7621         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7622                      (match_operand:SI 2 "small_int" "")))
7623    (clobber (match_operand:SI 3 "register_operand" ""))]
7624   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7625    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7626    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7627    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7628    && (INTVAL (operands[2]) & 32) != 0"
7629
7630   [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7631    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7632
7633   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7634
7635
7636 (define_insn "lshrdi3_internal3"
7637   [(set (match_operand:DI 0 "register_operand" "=d")
7638         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7639                    (match_operand:SI 2 "small_int" "IJK")))
7640    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7641   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7642    && (INTVAL (operands[2]) & 63) < 32
7643    && (INTVAL (operands[2]) & 63) != 0"
7644   "*
7645 {
7646   int amount = INTVAL (operands[2]);
7647
7648   operands[2] = GEN_INT (amount & 31);
7649   operands[4] = GEN_INT ((-amount) & 31);
7650
7651   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7652 }"
7653   [(set_attr "type"     "darith")
7654    (set_attr "mode"     "DI")
7655    (set_attr "length"   "16")])
7656
7657
7658 (define_split
7659   [(set (match_operand:DI 0 "register_operand" "")
7660         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7661                      (match_operand:SI 2 "small_int" "")))
7662    (clobber (match_operand:SI 3 "register_operand" ""))]
7663   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7664    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7665    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7666    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7667    && (INTVAL (operands[2]) & 63) < 32
7668    && (INTVAL (operands[2]) & 63) != 0"
7669
7670   [(set (subreg:SI (match_dup 0) 0)
7671         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7672                      (match_dup 2)))
7673
7674    (set (match_dup 3)
7675         (ashift:SI (subreg:SI (match_dup 1) 4)
7676                    (match_dup 4)))
7677
7678    (set (subreg:SI (match_dup 0) 0)
7679         (ior:SI (subreg:SI (match_dup 0) 0)
7680                 (match_dup 3)))
7681
7682    (set (subreg:SI (match_dup 0) 4)
7683         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7684                      (match_dup 2)))]
7685   "
7686 {
7687   int amount = INTVAL (operands[2]);
7688   operands[2] = GEN_INT (amount & 31);
7689   operands[4] = GEN_INT ((-amount) & 31);
7690 }")
7691
7692
7693 (define_split
7694   [(set (match_operand:DI 0 "register_operand" "")
7695         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7696                      (match_operand:SI 2 "small_int" "")))
7697    (clobber (match_operand:SI 3 "register_operand" ""))]
7698   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7699    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7700    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7701    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7702    && (INTVAL (operands[2]) & 63) < 32
7703    && (INTVAL (operands[2]) & 63) != 0"
7704
7705   [(set (subreg:SI (match_dup 0) 4)
7706         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7707                      (match_dup 2)))
7708
7709    (set (match_dup 3)
7710         (ashift:SI (subreg:SI (match_dup 1) 0)
7711                    (match_dup 4)))
7712
7713    (set (subreg:SI (match_dup 0) 4)
7714         (ior:SI (subreg:SI (match_dup 0) 4)
7715                 (match_dup 3)))
7716
7717    (set (subreg:SI (match_dup 0) 0)
7718         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7719                      (match_dup 2)))]
7720   "
7721 {
7722   int amount = INTVAL (operands[2]);
7723   operands[2] = GEN_INT (amount & 31);
7724   operands[4] = GEN_INT ((-amount) & 31);
7725 }")
7726
7727
7728 (define_insn "lshrdi3_internal4"
7729   [(set (match_operand:DI 0 "register_operand" "=d")
7730         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7731                      (match_operand:SI 2 "arith_operand" "dI")))]
7732   "TARGET_64BIT && !TARGET_MIPS16"
7733   "*
7734 {
7735   if (GET_CODE (operands[2]) == CONST_INT)
7736     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7737
7738   return \"dsrl\\t%0,%1,%2\";
7739 }"
7740   [(set_attr "type"     "arith")
7741    (set_attr "mode"     "DI")])
7742
7743 (define_insn ""
7744   [(set (match_operand:DI 0 "register_operand" "=d,d")
7745         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7746                      (match_operand:SI 2 "arith_operand" "d,I")))]
7747   "TARGET_64BIT && TARGET_MIPS16"
7748   "*
7749 {
7750   if (GET_CODE (operands[2]) == CONST_INT)
7751     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7752
7753   return \"dsrl\\t%0,%2\";
7754 }"
7755   [(set_attr "type"     "arith")
7756    (set_attr "mode"     "DI")
7757    (set_attr_alternative "length"
7758                 [(const_int 4)
7759                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7760                                (const_int 4)
7761                                (const_int 8))])])
7762
7763 (define_insn "rotrsi3"
7764   [(set (match_operand:SI              0 "register_operand" "=d")
7765         (rotatert:SI (match_operand:SI 1 "register_operand" "d")
7766                      (match_operand:SI 2 "arith_operand"    "dn")))]
7767   "ISA_HAS_ROTR_SI"
7768   "*
7769 {
7770   if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
7771     return \"rorv\\t%0,%1,%2\";
7772
7773   if ((GET_CODE (operands[2]) == CONST_INT)
7774       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
7775     abort ();
7776
7777   return \"ror\\t%0,%1,%2\";
7778 }"
7779   [(set_attr "type"     "arith")
7780    (set_attr "mode"     "SI")])
7781
7782 (define_insn "rotrdi3"
7783   [(set (match_operand:DI              0 "register_operand" "=d")
7784         (rotatert:DI (match_operand:DI 1 "register_operand" "d")
7785                      (match_operand:DI 2 "arith_operand"    "dn")))]
7786   "ISA_HAS_ROTR_DI"
7787   "*
7788 {
7789    if (TARGET_SR71K)
7790     {
7791       if (GET_CODE (operands[2]) != CONST_INT)
7792         return \"drorv\\t%0,%1,%2\";
7793
7794       if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
7795         return \"dror32\\t%0,%1,%2\";
7796     }
7797
7798   if ((GET_CODE (operands[2]) == CONST_INT)
7799       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
7800     abort ();
7801
7802   return \"dror\\t%0,%1,%2\";
7803 }"
7804   [(set_attr "type"     "arith")
7805    (set_attr "mode"     "DI")])
7806
7807
7808 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7809
7810 (define_split
7811   [(set (match_operand:DI 0 "register_operand" "")
7812         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7813                      (match_operand:SI 2 "const_int_operand" "")))]
7814   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7815    && GET_CODE (operands[2]) == CONST_INT
7816    && INTVAL (operands[2]) > 8
7817    && INTVAL (operands[2]) <= 16"
7818   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7819    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7820 "
7821 {
7822   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7823 }")
7824
7825 \f
7826 ;;
7827 ;;  ....................
7828 ;;
7829 ;;      COMPARISONS
7830 ;;
7831 ;;  ....................
7832
7833 ;; Flow here is rather complex:
7834 ;;
7835 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the
7836 ;;      arguments into the branch_cmp array, and the type into
7837 ;;      branch_type.  No RTL is generated.
7838 ;;
7839 ;;  2)  The appropriate branch define_expand is called, which then
7840 ;;      creates the appropriate RTL for the comparison and branch.
7841 ;;      Different CC modes are used, based on what type of branch is
7842 ;;      done, so that we can constrain things appropriately.  There
7843 ;;      are assumptions in the rest of GCC that break if we fold the
7844 ;;      operands into the branchs for integer operations, and use cc0
7845 ;;      for floating point, so we use the fp status register instead.
7846 ;;      If needed, an appropriate temporary is created to hold the
7847 ;;      of the integer compare.
7848
7849 (define_expand "cmpsi"
7850   [(set (cc0)
7851         (compare:CC (match_operand:SI 0 "register_operand" "")
7852                     (match_operand:SI 1 "arith_operand" "")))]
7853   ""
7854   "
7855 {
7856   if (operands[0])              /* avoid unused code message */
7857     {
7858       branch_cmp[0] = operands[0];
7859       branch_cmp[1] = operands[1];
7860       branch_type = CMP_SI;
7861       DONE;
7862     }
7863 }")
7864
7865 (define_expand "tstsi"
7866   [(set (cc0)
7867         (match_operand:SI 0 "register_operand" ""))]
7868   ""
7869   "
7870 {
7871   if (operands[0])              /* avoid unused code message */
7872     {
7873       branch_cmp[0] = operands[0];
7874       branch_cmp[1] = const0_rtx;
7875       branch_type = CMP_SI;
7876       DONE;
7877     }
7878 }")
7879
7880 (define_expand "cmpdi"
7881   [(set (cc0)
7882         (compare:CC (match_operand:DI 0 "se_register_operand" "")
7883                     (match_operand:DI 1 "se_arith_operand" "")))]
7884   "TARGET_64BIT"
7885   "
7886 {
7887   if (operands[0])              /* avoid unused code message */
7888     {
7889       branch_cmp[0] = operands[0];
7890       branch_cmp[1] = operands[1];
7891       branch_type = CMP_DI;
7892       DONE;
7893     }
7894 }")
7895
7896 (define_expand "tstdi"
7897   [(set (cc0)
7898         (match_operand:DI 0 "se_register_operand" ""))]
7899   "TARGET_64BIT"
7900   "
7901 {
7902   if (operands[0])              /* avoid unused code message */
7903     {
7904       branch_cmp[0] = operands[0];
7905       branch_cmp[1] = const0_rtx;
7906       branch_type = CMP_DI;
7907       DONE;
7908     }
7909 }")
7910
7911 (define_expand "cmpdf"
7912   [(set (cc0)
7913         (compare:CC (match_operand:DF 0 "register_operand" "")
7914                     (match_operand:DF 1 "register_operand" "")))]
7915   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7916   "
7917 {
7918   if (operands[0])              /* avoid unused code message */
7919     {
7920       branch_cmp[0] = operands[0];
7921       branch_cmp[1] = operands[1];
7922       branch_type = CMP_DF;
7923       DONE;
7924     }
7925 }")
7926
7927 (define_expand "cmpsf"
7928   [(set (cc0)
7929         (compare:CC (match_operand:SF 0 "register_operand" "")
7930                     (match_operand:SF 1 "register_operand" "")))]
7931   "TARGET_HARD_FLOAT"
7932   "
7933 {
7934   if (operands[0])              /* avoid unused code message */
7935     {
7936       branch_cmp[0] = operands[0];
7937       branch_cmp[1] = operands[1];
7938       branch_type = CMP_SF;
7939       DONE;
7940     }
7941 }")
7942
7943 \f
7944 ;;
7945 ;;  ....................
7946 ;;
7947 ;;      CONDITIONAL BRANCHES
7948 ;;
7949 ;;  ....................
7950
7951 ;; Conditional branches on floating-point equality tests.
7952
7953 (define_insn "branch_fp"
7954   [(set (pc)
7955         (if_then_else
7956          (match_operator:CC 0 "cmp_op"
7957                             [(match_operand:CC 2 "register_operand" "z")
7958                              (const_int 0)])
7959          (label_ref (match_operand 1 "" ""))
7960          (pc)))]
7961   "TARGET_HARD_FLOAT"
7962   "*
7963 {
7964   return mips_output_conditional_branch (insn,
7965                                          operands,
7966                                          /*two_operands_p=*/0,
7967                                          /*float_p=*/1,
7968                                          /*inverted_p=*/0,
7969                                          get_attr_length (insn));
7970 }"
7971   [(set_attr "type"     "branch")
7972    (set_attr "mode"     "none")])
7973
7974 (define_insn "branch_fp_inverted"
7975   [(set (pc)
7976         (if_then_else
7977          (match_operator:CC 0 "cmp_op"
7978                             [(match_operand:CC 2 "register_operand" "z")
7979                              (const_int 0)])
7980          (pc)
7981          (label_ref (match_operand 1 "" ""))))]
7982   "TARGET_HARD_FLOAT"
7983   "*
7984 {
7985   return mips_output_conditional_branch (insn,
7986                                          operands,
7987                                          /*two_operands_p=*/0,
7988                                          /*float_p=*/1,
7989                                          /*inverted_p=*/1,
7990                                          get_attr_length (insn));
7991 }"
7992   [(set_attr "type"     "branch")
7993    (set_attr "mode"     "none")])
7994
7995 ;; Conditional branches on comparisons with zero.
7996
7997 (define_insn "branch_zero"
7998   [(set (pc)
7999         (if_then_else
8000          (match_operator:SI 0 "cmp_op"
8001                             [(match_operand:SI 2 "register_operand" "d")
8002                              (const_int 0)])
8003         (label_ref (match_operand 1 "" ""))
8004         (pc)))]
8005   "!TARGET_MIPS16"
8006   "*
8007 {
8008   return mips_output_conditional_branch (insn,
8009                                          operands,
8010                                          /*two_operands_p=*/0,
8011                                          /*float_p=*/0,
8012                                          /*inverted_p=*/0,
8013                                          get_attr_length (insn));
8014 }"
8015   [(set_attr "type"     "branch")
8016    (set_attr "mode"     "none")])
8017
8018 (define_insn "branch_zero_inverted"
8019   [(set (pc)
8020         (if_then_else
8021          (match_operator:SI 0 "cmp_op"
8022                             [(match_operand:SI 2 "register_operand" "d")
8023                              (const_int 0)])
8024         (pc)
8025         (label_ref (match_operand 1 "" ""))))]
8026   "!TARGET_MIPS16"
8027   "*
8028 {
8029   return mips_output_conditional_branch (insn,
8030                                          operands,
8031                                          /*two_operands_p=*/0,
8032                                          /*float_p=*/0,
8033                                          /*inverted_p=*/1,
8034                                          get_attr_length (insn));
8035 }"
8036   [(set_attr "type"     "branch")
8037    (set_attr "mode"     "none")])
8038
8039 (define_insn "branch_zero_di"
8040   [(set (pc)
8041         (if_then_else
8042          (match_operator:DI 0 "cmp_op"
8043                             [(match_operand:DI 2 "se_register_operand" "d")
8044                              (const_int 0)])
8045         (label_ref (match_operand 1 "" ""))
8046         (pc)))]
8047   "!TARGET_MIPS16"
8048   "*
8049 {
8050   return mips_output_conditional_branch (insn,
8051                                          operands,
8052                                          /*two_operands_p=*/0,
8053                                          /*float_p=*/0,
8054                                          /*inverted_p=*/0,
8055                                          get_attr_length (insn));
8056 }"
8057   [(set_attr "type"     "branch")
8058    (set_attr "mode"     "none")])
8059
8060 (define_insn "branch_zero_di_inverted"
8061   [(set (pc)
8062         (if_then_else
8063          (match_operator:DI 0 "cmp_op"
8064                             [(match_operand:DI 2 "se_register_operand" "d")
8065                              (const_int 0)])
8066         (pc)
8067         (label_ref (match_operand 1 "" ""))))]
8068   "!TARGET_MIPS16"
8069   "*
8070 {
8071   return mips_output_conditional_branch (insn,
8072                                          operands,
8073                                          /*two_operands_p=*/0,
8074                                          /*float_p=*/0,
8075                                          /*inverted_p=*/1,
8076                                          get_attr_length (insn));
8077 }"
8078   [(set_attr "type"     "branch")
8079    (set_attr "mode"     "none")])
8080
8081 ;; Conditional branch on equality comparision.
8082
8083 (define_insn "branch_equality"
8084   [(set (pc)
8085         (if_then_else
8086          (match_operator:SI 0 "equality_op"
8087                             [(match_operand:SI 2 "register_operand" "d")
8088                              (match_operand:SI 3 "register_operand" "d")])
8089          (label_ref (match_operand 1 "" ""))
8090          (pc)))]
8091   "!TARGET_MIPS16"
8092   "*
8093 {
8094   return mips_output_conditional_branch (insn,
8095                                          operands,
8096                                          /*two_operands_p=*/1,
8097                                          /*float_p=*/0,
8098                                          /*inverted_p=*/0,
8099                                          get_attr_length (insn));
8100 }"
8101   [(set_attr "type"     "branch")
8102    (set_attr "mode"     "none")])
8103
8104 (define_insn "branch_equality_di"
8105   [(set (pc)
8106         (if_then_else
8107          (match_operator:DI 0 "equality_op"
8108                             [(match_operand:DI 2 "se_register_operand" "d")
8109                              (match_operand:DI 3 "se_register_operand" "d")])
8110         (label_ref (match_operand 1 "" ""))
8111         (pc)))]
8112   "!TARGET_MIPS16"
8113   "*
8114 {
8115   return mips_output_conditional_branch (insn,
8116                                          operands,
8117                                          /*two_operands_p=*/1,
8118                                          /*float_p=*/0,
8119                                          /*inverted_p=*/0,
8120                                          get_attr_length (insn));
8121 }"
8122   [(set_attr "type"     "branch")
8123    (set_attr "mode"     "none")])
8124
8125 (define_insn "branch_equality_inverted"
8126   [(set (pc)
8127         (if_then_else
8128          (match_operator:SI 0 "equality_op"
8129                             [(match_operand:SI 2 "register_operand" "d")
8130                              (match_operand:SI 3 "register_operand" "d")])
8131          (pc)
8132          (label_ref (match_operand 1 "" ""))))]
8133   "!TARGET_MIPS16"
8134   "*
8135 {
8136   return mips_output_conditional_branch (insn,
8137                                          operands,
8138                                          /*two_operands_p=*/1,
8139                                          /*float_p=*/0,
8140                                          /*inverted_p=*/1,
8141                                          get_attr_length (insn));
8142 }"
8143   [(set_attr "type"     "branch")
8144    (set_attr "mode"     "none")])
8145
8146 (define_insn "branch_equality_di_inverted"
8147   [(set (pc)
8148         (if_then_else
8149          (match_operator:DI 0 "equality_op"
8150                             [(match_operand:DI 2 "se_register_operand" "d")
8151                              (match_operand:DI 3 "se_register_operand" "d")])
8152         (pc)
8153         (label_ref (match_operand 1 "" ""))))]
8154   "!TARGET_MIPS16"
8155   "*
8156 {
8157   return mips_output_conditional_branch (insn,
8158                                          operands,
8159                                          /*two_operands_p=*/1,
8160                                          /*float_p=*/0,
8161                                          /*inverted_p=*/1,
8162                                          get_attr_length (insn));
8163 }"
8164   [(set_attr "type"     "branch")
8165    (set_attr "mode"     "none")])
8166
8167 ;; MIPS16 branches
8168
8169 (define_insn ""
8170   [(set (pc)
8171         (if_then_else (match_operator:SI 0 "equality_op"
8172                                          [(match_operand:SI 1 "register_operand" "d,t")
8173                                           (const_int 0)])
8174         (match_operand 2 "pc_or_label_operand" "")
8175         (match_operand 3 "pc_or_label_operand" "")))]
8176   "TARGET_MIPS16"
8177   "*
8178 {
8179   if (operands[2] != pc_rtx)
8180     {
8181       if (which_alternative == 0)
8182         return \"%*b%C0z\\t%1,%2\";
8183       else
8184         return \"%*bt%C0z\\t%2\";
8185     }
8186   else
8187     {
8188       if (which_alternative == 0)
8189         return \"%*b%N0z\\t%1,%3\";
8190       else
8191         return \"%*bt%N0z\\t%3\";
8192     }
8193 }"
8194   [(set_attr "type"     "branch")
8195    (set_attr "mode"     "none")
8196    (set_attr "length"   "8")])
8197
8198 (define_insn ""
8199   [(set (pc)
8200         (if_then_else (match_operator:DI 0 "equality_op"
8201                                          [(match_operand:DI 1 "se_register_operand" "d,t")
8202                                           (const_int 0)])
8203         (match_operand 2 "pc_or_label_operand" "")
8204         (match_operand 3 "pc_or_label_operand" "")))]
8205   "TARGET_MIPS16"
8206   "*
8207 {
8208   if (operands[2] != pc_rtx)
8209     {
8210       if (which_alternative == 0)
8211         return \"%*b%C0z\\t%1,%2\";
8212       else
8213         return \"%*bt%C0z\\t%2\";
8214     }
8215   else
8216     {
8217       if (which_alternative == 0)
8218         return \"%*b%N0z\\t%1,%3\";
8219       else
8220         return \"%*bt%N0z\\t%3\";
8221     }
8222 }"
8223   [(set_attr "type"     "branch")
8224    (set_attr "mode"     "none")
8225    (set_attr "length"   "8")])
8226
8227 (define_expand "bunordered"
8228   [(set (pc)
8229         (if_then_else (unordered:CC (cc0)
8230                                     (const_int 0))
8231                       (label_ref (match_operand 0 "" ""))
8232                       (pc)))]
8233   ""
8234   "
8235 {
8236   if (operands[0])              /* avoid unused code warning */
8237     {
8238       gen_conditional_branch (operands, UNORDERED);
8239       DONE;
8240     }
8241 }")
8242
8243 (define_expand "bordered"
8244   [(set (pc)
8245         (if_then_else (ordered:CC (cc0)
8246                                   (const_int 0))
8247                       (label_ref (match_operand 0 "" ""))
8248                       (pc)))]
8249   ""
8250   "
8251 {
8252   if (operands[0])              /* avoid unused code warning */
8253      {
8254         gen_conditional_branch (operands, ORDERED);
8255         DONE;
8256      }
8257 }")
8258
8259 (define_expand "bunlt"
8260   [(set (pc)
8261         (if_then_else (unlt:CC (cc0)
8262                                (const_int 0))
8263                       (label_ref (match_operand 0 "" ""))
8264                       (pc)))]
8265   ""
8266   "
8267 {
8268   if (operands[0])              /* avoid unused code warning */
8269      {
8270         gen_conditional_branch (operands, UNLT);
8271         DONE;
8272      }
8273 }")
8274
8275 (define_expand "bunge"
8276   [(set (pc)
8277         (if_then_else (unge:CC (cc0)
8278                                (const_int 0))
8279                       (label_ref (match_operand 0 "" ""))
8280                       (pc)))]
8281   ""
8282   "
8283 {
8284   gen_conditional_branch (operands, UNGE);
8285   DONE;
8286 }")
8287
8288 (define_expand "buneq"
8289   [(set (pc)
8290         (if_then_else (uneq:CC (cc0)
8291                                (const_int 0))
8292                       (label_ref (match_operand 0 "" ""))
8293                       (pc)))]
8294   ""
8295   "
8296 {
8297   if (operands[0])              /* avoid unused code warning */
8298      {
8299         gen_conditional_branch (operands, UNEQ);
8300         DONE;
8301      }
8302 }")
8303
8304 (define_expand "bltgt"
8305   [(set (pc)
8306         (if_then_else (ltgt:CC (cc0)
8307                                (const_int 0))
8308                       (label_ref (match_operand 0 "" ""))
8309                       (pc)))]
8310   ""
8311   "
8312 {
8313   gen_conditional_branch (operands, LTGT);
8314   DONE;
8315 }")
8316
8317 (define_expand "bunle"
8318   [(set (pc)
8319         (if_then_else (unle:CC (cc0)
8320                                (const_int 0))
8321                       (label_ref (match_operand 0 "" ""))
8322                       (pc)))]
8323   ""
8324   "
8325 {
8326   if (operands[0])              /* avoid unused code warning */
8327      {
8328         gen_conditional_branch (operands, UNLE);
8329         DONE;
8330      }
8331 }")
8332
8333 (define_expand "bungt"
8334   [(set (pc)
8335         (if_then_else (ungt:CC (cc0)
8336                                (const_int 0))
8337                       (label_ref (match_operand 0 "" ""))
8338                       (pc)))]
8339   ""
8340   "
8341 {
8342   gen_conditional_branch (operands, UNGT);
8343   DONE;
8344 }")
8345
8346 (define_expand "beq"
8347   [(set (pc)
8348         (if_then_else (eq:CC (cc0)
8349                              (const_int 0))
8350                       (label_ref (match_operand 0 "" ""))
8351                       (pc)))]
8352   ""
8353   "
8354 {
8355   if (operands[0])              /* avoid unused code warning */
8356     {
8357       gen_conditional_branch (operands, EQ);
8358       DONE;
8359     }
8360 }")
8361
8362 (define_expand "bne"
8363   [(set (pc)
8364         (if_then_else (ne:CC (cc0)
8365                              (const_int 0))
8366                       (label_ref (match_operand 0 "" ""))
8367                       (pc)))]
8368   ""
8369   "
8370 {
8371   if (operands[0])              /* avoid unused code warning */
8372     {
8373       gen_conditional_branch (operands, NE);
8374       DONE;
8375     }
8376 }")
8377
8378 (define_expand "bgt"
8379   [(set (pc)
8380         (if_then_else (gt:CC (cc0)
8381                              (const_int 0))
8382                       (label_ref (match_operand 0 "" ""))
8383                       (pc)))]
8384   ""
8385   "
8386 {
8387   if (operands[0])              /* avoid unused code warning */
8388     {
8389       gen_conditional_branch (operands, GT);
8390       DONE;
8391     }
8392 }")
8393
8394 (define_expand "bge"
8395   [(set (pc)
8396         (if_then_else (ge:CC (cc0)
8397                              (const_int 0))
8398                       (label_ref (match_operand 0 "" ""))
8399                       (pc)))]
8400   ""
8401   "
8402 {
8403   if (operands[0])              /* avoid unused code warning */
8404     {
8405       gen_conditional_branch (operands, GE);
8406       DONE;
8407     }
8408 }")
8409
8410 (define_expand "blt"
8411   [(set (pc)
8412         (if_then_else (lt:CC (cc0)
8413                              (const_int 0))
8414                       (label_ref (match_operand 0 "" ""))
8415                       (pc)))]
8416   ""
8417   "
8418 {
8419   if (operands[0])              /* avoid unused code warning */
8420     {
8421       gen_conditional_branch (operands, LT);
8422       DONE;
8423     }
8424 }")
8425
8426 (define_expand "ble"
8427   [(set (pc)
8428         (if_then_else (le:CC (cc0)
8429                              (const_int 0))
8430                       (label_ref (match_operand 0 "" ""))
8431                       (pc)))]
8432   ""
8433   "
8434 {
8435   if (operands[0])              /* avoid unused code warning */
8436     {
8437       gen_conditional_branch (operands, LE);
8438       DONE;
8439     }
8440 }")
8441
8442 (define_expand "bgtu"
8443   [(set (pc)
8444         (if_then_else (gtu:CC (cc0)
8445                               (const_int 0))
8446                       (label_ref (match_operand 0 "" ""))
8447                       (pc)))]
8448   ""
8449   "
8450 {
8451   if (operands[0])              /* avoid unused code warning */
8452     {
8453       gen_conditional_branch (operands, GTU);
8454       DONE;
8455     }
8456 }")
8457
8458 (define_expand "bgeu"
8459   [(set (pc)
8460         (if_then_else (geu:CC (cc0)
8461                               (const_int 0))
8462                       (label_ref (match_operand 0 "" ""))
8463                       (pc)))]
8464   ""
8465   "
8466 {
8467   if (operands[0])              /* avoid unused code warning */
8468     {
8469       gen_conditional_branch (operands, GEU);
8470       DONE;
8471     }
8472 }")
8473
8474
8475 (define_expand "bltu"
8476   [(set (pc)
8477         (if_then_else (ltu:CC (cc0)
8478                               (const_int 0))
8479                       (label_ref (match_operand 0 "" ""))
8480                       (pc)))]
8481   ""
8482   "
8483 {
8484   if (operands[0])              /* avoid unused code warning */
8485     {
8486       gen_conditional_branch (operands, LTU);
8487       DONE;
8488     }
8489 }")
8490
8491 (define_expand "bleu"
8492   [(set (pc)
8493         (if_then_else (leu:CC (cc0)
8494                               (const_int 0))
8495                       (label_ref (match_operand 0 "" ""))
8496                       (pc)))]
8497   ""
8498   "
8499 {
8500   if (operands[0])              /* avoid unused code warning */
8501     {
8502       gen_conditional_branch (operands, LEU);
8503       DONE;
8504     }
8505 }")
8506
8507 \f
8508 ;;
8509 ;;  ....................
8510 ;;
8511 ;;      SETTING A REGISTER FROM A COMPARISON
8512 ;;
8513 ;;  ....................
8514
8515 (define_expand "seq"
8516   [(set (match_operand:SI 0 "register_operand" "=d")
8517         (eq:SI (match_dup 1)
8518                (match_dup 2)))]
8519   ""
8520   "
8521 {
8522   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8523     FAIL;
8524
8525   /* set up operands from compare.  */
8526   operands[1] = branch_cmp[0];
8527   operands[2] = branch_cmp[1];
8528
8529   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8530     {
8531       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8532       DONE;
8533     }
8534
8535   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8536     operands[2] = force_reg (SImode, operands[2]);
8537
8538   /* fall through and generate default code */
8539 }")
8540
8541
8542 (define_insn "seq_si_zero"
8543   [(set (match_operand:SI 0 "register_operand" "=d")
8544         (eq:SI (match_operand:SI 1 "register_operand" "d")
8545                (const_int 0)))]
8546   "!TARGET_MIPS16"
8547   "sltu\\t%0,%1,1"
8548   [(set_attr "type"     "arith")
8549    (set_attr "mode"     "SI")])
8550
8551 (define_insn ""
8552   [(set (match_operand:SI 0 "register_operand" "=t")
8553         (eq:SI (match_operand:SI 1 "register_operand" "d")
8554                (const_int 0)))]
8555   "TARGET_MIPS16"
8556   "sltu\\t%1,1"
8557   [(set_attr "type"     "arith")
8558    (set_attr "mode"     "SI")])
8559
8560 (define_insn "seq_di_zero"
8561   [(set (match_operand:DI 0 "register_operand" "=d")
8562         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8563                (const_int 0)))]
8564   "TARGET_64BIT && !TARGET_MIPS16"
8565   "sltu\\t%0,%1,1"
8566   [(set_attr "type"     "arith")
8567    (set_attr "mode"     "DI")])
8568
8569 (define_insn ""
8570   [(set (match_operand:DI 0 "register_operand" "=t")
8571         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8572                (const_int 0)))]
8573   "TARGET_64BIT && TARGET_MIPS16"
8574   "sltu\\t%1,1"
8575   [(set_attr "type"     "arith")
8576    (set_attr "mode"     "DI")])
8577
8578 (define_insn "seq_si"
8579   [(set (match_operand:SI 0 "register_operand" "=d,d")
8580         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8581                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8582   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8583   "@
8584    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8585    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8586   [(set_attr "type"     "arith")
8587    (set_attr "mode"     "SI")
8588    (set_attr "length"   "8")])
8589
8590 (define_split
8591   [(set (match_operand:SI 0 "register_operand" "")
8592         (eq:SI (match_operand:SI 1 "register_operand" "")
8593                (match_operand:SI 2 "uns_arith_operand" "")))]
8594   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8595     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8596   [(set (match_dup 0)
8597         (xor:SI (match_dup 1)
8598                 (match_dup 2)))
8599    (set (match_dup 0)
8600         (ltu:SI (match_dup 0)
8601                 (const_int 1)))]
8602   "")
8603
8604 (define_insn "seq_di"
8605   [(set (match_operand:DI 0 "register_operand" "=d,d")
8606         (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8607                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8608   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8609   "@
8610    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8611    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8612   [(set_attr "type"     "arith")
8613    (set_attr "mode"     "DI")
8614    (set_attr "length"   "8")])
8615
8616 (define_split
8617   [(set (match_operand:DI 0 "register_operand" "")
8618         (eq:DI (match_operand:DI 1 "se_register_operand" "")
8619                (match_operand:DI 2 "se_uns_arith_operand" "")))]
8620   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8621     && !TARGET_MIPS16
8622     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8623   [(set (match_dup 0)
8624         (xor:DI (match_dup 1)
8625                 (match_dup 2)))
8626    (set (match_dup 0)
8627         (ltu:DI (match_dup 0)
8628                 (const_int 1)))]
8629   "")
8630
8631 ;; On the mips16 the default code is better than using sltu.
8632
8633 (define_expand "sne"
8634   [(set (match_operand:SI 0 "register_operand" "=d")
8635         (ne:SI (match_dup 1)
8636                (match_dup 2)))]
8637   "!TARGET_MIPS16"
8638   "
8639 {
8640   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8641     FAIL;
8642
8643   /* set up operands from compare.  */
8644   operands[1] = branch_cmp[0];
8645   operands[2] = branch_cmp[1];
8646
8647   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
8648     {
8649       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8650       DONE;
8651     }
8652
8653   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8654     operands[2] = force_reg (SImode, operands[2]);
8655
8656   /* fall through and generate default code */
8657 }")
8658
8659 (define_insn "sne_si_zero"
8660   [(set (match_operand:SI 0 "register_operand" "=d")
8661         (ne:SI (match_operand:SI 1 "register_operand" "d")
8662                (const_int 0)))]
8663   "!TARGET_MIPS16"
8664   "sltu\\t%0,%.,%1"
8665   [(set_attr "type"     "arith")
8666    (set_attr "mode"     "SI")])
8667
8668 (define_insn "sne_di_zero"
8669   [(set (match_operand:DI 0 "register_operand" "=d")
8670         (ne:DI (match_operand:DI 1 "se_register_operand" "d")
8671                (const_int 0)))]
8672   "TARGET_64BIT && !TARGET_MIPS16"
8673   "sltu\\t%0,%.,%1"
8674   [(set_attr "type"     "arith")
8675    (set_attr "mode"     "DI")])
8676
8677 (define_insn "sne_si"
8678   [(set (match_operand:SI 0 "register_operand" "=d,d")
8679         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8680                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8681   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8682   "@
8683     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8684     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8685   [(set_attr "type"     "arith")
8686    (set_attr "mode"     "SI")
8687    (set_attr "length"   "8")])
8688
8689 (define_split
8690   [(set (match_operand:SI 0 "register_operand" "")
8691         (ne:SI (match_operand:SI 1 "register_operand" "")
8692                (match_operand:SI 2 "uns_arith_operand" "")))]
8693   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8694     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8695   [(set (match_dup 0)
8696         (xor:SI (match_dup 1)
8697                 (match_dup 2)))
8698    (set (match_dup 0)
8699         (gtu:SI (match_dup 0)
8700                 (const_int 0)))]
8701   "")
8702
8703 (define_insn "sne_di"
8704   [(set (match_operand:DI 0 "register_operand" "=d,d")
8705         (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8706                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8707   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8708   "@
8709     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8710     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8711   [(set_attr "type"     "arith")
8712    (set_attr "mode"     "DI")
8713    (set_attr "length"   "8")])
8714
8715 (define_split
8716   [(set (match_operand:DI 0 "register_operand" "")
8717         (ne:DI (match_operand:DI 1 "se_register_operand" "")
8718                (match_operand:DI 2 "se_uns_arith_operand" "")))]
8719   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8720     && !TARGET_MIPS16
8721     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8722   [(set (match_dup 0)
8723         (xor:DI (match_dup 1)
8724                 (match_dup 2)))
8725    (set (match_dup 0)
8726         (gtu:DI (match_dup 0)
8727                 (const_int 0)))]
8728   "")
8729
8730 (define_expand "sgt"
8731   [(set (match_operand:SI 0 "register_operand" "=d")
8732         (gt:SI (match_dup 1)
8733                (match_dup 2)))]
8734   ""
8735   "
8736 {
8737   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8738     FAIL;
8739
8740   /* set up operands from compare.  */
8741   operands[1] = branch_cmp[0];
8742   operands[2] = branch_cmp[1];
8743
8744   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8745     {
8746       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8747       DONE;
8748     }
8749
8750   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8751     operands[2] = force_reg (SImode, operands[2]);
8752
8753   /* fall through and generate default code */
8754 }")
8755
8756 (define_insn "sgt_si"
8757   [(set (match_operand:SI 0 "register_operand" "=d")
8758         (gt:SI (match_operand:SI 1 "register_operand" "d")
8759                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8760   "!TARGET_MIPS16"
8761   "slt\\t%0,%z2,%1"
8762   [(set_attr "type"     "arith")
8763    (set_attr "mode"     "SI")])
8764
8765 (define_insn ""
8766   [(set (match_operand:SI 0 "register_operand" "=t")
8767         (gt:SI (match_operand:SI 1 "register_operand" "d")
8768                (match_operand:SI 2 "register_operand" "d")))]
8769   "TARGET_MIPS16"
8770   "slt\\t%2,%1"
8771   [(set_attr "type"     "arith")
8772    (set_attr "mode"     "SI")])
8773
8774 (define_insn "sgt_di"
8775   [(set (match_operand:DI 0 "register_operand" "=d")
8776         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8777                (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8778   "TARGET_64BIT && !TARGET_MIPS16"
8779   "slt\\t%0,%z2,%1"
8780   [(set_attr "type"     "arith")
8781    (set_attr "mode"     "DI")])
8782
8783 (define_insn ""
8784   [(set (match_operand:DI 0 "register_operand" "=d")
8785         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8786                (match_operand:DI 2 "se_register_operand" "d")))]
8787   "TARGET_64BIT && TARGET_MIPS16"
8788   "slt\\t%2,%1"
8789   [(set_attr "type"     "arith")
8790    (set_attr "mode"     "DI")])
8791
8792 (define_expand "sge"
8793   [(set (match_operand:SI 0 "register_operand" "=d")
8794         (ge:SI (match_dup 1)
8795                (match_dup 2)))]
8796   ""
8797   "
8798 {
8799   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8800     FAIL;
8801
8802   /* set up operands from compare.  */
8803   operands[1] = branch_cmp[0];
8804   operands[2] = branch_cmp[1];
8805
8806   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8807     {
8808       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8809       DONE;
8810     }
8811
8812   /* fall through and generate default code */
8813 }")
8814
8815 (define_insn "sge_si"
8816   [(set (match_operand:SI 0 "register_operand" "=d")
8817         (ge:SI (match_operand:SI 1 "register_operand" "d")
8818                (match_operand:SI 2 "arith_operand" "dI")))]
8819   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8820   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8821   [(set_attr "type"     "arith")
8822    (set_attr "mode"     "SI")
8823    (set_attr "length"   "8")])
8824
8825 (define_split
8826   [(set (match_operand:SI 0 "register_operand" "")
8827         (ge:SI (match_operand:SI 1 "register_operand" "")
8828                (match_operand:SI 2 "arith_operand" "")))]
8829   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8830   [(set (match_dup 0)
8831         (lt:SI (match_dup 1)
8832                (match_dup 2)))
8833    (set (match_dup 0)
8834         (xor:SI (match_dup 0)
8835                 (const_int 1)))]
8836   "")
8837
8838 (define_insn "sge_di"
8839   [(set (match_operand:DI 0 "register_operand" "=d")
8840         (ge:DI (match_operand:DI 1 "se_register_operand" "d")
8841                (match_operand:DI 2 "se_arith_operand" "dI")))]
8842   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8843   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8844   [(set_attr "type"     "arith")
8845    (set_attr "mode"     "DI")
8846    (set_attr "length"   "8")])
8847
8848 (define_split
8849   [(set (match_operand:DI 0 "register_operand" "")
8850         (ge:DI (match_operand:DI 1 "se_register_operand" "")
8851                (match_operand:DI 2 "se_arith_operand" "")))]
8852   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8853    && !TARGET_MIPS16"
8854   [(set (match_dup 0)
8855         (lt:DI (match_dup 1)
8856                (match_dup 2)))
8857    (set (match_dup 0)
8858         (xor:DI (match_dup 0)
8859                 (const_int 1)))]
8860   "")
8861
8862 (define_expand "slt"
8863   [(set (match_operand:SI 0 "register_operand" "=d")
8864         (lt:SI (match_dup 1)
8865                (match_dup 2)))]
8866   ""
8867   "
8868 {
8869   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8870     FAIL;
8871
8872   /* set up operands from compare.  */
8873   operands[1] = branch_cmp[0];
8874   operands[2] = branch_cmp[1];
8875
8876   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8877     {
8878       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8879       DONE;
8880     }
8881
8882   /* fall through and generate default code */
8883 }")
8884
8885 (define_insn "slt_si"
8886   [(set (match_operand:SI 0 "register_operand" "=d")
8887         (lt:SI (match_operand:SI 1 "register_operand" "d")
8888                (match_operand:SI 2 "arith_operand" "dI")))]
8889   "!TARGET_MIPS16"
8890   "slt\\t%0,%1,%2"
8891   [(set_attr "type"     "arith")
8892    (set_attr "mode"     "SI")])
8893
8894 (define_insn ""
8895   [(set (match_operand:SI 0 "register_operand" "=t,t")
8896         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8897                (match_operand:SI 2 "arith_operand" "d,I")))]
8898   "TARGET_MIPS16"
8899   "slt\\t%1,%2"
8900   [(set_attr "type"     "arith")
8901    (set_attr "mode"     "SI")
8902    (set_attr_alternative "length"
8903                 [(const_int 4)
8904                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8905                                (const_int 4)
8906                                (const_int 8))])])
8907
8908 (define_insn "slt_di"
8909   [(set (match_operand:DI 0 "register_operand" "=d")
8910         (lt:DI (match_operand:DI 1 "se_register_operand" "d")
8911                (match_operand:DI 2 "se_arith_operand" "dI")))]
8912   "TARGET_64BIT && !TARGET_MIPS16"
8913   "slt\\t%0,%1,%2"
8914   [(set_attr "type"     "arith")
8915    (set_attr "mode"     "DI")])
8916
8917 (define_insn ""
8918   [(set (match_operand:DI 0 "register_operand" "=t,t")
8919         (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
8920                (match_operand:DI 2 "se_arith_operand" "d,I")))]
8921   "TARGET_64BIT && TARGET_MIPS16"
8922   "slt\\t%1,%2"
8923   [(set_attr "type"     "arith")
8924    (set_attr "mode"     "DI")
8925    (set_attr_alternative "length"
8926                 [(const_int 4)
8927                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8928                                (const_int 4)
8929                                (const_int 8))])])
8930
8931 (define_expand "sle"
8932   [(set (match_operand:SI 0 "register_operand" "=d")
8933         (le:SI (match_dup 1)
8934                (match_dup 2)))]
8935   ""
8936   "
8937 {
8938   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8939     FAIL;
8940
8941   /* set up operands from compare.  */
8942   operands[1] = branch_cmp[0];
8943   operands[2] = branch_cmp[1];
8944
8945   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8946     {
8947       gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8948       DONE;
8949     }
8950
8951   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8952     operands[2] = force_reg (SImode, operands[2]);
8953
8954   /* fall through and generate default code */
8955 }")
8956
8957 (define_insn "sle_si_const"
8958   [(set (match_operand:SI 0 "register_operand" "=d")
8959         (le:SI (match_operand:SI 1 "register_operand" "d")
8960                (match_operand:SI 2 "small_int" "I")))]
8961   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8962   "*
8963 {
8964   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8965   return \"slt\\t%0,%1,%2\";
8966 }"
8967   [(set_attr "type"     "arith")
8968    (set_attr "mode"     "SI")])
8969
8970 (define_insn ""
8971   [(set (match_operand:SI 0 "register_operand" "=t")
8972         (le:SI (match_operand:SI 1 "register_operand" "d")
8973                (match_operand:SI 2 "small_int" "I")))]
8974   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8975   "*
8976 {
8977   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8978   return \"slt\\t%1,%2\";
8979 }"
8980   [(set_attr "type"     "arith")
8981    (set_attr "mode"     "SI")
8982    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8983                                       (const_int 4)
8984                                       (const_int 8)))])
8985
8986 (define_insn "sle_di_const"
8987   [(set (match_operand:DI 0 "register_operand" "=d")
8988         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8989                (match_operand:DI 2 "small_int" "I")))]
8990   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8991   "*
8992 {
8993   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8994   return \"slt\\t%0,%1,%2\";
8995 }"
8996   [(set_attr "type"     "arith")
8997    (set_attr "mode"     "DI")])
8998
8999 (define_insn ""
9000   [(set (match_operand:DI 0 "register_operand" "=t")
9001         (le:DI (match_operand:DI 1 "se_register_operand" "d")
9002                (match_operand:DI 2 "small_int" "I")))]
9003   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9004   "*
9005 {
9006   operands[2] = GEN_INT (INTVAL (operands[2])+1);
9007   return \"slt\\t%1,%2\";
9008 }"
9009   [(set_attr "type"     "arith")
9010    (set_attr "mode"     "DI")
9011    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9012                                       (const_int 4)
9013                                       (const_int 8)))])
9014
9015 (define_insn "sle_si_reg"
9016   [(set (match_operand:SI 0 "register_operand" "=d")
9017         (le:SI (match_operand:SI 1 "register_operand" "d")
9018                (match_operand:SI 2 "register_operand" "d")))]
9019   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9020   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9021   [(set_attr "type"     "arith")
9022    (set_attr "mode"     "SI")
9023    (set_attr "length"   "8")])
9024
9025 (define_split
9026   [(set (match_operand:SI 0 "register_operand" "")
9027         (le:SI (match_operand:SI 1 "register_operand" "")
9028                (match_operand:SI 2 "register_operand" "")))]
9029   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
9030   [(set (match_dup 0)
9031         (lt:SI (match_dup 2)
9032                (match_dup 1)))
9033    (set (match_dup 0)
9034         (xor:SI (match_dup 0)
9035                 (const_int 1)))]
9036   "")
9037
9038 (define_insn "sle_di_reg"
9039   [(set (match_operand:DI 0 "register_operand" "=d")
9040         (le:DI (match_operand:DI 1 "se_register_operand" "d")
9041                (match_operand:DI 2 "se_register_operand" "d")))]
9042   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9043   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9044   [(set_attr "type"     "arith")
9045    (set_attr "mode"     "DI")
9046    (set_attr "length"   "8")])
9047
9048 (define_split
9049   [(set (match_operand:DI 0 "register_operand" "")
9050         (le:DI (match_operand:DI 1 "se_register_operand" "")
9051                (match_operand:DI 2 "se_register_operand" "")))]
9052   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9053    && !TARGET_MIPS16"
9054   [(set (match_dup 0)
9055         (lt:DI (match_dup 2)
9056                (match_dup 1)))
9057    (set (match_dup 0)
9058         (xor:DI (match_dup 0)
9059                 (const_int 1)))]
9060   "")
9061
9062 (define_expand "sgtu"
9063   [(set (match_operand:SI 0 "register_operand" "=d")
9064         (gtu:SI (match_dup 1)
9065                 (match_dup 2)))]
9066   ""
9067   "
9068 {
9069   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
9070     FAIL;
9071
9072   /* set up operands from compare.  */
9073   operands[1] = branch_cmp[0];
9074   operands[2] = branch_cmp[1];
9075
9076   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
9077     {
9078       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
9079       DONE;
9080     }
9081
9082   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
9083     operands[2] = force_reg (SImode, operands[2]);
9084
9085   /* fall through and generate default code */
9086 }")
9087
9088 (define_insn "sgtu_si"
9089   [(set (match_operand:SI 0 "register_operand" "=d")
9090         (gtu:SI (match_operand:SI 1 "register_operand" "d")
9091                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
9092   "!TARGET_MIPS16"
9093   "sltu\\t%0,%z2,%1"
9094   [(set_attr "type"     "arith")
9095    (set_attr "mode"     "SI")])
9096
9097 (define_insn ""
9098   [(set (match_operand:SI 0 "register_operand" "=t")
9099         (gtu:SI (match_operand:SI 1 "register_operand" "d")
9100                 (match_operand:SI 2 "register_operand" "d")))]
9101   "TARGET_MIPS16"
9102   "sltu\\t%2,%1"
9103   [(set_attr "type"     "arith")
9104    (set_attr "mode"     "SI")])
9105
9106 (define_insn "sgtu_di"
9107   [(set (match_operand:DI 0 "register_operand" "=d")
9108         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
9109                 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
9110   "TARGET_64BIT && !TARGET_MIPS16"
9111   "sltu\\t%0,%z2,%1"
9112   [(set_attr "type"     "arith")
9113    (set_attr "mode"     "DI")])
9114
9115 (define_insn ""
9116   [(set (match_operand:DI 0 "register_operand" "=t")
9117         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
9118                 (match_operand:DI 2 "se_register_operand" "d")))]
9119   "TARGET_64BIT && TARGET_MIPS16"
9120   "sltu\\t%2,%1"
9121   [(set_attr "type"     "arith")
9122    (set_attr "mode"     "DI")])
9123
9124 (define_expand "sgeu"
9125   [(set (match_operand:SI 0 "register_operand" "=d")
9126         (geu:SI (match_dup 1)
9127                 (match_dup 2)))]
9128   ""
9129   "
9130 {
9131   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
9132     FAIL;
9133
9134   /* set up operands from compare.  */
9135   operands[1] = branch_cmp[0];
9136   operands[2] = branch_cmp[1];
9137
9138   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
9139     {
9140       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
9141       DONE;
9142     }
9143
9144   /* fall through and generate default code */
9145 }")
9146
9147 (define_insn "sgeu_si"
9148   [(set (match_operand:SI 0 "register_operand" "=d")
9149         (geu:SI (match_operand:SI 1 "register_operand" "d")
9150                 (match_operand:SI 2 "arith_operand" "dI")))]
9151   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9152   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
9153   [(set_attr "type"     "arith")
9154    (set_attr "mode"     "SI")
9155    (set_attr "length"   "8")])
9156
9157 (define_split
9158   [(set (match_operand:SI 0 "register_operand" "")
9159         (geu:SI (match_operand:SI 1 "register_operand" "")
9160                 (match_operand:SI 2 "arith_operand" "")))]
9161   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
9162   [(set (match_dup 0)
9163         (ltu:SI (match_dup 1)
9164                 (match_dup 2)))
9165    (set (match_dup 0)
9166         (xor:SI (match_dup 0)
9167                 (const_int 1)))]
9168   "")
9169
9170 (define_insn "sgeu_di"
9171   [(set (match_operand:DI 0 "register_operand" "=d")
9172         (geu:DI (match_operand:DI 1 "se_register_operand" "d")
9173                 (match_operand:DI 2 "se_arith_operand" "dI")))]
9174   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9175   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
9176   [(set_attr "type"     "arith")
9177    (set_attr "mode"     "DI")
9178    (set_attr "length"   "8")])
9179
9180 (define_split
9181   [(set (match_operand:DI 0 "register_operand" "")
9182         (geu:DI (match_operand:DI 1 "se_register_operand" "")
9183                 (match_operand:DI 2 "se_arith_operand" "")))]
9184   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9185    && !TARGET_MIPS16"
9186   [(set (match_dup 0)
9187         (ltu:DI (match_dup 1)
9188                 (match_dup 2)))
9189    (set (match_dup 0)
9190         (xor:DI (match_dup 0)
9191                 (const_int 1)))]
9192   "")
9193
9194 (define_expand "sltu"
9195   [(set (match_operand:SI 0 "register_operand" "=d")
9196         (ltu:SI (match_dup 1)
9197                 (match_dup 2)))]
9198   ""
9199   "
9200 {
9201   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
9202     FAIL;
9203
9204   /* set up operands from compare.  */
9205   operands[1] = branch_cmp[0];
9206   operands[2] = branch_cmp[1];
9207
9208   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
9209     {
9210       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
9211       DONE;
9212     }
9213
9214   /* fall through and generate default code */
9215 }")
9216
9217 (define_insn "sltu_si"
9218   [(set (match_operand:SI 0 "register_operand" "=d")
9219         (ltu:SI (match_operand:SI 1 "register_operand" "d")
9220                 (match_operand:SI 2 "arith_operand" "dI")))]
9221   "!TARGET_MIPS16"
9222   "sltu\\t%0,%1,%2"
9223   [(set_attr "type"     "arith")
9224    (set_attr "mode"     "SI")])
9225
9226 (define_insn ""
9227   [(set (match_operand:SI 0 "register_operand" "=t,t")
9228         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
9229                 (match_operand:SI 2 "arith_operand" "d,I")))]
9230   "TARGET_MIPS16"
9231   "sltu\\t%1,%2"
9232   [(set_attr "type"     "arith")
9233    (set_attr "mode"     "SI")
9234    (set_attr_alternative "length"
9235                 [(const_int 4)
9236                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
9237                                (const_int 4)
9238                                (const_int 8))])])
9239
9240 (define_insn "sltu_di"
9241   [(set (match_operand:DI 0 "register_operand" "=d")
9242         (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
9243                 (match_operand:DI 2 "se_arith_operand" "dI")))]
9244   "TARGET_64BIT && !TARGET_MIPS16"
9245   "sltu\\t%0,%1,%2"
9246   [(set_attr "type"     "arith")
9247    (set_attr "mode"     "DI")])
9248
9249 (define_insn ""
9250   [(set (match_operand:DI 0 "register_operand" "=t,t")
9251         (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
9252                 (match_operand:DI 2 "se_arith_operand" "d,I")))]
9253   "TARGET_64BIT && TARGET_MIPS16"
9254   "sltu\\t%1,%2"
9255   [(set_attr "type"     "arith")
9256    (set_attr "mode"     "DI")
9257    (set_attr_alternative "length"
9258                 [(const_int 4)
9259                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
9260                                (const_int 4)
9261                                (const_int 8))])])
9262
9263 (define_expand "sleu"
9264   [(set (match_operand:SI 0 "register_operand" "=d")
9265         (leu:SI (match_dup 1)
9266                 (match_dup 2)))]
9267   ""
9268   "
9269 {
9270   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
9271     FAIL;
9272
9273   /* set up operands from compare.  */
9274   operands[1] = branch_cmp[0];
9275   operands[2] = branch_cmp[1];
9276
9277   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
9278     {
9279       gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
9280       DONE;
9281     }
9282
9283   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
9284     operands[2] = force_reg (SImode, operands[2]);
9285
9286   /* fall through and generate default code */
9287 }")
9288
9289 (define_insn "sleu_si_const"
9290   [(set (match_operand:SI 0 "register_operand" "=d")
9291         (leu:SI (match_operand:SI 1 "register_operand" "d")
9292                 (match_operand:SI 2 "small_int" "I")))]
9293   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9294   "*
9295 {
9296   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9297   return \"sltu\\t%0,%1,%2\";
9298 }"
9299   [(set_attr "type"     "arith")
9300    (set_attr "mode"     "SI")])
9301
9302 (define_insn ""
9303   [(set (match_operand:SI 0 "register_operand" "=t")
9304         (leu:SI (match_operand:SI 1 "register_operand" "d")
9305                 (match_operand:SI 2 "small_int" "I")))]
9306   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9307   "*
9308 {
9309   operands[2] = GEN_INT (INTVAL (operands[2])+1);
9310   return \"sltu\\t%1,%2\";
9311 }"
9312   [(set_attr "type"     "arith")
9313    (set_attr "mode"     "SI")
9314    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9315                                       (const_int 4)
9316                                       (const_int 8)))])
9317
9318 (define_insn "sleu_di_const"
9319   [(set (match_operand:DI 0 "register_operand" "=d")
9320         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9321                 (match_operand:DI 2 "small_int" "I")))]
9322   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9323   "*
9324 {
9325   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9326   return \"sltu\\t%0,%1,%2\";
9327 }"
9328   [(set_attr "type"     "arith")
9329    (set_attr "mode"     "DI")])
9330
9331 (define_insn ""
9332   [(set (match_operand:DI 0 "register_operand" "=t")
9333         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9334                 (match_operand:DI 2 "small_int" "I")))]
9335   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9336   "*
9337 {
9338   operands[2] = GEN_INT (INTVAL (operands[2])+1);
9339   return \"sltu\\t%1,%2\";
9340 }"
9341   [(set_attr "type"     "arith")
9342    (set_attr "mode"     "DI")
9343    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9344                                       (const_int 4)
9345                                       (const_int 8)))])
9346
9347 (define_insn "sleu_si_reg"
9348   [(set (match_operand:SI 0 "register_operand" "=d")
9349         (leu:SI (match_operand:SI 1 "register_operand" "d")
9350                 (match_operand:SI 2 "register_operand" "d")))]
9351   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9352   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9353   [(set_attr "type"     "arith")
9354    (set_attr "mode"     "SI")
9355    (set_attr "length"   "8")])
9356
9357 (define_split
9358   [(set (match_operand:SI 0 "register_operand" "")
9359         (leu:SI (match_operand:SI 1 "register_operand" "")
9360                 (match_operand:SI 2 "register_operand" "")))]
9361   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
9362   [(set (match_dup 0)
9363         (ltu:SI (match_dup 2)
9364                 (match_dup 1)))
9365    (set (match_dup 0)
9366         (xor:SI (match_dup 0)
9367                 (const_int 1)))]
9368   "")
9369
9370 (define_insn "sleu_di_reg"
9371   [(set (match_operand:DI 0 "register_operand" "=d")
9372         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9373                 (match_operand:DI 2 "se_register_operand" "d")))]
9374   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9375   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9376   [(set_attr "type"     "arith")
9377    (set_attr "mode"     "DI")
9378    (set_attr "length"   "8")])
9379
9380 (define_split
9381   [(set (match_operand:DI 0 "register_operand" "")
9382         (leu:DI (match_operand:DI 1 "se_register_operand" "")
9383                 (match_operand:DI 2 "se_register_operand" "")))]
9384   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9385    && !TARGET_MIPS16"
9386   [(set (match_dup 0)
9387         (ltu:DI (match_dup 2)
9388                 (match_dup 1)))
9389    (set (match_dup 0)
9390         (xor:DI (match_dup 0)
9391                 (const_int 1)))]
9392   "")
9393
9394 \f
9395 ;;
9396 ;;  ....................
9397 ;;
9398 ;;      FLOATING POINT COMPARISONS
9399 ;;
9400 ;;  ....................
9401
9402 (define_insn "sunordered_df"
9403   [(set (match_operand:CC 0 "register_operand" "=z")
9404         (unordered:CC (match_operand:DF 1 "register_operand" "f")
9405                       (match_operand:DF 2 "register_operand" "f")))]
9406   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9407   "*
9408 {
9409  return mips_fill_delay_slot (\"c.un.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9410 }"
9411  [(set_attr "type"      "fcmp")
9412   (set_attr "mode"      "FPSW")])
9413
9414 (define_insn "sunlt_df"
9415   [(set (match_operand:CC 0 "register_operand" "=z")
9416         (unlt:CC (match_operand:DF 1 "register_operand" "f")
9417                  (match_operand:DF 2 "register_operand" "f")))]
9418   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9419   "*
9420 {
9421  return mips_fill_delay_slot (\"c.ult.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9422 }"
9423  [(set_attr "type"      "fcmp")
9424   (set_attr "mode"      "FPSW")])
9425
9426 (define_insn "suneq_df"
9427   [(set (match_operand:CC 0 "register_operand" "=z")
9428         (uneq:CC (match_operand:DF 1 "register_operand" "f")
9429                  (match_operand:DF 2 "register_operand" "f")))]
9430   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9431   "*
9432 {
9433  return mips_fill_delay_slot (\"c.ueq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9434 }"
9435  [(set_attr "type"      "fcmp")
9436   (set_attr "mode"      "FPSW")])
9437
9438 (define_insn "sunle_df"
9439   [(set (match_operand:CC 0 "register_operand" "=z")
9440         (unle:CC (match_operand:DF 1 "register_operand" "f")
9441                  (match_operand:DF 2 "register_operand" "f")))]
9442   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9443   "*
9444 {
9445  return mips_fill_delay_slot (\"c.ule.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9446 }"
9447  [(set_attr "type"      "fcmp")
9448   (set_attr "mode"      "FPSW")])
9449
9450 (define_insn "seq_df"
9451   [(set (match_operand:CC 0 "register_operand" "=z")
9452         (eq:CC (match_operand:DF 1 "register_operand" "f")
9453                (match_operand:DF 2 "register_operand" "f")))]
9454   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9455   "*
9456 {
9457   return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9458 }"
9459  [(set_attr "type"      "fcmp")
9460   (set_attr "mode"      "FPSW")])
9461
9462 (define_insn "slt_df"
9463   [(set (match_operand:CC 0 "register_operand" "=z")
9464         (lt:CC (match_operand:DF 1 "register_operand" "f")
9465                (match_operand:DF 2 "register_operand" "f")))]
9466   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9467   "*
9468 {
9469   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9470 }"
9471  [(set_attr "type"      "fcmp")
9472   (set_attr "mode"      "FPSW")])
9473
9474 (define_insn "sle_df"
9475   [(set (match_operand:CC 0 "register_operand" "=z")
9476         (le:CC (match_operand:DF 1 "register_operand" "f")
9477                (match_operand:DF 2 "register_operand" "f")))]
9478   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9479   "*
9480 {
9481   return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9482 }"
9483  [(set_attr "type"      "fcmp")
9484   (set_attr "mode"      "FPSW")])
9485
9486 (define_insn "sgt_df"
9487   [(set (match_operand:CC 0 "register_operand" "=z")
9488         (gt:CC (match_operand:DF 1 "register_operand" "f")
9489                (match_operand:DF 2 "register_operand" "f")))]
9490   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9491   "*
9492 {
9493   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9494 }"
9495  [(set_attr "type"      "fcmp")
9496   (set_attr "mode"      "FPSW")])
9497
9498 (define_insn "sge_df"
9499   [(set (match_operand:CC 0 "register_operand" "=z")
9500         (ge:CC (match_operand:DF 1 "register_operand" "f")
9501                (match_operand:DF 2 "register_operand" "f")))]
9502   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9503   "*
9504 {
9505   return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9506 }"
9507  [(set_attr "type"      "fcmp")
9508   (set_attr "mode"      "FPSW")])
9509
9510 (define_insn "sunordered_sf"
9511   [(set (match_operand:CC 0 "register_operand" "=z")
9512         (unordered:CC (match_operand:SF 1 "register_operand" "f")
9513                       (match_operand:SF 2 "register_operand" "f")))]
9514   "TARGET_HARD_FLOAT"
9515   "*
9516 {
9517  return mips_fill_delay_slot (\"c.un.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9518 }"
9519  [(set_attr "type"      "fcmp")
9520   (set_attr "mode"      "FPSW")])
9521
9522 (define_insn "sunlt_sf"
9523   [(set (match_operand:CC 0 "register_operand" "=z")
9524         (unlt:CC (match_operand:SF 1 "register_operand" "f")
9525                  (match_operand:SF 2 "register_operand" "f")))]
9526   "TARGET_HARD_FLOAT"
9527   "*
9528 {
9529  return mips_fill_delay_slot (\"c.ult.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9530 }"
9531  [(set_attr "type"      "fcmp")
9532   (set_attr "mode"      "FPSW")])
9533
9534 (define_insn "suneq_sf"
9535   [(set (match_operand:CC 0 "register_operand" "=z")
9536         (uneq:CC (match_operand:SF 1 "register_operand" "f")
9537                  (match_operand:SF 2 "register_operand" "f")))]
9538   "TARGET_HARD_FLOAT"
9539   "*
9540 {
9541  return mips_fill_delay_slot (\"c.ueq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9542 }"
9543  [(set_attr "type"      "fcmp")
9544   (set_attr "mode"      "FPSW")])
9545
9546 (define_insn "sunle_sf"
9547   [(set (match_operand:CC 0 "register_operand" "=z")
9548         (unle:CC (match_operand:SF 1 "register_operand" "f")
9549                  (match_operand:SF 2 "register_operand" "f")))]
9550   "TARGET_HARD_FLOAT"
9551   "*
9552 {
9553  return mips_fill_delay_slot (\"c.ule.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9554 }"
9555  [(set_attr "type"      "fcmp")
9556   (set_attr "mode"      "FPSW")])
9557
9558 (define_insn "seq_sf"
9559   [(set (match_operand:CC 0 "register_operand" "=z")
9560         (eq:CC (match_operand:SF 1 "register_operand" "f")
9561                (match_operand:SF 2 "register_operand" "f")))]
9562   "TARGET_HARD_FLOAT"
9563   "*
9564 {
9565   return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9566 }"
9567  [(set_attr "type"      "fcmp")
9568   (set_attr "mode"      "FPSW")])
9569
9570 (define_insn "slt_sf"
9571   [(set (match_operand:CC 0 "register_operand" "=z")
9572         (lt:CC (match_operand:SF 1 "register_operand" "f")
9573                (match_operand:SF 2 "register_operand" "f")))]
9574   "TARGET_HARD_FLOAT"
9575   "*
9576 {
9577   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9578 }"
9579  [(set_attr "type"      "fcmp")
9580   (set_attr "mode"      "FPSW")])
9581
9582 (define_insn "sle_sf"
9583   [(set (match_operand:CC 0 "register_operand" "=z")
9584         (le:CC (match_operand:SF 1 "register_operand" "f")
9585                (match_operand:SF 2 "register_operand" "f")))]
9586   "TARGET_HARD_FLOAT"
9587   "*
9588 {
9589   return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9590 }"
9591  [(set_attr "type"      "fcmp")
9592   (set_attr "mode"      "FPSW")])
9593
9594 (define_insn "sgt_sf"
9595   [(set (match_operand:CC 0 "register_operand" "=z")
9596         (gt:CC (match_operand:SF 1 "register_operand" "f")
9597                (match_operand:SF 2 "register_operand" "f")))]
9598   "TARGET_HARD_FLOAT"
9599   "*
9600 {
9601   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9602 }"
9603  [(set_attr "type"      "fcmp")
9604   (set_attr "mode"      "FPSW")])
9605
9606 (define_insn "sge_sf"
9607   [(set (match_operand:CC 0 "register_operand" "=z")
9608         (ge:CC (match_operand:SF 1 "register_operand" "f")
9609                (match_operand:SF 2 "register_operand" "f")))]
9610   "TARGET_HARD_FLOAT"
9611   "*
9612 {
9613   return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9614 }"
9615  [(set_attr "type"      "fcmp")
9616   (set_attr "mode"      "FPSW")])
9617
9618 \f
9619 ;;
9620 ;;  ....................
9621 ;;
9622 ;;      UNCONDITIONAL BRANCHES
9623 ;;
9624 ;;  ....................
9625
9626 ;; Unconditional branches.
9627
9628 (define_insn "jump"
9629   [(set (pc)
9630         (label_ref (match_operand 0 "" "")))]
9631   "!TARGET_MIPS16"
9632   "*
9633 {
9634   if (flag_pic && ! TARGET_EMBEDDED_PIC)
9635     {
9636       if (get_attr_length (insn) <= 8)
9637         return \"%*b\\t%l0\";
9638       else if (Pmode == DImode)
9639         return \"%[dla\\t%@,%l0\;%*jr\\t%@%]\";
9640       else
9641         return \"%[la\\t%@,%l0\;%*jr\\t%@%]\";
9642     }
9643   else
9644     return \"%*j\\t%l0\";
9645 }"
9646   [(set_attr "type"     "jump")
9647    (set_attr "mode"     "none")
9648    (set (attr "length")
9649         ;; we can't use `j' when emitting non-embedded PIC, so we emit
9650         ;; branch, if it's in range, or load the address of the branch
9651         ;; target into $at in a PIC-compatible way and then jump to it.
9652         (if_then_else 
9653          (ior (eq (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
9654                   (const_int 0))
9655               (lt (abs (minus (match_dup 0)
9656                               (plus (pc) (const_int 4))))
9657                   (const_int 131072)))
9658          (const_int 4) (const_int 16)))])
9659
9660 ;; We need a different insn for the mips16, because a mips16 branch
9661 ;; does not have a delay slot.
9662
9663 (define_insn ""
9664   [(set (pc)
9665         (label_ref (match_operand 0 "" "")))]
9666   "TARGET_MIPS16"
9667   "b\\t%l0"
9668   [(set_attr "type"     "branch")
9669    (set_attr "mode"     "none")
9670    (set_attr "length"   "8")])
9671
9672 (define_expand "indirect_jump"
9673   [(set (pc) (match_operand 0 "register_operand" "d"))]
9674   ""
9675   "
9676 {
9677   rtx dest;
9678
9679   if (operands[0])              /* eliminate unused code warnings */
9680     {
9681       dest = operands[0];
9682       if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9683         operands[0] = copy_to_mode_reg (Pmode, dest);
9684
9685       if (!(Pmode == DImode))
9686         emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9687       else
9688         emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9689
9690       DONE;
9691     }
9692 }")
9693
9694 (define_insn "indirect_jump_internal1"
9695   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
9696   "!(Pmode == DImode)"
9697   "%*j\\t%0"
9698   [(set_attr "type"     "jump")
9699    (set_attr "mode"     "none")])
9700
9701 (define_insn "indirect_jump_internal2"
9702   [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
9703   "Pmode == DImode"
9704   "%*j\\t%0"
9705   [(set_attr "type"     "jump")
9706    (set_attr "mode"     "none")])
9707
9708 (define_expand "tablejump"
9709   [(set (pc)
9710         (match_operand 0 "register_operand" "d"))
9711    (use (label_ref (match_operand 1 "" "")))]
9712   ""
9713   "
9714 {
9715   if (operands[0])              /* eliminate unused code warnings */
9716     {
9717       if (TARGET_MIPS16)
9718         {
9719           if (GET_MODE (operands[0]) != HImode)
9720             abort ();
9721           if (!(Pmode == DImode))
9722             emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
9723           else
9724             emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
9725           DONE;
9726         }
9727
9728       if (GET_MODE (operands[0]) != Pmode)
9729         abort ();
9730
9731       if (! flag_pic)
9732         {
9733           if (!(Pmode == DImode))
9734             emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9735           else
9736             emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
9737         }
9738       else
9739         {
9740           if (!(Pmode == DImode))
9741             emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
9742           else
9743             emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
9744         }
9745
9746       DONE;
9747     }
9748 }")
9749
9750 (define_insn "tablejump_internal1"
9751   [(set (pc)
9752         (match_operand:SI 0 "register_operand" "d"))
9753    (use (label_ref (match_operand 1 "" "")))]
9754   "!(Pmode == DImode)"
9755   "%*j\\t%0"
9756   [(set_attr "type"     "jump")
9757    (set_attr "mode"     "none")])
9758
9759 (define_insn "tablejump_internal2"
9760   [(set (pc)
9761         (match_operand:DI 0 "se_register_operand" "d"))
9762    (use (label_ref (match_operand 1 "" "")))]
9763   "Pmode == DImode"
9764   "%*j\\t%0"
9765   [(set_attr "type"     "jump")
9766    (set_attr "mode"     "none")])
9767
9768 (define_expand "tablejump_internal3"
9769   [(parallel [(set (pc)
9770                    (plus:SI (match_operand:SI 0 "register_operand" "d")
9771                             (label_ref:SI (match_operand 1 "" ""))))
9772               (use (label_ref:SI (match_dup 1)))])]
9773   ""
9774   "")
9775
9776 (define_expand "tablejump_mips161"
9777   [(set (pc) (plus:SI (sign_extend:SI
9778                        (match_operand:HI 0 "register_operand" "d"))
9779                       (label_ref:SI (match_operand 1 "" ""))))]
9780   "TARGET_MIPS16 && !(Pmode == DImode)"
9781   "
9782 {
9783   if (operands[0])      /* eliminate unused code warnings.  */
9784     {
9785       rtx t1, t2, t3;
9786
9787       t1 = gen_reg_rtx (SImode);
9788       t2 = gen_reg_rtx (SImode);
9789       t3 = gen_reg_rtx (SImode);
9790       emit_insn (gen_extendhisi2 (t1, operands[0]));
9791       emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
9792       emit_insn (gen_addsi3 (t3, t1, t2));
9793       emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
9794       DONE;
9795     }
9796 }")
9797
9798 (define_expand "tablejump_mips162"
9799   [(set (pc) (plus:DI (sign_extend:DI
9800                        (match_operand:HI 0 "register_operand" "d"))
9801                       (label_ref:DI (match_operand 1 "" ""))))]
9802   "TARGET_MIPS16 && Pmode == DImode"
9803   "
9804 {
9805   if (operands[0])      /* eliminate unused code warnings.  */
9806     {
9807       rtx t1, t2, t3;
9808
9809       t1 = gen_reg_rtx (DImode);
9810       t2 = gen_reg_rtx (DImode);
9811       t3 = gen_reg_rtx (DImode);
9812       emit_insn (gen_extendhidi2 (t1, operands[0]));
9813       emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
9814       emit_insn (gen_adddi3 (t3, t1, t2));
9815       emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
9816       DONE;
9817     }
9818 }")
9819
9820 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
9821 ;;; it is not valid.  ??? With the USE, the condition tests may not be required
9822 ;;; any longer.
9823
9824 ;;; ??? The length depends on the ABI.  It is two for o32, and one for n32.
9825 ;;; We just use the conservative number here.
9826
9827 (define_insn ""
9828   [(set (pc)
9829         (plus:SI (match_operand:SI 0 "register_operand" "d")
9830                  (label_ref:SI (match_operand 1 "" ""))))
9831    (use (label_ref:SI (match_dup 1)))]
9832   "!(Pmode == DImode) && next_active_insn (insn) != 0
9833    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9834    && PREV_INSN (next_active_insn (insn)) == operands[1]"
9835   "*
9836 {
9837   /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic.  */
9838   if (mips_abi == ABI_32 || mips_abi == ABI_O64
9839       || (mips_abi == ABI_N32 && TARGET_GAS))
9840     output_asm_insn (\".cpadd\\t%0\", operands);
9841   return \"%*j\\t%0\";
9842 }"
9843   [(set_attr "type"     "jump")
9844    (set_attr "mode"     "none")
9845    (set_attr "length"   "8")])
9846
9847 (define_expand "tablejump_internal4"
9848   [(parallel [(set (pc)
9849                    (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9850                             (label_ref:DI (match_operand 1 "" ""))))
9851               (use (label_ref:DI (match_dup 1)))])]
9852   ""
9853   "")
9854
9855 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
9856 ;;; it is not valid.  ??? With the USE, the condition tests may not be required
9857 ;;; any longer.
9858
9859 (define_insn ""
9860   [(set (pc)
9861         (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9862                  (label_ref:DI (match_operand 1 "" ""))))
9863    (use (label_ref:DI (match_dup 1)))]
9864   "Pmode == DImode && next_active_insn (insn) != 0
9865    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9866    && PREV_INSN (next_active_insn (insn)) == operands[1]"
9867   "*
9868 {
9869   /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic.  */
9870   if (TARGET_GAS && mips_abi == ABI_64)
9871     output_asm_insn (\".cpadd\\t%0\", operands);
9872   return \"%*j\\t%0\";
9873 }"
9874   [(set_attr "type"     "jump")
9875    (set_attr "mode"     "none")
9876    (set_attr "length"   "8")])
9877
9878 ;; Implement a switch statement when generating embedded PIC code.
9879 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
9880
9881 (define_expand "casesi"
9882   [(set (match_dup 5)
9883         (minus:SI (match_operand:SI 0 "register_operand" "d")
9884                   (match_operand:SI 1 "arith_operand" "dI")))
9885    (set (cc0)
9886         (compare:CC (match_dup 5)
9887                     (match_operand:SI 2 "arith_operand" "")))
9888    (set (pc)
9889         (if_then_else (gtu (cc0)
9890                            (const_int 0))
9891                       (label_ref (match_operand 4 "" ""))
9892                       (pc)))
9893    (parallel
9894     [(set (pc)
9895           (mem:SI (plus:SI (mult:SI (match_dup 5)
9896                                     (const_int 4))
9897                            (label_ref (match_operand 3 "" "")))))
9898      (clobber (match_scratch:SI 6 ""))
9899      (clobber (reg:SI 31))])]
9900   "TARGET_EMBEDDED_PIC"
9901   "
9902 {
9903   if (operands[0])
9904     {
9905       rtx reg = gen_reg_rtx (SImode);
9906
9907       /* If the index is too large, go to the default label.  */
9908       emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9909       emit_insn (gen_cmpsi (reg, operands[2]));
9910       emit_insn (gen_bgtu (operands[4]));
9911
9912       /* Do the PIC jump.  */
9913       if (Pmode != DImode)
9914         emit_jump_insn (gen_casesi_internal (reg, operands[3],
9915                                              gen_reg_rtx (SImode)));
9916       else
9917         emit_jump_insn (gen_casesi_internal_di (reg, operands[3],
9918                                                 gen_reg_rtx (DImode)));
9919
9920       DONE;
9921     }
9922 }")
9923
9924 ;; An embedded PIC switch statement looks like this:
9925 ;;      bal     $LS1
9926 ;;      sll     $reg,$index,2
9927 ;; $LS1:
9928 ;;      addu    $reg,$reg,$31
9929 ;;      lw      $reg,$L1-$LS1($reg)
9930 ;;      addu    $reg,$reg,$31
9931 ;;      j       $reg
9932 ;; $L1:
9933 ;;      .word   case1-$LS1
9934 ;;      .word   case2-$LS1
9935 ;;      ...
9936
9937 (define_insn "casesi_internal"
9938   [(set (pc)
9939         (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9940                                   (const_int 4))
9941                          (label_ref (match_operand 1 "" "")))))
9942    (clobber (match_operand:SI 2 "register_operand" "=d"))
9943    (clobber (reg:SI 31))]
9944   "TARGET_EMBEDDED_PIC"
9945   "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9946 lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2"
9947   [(set_attr "type"     "jump")
9948    (set_attr "mode"     "none")
9949    (set_attr "length"   "24")])
9950
9951 ;; This code assumes that the table index will never be >= 29 bits wide,
9952 ;; which allows the 'sign extend' from SI to DI be a no-op.
9953 (define_insn "casesi_internal_di"
9954   [(set (pc)
9955         (mem:DI (plus:DI (sign_extend:DI
9956                           (mult:SI (match_operand:SI 0 "register_operand" "d")
9957                                   (const_int 8)))
9958                          (label_ref (match_operand 1 "" "")))))
9959    (clobber (match_operand:DI 2 "register_operand" "=d"))
9960    (clobber (reg:DI 31))]
9961   "TARGET_EMBEDDED_PIC"
9962   "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
9963 ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
9964   [(set_attr "type"     "jump")
9965    (set_attr "mode"     "none")
9966    (set_attr "length"   "24")])
9967
9968 ;; For o32/n32/n64, we save the gp in the jmp_buf as well.  While it is
9969 ;; possible to either pull it off the stack (in the o32 case) or recalculate
9970 ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9971 ;; this is easy.
9972
9973 (define_expand "builtin_setjmp_setup"
9974   [(unspec [(match_operand 0 "register_operand" "r")] UNSPEC_SETJMP)]
9975   "TARGET_ABICALLS"
9976   "
9977 {
9978   if (Pmode == DImode)
9979     emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9980   else
9981     emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9982   DONE;
9983 }")
9984
9985 (define_expand "builtin_setjmp_setup_32"
9986   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9987                    (const_int 12)))
9988       (reg:SI 28))]
9989   "TARGET_ABICALLS && ! (Pmode == DImode)"
9990   "")
9991
9992 (define_expand "builtin_setjmp_setup_64"
9993   [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9994                    (const_int 24)))
9995       (reg:DI 28))]
9996   "TARGET_ABICALLS && Pmode == DImode"
9997   "")
9998
9999 ;; For o32/n32/n64, we need to arrange for longjmp to put the
10000 ;; target address in t9 so that we can use it for loading $gp.
10001
10002 (define_expand "builtin_longjmp"
10003   [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPEC_LONGJMP)]
10004   "TARGET_ABICALLS"
10005   "
10006 {
10007   /* The elements of the buffer are, in order:  */
10008   int W = (Pmode == DImode ? 8 : 4);
10009   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
10010   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
10011   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
10012   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
10013   rtx pv = gen_rtx_REG (Pmode, 25);
10014   rtx gp = gen_rtx_REG (Pmode, 28);
10015
10016   /* This bit is the same as expand_builtin_longjmp.  */
10017   emit_move_insn (hard_frame_pointer_rtx, fp);
10018   emit_move_insn (pv, lab);
10019   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
10020   emit_move_insn (gp, gpv);
10021   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
10022   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
10023   emit_insn (gen_rtx_USE (VOIDmode, gp));
10024   emit_indirect_jump (pv);
10025   DONE;
10026 }")
10027 \f
10028 ;;
10029 ;;  ....................
10030 ;;
10031 ;;      Function prologue/epilogue
10032 ;;
10033 ;;  ....................
10034 ;;
10035
10036 (define_expand "prologue"
10037   [(const_int 1)]
10038   ""
10039   "
10040 {
10041   if (mips_isa >= 0)            /* avoid unused code warnings */
10042     {
10043       mips_expand_prologue ();
10044       DONE;
10045     }
10046 }")
10047
10048 ;; Block any insns from being moved before this point, since the
10049 ;; profiling call to mcount can use various registers that aren't
10050 ;; saved or used to pass arguments.
10051
10052 (define_insn "blockage"
10053   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
10054   ""
10055   ""
10056   [(set_attr "type"     "unknown")
10057    (set_attr "mode"     "none")
10058    (set_attr "length"   "0")])
10059
10060 (define_expand "epilogue"
10061   [(const_int 2)]
10062   ""
10063   "
10064 {
10065   if (mips_isa >= 0)            /* avoid unused code warnings */
10066     {
10067       mips_expand_epilogue ();
10068       DONE;
10069     }
10070 }")
10071
10072 ;; Trivial return.  Make it look like a normal return insn as that
10073 ;; allows jump optimizations to work better .
10074 (define_insn "return"
10075   [(return)]
10076   "mips_can_use_return_insn ()"
10077   "%*j\\t$31"
10078   [(set_attr "type"     "jump")
10079    (set_attr "mode"     "none")])
10080
10081 ;; Normal return.
10082
10083 (define_insn "return_internal"
10084   [(use (match_operand 0 "pmode_register_operand" ""))
10085    (return)]
10086   ""
10087   "*
10088 {
10089   return \"%*j\\t%0\";
10090 }"
10091   [(set_attr "type"     "jump")
10092    (set_attr "mode"     "none")])
10093
10094 ;; When generating embedded PIC code we need to get the address of the
10095 ;; current function.  This specialized instruction does just that.
10096
10097 (define_insn "get_fnaddr"
10098   [(set (match_operand 0 "register_operand" "=d")
10099         (unspec [(match_operand 1 "" "")] UNSPEC_GET_FNADDR))
10100    (clobber (reg:SI 31))]
10101   "TARGET_EMBEDDED_PIC
10102    && GET_CODE (operands[1]) == SYMBOL_REF"
10103   "%($LF%= = . + 8\;bal\\t$LF%=\;nop;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
10104   [(set_attr "type"     "call")
10105    (set_attr "mode"     "none")
10106    (set_attr "length"   "20")])
10107
10108 ;; This is used in compiling the unwind routines.
10109 (define_expand "eh_return"
10110   [(use (match_operand 0 "general_operand" ""))
10111    (use (match_operand 1 "general_operand" ""))]
10112   ""
10113   "
10114 {
10115   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
10116
10117   if (GET_MODE (operands[1]) != gpr_mode)
10118     operands[1] = convert_to_mode (gpr_mode, operands[1], 0);
10119   if (TARGET_64BIT)
10120     emit_insn (gen_eh_set_lr_di (operands[1]));
10121   else
10122     emit_insn (gen_eh_set_lr_si (operands[1]));
10123
10124   emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]);
10125   DONE;
10126 }")
10127
10128 ;; Clobber the return address on the stack.  We can't expand this
10129 ;; until we know where it will be put in the stack frame.
10130
10131 (define_insn "eh_set_lr_si"
10132   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
10133    (clobber (match_scratch:SI 1 "=&d"))]
10134   "! TARGET_64BIT"
10135   "#")
10136
10137 (define_insn "eh_set_lr_di"
10138   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
10139    (clobber (match_scratch:DI 1 "=&d"))]
10140   "TARGET_64BIT"
10141   "#")
10142
10143 (define_split
10144   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
10145    (clobber (match_scratch 1 ""))]
10146   "reload_completed && !TARGET_DEBUG_D_MODE"
10147   [(const_int 0)]
10148   "
10149 {
10150   mips_set_return_address (operands[0], operands[1]);
10151   DONE;
10152 }")
10153
10154 (define_insn "exception_receiver"
10155   [(unspec_volatile [(const_int 0)] UNSPEC_EH_RECEIVER)]
10156   "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
10157   "* return mips_restore_gp (operands, insn);"
10158   [(set_attr "type"   "load")
10159    (set_attr "length" "8")])
10160 \f
10161 ;;
10162 ;;  ....................
10163 ;;
10164 ;;      FUNCTION CALLS
10165 ;;
10166 ;;  ....................
10167
10168 ;; calls.c now passes a third argument, make saber happy
10169
10170 (define_expand "call"
10171   [(parallel [(call (match_operand 0 "memory_operand" "m")
10172                     (match_operand 1 "" "i"))
10173               (clobber (reg:SI 31))
10174               (use (match_operand 2 "" ""))             ;; next_arg_reg
10175               (use (match_operand 3 "" ""))])]          ;; struct_value_size_rtx
10176   ""
10177   "
10178 {
10179   rtx addr;
10180
10181   if (operands[0])              /* eliminate unused code warnings */
10182     {
10183       addr = XEXP (operands[0], 0);
10184       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
10185           || ! call_insn_operand (addr, VOIDmode))
10186         XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
10187
10188       /* In order to pass small structures by value in registers
10189          compatibly with the MIPS compiler, we need to shift the value
10190          into the high part of the register.  Function_arg has encoded
10191          a PARALLEL rtx, holding a vector of adjustments to be made
10192          as the next_arg_reg variable, so we split up the insns,
10193          and emit them separately.  */
10194
10195       if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
10196         {
10197           rtvec adjust = XVEC (operands[2], 0);
10198           int num = GET_NUM_ELEM (adjust);
10199           int i;
10200
10201           for (i = 0; i < num; i++)
10202             emit_insn (RTVEC_ELT (adjust, i));
10203         }
10204
10205       if (TARGET_MIPS16
10206           && mips16_hard_float
10207           && operands[2] != 0
10208           && (int) GET_MODE (operands[2]) != 0)
10209         {
10210           if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
10211                                       (int) GET_MODE (operands[2])))
10212             DONE;
10213         }
10214
10215       emit_call_insn (gen_call_internal0 (operands[0], operands[1],
10216                                           gen_rtx_REG (SImode,
10217                                                        GP_REG_FIRST + 31)));
10218       DONE;
10219     }
10220 }")
10221
10222 (define_expand "call_internal0"
10223   [(parallel [(call (match_operand 0 "" "")
10224                     (match_operand 1 "" ""))
10225               (clobber (match_operand:SI 2 "" ""))])]
10226   ""
10227   "")
10228
10229 ;; We need to recognize reg:SI 31 specially for the mips16, because we
10230 ;; don't have a constraint letter for it.
10231
10232 (define_insn ""
10233   [(call (mem (match_operand 0 "call_insn_operand" "ei"))
10234          (match_operand 1 "" "i"))
10235    (clobber (match_operand:SI 2 "register_operand" "=y"))]
10236   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
10237    && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
10238   "%*jal\\t%0"
10239   [(set_attr "type"     "call")
10240    (set_attr "mode"     "none")
10241    (set_attr "length"   "8")])
10242
10243 (define_insn "call_internal1"
10244   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
10245          (match_operand 1 "" "i"))
10246    (clobber (match_operand:SI 2 "register_operand" "=d"))]
10247   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10248   "*
10249 {
10250   register rtx target = operands[0];
10251
10252   if (GET_CODE (target) == CONST_INT)
10253     return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
10254   else if (CONSTANT_ADDRESS_P (target))
10255     return \"%*jal\\t%0\";
10256   else
10257     return \"%*jal\\t%2,%0\";
10258 }"
10259   [(set_attr "type"     "call")
10260    (set_attr "mode"     "none")])
10261
10262 (define_insn "call_internal2"
10263   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
10264          (match_operand 1 "" "i"))
10265    (clobber (match_operand:SI 2 "register_operand" "=d"))]
10266   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10267   "*
10268 {
10269   register rtx target = operands[0];
10270
10271   if (GET_CODE (target) == CONST_INT)
10272     return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
10273   else if (CONSTANT_ADDRESS_P (target))
10274     {
10275       if (GET_MODE (target) == SImode)
10276         return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
10277       else
10278         return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
10279     }
10280   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10281     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
10282   else
10283     return \"jal\\t%2,%0\";
10284 }"
10285   [(set_attr "type"     "call")
10286    (set_attr "mode"     "none")
10287    (set_attr "length"   "8")])
10288
10289 (define_insn "call_internal3a"
10290   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
10291          (match_operand 1 "" "i"))
10292    (clobber (match_operand:SI 2 "register_operand" "=d"))]
10293   "!TARGET_MIPS16
10294    && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10295   "%*jal\\t%2,%0"
10296   [(set_attr "type"     "call")
10297    (set_attr "mode"     "none")])
10298
10299 (define_insn "call_internal3b"
10300   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
10301          (match_operand 1 "" "i"))
10302    (clobber (match_operand:SI 2 "register_operand" "=d"))]
10303   "!TARGET_MIPS16
10304    && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10305   "%*jal\\t%2,%0"
10306   [(set_attr "type"     "call")
10307    (set_attr "mode"     "none")
10308    (set_attr "length"   "1")])
10309
10310 (define_insn "call_internal3c"
10311   [(call (mem:SI (match_operand:SI 0 "register_operand" "e"))
10312          (match_operand 1 "" "i"))
10313    (clobber (match_operand:SI 2 "register_operand" "=y"))]
10314   "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
10315    && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
10316   "%*jal\\t%2,%0"
10317   [(set_attr "type"     "call")
10318    (set_attr "mode"     "none")])
10319
10320 (define_insn "call_internal4a"
10321   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
10322          (match_operand 1 "" "i"))
10323    (clobber (match_operand:SI 2 "register_operand" "=d"))]
10324   "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
10325   "*
10326 {
10327   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
10328     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
10329   else
10330     return \"jal\\t%2,%0\";
10331 }"
10332   [(set_attr "type"     "call")
10333    (set_attr "mode"     "none")
10334    (set_attr "length"   "8")])
10335
10336 (define_insn "call_internal4b"
10337   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
10338          (match_operand 1 "" "i"))
10339    (clobber (match_operand:SI 2 "register_operand" "=d"))]
10340   "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
10341   "*
10342 {
10343   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
10344     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
10345   else
10346     return \"jal\\t%2,%0\";
10347 }"
10348   [(set_attr "type"     "call")
10349    (set_attr "mode"     "none")
10350    (set_attr "length"   "8")])
10351
10352 ;; calls.c now passes a fourth argument, make saber happy
10353
10354 (define_expand "call_value"
10355   [(parallel [(set (match_operand 0 "register_operand" "=df")
10356                    (call (match_operand 1 "memory_operand" "m")
10357                          (match_operand 2 "" "i")))
10358               (clobber (reg:SI 31))
10359               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
10360   ""
10361   "
10362 {
10363   rtx addr;
10364
10365   if (operands[0])              /* eliminate unused code warning */
10366     {
10367       addr = XEXP (operands[1], 0);
10368       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
10369           || ! call_insn_operand (addr, VOIDmode))
10370         XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
10371
10372       /* In order to pass small structures by value in registers
10373          compatibly with the MIPS compiler, we need to shift the value
10374          into the high part of the register.  Function_arg has encoded
10375          a PARALLEL rtx, holding a vector of adjustments to be made
10376          as the next_arg_reg variable, so we split up the insns,
10377          and emit them separately.  */
10378
10379       if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
10380         {
10381           rtvec adjust = XVEC (operands[3], 0);
10382           int num = GET_NUM_ELEM (adjust);
10383           int i;
10384
10385           for (i = 0; i < num; i++)
10386             emit_insn (RTVEC_ELT (adjust, i));
10387         }
10388
10389       if (TARGET_MIPS16
10390           && mips16_hard_float
10391           && ((operands[3] != 0
10392                && (int) GET_MODE (operands[3]) != 0)
10393               || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
10394         {
10395           if (build_mips16_call_stub (operands[0], operands[1], operands[2],
10396                                       (operands[3] == 0 ? 0
10397                                        : (int) GET_MODE (operands[3]))))
10398             DONE;
10399         }
10400
10401       /* Handle Irix6 function calls that have multiple non-contiguous
10402          results.  */
10403       if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
10404         {
10405           emit_call_insn (gen_call_value_multiple_internal0
10406                           (XEXP (XVECEXP (operands[0], 0, 0), 0),
10407                            operands[1], operands[2],
10408                            XEXP (XVECEXP (operands[0], 0, 1), 0),
10409                            gen_rtx_REG (SImode, GP_REG_FIRST + 31)));
10410           DONE;
10411         }
10412
10413       /* We have a call returning a DImode structure in an FP reg.
10414          Strip off the now unnecessary PARALLEL.  */
10415       if (GET_CODE (operands[0]) == PARALLEL)
10416         operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
10417
10418       emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
10419                                                 gen_rtx_REG (SImode,
10420                                                              GP_REG_FIRST + 31)));
10421
10422       DONE;
10423     }
10424 }")
10425
10426 (define_expand "call_value_internal0"
10427   [(parallel [(set (match_operand 0 "" "")
10428                    (call (match_operand 1 "" "")
10429                          (match_operand 2 "" "")))
10430               (clobber (match_operand:SI 3 "" ""))])]
10431   ""
10432   "")
10433
10434 ;; Recognize $31 specially on the mips16, because we don't have a
10435 ;; constraint letter for it.
10436
10437 (define_insn ""
10438   [(set (match_operand 0 "register_operand" "=d")
10439         (call (mem (match_operand 1 "call_insn_operand" "ei"))
10440               (match_operand 2 "" "i")))
10441    (clobber (match_operand:SI 3 "register_operand" "=y"))]
10442   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
10443    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10444   "%*jal\\t%1"
10445   [(set_attr "type"     "call")
10446    (set_attr "mode"     "none")
10447    (set_attr "length"   "8")])
10448
10449 (define_insn "call_value_internal1"
10450   [(set (match_operand 0 "register_operand" "=df")
10451         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10452               (match_operand 2 "" "i")))
10453    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10454   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10455   "*
10456 {
10457   register rtx target = operands[1];
10458
10459   if (GET_CODE (target) == CONST_INT)
10460     return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
10461   else if (CONSTANT_ADDRESS_P (target))
10462     return \"%*jal\\t%1\";
10463   else
10464     return \"%*jal\\t%3,%1\";
10465 }"
10466   [(set_attr "type"     "call")
10467    (set_attr "mode"     "none")])
10468
10469 (define_insn "call_value_internal2"
10470   [(set (match_operand 0 "register_operand" "=df")
10471         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10472               (match_operand 2 "" "i")))
10473    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10474   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10475   "*
10476 {
10477   register rtx target = operands[1];
10478
10479   if (GET_CODE (target) == CONST_INT)
10480     return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
10481   else if (CONSTANT_ADDRESS_P (target))
10482     {
10483       if (GET_MODE (target) == SImode)
10484         return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
10485       else
10486         return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
10487     }
10488   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10489     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10490   else
10491     return \"jal\\t%3,%1\";
10492 }"
10493   [(set_attr "type"     "call")
10494    (set_attr "mode"     "none")
10495    (set_attr "length"   "8")])
10496
10497 (define_insn "call_value_internal3a"
10498   [(set (match_operand 0 "register_operand" "=df")
10499         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10500               (match_operand 2 "" "i")))
10501    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10502   "!TARGET_MIPS16
10503    && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10504   "%*jal\\t%3,%1"
10505   [(set_attr "type"     "call")
10506    (set_attr "mode"     "none")])
10507
10508 (define_insn "call_value_internal3b"
10509   [(set (match_operand 0 "register_operand" "=df")
10510         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10511               (match_operand 2 "" "i")))
10512    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10513   "!TARGET_MIPS16
10514    && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10515   "%*jal\\t%3,%1"
10516   [(set_attr "type"     "call")
10517    (set_attr "mode"     "none")])
10518
10519 (define_insn "call_value_internal3c"
10520   [(set (match_operand 0 "register_operand" "=df")
10521         (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
10522               (match_operand 2 "" "i")))
10523    (clobber (match_operand:SI 3 "register_operand" "=y"))]
10524   "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
10525    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10526   "%*jal\\t%3,%1"
10527   [(set_attr "type"     "call")
10528    (set_attr "mode"     "none")])
10529
10530 (define_insn "call_value_internal4a"
10531   [(set (match_operand 0 "register_operand" "=df")
10532         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10533               (match_operand 2 "" "i")))
10534    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10535   "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
10536   "*
10537 {
10538   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10539     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10540   else
10541     return \"jal\\t%3,%1\";
10542 }"
10543   [(set_attr "type"     "call")
10544    (set_attr "mode"     "none")
10545    (set_attr "length"   "8")])
10546
10547 (define_insn "call_value_internal4b"
10548   [(set (match_operand 0 "register_operand" "=df")
10549         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10550               (match_operand 2 "" "i")))
10551    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10552   "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
10553   "*
10554 {
10555   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10556     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10557   else
10558     return \"jal\\t%3,%1\";
10559 }"
10560   [(set_attr "type"     "call")
10561    (set_attr "mode"     "none")
10562    (set_attr "length"   "8")])
10563
10564 (define_expand "call_value_multiple_internal0"
10565   [(parallel [(set (match_operand 0 "" "")
10566                    (call (match_operand 1 "" "")
10567                          (match_operand 2 "" "")))
10568               (set (match_operand 3 "" "")
10569                    (call (match_dup 1)
10570                          (match_dup 2)))
10571               (clobber (match_operand:SI 4 "" ""))])]
10572   ""
10573   "")
10574
10575 ;; ??? May eventually need all 6 versions of the call patterns with multiple
10576 ;; return values.
10577
10578 (define_insn "call_value_multiple_internal1"
10579   [(set (match_operand 0 "register_operand" "=df")
10580         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10581               (match_operand 2 "" "i")))
10582    (set (match_operand 3 "register_operand" "=df")
10583         (call (mem (match_dup 1))
10584               (match_dup 2)))
10585   (clobber (match_operand:SI 4 "register_operand" "=d"))]
10586   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10587   "*
10588 {
10589   register rtx target = operands[1];
10590
10591   if (GET_CODE (target) == CONST_INT)
10592     return \"%[li\\t%@,%1\\n\\t%*jal\\t%4,%@%]\";
10593   else if (CONSTANT_ADDRESS_P (target))
10594     return \"%*jal\\t%1\";
10595   else
10596     return \"%*jal\\t%4,%1\";
10597 }"
10598   [(set_attr "type"     "call")
10599    (set_attr "mode"     "none")])
10600
10601 (define_insn "call_value_multiple_internal2"
10602   [(set (match_operand 0 "register_operand" "=df")
10603         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10604               (match_operand 2 "" "i")))
10605    (set (match_operand 3 "register_operand" "=df")
10606         (call (mem (match_dup 1))
10607               (match_dup 2)))
10608    (clobber (match_operand:SI 4 "register_operand" "=d"))]
10609   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10610   "*
10611 {
10612   register rtx target = operands[1];
10613
10614   if (GET_CODE (target) == CONST_INT)
10615     return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
10616   else if (CONSTANT_ADDRESS_P (target))
10617     {
10618       if (GET_MODE (target) == SImode)
10619         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10620       else
10621         return \"dla\\t%^,%1\\n\\tjal\\t%4,%^\";
10622     }
10623   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10624     return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
10625   else
10626     return \"jal\\t%4,%1\";
10627 }"
10628   [(set_attr "type"     "call")
10629    (set_attr "mode"     "none")
10630    (set_attr "length"   "8")])
10631
10632
10633 ;; Call subroutine returning any type.
10634
10635 (define_expand "untyped_call"
10636   [(parallel [(call (match_operand 0 "" "")
10637                     (const_int 0))
10638               (match_operand 1 "" "")
10639               (match_operand 2 "" "")])]
10640   ""
10641   "
10642 {
10643   if (operands[0])              /* silence statement not reached warnings */
10644     {
10645       int i;
10646
10647       emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
10648
10649       for (i = 0; i < XVECLEN (operands[2], 0); i++)
10650         {
10651           rtx set = XVECEXP (operands[2], 0, i);
10652           emit_move_insn (SET_DEST (set), SET_SRC (set));
10653         }
10654
10655       emit_insn (gen_blockage ());
10656       DONE;
10657     }
10658 }")
10659 \f
10660 ;;
10661 ;;  ....................
10662 ;;
10663 ;;      MISC.
10664 ;;
10665 ;;  ....................
10666 ;;
10667
10668
10669 (define_expand "prefetch"
10670   [(prefetch (match_operand 0 "address_operand" "")
10671              (match_operand 1 "const_int_operand" "")
10672              (match_operand 2 "const_int_operand" ""))]
10673   "ISA_HAS_PREFETCH"
10674 "{
10675      if (symbolic_operand (operands[0], GET_MODE (operands[0])))
10676         operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
10677 }")
10678
10679 (define_insn "prefetch_si_address"
10680   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
10681                       (match_operand:SI 3 "const_int_operand" "i"))
10682              (match_operand:SI 1 "const_int_operand" "n")
10683              (match_operand:SI 2 "const_int_operand" "n"))]
10684   "ISA_HAS_PREFETCH && Pmode == SImode"
10685   "* return mips_emit_prefetch (operands);"
10686   [(set_attr "type" "load")])
10687
10688 (define_insn "prefetch_si"
10689   [(prefetch (match_operand:SI 0 "register_operand" "r")
10690              (match_operand:SI 1 "const_int_operand" "n")
10691              (match_operand:SI 2 "const_int_operand" "n"))]
10692   "ISA_HAS_PREFETCH && Pmode == SImode"
10693   "* return mips_emit_prefetch (operands);"
10694   [(set_attr "type" "load")])
10695
10696 (define_insn "prefetch_di_address"
10697   [(prefetch (plus:DI (match_operand:DI 0 "se_register_operand" "r")
10698                       (match_operand:DI 3 "const_int_operand" "i"))
10699              (match_operand:DI 1 "const_int_operand" "n")
10700              (match_operand:DI 2 "const_int_operand" "n"))]
10701   "ISA_HAS_PREFETCH && Pmode == DImode"
10702   "* return mips_emit_prefetch (operands);"
10703   [(set_attr "type" "load")])
10704
10705 (define_insn "prefetch_di"
10706   [(prefetch (match_operand:DI 0 "se_register_operand" "r")
10707              (match_operand:DI 1 "const_int_operand" "n")
10708              (match_operand:DI 2 "const_int_operand" "n"))]
10709   "ISA_HAS_PREFETCH && Pmode == DImode"
10710   "* return mips_emit_prefetch (operands);"
10711   [(set_attr "type" "load")])
10712
10713 (define_insn "nop"
10714   [(const_int 0)]
10715   ""
10716   "%(nop%)"
10717   [(set_attr "type"     "nop")
10718    (set_attr "mode"     "none")])
10719
10720 ;; The MIPS chip does not seem to require stack probes.
10721 ;;
10722 ;; (define_expand "probe"
10723 ;;   [(set (match_dup 0)
10724 ;;      (match_dup 1))]
10725 ;;   ""
10726 ;;   "
10727 ;; {
10728 ;;   operands[0] = gen_reg_rtx (SImode);
10729 ;;   operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
10730 ;;   MEM_VOLATILE_P (operands[1]) = TRUE;
10731 ;;
10732 ;;   /* fall through and generate default code */
10733 ;; }")
10734 ;;
10735 \f
10736 ;;
10737 ;; MIPS4 Conditional move instructions.
10738
10739 (define_insn ""
10740   [(set (match_operand:SI 0 "register_operand" "=d,d")
10741         (if_then_else:SI
10742          (match_operator 4 "equality_op"
10743                          [(match_operand:SI 1 "register_operand" "d,d")
10744                           (const_int 0)])
10745          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10746          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10747   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10748   "@
10749     mov%B4\\t%0,%z2,%1
10750     mov%b4\\t%0,%z3,%1"
10751   [(set_attr "type" "move")
10752    (set_attr "mode" "SI")])
10753
10754 (define_insn ""
10755   [(set (match_operand:SI 0 "register_operand" "=d,d")
10756         (if_then_else:SI
10757          (match_operator 4 "equality_op"
10758                          [(match_operand:DI 1 "se_register_operand" "d,d")
10759                           (const_int 0)])
10760          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10761          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10762   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10763   "@
10764     mov%B4\\t%0,%z2,%1
10765     mov%b4\\t%0,%z3,%1"
10766   [(set_attr "type" "move")
10767    (set_attr "mode" "SI")])
10768
10769 (define_insn ""
10770   [(set (match_operand:SI 0 "register_operand" "=d,d")
10771         (if_then_else:SI
10772          (match_operator 3 "equality_op" [(match_operand:CC 4
10773                                                             "register_operand"
10774                                                             "z,z")
10775                                           (const_int 0)])
10776          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
10777          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
10778   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10779   "@
10780     mov%T3\\t%0,%z1,%4
10781     mov%t3\\t%0,%z2,%4"
10782   [(set_attr "type" "move")
10783    (set_attr "mode" "SI")])
10784
10785 (define_insn ""
10786   [(set (match_operand:DI 0 "register_operand" "=d,d")
10787         (if_then_else:DI
10788          (match_operator 4 "equality_op"
10789                          [(match_operand:SI 1 "register_operand" "d,d")
10790                           (const_int 0)])
10791          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10792          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10793   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10794   "@
10795     mov%B4\\t%0,%z2,%1
10796     mov%b4\\t%0,%z3,%1"
10797   [(set_attr "type" "move")
10798    (set_attr "mode" "DI")])
10799
10800 (define_insn ""
10801   [(set (match_operand:DI 0 "register_operand" "=d,d")
10802         (if_then_else:DI
10803          (match_operator 4 "equality_op"
10804                          [(match_operand:DI 1 "se_register_operand" "d,d")
10805                           (const_int 0)])
10806          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10807          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10808   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10809   "@
10810     mov%B4\\t%0,%z2,%1
10811     mov%b4\\t%0,%z3,%1"
10812   [(set_attr "type" "move")
10813    (set_attr "mode" "DI")])
10814
10815 (define_insn ""
10816   [(set (match_operand:DI 0 "register_operand" "=d,d")
10817         (if_then_else:DI
10818          (match_operator 3 "equality_op" [(match_operand:CC 4
10819                                                             "register_operand"
10820                                                             "z,z")
10821                                           (const_int 0)])
10822          (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
10823          (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
10824   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
10825   "@
10826     mov%T3\\t%0,%z1,%4
10827     mov%t3\\t%0,%z2,%4"
10828   [(set_attr "type" "move")
10829    (set_attr "mode" "DI")])
10830
10831 (define_insn ""
10832   [(set (match_operand:SF 0 "register_operand" "=f,f")
10833         (if_then_else:SF
10834          (match_operator 4 "equality_op"
10835                          [(match_operand:SI 1 "register_operand" "d,d")
10836                           (const_int 0)])
10837          (match_operand:SF 2 "register_operand" "f,0")
10838          (match_operand:SF 3 "register_operand" "0,f")))]
10839   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10840   "@
10841     mov%B4.s\\t%0,%2,%1
10842     mov%b4.s\\t%0,%3,%1"
10843   [(set_attr "type" "move")
10844    (set_attr "mode" "SF")])
10845
10846 (define_insn ""
10847   [(set (match_operand:SF 0 "register_operand" "=f,f")
10848         (if_then_else:SF
10849          (match_operator 4 "equality_op"
10850                          [(match_operand:DI 1 "se_register_operand" "d,d")
10851                           (const_int 0)])
10852          (match_operand:SF 2 "register_operand" "f,0")
10853          (match_operand:SF 3 "register_operand" "0,f")))]
10854   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10855   "@
10856     mov%B4.s\\t%0,%2,%1
10857     mov%b4.s\\t%0,%3,%1"
10858   [(set_attr "type" "move")
10859    (set_attr "mode" "SF")])
10860
10861 (define_insn ""
10862   [(set (match_operand:SF 0 "register_operand" "=f,f")
10863         (if_then_else:SF
10864          (match_operator 3 "equality_op" [(match_operand:CC 4
10865                                                             "register_operand"
10866                                                             "z,z")
10867                                           (const_int 0)])
10868          (match_operand:SF 1 "register_operand" "f,0")
10869          (match_operand:SF 2 "register_operand" "0,f")))]
10870   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10871   "@
10872     mov%T3.s\\t%0,%1,%4
10873     mov%t3.s\\t%0,%2,%4"
10874   [(set_attr "type" "move")
10875    (set_attr "mode" "SF")])
10876
10877 (define_insn ""
10878   [(set (match_operand:DF 0 "register_operand" "=f,f")
10879         (if_then_else:DF
10880          (match_operator 4 "equality_op"
10881                          [(match_operand:SI 1 "register_operand" "d,d")
10882                           (const_int 0)])
10883          (match_operand:DF 2 "register_operand" "f,0")
10884          (match_operand:DF 3 "register_operand" "0,f")))]
10885   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10886   "@
10887     mov%B4.d\\t%0,%2,%1
10888     mov%b4.d\\t%0,%3,%1"
10889   [(set_attr "type" "move")
10890    (set_attr "mode" "DF")])
10891
10892 (define_insn ""
10893   [(set (match_operand:DF 0 "register_operand" "=f,f")
10894         (if_then_else:DF
10895          (match_operator 4 "equality_op"
10896                          [(match_operand:DI 1 "se_register_operand" "d,d")
10897                           (const_int 0)])
10898          (match_operand:DF 2 "register_operand" "f,0")
10899          (match_operand:DF 3 "register_operand" "0,f")))]
10900   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10901   "@
10902     mov%B4.d\\t%0,%2,%1
10903     mov%b4.d\\t%0,%3,%1"
10904   [(set_attr "type" "move")
10905    (set_attr "mode" "DF")])
10906
10907 (define_insn ""
10908   [(set (match_operand:DF 0 "register_operand" "=f,f")
10909         (if_then_else:DF
10910          (match_operator 3 "equality_op" [(match_operand:CC 4
10911                                                             "register_operand"
10912                                                             "z,z")
10913                                           (const_int 0)])
10914          (match_operand:DF 1 "register_operand" "f,0")
10915          (match_operand:DF 2 "register_operand" "0,f")))]
10916   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10917   "@
10918     mov%T3.d\\t%0,%1,%4
10919     mov%t3.d\\t%0,%2,%4"
10920   [(set_attr "type" "move")
10921    (set_attr "mode" "DF")])
10922
10923 ;; These are the main define_expand's used to make conditional moves.
10924
10925 (define_expand "movsicc"
10926   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10927    (set (match_operand:SI 0 "register_operand" "")
10928         (if_then_else:SI (match_dup 5)
10929                          (match_operand:SI 2 "reg_or_0_operand" "")
10930                          (match_operand:SI 3 "reg_or_0_operand" "")))]
10931   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10932   "
10933 {
10934   gen_conditional_move (operands);
10935   DONE;
10936 }")
10937
10938 (define_expand "movdicc"
10939   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10940    (set (match_operand:DI 0 "register_operand" "")
10941         (if_then_else:DI (match_dup 5)
10942                          (match_operand:DI 2 "se_reg_or_0_operand" "")
10943                          (match_operand:DI 3 "se_reg_or_0_operand" "")))]
10944   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10945   "
10946 {
10947   gen_conditional_move (operands);
10948   DONE;
10949 }")
10950
10951 (define_expand "movsfcc"
10952   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10953    (set (match_operand:SF 0 "register_operand" "")
10954         (if_then_else:SF (match_dup 5)
10955                          (match_operand:SF 2 "register_operand" "")
10956                          (match_operand:SF 3 "register_operand" "")))]
10957   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10958   "
10959 {
10960   gen_conditional_move (operands);
10961   DONE;
10962 }")
10963
10964 (define_expand "movdfcc"
10965   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10966    (set (match_operand:DF 0 "register_operand" "")
10967         (if_then_else:DF (match_dup 5)
10968                          (match_operand:DF 2 "register_operand" "")
10969                          (match_operand:DF 3 "register_operand" "")))]
10970   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10971   "
10972 {
10973   gen_conditional_move (operands);
10974   DONE;
10975 }")
10976 \f
10977 ;;
10978 ;;  ....................
10979 ;;
10980 ;;      mips16 inline constant tables
10981 ;;
10982 ;;  ....................
10983 ;;
10984
10985 (define_insn "consttable_qi"
10986   [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")]
10987                     UNSPEC_CONSTTABLE_QI)]
10988   "TARGET_MIPS16"
10989   "*
10990 {
10991   assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
10992   return \"\";
10993 }"
10994   [(set_attr "type"     "unknown")
10995    (set_attr "mode"     "QI")
10996    (set_attr "length"   "8")])
10997
10998 (define_insn "consttable_hi"
10999   [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")]
11000                     UNSPEC_CONSTTABLE_HI)]
11001   "TARGET_MIPS16"
11002   "*
11003 {
11004   assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
11005   return \"\";
11006 }"
11007   [(set_attr "type"     "unknown")
11008    (set_attr "mode"     "HI")
11009    (set_attr "length"   "8")])
11010
11011 (define_insn "consttable_si"
11012   [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")]
11013                     UNSPEC_CONSTTABLE_SI)]
11014   "TARGET_MIPS16"
11015   "*
11016 {
11017   assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
11018   return \"\";
11019 }"
11020   [(set_attr "type"     "unknown")
11021    (set_attr "mode"     "SI")
11022    (set_attr "length"   "8")])
11023
11024 (define_insn "consttable_di"
11025   [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")]
11026                     UNSPEC_CONSTTABLE_DI)]
11027   "TARGET_MIPS16"
11028   "*
11029 {
11030   assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
11031   return \"\";
11032 }"
11033   [(set_attr "type"     "unknown")
11034    (set_attr "mode"     "DI")
11035    (set_attr "length"   "16")])
11036
11037 (define_insn "consttable_sf"
11038   [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")]
11039                     UNSPEC_CONSTTABLE_SF)]
11040   "TARGET_MIPS16"
11041   "*
11042 {
11043   REAL_VALUE_TYPE d;
11044
11045   if (GET_CODE (operands[0]) != CONST_DOUBLE)
11046     abort ();
11047   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11048   assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
11049   return \"\";
11050 }"
11051   [(set_attr "type"     "unknown")
11052    (set_attr "mode"     "SF")
11053    (set_attr "length"   "8")])
11054
11055 (define_insn "consttable_df"
11056   [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")]
11057                     UNSPEC_CONSTTABLE_DF)]
11058   "TARGET_MIPS16"
11059   "*
11060 {
11061   REAL_VALUE_TYPE d;
11062
11063   if (GET_CODE (operands[0]) != CONST_DOUBLE)
11064     abort ();
11065   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11066   assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
11067   return \"\";
11068 }"
11069   [(set_attr "type"     "unknown")
11070    (set_attr "mode"     "DF")
11071    (set_attr "length"   "16")])
11072
11073 (define_insn "align_2"
11074   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_2)]
11075   "TARGET_MIPS16"
11076   ".align 1"
11077   [(set_attr "type"     "unknown")
11078    (set_attr "mode"     "HI")
11079    (set_attr "length"   "8")])
11080
11081 (define_insn "align_4"
11082   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_4)]
11083   "TARGET_MIPS16"
11084   ".align 2"
11085   [(set_attr "type"     "unknown")
11086    (set_attr "mode"     "SI")
11087    (set_attr "length"   "8")])
11088
11089 (define_insn "align_8"
11090   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_8)]
11091   "TARGET_MIPS16"
11092   ".align 3"
11093   [(set_attr "type"     "unknown")
11094    (set_attr "mode"     "DI")
11095    (set_attr "length"   "12")])
11096 \f
11097 ;;
11098 ;;  ....................
11099 ;;
11100 ;;      mips16 peepholes
11101 ;;
11102 ;;  ....................
11103 ;;
11104
11105 ;; On the mips16, reload will sometimes decide that a pseudo register
11106 ;; should go into $24, and then later on have to reload that register.
11107 ;; When that happens, we get a load of a general register followed by
11108 ;; a move from the general register to $24 followed by a branch.
11109 ;; These peepholes catch the common case, and fix it to just use the
11110 ;; general register for the branch.
11111
11112 (define_peephole
11113   [(set (match_operand:SI 0 "register_operand" "=t")
11114         (match_operand:SI 1 "register_operand" "d"))
11115    (set (pc)
11116         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
11117                                                           (const_int 0)])
11118                       (match_operand 3 "pc_or_label_operand" "")
11119                       (match_operand 4 "pc_or_label_operand" "")))]
11120   "TARGET_MIPS16
11121    && GET_CODE (operands[0]) == REG
11122    && REGNO (operands[0]) == 24
11123    && dead_or_set_p (insn, operands[0])
11124    && GET_CODE (operands[1]) == REG
11125    && M16_REG_P (REGNO (operands[1]))"
11126   "*
11127 {
11128   if (operands[3] != pc_rtx)
11129     return \"%*b%C2z\\t%1,%3\";
11130   else
11131     return \"%*b%N2z\\t%1,%4\";
11132 }"
11133   [(set_attr "type"     "branch")
11134    (set_attr "mode"     "none")
11135    (set_attr "length"   "8")])
11136
11137 (define_peephole
11138   [(set (match_operand:DI 0 "register_operand" "=t")
11139         (match_operand:DI 1 "register_operand" "d"))
11140    (set (pc)
11141         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
11142                                                           (const_int 0)])
11143                       (match_operand 3 "pc_or_label_operand" "")
11144                       (match_operand 4 "pc_or_label_operand" "")))]
11145   "TARGET_MIPS16 && TARGET_64BIT
11146    && GET_CODE (operands[0]) == REG
11147    && REGNO (operands[0]) == 24
11148    && dead_or_set_p (insn, operands[0])
11149    && GET_CODE (operands[1]) == REG
11150    && M16_REG_P (REGNO (operands[1]))"
11151   "*
11152 {
11153   if (operands[3] != pc_rtx)
11154     return \"%*b%C2z\\t%1,%3\";
11155   else
11156     return \"%*b%N2z\\t%1,%4\";
11157 }"
11158   [(set_attr "type"     "branch")
11159    (set_attr "mode"     "none")
11160    (set_attr "length"   "8")])
11161
11162 ;; We can also have the reverse reload: reload will spill $24 into
11163 ;; another register, and then do a branch on that register when it
11164 ;; could have just stuck with $24.
11165
11166 (define_peephole
11167   [(set (match_operand:SI 0 "register_operand" "=d")
11168         (match_operand:SI 1 "register_operand" "t"))
11169    (set (pc)
11170         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
11171                                                           (const_int 0)])
11172                       (match_operand 3 "pc_or_label_operand" "")
11173                       (match_operand 4 "pc_or_label_operand" "")))]
11174   "TARGET_MIPS16
11175    && GET_CODE (operands[1]) == REG
11176    && REGNO (operands[1]) == 24
11177    && GET_CODE (operands[0]) == REG
11178    && M16_REG_P (REGNO (operands[0]))
11179    && dead_or_set_p (insn, operands[0])"
11180   "*
11181 {
11182   if (operands[3] != pc_rtx)
11183     return \"%*bt%C2z\\t%3\";
11184   else
11185     return \"%*bt%N2z\\t%4\";
11186 }"
11187   [(set_attr "type"     "branch")
11188    (set_attr "mode"     "none")
11189    (set_attr "length"   "8")])
11190
11191 (define_peephole
11192   [(set (match_operand:DI 0 "register_operand" "=d")
11193         (match_operand:DI 1 "register_operand" "t"))
11194    (set (pc)
11195         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
11196                                                           (const_int 0)])
11197                       (match_operand 3 "pc_or_label_operand" "")
11198                       (match_operand 4 "pc_or_label_operand" "")))]
11199   "TARGET_MIPS16 && TARGET_64BIT
11200    && GET_CODE (operands[1]) == REG
11201    && REGNO (operands[1]) == 24
11202    && GET_CODE (operands[0]) == REG
11203    && M16_REG_P (REGNO (operands[0]))
11204    && dead_or_set_p (insn, operands[0])"
11205   "*
11206 {
11207   if (operands[3] != pc_rtx)
11208     return \"%*bt%C2z\\t%3\";
11209   else
11210     return \"%*bt%N2z\\t%4\";
11211 }"
11212   [(set_attr "type"     "branch")
11213    (set_attr "mode"     "none")
11214    (set_attr "length"   "8")])
11215
11216 ;; For the rare case where we need to load an address into a register
11217 ;; that can not be recognized by the normal movsi/addsi instructions.
11218 ;; I have no idea how many insns this can actually generate.  It should
11219 ;; be rare, so over-estimating as 10 instructions should not have any
11220 ;; real performance impact.
11221 (define_insn "leasi"
11222   [(set (match_operand:SI 0 "register_operand" "=d")
11223         (match_operand:SI 1 "address_operand" "p"))]
11224   "Pmode == SImode"
11225   "la %0,%a1"
11226   [(set_attr "type"     "arith")
11227    (set_attr "mode"     "SI")
11228    (set_attr "length"   "40")])
11229
11230 ;; Similarly for targets where we have 64bit pointers.
11231 (define_insn "leadi"
11232   [(set (match_operand:DI 0 "register_operand" "=d")
11233         (match_operand:DI 1 "address_operand" "p"))]
11234   "Pmode == DImode"
11235   "dla %0,%a1"
11236   [(set_attr "type"     "arith")
11237    (set_attr "mode"     "DI")
11238    (set_attr "length"   "40")])