OSDN Git Service

2002-06-05 Eric Christopher <echristo@redhat.com>
[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 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 ;; idiv         integer divide
72 ;; icmp         integer compare
73 ;; fadd         floating point add/subtract
74 ;; fmul         floating point multiply
75 ;; fmadd        floating point multiply-add
76 ;; fdiv         floating point divide
77 ;; fabs         floating point absolute value
78 ;; fneg         floating point negation
79 ;; fcmp         floating point compare
80 ;; fcvt         floating point convert
81 ;; fsqrt        floating point square root
82 ;; multi        multiword sequence (or user asm statements)
83 ;; nop          no operation
84
85 (define_attr "type"
86   "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop"
87   (const_string "unknown"))
88
89 ;; Main data type used by the insn
90 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
91
92 ;; Length (in # of bytes).  A conditional branch is allowed only to a
93 ;; location within a signed 18-bit offset of the delay slot.  If that
94 ;; provides too smal a range, we use the `j' instruction.  This
95 ;; instruction takes a 28-bit value, but that value is not an offset.
96 ;; Instead, it's bitwise-ored with the high-order four bits of the
97 ;; instruction in the delay slot, which means it cannot be used to
98 ;; cross a 256MB boundary.  We could fall back back on the jr,
99 ;; instruction which allows full access to the entire address space,
100 ;; but we do not do so at present.
101
102 (define_attr "length" ""
103    (cond [(eq_attr "type" "branch")
104           (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
105                      (const_int 131072))
106                  (const_int 4)]
107                  (const_int 12))]
108           (const_int 4)))
109
110 ;; Attribute describing the processor.  This attribute must match exactly
111 ;; with the processor_type enumeration in mips.h.
112
113 ;; Attribute describing the processor
114 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
115 ;;   (const
116 ;;    (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000"))   (const_string "r3000")
117 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000"))   (const_string "r4000")
118 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000"))   (const_string "r6000")]
119 ;;          (const_string "default"))))
120
121 ;; ??? Fix everything that tests this attribute.
122 (define_attr "cpu"
123   "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000,r4kc,r5kc,r20kc"
124   (const (symbol_ref "mips_cpu_attr")))
125
126 ;; Does the instruction have a mandatory delay slot?
127 ;;   The 3900, is (mostly) mips1, but does not have a mandatory load delay
128 ;;   slot.
129 (define_attr "dslot" "no,yes"
130   (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp")
131                      (and (eq_attr "type" "load")
132                           (and (eq (symbol_ref "mips_isa") (const_int 1))
133                                (and (eq (symbol_ref "mips16") (const_int 0))
134                                     (eq_attr "cpu" "!r3900")))))
135                 (const_string "yes")
136                 (const_string "no")))
137
138 ;; Can the instruction be put into a delay slot?
139 (define_attr "can_delay" "no,yes"
140   (if_then_else (and (eq_attr "dslot" "no")
141                      ; ADJUST_INSN_LENGTH divides length by 2 on mips16,
142                      ; so cope with it here.
143                      (ior (and (eq (symbol_ref "mips16") (const_int 0))
144                                    (eq_attr "length" "4"))
145                           (and (ne (symbol_ref "mips16") (const_int 0))
146                                (eq_attr "length" "2"))))
147                 (const_string "yes")
148                 (const_string "no")))
149
150 ;; Attribute defining whether or not we can use the branch-likely instructions
151
152 (define_attr "branch_likely" "no,yes"
153   (const
154    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
155                  (const_string "yes")
156                  (const_string "no"))))
157
158
159 ;; Describe a user's asm statement.
160 (define_asm_attributes
161   [(set_attr "type" "multi")])
162
163 ;; whether or not generating calls to position independent functions
164 (define_attr "abicalls" "no,yes"
165   (const (symbol_ref "mips_abicalls_attr")))
166
167 \f
168
169 ;; .........................
170 ;;
171 ;;      Delay slots, can't describe load/fcmp/xfer delay slots here
172 ;;
173 ;; .........................
174
175 (define_delay (and (eq_attr "type" "branch")
176                    (eq (symbol_ref "mips16") (const_int 0)))
177   [(eq_attr "can_delay" "yes")
178    (nil)
179    (and (eq_attr "branch_likely" "yes")
180         (and (eq_attr "dslot" "no")
181              (eq_attr "length" "4")))])
182
183 (define_delay (eq_attr "type" "jump")
184   [(eq_attr "can_delay" "yes")
185    (nil)
186    (nil)])
187
188 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
189   [(eq_attr "can_delay" "yes")
190    (nil)
191    (nil)])
192
193 \f
194
195 ;; .........................
196 ;;
197 ;;      Functional units
198 ;;
199 ;; .........................
200
201 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
202 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
203
204 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
205
206 (define_function_unit "memory" 1 0
207   (and (eq_attr "type" "load")
208        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
209   3 0)
210
211 (define_function_unit "memory" 1 0
212   (and (eq_attr "type" "load")
213        (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
214   2 0)
215
216 (define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
217
218 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
219
220 (define_function_unit "imuldiv"  1 0
221   (eq_attr "type" "hilo")
222   1 3)
223
224 (define_function_unit "imuldiv"  1 0
225   (and (eq_attr "type" "imul")
226        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
227   17 17)
228
229 ;; On them mips16, we want to stronly discourage a mult from appearing
230 ;; after an mflo, since that requires explicit nop instructions.  We
231 ;; do this by pretending that mflo ties up the function unit for long
232 ;; enough that the scheduler will ignore load stalls and the like when
233 ;; selecting instructions to between the two instructions.
234
235 (define_function_unit "imuldiv" 1 0
236   (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
237   1 5)
238
239 (define_function_unit "imuldiv"  1 0
240   (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
241   12 12)
242
243 (define_function_unit "imuldiv"  1 0
244   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
245   10 10)
246
247 (define_function_unit "imuldiv"  1 0
248   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
249   4 4)
250
251 (define_function_unit "imuldiv"  1 0
252   (and (eq_attr "type" "imul")
253        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
254   1 1)
255
256 (define_function_unit "imuldiv"  1 0
257   (and (eq_attr "type" "imul")
258        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
259   4 4)
260
261 (define_function_unit "imuldiv"  1 0
262   (and (eq_attr "type" "imul")
263        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
264   5 5)
265
266 (define_function_unit "imuldiv"  1 0
267   (and (eq_attr "type" "imul")
268        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
269   8 8)
270
271 (define_function_unit "imuldiv"  1 0
272   (and (eq_attr "type" "imul")
273        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
274   9 9)
275
276 (define_function_unit "imuldiv"  1 0
277   (and (eq_attr "type" "idiv")
278        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
279   38 38)
280
281 (define_function_unit "imuldiv"  1 0
282   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
283   35 35)
284
285 (define_function_unit "imuldiv"  1 0
286   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
287   42 42)
288
289 (define_function_unit "imuldiv"  1 0
290   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
291   36 36)
292
293 (define_function_unit "imuldiv"  1 0
294   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
295   69 69)
296
297 (define_function_unit "imuldiv" 1 0
298   (and (eq_attr "type" "idiv")
299        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
300   35 35)
301
302 (define_function_unit "imuldiv" 1 0
303   (and (eq_attr "type" "idiv")
304        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
305   67 67)
306
307 (define_function_unit "imuldiv" 1 0
308   (and (eq_attr "type" "idiv")
309        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
310   37 37)
311
312 (define_function_unit "imuldiv" 1 0
313   (and (eq_attr "type" "idiv")
314        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
315   69 69)
316
317 (define_function_unit "imuldiv" 1 0
318   (and (eq_attr "type" "idiv")
319        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
320   36 36)
321
322 (define_function_unit "imuldiv" 1 0
323   (and (eq_attr "type" "idiv")
324        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
325   68 68)
326
327 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
328 ;; the FP hardware is part of the normal ALU circuitry.  This means FP
329 ;; instructions affect the pipe-line, and no functional unit
330 ;; parallelism can occur on R4300 processors.  To force GCC into coding
331 ;; for only a single functional unit, we force the R4300 FP
332 ;; instructions to be processed in the "imuldiv" unit.
333
334 (define_function_unit "adder" 1 1
335   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
336   3 0)
337
338 (define_function_unit "adder" 1 1
339   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
340   2 0)
341
342 (define_function_unit "adder" 1 1
343   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
344   1 0)
345
346 (define_function_unit "adder" 1 1
347   (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
348   4 0)
349
350 (define_function_unit "adder" 1 1
351   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
352   2 0)
353
354 (define_function_unit "adder" 1 1
355   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
356   3 0)
357
358 (define_function_unit "adder" 1 1
359   (and (eq_attr "type" "fabs,fneg")
360        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
361   2 0)
362
363 (define_function_unit "adder" 1 1
364   (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
365   1 0)
366
367 (define_function_unit "mult" 1 1
368   (and (eq_attr "type" "fmul")
369        (and (eq_attr "mode" "SF")
370             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
371   7 0)
372
373 (define_function_unit "mult" 1 1
374   (and (eq_attr "type" "fmul")
375        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
376   4 0)
377
378 (define_function_unit "mult" 1 1
379   (and (eq_attr "type" "fmul")
380        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
381   5 0)
382
383 (define_function_unit "mult" 1 1
384   (and (eq_attr "type" "fmul")
385        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
386   8 0)
387
388 (define_function_unit "mult" 1 1
389   (and (eq_attr "type" "fmul")
390        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
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,r5000")))
396   5 0)
397
398 (define_function_unit "mult" 1 1
399   (and (eq_attr "type" "fmul")
400        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
401   6 0)
402
403 (define_function_unit "divide" 1 1
404   (and (eq_attr "type" "fdiv")
405        (and (eq_attr "mode" "SF")
406             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
407   23 0)
408
409 (define_function_unit "divide" 1 1
410   (and (eq_attr "type" "fdiv")
411        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
412   12 0)
413
414 (define_function_unit "divide" 1 1
415   (and (eq_attr "type" "fdiv")
416        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
417   15 0)
418
419 (define_function_unit "divide" 1 1
420   (and (eq_attr "type" "fdiv")
421        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
422   32 0)
423
424 (define_function_unit "divide" 1 1
425   (and (eq_attr "type" "fdiv")
426        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
427   21 0)
428
429 (define_function_unit "divide" 1 1
430   (and (eq_attr "type" "fdiv")
431        (and (eq_attr "mode" "DF")
432             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
433   36 0)
434
435 (define_function_unit "divide" 1 1
436   (and (eq_attr "type" "fdiv")
437        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
438   19 0)
439
440 (define_function_unit "divide" 1 1
441   (and (eq_attr "type" "fdiv")
442        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
443   16 0)
444
445 (define_function_unit "divide" 1 1
446   (and (eq_attr "type" "fdiv")
447        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
448   61 0)
449
450 ;;; ??? Is this number right?
451 (define_function_unit "divide" 1 1
452   (and (eq_attr "type" "fsqrt")
453        (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
454   54 0)
455
456 (define_function_unit "divide" 1 1
457   (and (eq_attr "type" "fsqrt")
458        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
459   31 0)
460
461 (define_function_unit "divide" 1 1
462   (and (eq_attr "type" "fsqrt")
463        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
464   21 0)
465
466 ;;; ??? Is this number right?
467 (define_function_unit "divide" 1 1
468   (and (eq_attr "type" "fsqrt")
469        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
470   112 0)
471
472 (define_function_unit "divide" 1 1
473   (and (eq_attr "type" "fsqrt")
474        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
475   60 0)
476
477 (define_function_unit "divide" 1 1
478   (and (eq_attr "type" "fsqrt")
479        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
480   36 0)
481
482 ;; R4300 FP instruction classes treated as part of the "imuldiv"
483 ;; functional unit:
484
485 (define_function_unit "imuldiv" 1 0
486   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
487   3 3)
488
489 (define_function_unit "imuldiv" 1 0
490   (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
491   1 1)
492
493 (define_function_unit "imuldiv" 1 0
494   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
495   5 5)
496 (define_function_unit "imuldiv" 1 0
497   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
498   8 8)
499
500 (define_function_unit "imuldiv" 1 0
501   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
502        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
503   29 29)
504 (define_function_unit "imuldiv" 1 0
505   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
506        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
507   58 58)
508 \f
509 ;; The following functional units do not use the cpu type, and use
510 ;; much less memory in genattrtab.c.
511
512 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "load")                                3 0)
513 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "store")                               1 0)
514 ;;
515 ;; (define_function_unit "fp_comp"  1 0 (eq_attr "type" "fcmp")                                2 0)
516 ;;
517 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer")                                2 0)
518 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo")                                3 0)
519 ;;
520 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "imul")                               17 0)
521 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "idiv")                               38 0)
522 ;;
523 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fadd")                                4 0)
524 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fabs,fneg")                           2 0)
525 ;;
526 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF"))    7 0)
527 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF"))    8 0)
528 ;;
529 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF"))   23 0)
530 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF"))   36 0)
531 ;;
532 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF"))  54 0)
533 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
534 \f
535 ;;
536 ;;  ....................
537 ;;
538 ;;      CONDITIONAL TRAPS
539 ;;
540 ;;  ....................
541 ;;
542
543 (define_insn "trap"
544   [(trap_if (const_int 1) (const_int 0))]
545   ""
546   "*
547 {
548   if (ISA_HAS_COND_TRAP)
549     return \"teq\\t$0,$0\";
550   else if (TARGET_MIPS16)
551     return \"break 0\";
552   else
553     return \"break\";
554 }")
555
556 (define_expand "conditional_trap"
557   [(trap_if (match_operator 0 "cmp_op"
558                             [(match_dup 2) (match_dup 3)])
559             (match_operand 1 "const_int_operand" ""))]
560   "ISA_HAS_COND_TRAP"
561   "
562 {
563   mips_gen_conditional_trap (operands);
564   DONE;
565 }")
566
567 ;; Match a TRAP_IF with 2nd arg of 0.  The div_trap_* insns match a
568 ;; 2nd arg of any CONST_INT, so this insn must appear first.
569 ;; gen_div_trap always generates TRAP_IF with 2nd arg of 6 or 7.
570
571 (define_insn ""
572   [(trap_if (match_operator 0 "trap_cmp_op"
573                             [(match_operand:SI 1 "reg_or_0_operand" "d")
574                              (match_operand:SI 2 "nonmemory_operand" "dI")])
575             (const_int 0))]
576   "ISA_HAS_COND_TRAP"
577   "t%C0\\t%z1,%z2")
578 \f
579 ;;
580 ;;  ....................
581 ;;
582 ;;      ADDITION
583 ;;
584 ;;  ....................
585 ;;
586
587 (define_insn "adddf3"
588   [(set (match_operand:DF 0 "register_operand" "=f")
589         (plus:DF (match_operand:DF 1 "register_operand" "f")
590                  (match_operand:DF 2 "register_operand" "f")))]
591   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
592   "add.d\\t%0,%1,%2"
593   [(set_attr "type"     "fadd")
594    (set_attr "mode"     "DF")])
595
596 (define_insn "addsf3"
597   [(set (match_operand:SF 0 "register_operand" "=f")
598         (plus:SF (match_operand:SF 1 "register_operand" "f")
599                  (match_operand:SF 2 "register_operand" "f")))]
600   "TARGET_HARD_FLOAT"
601   "add.s\\t%0,%1,%2"
602   [(set_attr "type"     "fadd")
603    (set_attr "mode"     "SF")])
604
605 (define_expand "addsi3"
606   [(set (match_operand:SI 0 "register_operand" "=d")
607         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
608                  (match_operand:SI 2 "arith_operand" "dI")))]
609   ""
610   "
611 {
612   /* The mips16 assembler handles -32768 correctly, and so does gas,
613      but some other MIPS assemblers think that -32768 needs to be
614      loaded into a register before it can be added in.  */
615   if (! TARGET_MIPS16
616       && ! TARGET_GAS
617       && GET_CODE (operands[2]) == CONST_INT
618       && INTVAL (operands[2]) == -32768)
619     operands[2] = force_reg (SImode, operands[2]);
620
621   /* If a large stack adjustment was forced into a register, we may be
622      asked to generate rtx such as:
623
624         (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
625
626      but no such instruction is available in mips16.  Handle it by
627      using a temporary.  */
628   if (TARGET_MIPS16
629       && REGNO (operands[0]) == STACK_POINTER_REGNUM
630       && ((GET_CODE (operands[1]) == REG
631            && REGNO (operands[1]) != STACK_POINTER_REGNUM)
632           || GET_CODE (operands[2]) != CONST_INT))
633     {
634       rtx tmp = gen_reg_rtx (SImode);
635
636       emit_move_insn (tmp, operands[1]);
637       emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
638       emit_move_insn (operands[0], tmp);
639       DONE;
640     }
641 }")
642
643 (define_insn "addsi3_internal"
644   [(set (match_operand:SI 0 "register_operand" "=d")
645         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
646                  (match_operand:SI 2 "arith_operand" "dI")))]
647   "! TARGET_MIPS16
648    && (TARGET_GAS
649        || GET_CODE (operands[2]) != CONST_INT
650        || INTVAL (operands[2]) != -32768)"
651   "addu\\t%0,%z1,%2"
652   [(set_attr "type"     "arith")
653    (set_attr "mode"     "SI")])
654
655 ;; For the mips16, we need to recognize stack pointer additions
656 ;; explicitly, since we don't have a constraint for $sp.  These insns
657 ;; will be generated by the save_restore_insns functions.
658
659 (define_insn ""
660   [(set (reg:SI 29)
661         (plus:SI (reg:SI 29)
662                  (match_operand:SI 0 "small_int" "I")))]
663   "TARGET_MIPS16"
664   "addu\\t%$,%$,%0"
665   [(set_attr "type"     "arith")
666    (set_attr "mode"     "SI")
667    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
668                                       (const_int 4)
669                                       (const_int 8)))])
670
671 (define_insn ""
672   [(set (match_operand:SI 0 "register_operand" "=d")
673         (plus:SI (reg:SI 29)
674                  (match_operand:SI 1 "small_int" "I")))]
675   "TARGET_MIPS16"
676   "addu\\t%0,%$,%1"
677   [(set_attr "type"     "arith")
678    (set_attr "mode"     "SI")
679    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
680                                       (const_int 4)
681                                       (const_int 8)))])
682
683 (define_insn ""
684   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
685         (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
686                  (match_operand:SI 2 "arith_operand" "IQ,O,d")))]
687   "TARGET_MIPS16
688    && (GET_CODE (operands[1]) != REG
689        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
690        || M16_REG_P (REGNO (operands[1]))
691        || REGNO (operands[1]) == ARG_POINTER_REGNUM
692        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
693        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
694    && (GET_CODE (operands[2]) != REG
695        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
696        || M16_REG_P (REGNO (operands[2]))
697        || REGNO (operands[2]) == ARG_POINTER_REGNUM
698        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
699        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
700   "*
701 {
702   if (REGNO (operands[0]) == REGNO (operands[1]))
703     return \"addu\\t%0,%2\";
704   return \"addu\\t%0,%1,%2\";
705 }"
706   [(set_attr "type"     "arith")
707    (set_attr "mode"     "SI")
708    (set_attr_alternative "length"
709                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
710                                (const_int 4)
711                                (const_int 8))
712                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
713                                (const_int 4)
714                                (const_int 8))
715                  (const_int 4)])])
716
717
718 ;; On the mips16, we can sometimes split an add of a constant which is
719 ;; a 4 byte instruction into two adds which are both 2 byte
720 ;; instructions.  There are two cases: one where we are adding a
721 ;; constant plus a register to another register, and one where we are
722 ;; simply adding a constant to a register.
723
724 (define_split
725   [(set (match_operand:SI 0 "register_operand" "")
726         (plus:SI (match_dup 0)
727                  (match_operand:SI 1 "const_int_operand" "")))]
728   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
729    && GET_CODE (operands[0]) == REG
730    && M16_REG_P (REGNO (operands[0]))
731    && GET_CODE (operands[1]) == CONST_INT
732    && ((INTVAL (operands[1]) > 0x7f
733         && INTVAL (operands[1]) <= 0x7f + 0x7f)
734        || (INTVAL (operands[1]) < - 0x80
735            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
736   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
737    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
738   "
739 {
740   HOST_WIDE_INT val = INTVAL (operands[1]);
741
742   if (val >= 0)
743     {
744       operands[1] = GEN_INT (0x7f);
745       operands[2] = GEN_INT (val - 0x7f);
746     }
747   else
748     {
749       operands[1] = GEN_INT (- 0x80);
750       operands[2] = GEN_INT (val + 0x80);
751     }
752 }")
753
754 (define_split
755   [(set (match_operand:SI 0 "register_operand" "")
756         (plus:SI (match_operand:SI 1 "register_operand" "")
757                  (match_operand:SI 2 "const_int_operand" "")))]
758   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
759    && GET_CODE (operands[0]) == REG
760    && M16_REG_P (REGNO (operands[0]))
761    && GET_CODE (operands[1]) == REG
762    && M16_REG_P (REGNO (operands[1]))
763    && REGNO (operands[0]) != REGNO (operands[1])
764    && GET_CODE (operands[2]) == CONST_INT
765    && ((INTVAL (operands[2]) > 0x7
766         && INTVAL (operands[2]) <= 0x7 + 0x7f)
767        || (INTVAL (operands[2]) < - 0x8
768            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
769   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
770    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
771   "
772 {
773   HOST_WIDE_INT val = INTVAL (operands[2]);
774
775   if (val >= 0)
776     {
777       operands[2] = GEN_INT (0x7);
778       operands[3] = GEN_INT (val - 0x7);
779     }
780   else
781     {
782       operands[2] = GEN_INT (- 0x8);
783       operands[3] = GEN_INT (val + 0x8);
784     }
785 }")
786
787 (define_expand "adddi3"
788   [(parallel [(set (match_operand:DI 0 "register_operand" "")
789                    (plus:DI (match_operand:DI 1 "se_register_operand" "")
790                             (match_operand:DI 2 "se_arith_operand" "")))
791               (clobber (match_dup 3))])]
792   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
793   "
794 {
795   /* The mips16 assembler handles -32768 correctly, and so does gas,
796      but some other MIPS assemblers think that -32768 needs to be
797      loaded into a register before it can be added in.  */
798   if (! TARGET_MIPS16
799       && ! TARGET_GAS
800       && GET_CODE (operands[2]) == CONST_INT
801       && INTVAL (operands[2]) == -32768)
802     operands[2] = force_reg (DImode, operands[2]);
803
804   /* If a large stack adjustment was forced into a register, we may be
805      asked to generate rtx such as:
806
807         (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
808
809      but no such instruction is available in mips16.  Handle it by
810      using a temporary.  */
811   if (TARGET_MIPS16
812       && REGNO (operands[0]) == STACK_POINTER_REGNUM
813       && ((GET_CODE (operands[1]) == REG
814            && REGNO (operands[1]) != STACK_POINTER_REGNUM)
815           || GET_CODE (operands[2]) != CONST_INT))
816     {
817       rtx tmp = gen_reg_rtx (DImode);
818
819       emit_move_insn (tmp, operands[1]);
820       emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
821       emit_move_insn (operands[0], tmp);
822       DONE;
823     }
824
825   if (TARGET_64BIT)
826     {
827       emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
828                                         operands[2]));
829       DONE;
830     }
831
832   operands[3] = gen_reg_rtx (SImode);
833 }")
834
835 (define_insn "adddi3_internal_1"
836   [(set (match_operand:DI 0 "register_operand" "=d,&d")
837         (plus:DI (match_operand:DI 1 "register_operand" "0,d")
838                  (match_operand:DI 2 "register_operand" "d,d")))
839    (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
840   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
841   "*
842 {
843   return (REGNO (operands[0]) == REGNO (operands[1])
844           && REGNO (operands[0]) == REGNO (operands[2]))
845     ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
846     : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
847 }"
848   [(set_attr "type"     "darith")
849    (set_attr "mode"     "DI")
850    (set_attr "length"   "16")])
851
852 (define_split
853   [(set (match_operand:DI 0 "register_operand" "")
854         (plus:DI (match_operand:DI 1 "register_operand" "")
855                  (match_operand:DI 2 "register_operand" "")))
856    (clobber (match_operand:SI 3 "register_operand" ""))]
857   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
858    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
859    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
860    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
861    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
862    && (REGNO (operands[0]) != REGNO (operands[1])
863        || REGNO (operands[0]) != REGNO (operands[2]))"
864
865   [(set (subreg:SI (match_dup 0) 0)
866         (plus:SI (subreg:SI (match_dup 1) 0)
867                  (subreg:SI (match_dup 2) 0)))
868
869    (set (match_dup 3)
870         (ltu:SI (subreg:SI (match_dup 0) 0)
871                 (subreg:SI (match_dup 2) 0)))
872
873    (set (subreg:SI (match_dup 0) 4)
874         (plus:SI (subreg:SI (match_dup 1) 4)
875                  (subreg:SI (match_dup 2) 4)))
876
877    (set (subreg:SI (match_dup 0) 4)
878         (plus:SI (subreg:SI (match_dup 0) 4)
879                  (match_dup 3)))]
880   "")
881
882 (define_split
883   [(set (match_operand:DI 0 "register_operand" "")
884         (plus:DI (match_operand:DI 1 "register_operand" "")
885                  (match_operand:DI 2 "register_operand" "")))
886    (clobber (match_operand:SI 3 "register_operand" ""))]
887   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
888    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
889    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
890    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
891    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
892    && (REGNO (operands[0]) != REGNO (operands[1])
893        || REGNO (operands[0]) != REGNO (operands[2]))"
894
895   [(set (subreg:SI (match_dup 0) 4)
896         (plus:SI (subreg:SI (match_dup 1) 4)
897                  (subreg:SI (match_dup 2) 4)))
898
899    (set (match_dup 3)
900         (ltu:SI (subreg:SI (match_dup 0) 4)
901                 (subreg:SI (match_dup 2) 4)))
902
903    (set (subreg:SI (match_dup 0) 0)
904         (plus:SI (subreg:SI (match_dup 1) 0)
905                  (subreg:SI (match_dup 2) 0)))
906
907    (set (subreg:SI (match_dup 0) 0)
908         (plus:SI (subreg:SI (match_dup 0) 0)
909                  (match_dup 3)))]
910   "")
911
912 (define_insn "adddi3_internal_2"
913   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
914         (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
915                  (match_operand:DI 2 "small_int" "P,J,N")))
916    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
917   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
918    && (TARGET_GAS
919        || GET_CODE (operands[2]) != CONST_INT
920        || INTVAL (operands[2]) != -32768)"
921   "@
922    addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
923    move\\t%L0,%L1\;move\\t%M0,%M1
924    subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
925   [(set_attr "type"     "darith")
926    (set_attr "mode"     "DI")
927    (set_attr "length"   "12,8,16")])
928
929 (define_split
930   [(set (match_operand:DI 0 "register_operand" "")
931         (plus:DI (match_operand:DI 1 "register_operand" "")
932                  (match_operand:DI 2 "small_int" "")))
933    (clobber (match_operand:SI 3 "register_operand" ""))]
934   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
935    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
936    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
937    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
938    && INTVAL (operands[2]) > 0"
939
940   [(set (subreg:SI (match_dup 0) 0)
941         (plus:SI (subreg:SI (match_dup 1) 0)
942                  (match_dup 2)))
943
944    (set (match_dup 3)
945         (ltu:SI (subreg:SI (match_dup 0) 0)
946                 (match_dup 2)))
947
948    (set (subreg:SI (match_dup 0) 4)
949         (plus:SI (subreg:SI (match_dup 1) 4)
950                  (match_dup 3)))]
951   "")
952
953 (define_split
954   [(set (match_operand:DI 0 "register_operand" "")
955         (plus:DI (match_operand:DI 1 "register_operand" "")
956                  (match_operand:DI 2 "small_int" "")))
957    (clobber (match_operand:SI 3 "register_operand" ""))]
958   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
959    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
960    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
961    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
962    && INTVAL (operands[2]) > 0"
963
964   [(set (subreg:SI (match_dup 0) 4)
965         (plus:SI (subreg:SI (match_dup 1) 4)
966                  (match_dup 2)))
967
968    (set (match_dup 3)
969         (ltu:SI (subreg:SI (match_dup 0) 4)
970                 (match_dup 2)))
971
972    (set (subreg:SI (match_dup 0) 0)
973         (plus:SI (subreg:SI (match_dup 1) 0)
974                  (match_dup 3)))]
975   "")
976
977 (define_insn "adddi3_internal_3"
978   [(set (match_operand:DI 0 "register_operand" "=d")
979         (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
980                  (match_operand:DI 2 "se_arith_operand" "dI")))]
981   "TARGET_64BIT
982    && !TARGET_MIPS16
983    && (TARGET_GAS
984        || GET_CODE (operands[2]) != CONST_INT
985        || INTVAL (operands[2]) != -32768)"
986   "*
987 {
988   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
989     ? \"dsubu\\t%0,%z1,%n2\"
990     : \"daddu\\t%0,%z1,%2\";
991 }"
992   [(set_attr "type"     "darith")
993    (set_attr "mode"     "DI")])
994
995 ;; For the mips16, we need to recognize stack pointer additions
996 ;; explicitly, since we don't have a constraint for $sp.  These insns
997 ;; will be generated by the save_restore_insns functions.
998
999 (define_insn ""
1000   [(set (reg:DI 29)
1001         (plus:DI (reg:DI 29)
1002                  (match_operand:DI 0 "small_int" "I")))]
1003   "TARGET_MIPS16 && TARGET_64BIT"
1004   "daddu\\t%$,%$,%0"
1005   [(set_attr "type"     "arith")
1006    (set_attr "mode"     "DI")
1007    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
1008                                       (const_int 4)
1009                                       (const_int 8)))])
1010
1011 (define_insn ""
1012   [(set (match_operand:DI 0 "register_operand" "=d")
1013         (plus:DI (reg:DI 29)
1014                  (match_operand:DI 1 "small_int" "I")))]
1015   "TARGET_MIPS16 && TARGET_64BIT"
1016   "daddu\\t%0,%$,%1"
1017   [(set_attr "type"     "arith")
1018    (set_attr "mode"     "DI")
1019    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
1020                                       (const_int 4)
1021                                       (const_int 8)))])
1022
1023 (define_insn ""
1024   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1025         (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1026                  (match_operand:DI 2 "arith_operand" "IQ,O,d")))]
1027   "TARGET_MIPS16 && TARGET_64BIT
1028    && (GET_CODE (operands[1]) != REG
1029        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
1030        || M16_REG_P (REGNO (operands[1]))
1031        || REGNO (operands[1]) == ARG_POINTER_REGNUM
1032        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
1033        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
1034    && (GET_CODE (operands[2]) != REG
1035        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
1036        || M16_REG_P (REGNO (operands[2]))
1037        || REGNO (operands[2]) == ARG_POINTER_REGNUM
1038        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
1039        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
1040   "*
1041 {
1042   if (REGNO (operands[0]) == REGNO (operands[1]))
1043     return \"daddu\\t%0,%2\";
1044   return \"daddu\\t%0,%1,%2\";
1045 }"
1046   [(set_attr "type"     "arith")
1047    (set_attr "mode"     "DI")
1048    (set_attr_alternative "length"
1049                 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
1050                                (const_int 4)
1051                                (const_int 8))
1052                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1053                                (const_int 4)
1054                                (const_int 8))
1055                  (const_int 4)])])
1056
1057
1058 ;; On the mips16, we can sometimes split an add of a constant which is
1059 ;; a 4 byte instruction into two adds which are both 2 byte
1060 ;; instructions.  There are two cases: one where we are adding a
1061 ;; constant plus a register to another register, and one where we are
1062 ;; simply adding a constant to a register.
1063
1064 (define_split
1065   [(set (match_operand:DI 0 "register_operand" "")
1066         (plus:DI (match_dup 0)
1067                  (match_operand:DI 1 "const_int_operand" "")))]
1068   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1069    && GET_CODE (operands[0]) == REG
1070    && M16_REG_P (REGNO (operands[0]))
1071    && GET_CODE (operands[1]) == CONST_INT
1072    && ((INTVAL (operands[1]) > 0xf
1073         && INTVAL (operands[1]) <= 0xf + 0xf)
1074        || (INTVAL (operands[1]) < - 0x10
1075            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1076   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1077    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1078   "
1079 {
1080   HOST_WIDE_INT val = INTVAL (operands[1]);
1081
1082   if (val >= 0)
1083     {
1084       operands[1] = GEN_INT (0xf);
1085       operands[2] = GEN_INT (val - 0xf);
1086     }
1087   else
1088     {
1089       operands[1] = GEN_INT (- 0x10);
1090       operands[2] = GEN_INT (val + 0x10);
1091     }
1092 }")
1093
1094 (define_split
1095   [(set (match_operand:DI 0 "register_operand" "")
1096         (plus:DI (match_operand:DI 1 "register_operand" "")
1097                  (match_operand:DI 2 "const_int_operand" "")))]
1098   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1099    && GET_CODE (operands[0]) == REG
1100    && M16_REG_P (REGNO (operands[0]))
1101    && GET_CODE (operands[1]) == REG
1102    && M16_REG_P (REGNO (operands[1]))
1103    && REGNO (operands[0]) != REGNO (operands[1])
1104    && GET_CODE (operands[2]) == CONST_INT
1105    && ((INTVAL (operands[2]) > 0x7
1106         && INTVAL (operands[2]) <= 0x7 + 0xf)
1107        || (INTVAL (operands[2]) < - 0x8
1108            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1109   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1110    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1111   "
1112 {
1113   HOST_WIDE_INT val = INTVAL (operands[2]);
1114
1115   if (val >= 0)
1116     {
1117       operands[2] = GEN_INT (0x7);
1118       operands[3] = GEN_INT (val - 0x7);
1119     }
1120   else
1121     {
1122       operands[2] = GEN_INT (- 0x8);
1123       operands[3] = GEN_INT (val + 0x8);
1124     }
1125 }")
1126
1127 (define_insn "addsi3_internal_2"
1128   [(set (match_operand:DI 0 "register_operand" "=d")
1129         (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1130                                  (match_operand:SI 2 "arith_operand" "dI"))))]
1131   "TARGET_64BIT
1132    && !TARGET_MIPS16
1133    && (TARGET_GAS
1134        || GET_CODE (operands[2]) != CONST_INT
1135        || INTVAL (operands[2]) != -32768)"
1136   "*
1137 {
1138   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1139     ? \"subu\\t%0,%z1,%n2\"
1140     : \"addu\\t%0,%z1,%2\";
1141 }"
1142   [(set_attr "type"     "arith")
1143    (set_attr "mode"     "SI")])
1144
1145 (define_insn ""
1146   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1147         (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1148                                  (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1149   "TARGET_MIPS16 && TARGET_64BIT"
1150   "*
1151 {
1152   if (REGNO (operands[0]) == REGNO (operands[1]))
1153     return \"addu\\t%0,%2\";
1154   return \"addu\\t%0,%1,%2\";
1155 }"
1156   [(set_attr "type"     "arith")
1157    (set_attr "mode"     "SI")
1158    (set_attr_alternative "length"
1159                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1160                                (const_int 4)
1161                                (const_int 8))
1162                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1163                                (const_int 4)
1164                                (const_int 8))
1165                  (const_int 4)])])
1166
1167 \f
1168 ;;
1169 ;;  ....................
1170 ;;
1171 ;;      SUBTRACTION
1172 ;;
1173 ;;  ....................
1174 ;;
1175
1176 (define_insn "subdf3"
1177   [(set (match_operand:DF 0 "register_operand" "=f")
1178         (minus:DF (match_operand:DF 1 "register_operand" "f")
1179                   (match_operand:DF 2 "register_operand" "f")))]
1180   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1181   "sub.d\\t%0,%1,%2"
1182   [(set_attr "type"     "fadd")
1183    (set_attr "mode"     "DF")])
1184
1185 (define_insn "subsf3"
1186   [(set (match_operand:SF 0 "register_operand" "=f")
1187         (minus:SF (match_operand:SF 1 "register_operand" "f")
1188                   (match_operand:SF 2 "register_operand" "f")))]
1189   "TARGET_HARD_FLOAT"
1190   "sub.s\\t%0,%1,%2"
1191   [(set_attr "type"     "fadd")
1192    (set_attr "mode"     "SF")])
1193
1194 (define_expand "subsi3"
1195   [(set (match_operand:SI 0 "register_operand" "=d")
1196         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1197                   (match_operand:SI 2 "arith_operand" "dI")))]
1198   ""
1199   "
1200 {
1201   if (GET_CODE (operands[2]) == CONST_INT
1202       && (INTVAL (operands[2]) == -32768
1203           || (TARGET_MIPS16
1204               && INTVAL (operands[2]) == -0x4000)))
1205     operands[2] = force_reg (SImode, operands[2]);
1206 }")
1207
1208 (define_insn "subsi3_internal"
1209   [(set (match_operand:SI 0 "register_operand" "=d")
1210         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1211                   (match_operand:SI 2 "arith_operand" "dI")))]
1212   "!TARGET_MIPS16
1213    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1214   "subu\\t%0,%z1,%2"
1215   [(set_attr "type"     "arith")
1216    (set_attr "mode"     "SI")])
1217
1218 ;; For the mips16, we need to recognize stack pointer subtractions
1219 ;; explicitly, since we don't have a constraint for $sp.  These insns
1220 ;; will be generated by the save_restore_insns functions.
1221
1222 (define_insn ""
1223   [(set (reg:SI 29)
1224         (minus:SI (reg:SI 29)
1225                   (match_operand:SI 0 "small_int" "I")))]
1226   "TARGET_MIPS16
1227    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1228   "addu\\t%$,%$,%n0"
1229   [(set_attr "type"     "arith")
1230    (set_attr "mode"     "SI")
1231    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1232                                       (const_int 4)
1233                                       (const_int 8)))])
1234
1235 (define_insn ""
1236   [(set (match_operand:SI 0 "register_operand" "=d")
1237         (minus:SI (reg:SI 29)
1238                   (match_operand:SI 1 "small_int" "I")))]
1239   "TARGET_MIPS16
1240    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1241   "addu\\t%0,%$,%n1"
1242   [(set_attr "type"     "arith")
1243    (set_attr "mode"     "SI")
1244    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
1245                                       (const_int 4)
1246                                       (const_int 8)))])
1247
1248
1249 (define_insn ""
1250   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1251         (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1252                   (match_operand:SI 2 "arith_operand" "I,O,d")))]
1253   "TARGET_MIPS16
1254    && (GET_CODE (operands[2]) != CONST_INT
1255        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1256   "*
1257 {
1258   if (REGNO (operands[0]) == REGNO (operands[1]))
1259     return \"subu\\t%0,%2\";
1260   return \"subu\\t%0,%1,%2\";
1261 }"
1262   [(set_attr "type"     "arith")
1263    (set_attr "mode"     "SI")
1264    (set_attr_alternative "length"
1265                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1266                                (const_int 4)
1267                                (const_int 8))
1268                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1269                                (const_int 4)
1270                                (const_int 8))
1271                  (const_int 4)])])
1272
1273 ;; On the mips16, we can sometimes split an subtract of a constant
1274 ;; which is a 4 byte instruction into two adds which are both 2 byte
1275 ;; instructions.  There are two cases: one where we are setting a
1276 ;; register to a register minus a constant, and one where we are
1277 ;; simply subtracting a constant from a register.
1278
1279 (define_split
1280   [(set (match_operand:SI 0 "register_operand" "")
1281         (minus:SI (match_dup 0)
1282                   (match_operand:SI 1 "const_int_operand" "")))]
1283   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1284    && GET_CODE (operands[0]) == REG
1285    && M16_REG_P (REGNO (operands[0]))
1286    && GET_CODE (operands[1]) == CONST_INT
1287    && ((INTVAL (operands[1]) > 0x80
1288         && INTVAL (operands[1]) <= 0x80 + 0x80)
1289        || (INTVAL (operands[1]) < - 0x7f
1290            && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1291   [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1292    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1293   "
1294 {
1295   HOST_WIDE_INT val = INTVAL (operands[1]);
1296
1297   if (val >= 0)
1298     {
1299       operands[1] = GEN_INT (0x80);
1300       operands[2] = GEN_INT (val - 0x80);
1301     }
1302   else
1303     {
1304       operands[1] = GEN_INT (- 0x7f);
1305       operands[2] = GEN_INT (val + 0x7f);
1306     }
1307 }")
1308
1309 (define_split
1310   [(set (match_operand:SI 0 "register_operand" "")
1311         (minus:SI (match_operand:SI 1 "register_operand" "")
1312                   (match_operand:SI 2 "const_int_operand" "")))]
1313   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1314    && GET_CODE (operands[0]) == REG
1315    && M16_REG_P (REGNO (operands[0]))
1316    && GET_CODE (operands[1]) == REG
1317    && M16_REG_P (REGNO (operands[1]))
1318    && REGNO (operands[0]) != REGNO (operands[1])
1319    && GET_CODE (operands[2]) == CONST_INT
1320    && ((INTVAL (operands[2]) > 0x8
1321         && INTVAL (operands[2]) <= 0x8 + 0x80)
1322        || (INTVAL (operands[2]) < - 0x7
1323            && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1324   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1325    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1326   "
1327 {
1328   HOST_WIDE_INT val = INTVAL (operands[2]);
1329
1330   if (val >= 0)
1331     {
1332       operands[2] = GEN_INT (0x8);
1333       operands[3] = GEN_INT (val - 0x8);
1334     }
1335   else
1336     {
1337       operands[2] = GEN_INT (- 0x7);
1338       operands[3] = GEN_INT (val + 0x7);
1339     }
1340 }")
1341
1342 (define_expand "subdi3"
1343   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1344                    (minus:DI (match_operand:DI 1 "se_register_operand" "d")
1345                              (match_operand:DI 2 "se_register_operand" "d")))
1346               (clobber (match_dup 3))])]
1347   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1348   "
1349 {
1350   if (TARGET_64BIT)
1351     {
1352       emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1353                                         operands[2]));
1354       DONE;
1355     }
1356
1357   operands[3] = gen_reg_rtx (SImode);
1358 }")
1359
1360 (define_insn "subdi3_internal"
1361   [(set (match_operand:DI 0 "register_operand" "=d")
1362         (minus:DI (match_operand:DI 1 "register_operand" "d")
1363                   (match_operand:DI 2 "register_operand" "d")))
1364    (clobber (match_operand:SI 3 "register_operand" "=d"))]
1365   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1366   "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1367   [(set_attr "type"     "darith")
1368    (set_attr "mode"     "DI")
1369    (set_attr "length"   "16")])
1370
1371 (define_split
1372   [(set (match_operand:DI 0 "register_operand" "")
1373         (minus:DI (match_operand:DI 1 "register_operand" "")
1374                   (match_operand:DI 2 "register_operand" "")))
1375    (clobber (match_operand:SI 3 "register_operand" ""))]
1376   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1377    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1378    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1379    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1380    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1381
1382   [(set (match_dup 3)
1383         (ltu:SI (subreg:SI (match_dup 1) 0)
1384                 (subreg:SI (match_dup 2) 0)))
1385
1386    (set (subreg:SI (match_dup 0) 0)
1387         (minus:SI (subreg:SI (match_dup 1) 0)
1388                   (subreg:SI (match_dup 2) 0)))
1389
1390    (set (subreg:SI (match_dup 0) 4)
1391         (minus:SI (subreg:SI (match_dup 1) 4)
1392                   (subreg:SI (match_dup 2) 4)))
1393
1394    (set (subreg:SI (match_dup 0) 4)
1395         (minus:SI (subreg:SI (match_dup 0) 4)
1396                   (match_dup 3)))]
1397   "")
1398
1399 (define_split
1400   [(set (match_operand:DI 0 "register_operand" "")
1401         (minus:DI (match_operand:DI 1 "register_operand" "")
1402                   (match_operand:DI 2 "register_operand" "")))
1403    (clobber (match_operand:SI 3 "register_operand" ""))]
1404   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1405    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1406    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1407    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1408    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1409
1410   [(set (match_dup 3)
1411         (ltu:SI (subreg:SI (match_dup 1) 4)
1412                 (subreg:SI (match_dup 2) 4)))
1413
1414    (set (subreg:SI (match_dup 0) 4)
1415         (minus:SI (subreg:SI (match_dup 1) 4)
1416                   (subreg:SI (match_dup 2) 4)))
1417
1418    (set (subreg:SI (match_dup 0) 0)
1419         (minus:SI (subreg:SI (match_dup 1) 0)
1420                   (subreg:SI (match_dup 2) 0)))
1421
1422    (set (subreg:SI (match_dup 0) 0)
1423         (minus:SI (subreg:SI (match_dup 0) 0)
1424                   (match_dup 3)))]
1425   "")
1426
1427 (define_insn "subdi3_internal_2"
1428   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1429         (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1430                   (match_operand:DI 2 "small_int" "P,J,N")))
1431    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1432   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1433    && INTVAL (operands[2]) != -32768"
1434   "@
1435    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1436    move\\t%L0,%L1\;move\\t%M0,%M1
1437    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1438   [(set_attr "type"     "darith")
1439    (set_attr "mode"     "DI")
1440    (set_attr "length"   "12,8,16")])
1441
1442 (define_split
1443   [(set (match_operand:DI 0 "register_operand" "")
1444         (minus:DI (match_operand:DI 1 "register_operand" "")
1445                   (match_operand:DI 2 "small_int" "")))
1446    (clobber (match_operand:SI 3 "register_operand" ""))]
1447   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1448    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1449    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1450    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1451    && INTVAL (operands[2]) > 0"
1452
1453   [(set (match_dup 3)
1454         (ltu:SI (subreg:SI (match_dup 1) 0)
1455                 (match_dup 2)))
1456
1457    (set (subreg:SI (match_dup 0) 0)
1458         (minus:SI (subreg:SI (match_dup 1) 0)
1459                   (match_dup 2)))
1460
1461    (set (subreg:SI (match_dup 0) 4)
1462         (minus:SI (subreg:SI (match_dup 1) 4)
1463                   (match_dup 3)))]
1464   "")
1465
1466 (define_split
1467   [(set (match_operand:DI 0 "register_operand" "")
1468         (minus:DI (match_operand:DI 1 "register_operand" "")
1469                   (match_operand:DI 2 "small_int" "")))
1470    (clobber (match_operand:SI 3 "register_operand" ""))]
1471   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1472    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1473    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1474    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1475    && INTVAL (operands[2]) > 0"
1476
1477   [(set (match_dup 3)
1478         (ltu:SI (subreg:SI (match_dup 1) 4)
1479                 (match_dup 2)))
1480
1481    (set (subreg:SI (match_dup 0) 4)
1482         (minus:SI (subreg:SI (match_dup 1) 4)
1483                   (match_dup 2)))
1484
1485    (set (subreg:SI (match_dup 0) 0)
1486         (minus:SI (subreg:SI (match_dup 1) 0)
1487                   (match_dup 3)))]
1488   "")
1489
1490 (define_insn "subdi3_internal_3"
1491   [(set (match_operand:DI 0 "register_operand" "=d")
1492         (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
1493                   (match_operand:DI 2 "se_arith_operand" "dI")))]
1494   "TARGET_64BIT && !TARGET_MIPS16
1495    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1496   "*
1497 {
1498   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1499     ? \"daddu\\t%0,%z1,%n2\"
1500     : \"dsubu\\t%0,%z1,%2\";
1501 }"
1502   [(set_attr "type"     "darith")
1503    (set_attr "mode"     "DI")])
1504
1505 ;; For the mips16, we need to recognize stack pointer subtractions
1506 ;; explicitly, since we don't have a constraint for $sp.  These insns
1507 ;; will be generated by the save_restore_insns functions.
1508
1509 (define_insn ""
1510   [(set (reg:DI 29)
1511         (minus:DI (reg:DI 29)
1512                   (match_operand:DI 0 "small_int" "I")))]
1513   "TARGET_MIPS16
1514    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1515   "daddu\\t%$,%$,%n0"
1516   [(set_attr "type"     "arith")
1517    (set_attr "mode"     "DI")
1518    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1519                                       (const_int 4)
1520                                       (const_int 8)))])
1521
1522 (define_insn ""
1523   [(set (match_operand:DI 0 "register_operand" "=d")
1524         (minus:DI (reg:DI 29)
1525                   (match_operand:DI 1 "small_int" "I")))]
1526   "TARGET_MIPS16
1527    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1528   "daddu\\t%0,%$,%n1"
1529   [(set_attr "type"     "arith")
1530    (set_attr "mode"     "DI")
1531    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
1532                                       (const_int 4)
1533                                       (const_int 8)))])
1534
1535 (define_insn ""
1536   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1537         (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1538                   (match_operand:DI 2 "arith_operand" "I,O,d")))]
1539   "TARGET_MIPS16
1540    && (GET_CODE (operands[2]) != CONST_INT
1541        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1542   "*
1543 {
1544   if (REGNO (operands[0]) == REGNO (operands[1]))
1545     return \"dsubu\\t%0,%2\";
1546   return \"dsubu\\t%0,%1,%2\";
1547 }"
1548   [(set_attr "type"     "arith")
1549    (set_attr "mode"     "DI")
1550    (set_attr_alternative "length"
1551                 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
1552                                (const_int 4)
1553                                (const_int 8))
1554                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1555                                (const_int 4)
1556                                (const_int 8))
1557                  (const_int 4)])])
1558
1559 ;; On the mips16, we can sometimes split an add of a constant which is
1560 ;; a 4 byte instruction into two adds which are both 2 byte
1561 ;; instructions.  There are two cases: one where we are adding a
1562 ;; constant plus a register to another register, and one where we are
1563 ;; simply adding a constant to a register.
1564
1565 (define_split
1566   [(set (match_operand:DI 0 "register_operand" "")
1567         (minus:DI (match_dup 0)
1568                   (match_operand:DI 1 "const_int_operand" "")))]
1569   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1570    && GET_CODE (operands[0]) == REG
1571    && M16_REG_P (REGNO (operands[0]))
1572    && GET_CODE (operands[1]) == CONST_INT
1573    && ((INTVAL (operands[1]) > 0x10
1574         && INTVAL (operands[1]) <= 0x10 + 0x10)
1575        || (INTVAL (operands[1]) < - 0xf
1576            && INTVAL (operands[1]) >= - 0xf - 0xf))"
1577   [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1578    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1579   "
1580 {
1581   HOST_WIDE_INT val = INTVAL (operands[1]);
1582
1583   if (val >= 0)
1584     {
1585       operands[1] = GEN_INT (0xf);
1586       operands[2] = GEN_INT (val - 0xf);
1587     }
1588   else
1589     {
1590       operands[1] = GEN_INT (- 0x10);
1591       operands[2] = GEN_INT (val + 0x10);
1592     }
1593 }")
1594
1595 (define_split
1596   [(set (match_operand:DI 0 "register_operand" "")
1597         (minus:DI (match_operand:DI 1 "register_operand" "")
1598                   (match_operand:DI 2 "const_int_operand" "")))]
1599   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1600    && GET_CODE (operands[0]) == REG
1601    && M16_REG_P (REGNO (operands[0]))
1602    && GET_CODE (operands[1]) == REG
1603    && M16_REG_P (REGNO (operands[1]))
1604    && REGNO (operands[0]) != REGNO (operands[1])
1605    && GET_CODE (operands[2]) == CONST_INT
1606    && ((INTVAL (operands[2]) > 0x8
1607         && INTVAL (operands[2]) <= 0x8 + 0x10)
1608        || (INTVAL (operands[2]) < - 0x7
1609            && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1610   [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1611    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1612   "
1613 {
1614   HOST_WIDE_INT val = INTVAL (operands[2]);
1615
1616   if (val >= 0)
1617     {
1618       operands[2] = GEN_INT (0x8);
1619       operands[3] = GEN_INT (val - 0x8);
1620     }
1621   else
1622     {
1623       operands[2] = GEN_INT (- 0x7);
1624       operands[3] = GEN_INT (val + 0x7);
1625     }
1626 }")
1627
1628 (define_insn "subsi3_internal_2"
1629   [(set (match_operand:DI 0 "register_operand" "=d")
1630         (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1631                                   (match_operand:SI 2 "arith_operand" "dI"))))]
1632   "TARGET_64BIT && !TARGET_MIPS16
1633    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1634   "*
1635 {
1636   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1637     ? \"addu\\t%0,%z1,%n2\"
1638     : \"subu\\t%0,%z1,%2\";
1639 }"
1640   [(set_attr "type"     "arith")
1641    (set_attr "mode"     "DI")])
1642
1643 (define_insn ""
1644   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1645         (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1646                                   (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1647   "TARGET_64BIT && TARGET_MIPS16
1648    && (GET_CODE (operands[2]) != CONST_INT
1649        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1650   "*
1651 {
1652   if (REGNO (operands[0]) == REGNO (operands[1]))
1653     return \"subu\\t%0,%2\";
1654   return \"subu\\t%0,%1,%2\";
1655 }"
1656   [(set_attr "type"     "arith")
1657    (set_attr "mode"     "SI")
1658    (set_attr_alternative "length"
1659                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1660                                (const_int 4)
1661                                (const_int 8))
1662                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1663                                (const_int 4)
1664                                (const_int 8))
1665                  (const_int 4)])])
1666
1667
1668 \f
1669 ;;
1670 ;;  ....................
1671 ;;
1672 ;;      MULTIPLICATION
1673 ;;
1674 ;;  ....................
1675 ;;
1676
1677 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1678 ;; operands may corrupt immediately following multiplies. This is a
1679 ;; simple fix to insert NOPs.
1680
1681 (define_expand "muldf3"
1682   [(set (match_operand:DF 0 "register_operand" "=f")
1683         (mult:DF (match_operand:DF 1 "register_operand" "f")
1684                  (match_operand:DF 2 "register_operand" "f")))]
1685   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1686   "
1687 {
1688   if (!TARGET_MIPS4300)
1689     emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1690   else
1691     emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1692   DONE;
1693 }")
1694
1695 (define_insn "muldf3_internal"
1696   [(set (match_operand:DF 0 "register_operand" "=f")
1697         (mult:DF (match_operand:DF 1 "register_operand" "f")
1698                  (match_operand:DF 2 "register_operand" "f")))]
1699   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_MIPS4300"
1700   "mul.d\\t%0,%1,%2"
1701   [(set_attr "type"     "fmul")
1702    (set_attr "mode"     "DF")])
1703
1704 (define_insn "muldf3_r4300"
1705   [(set (match_operand:DF 0 "register_operand" "=f")
1706         (mult:DF (match_operand:DF 1 "register_operand" "f")
1707                  (match_operand:DF 2 "register_operand" "f")))]
1708   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_MIPS4300"
1709   "*
1710 {
1711   output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1712   if (TARGET_4300_MUL_FIX)
1713     output_asm_insn (\"nop\", operands);
1714   return \"\";
1715 }"
1716   [(set_attr "type"     "fmul")
1717    (set_attr "mode"     "DF")
1718    (set_attr "length"   "8")])  ;; mul.d + nop
1719
1720 (define_expand "mulsf3"
1721   [(set (match_operand:SF 0 "register_operand" "=f")
1722         (mult:SF (match_operand:SF 1 "register_operand" "f")
1723                  (match_operand:SF 2 "register_operand" "f")))]
1724   "TARGET_HARD_FLOAT"
1725   "
1726 {
1727   if (!TARGET_MIPS4300)
1728     emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1729   else
1730     emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1731   DONE;
1732 }")
1733
1734 (define_insn "mulsf3_internal"
1735   [(set (match_operand:SF 0 "register_operand" "=f")
1736         (mult:SF (match_operand:SF 1 "register_operand" "f")
1737                  (match_operand:SF 2 "register_operand" "f")))]
1738   "TARGET_HARD_FLOAT && !TARGET_MIPS4300"
1739   "mul.s\\t%0,%1,%2"
1740   [(set_attr "type"     "fmul")
1741    (set_attr "mode"     "SF")])
1742
1743 (define_insn "mulsf3_r4300"
1744   [(set (match_operand:SF 0 "register_operand" "=f")
1745         (mult:SF (match_operand:SF 1 "register_operand" "f")
1746                  (match_operand:SF 2 "register_operand" "f")))]
1747   "TARGET_HARD_FLOAT && TARGET_MIPS4300"
1748   "*
1749 {
1750   output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1751   if (TARGET_4300_MUL_FIX)
1752     output_asm_insn (\"nop\", operands);
1753   return \"\";
1754 }"
1755   [(set_attr "type"     "fmul")
1756    (set_attr "mode"     "SF")
1757    (set_attr "length"   "8")])  ;; mul.s + nop
1758
1759
1760 ;; ??? The R4000 (only) has a cpu bug.  If a double-word shift executes while
1761 ;; a multiply is in progress, it may give an incorrect result.  Avoid
1762 ;; this by keeping the mflo with the mult on the R4000.
1763
1764 (define_expand "mulsi3"
1765   [(set (match_operand:SI 0 "register_operand" "=l")
1766         (mult:SI (match_operand:SI 1 "register_operand" "d")
1767                  (match_operand:SI 2 "register_operand" "d")))
1768    (clobber (match_scratch:SI 3 "=h"))
1769    (clobber (match_scratch:SI 4 "=a"))]
1770   ""
1771   "
1772 {
1773   if (GENERATE_MULT3_SI || TARGET_MAD)
1774     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1775   else if (!TARGET_MIPS4000 || TARGET_MIPS16)
1776     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1777   else
1778     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1779   DONE;
1780 }")
1781
1782 (define_insn "mulsi3_mult3"
1783   [(set (match_operand:SI 0 "register_operand" "=d,l")
1784         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1785                  (match_operand:SI 2 "register_operand" "d,d")))
1786    (clobber (match_scratch:SI 3 "=h,h"))
1787    (clobber (match_scratch:SI 4 "=l,X"))
1788    (clobber (match_scratch:SI 5 "=a,a"))]
1789   "GENERATE_MULT3_SI
1790    || TARGET_MAD"
1791   "*
1792 {
1793   if (which_alternative == 1)
1794     return \"mult\\t%1,%2\";
1795   if (TARGET_MAD
1796       || mips_isa == 32
1797       || mips_isa == 64)
1798     return \"mul\\t%0,%1,%2\";
1799   return \"mult\\t%0,%1,%2\";
1800 }"
1801   [(set_attr "type"     "imul")
1802    (set_attr "mode"     "SI")])
1803
1804 (define_insn "mulsi3_internal"
1805   [(set (match_operand:SI 0 "register_operand" "=l")
1806         (mult:SI (match_operand:SI 1 "register_operand" "d")
1807                  (match_operand:SI 2 "register_operand" "d")))
1808    (clobber (match_scratch:SI 3 "=h"))
1809    (clobber (match_scratch:SI 4 "=a"))]
1810   "!TARGET_MIPS4000 || TARGET_MIPS16"
1811   "mult\\t%1,%2"
1812   [(set_attr "type"     "imul")
1813    (set_attr "mode"     "SI")])
1814
1815 (define_insn "mulsi3_r4000"
1816   [(set (match_operand:SI 0 "register_operand" "=d")
1817         (mult:SI (match_operand:SI 1 "register_operand" "d")
1818                  (match_operand:SI 2 "register_operand" "d")))
1819    (clobber (match_scratch:SI 3 "=h"))
1820    (clobber (match_scratch:SI 4 "=l"))
1821    (clobber (match_scratch:SI 5 "=a"))]
1822   "TARGET_MIPS4000 && !TARGET_MIPS16"
1823   "*
1824 {
1825   rtx xoperands[10];
1826
1827   xoperands[0] = operands[0];
1828   xoperands[1] = gen_rtx_REG (SImode, LO_REGNUM);
1829
1830   output_asm_insn (\"mult\\t%1,%2\", operands);
1831   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1832   return \"\";
1833 }"
1834   [(set_attr "type"     "imul")
1835    (set_attr "mode"     "SI")
1836    (set_attr "length"   "12")])         ;; mult + mflo + delay
1837
1838 ;; Multiply-accumulate patterns
1839
1840 ;; For processors that can copy the output to a general register:
1841 ;;
1842 ;; The all-d alternative is needed because the combiner will find this
1843 ;; pattern and then register alloc/reload will move registers around to
1844 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1845 ;;
1846 ;; The last alternative should be made slightly less desirable, but adding
1847 ;; "?" to the constraint is too strong, and causes values to be loaded into
1848 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1849 ;; trick.
1850 (define_insn "*mul_acc_si"
1851   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1852         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1853                           (match_operand:SI 2 "register_operand" "d,d,d"))
1854                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1855    (clobber (match_scratch:SI 4 "=h,h,h"))
1856    (clobber (match_scratch:SI 5 "=X,3,l"))
1857    (clobber (match_scratch:SI 6 "=a,a,a"))
1858    (clobber (match_scratch:SI 7 "=X,X,d"))]
1859   "(TARGET_MIPS3900
1860    || ISA_HAS_MADD_MSUB)
1861    && !TARGET_MIPS16"
1862   "*
1863 {
1864   static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
1865   if (which_alternative == 2)
1866     return \"#\";
1867   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1868     return \"#\";
1869   return madd[which_alternative];
1870 }"
1871   [(set_attr "type"     "imul,imul,multi")
1872    (set_attr "mode"     "SI")
1873    (set_attr "length"   "4,4,8")])
1874
1875 ;; Split the above insn if we failed to get LO allocated.
1876 (define_split
1877   [(set (match_operand:SI 0 "register_operand" "")
1878         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1879                           (match_operand:SI 2 "register_operand" ""))
1880                  (match_operand:SI 3 "register_operand" "")))
1881    (clobber (match_scratch:SI 4 ""))
1882    (clobber (match_scratch:SI 5 ""))
1883    (clobber (match_scratch:SI 6 ""))
1884    (clobber (match_scratch:SI 7 ""))]
1885   "reload_completed && !TARGET_DEBUG_D_MODE
1886    && GP_REG_P (true_regnum (operands[0]))
1887    && GP_REG_P (true_regnum (operands[3]))"
1888   [(parallel [(set (match_dup 7)
1889                    (mult:SI (match_dup 1) (match_dup 2)))
1890               (clobber (match_dup 4))
1891               (clobber (match_dup 5))
1892               (clobber (match_dup 6))])
1893    (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
1894   "")
1895
1896 ;; Splitter to copy result of MADD to a general register
1897 (define_split
1898   [(set (match_operand:SI                   0 "register_operand" "")
1899         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1900                           (match_operand:SI 2 "register_operand" ""))
1901                  (match_operand:SI          3 "register_operand" "")))
1902    (clobber (match_scratch:SI               4 ""))
1903    (clobber (match_scratch:SI               5 ""))
1904    (clobber (match_scratch:SI               6 ""))
1905    (clobber (match_scratch:SI               7 ""))]
1906   "reload_completed && !TARGET_DEBUG_D_MODE
1907    && GP_REG_P (true_regnum (operands[0]))
1908    && true_regnum (operands[3]) == LO_REGNUM"
1909   [(parallel [(set (match_dup 3)
1910                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1911                             (match_dup 3)))
1912               (clobber (match_dup 4))
1913               (clobber (match_dup 5))
1914               (clobber (match_dup 6))
1915               (clobber (match_dup 7))])
1916    (set (match_dup 0) (match_dup 3))]
1917   "")
1918
1919 (define_insn "*mul_sub_si"
1920   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1921         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1922                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1923                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1924    (clobber (match_scratch:SI 4 "=h,h,h"))
1925    (clobber (match_scratch:SI 5 "=X,3,l"))
1926    (clobber (match_scratch:SI 6 "=a,a,a"))
1927    (clobber (match_scratch:SI 7 "=X,X,d"))]
1928   "ISA_HAS_MADD_MSUB"
1929   "*
1930 {
1931   if (which_alternative != 0)
1932     return \"#\";
1933   return \"msub\\t%2,%3\";
1934 }"
1935   [(set_attr "type"     "imul,imul,multi")
1936    (set_attr "mode"     "SI")
1937    (set_attr "length"   "4,8,8")])
1938
1939 ;; Split the above insn if we failed to get LO allocated.
1940 (define_split
1941   [(set (match_operand:SI 0 "register_operand" "")
1942         (minus:SI (match_operand:SI 1 "register_operand" "")
1943                   (mult:SI (match_operand:SI 2 "register_operand" "")
1944                            (match_operand:SI 3 "register_operand" ""))))
1945    (clobber (match_scratch:SI 4 ""))
1946    (clobber (match_scratch:SI 5 ""))
1947    (clobber (match_scratch:SI 6 ""))
1948    (clobber (match_scratch:SI 7 ""))]
1949   "reload_completed && !TARGET_DEBUG_D_MODE
1950    && GP_REG_P (true_regnum (operands[0]))
1951    && GP_REG_P (true_regnum (operands[1]))"
1952   [(parallel [(set (match_dup 7)
1953                    (mult:SI (match_dup 2) (match_dup 3)))
1954               (clobber (match_dup 4))
1955               (clobber (match_dup 5))
1956               (clobber (match_dup 6))])
1957    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
1958   "")
1959
1960 ;; Splitter to copy result of MSUB to a general register
1961 (define_split
1962   [(set (match_operand:SI 0 "register_operand" "")
1963         (minus:SI (match_operand:SI 1 "register_operand" "")
1964                   (mult:SI (match_operand:SI 2 "register_operand" "")
1965                            (match_operand:SI 3 "register_operand" ""))))
1966    (clobber (match_scratch:SI 4 ""))
1967    (clobber (match_scratch:SI 5 ""))
1968    (clobber (match_scratch:SI 6 ""))
1969    (clobber (match_scratch:SI 7 ""))]
1970   "reload_completed && !TARGET_DEBUG_D_MODE
1971    && GP_REG_P (true_regnum (operands[0]))
1972    && true_regnum (operands[1]) == LO_REGNUM"
1973   [(parallel [(set (match_dup 1)
1974                    (minus:SI (match_dup 1)
1975                              (mult:SI (match_dup 2) (match_dup 3))))
1976               (clobber (match_dup 4))
1977               (clobber (match_dup 5))
1978               (clobber (match_dup 6))
1979               (clobber (match_dup 7))])
1980    (set (match_dup 0) (match_dup 1))]
1981   "")
1982
1983
1984 (define_split
1985   [(set (match_operand:SI 0 "register_operand" "")
1986         (minus:SI (match_operand:SI 1 "register_operand" "")
1987                   (mult:SI (match_operand:SI 2 "register_operand" "")
1988                            (match_operand:SI 3 "register_operand" ""))))
1989    (clobber (match_scratch:SI 4 ""))
1990    (clobber (match_scratch:SI 5 ""))
1991    (clobber (match_scratch:SI 6 ""))
1992    (clobber (match_scratch:SI 7 ""))]
1993   "reload_completed && !TARGET_DEBUG_D_MODE
1994    && GP_REG_P (true_regnum (operands[0]))
1995    && GP_REG_P (true_regnum (operands[1]))"
1996   [(parallel [(set (match_dup 7)
1997                    (mult:SI (match_dup 2) (match_dup 3)))
1998               (clobber (match_dup 4))
1999               (clobber (match_dup 5))
2000               (clobber (match_dup 6))])
2001    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
2002   "")
2003
2004 (define_expand "muldi3"
2005   [(set (match_operand:DI 0 "register_operand" "=l")
2006         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
2007                  (match_operand:DI 2 "register_operand" "d")))
2008    (clobber (match_scratch:DI 3 "=h"))
2009    (clobber (match_scratch:DI 4 "=a"))]
2010   "TARGET_64BIT"
2011
2012   "
2013 {
2014   if (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)
2015     emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
2016   else
2017     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
2018   DONE;
2019 }")
2020
2021 ;; Don't accept both operands using se_register_operand, because if
2022 ;; both operands are sign extended we would prefer to use mult in the
2023 ;; mulsidi3 pattern.  Commutativity should permit either operand to be
2024 ;; sign extended.
2025
2026 (define_insn "muldi3_internal"
2027   [(set (match_operand:DI 0 "register_operand" "=l")
2028         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
2029                  (match_operand:DI 2 "register_operand" "d")))
2030    (clobber (match_scratch:DI 3 "=h"))
2031    (clobber (match_scratch:DI 4 "=a"))]
2032   "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16"
2033   "dmult\\t%1,%2"
2034   [(set_attr "type"     "imul")
2035    (set_attr "mode"     "DI")])
2036
2037 (define_insn "muldi3_internal2"
2038   [(set (match_operand:DI 0 "register_operand" "=d")
2039         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
2040                  (match_operand:DI 2 "register_operand" "d")))
2041    (clobber (match_scratch:DI 3 "=h"))
2042    (clobber (match_scratch:DI 4 "=l"))
2043    (clobber (match_scratch:DI 5 "=a"))]
2044   "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)"
2045   "*
2046 {
2047   if (GENERATE_MULT3_DI)
2048     output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
2049   else
2050     {
2051       rtx xoperands[10];
2052
2053       xoperands[0] = operands[0];
2054       xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM);
2055
2056       output_asm_insn (\"dmult\\t%1,%2\", operands);
2057       output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2058     }
2059   return \"\";
2060 }"
2061   [(set_attr "type"     "imul")
2062    (set_attr "mode"     "DI")
2063    (set (attr "length")
2064         (if_then_else (ne (symbol_ref "GENERATE_MULT3_DI") (const_int 0))
2065                        (const_int 4)
2066                        (const_int 12)))])       ;; mult + mflo + delay
2067
2068 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
2069
2070 (define_expand "mulsidi3"
2071   [(set (match_operand:DI 0 "register_operand" "=x")
2072         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2073                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2074   ""
2075   "
2076 {
2077   rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
2078   if (TARGET_64BIT)
2079     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
2080                                    dummy, dummy));
2081   else
2082     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
2083                                       dummy, dummy));
2084   DONE;
2085 }")
2086
2087 (define_expand "umulsidi3"
2088   [(set (match_operand:DI 0 "register_operand" "=x")
2089         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2090                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2091   ""
2092   "
2093 {
2094   rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
2095   if (TARGET_64BIT)
2096     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
2097                                    dummy, dummy));
2098   else
2099     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
2100                                       dummy, dummy));
2101   DONE;
2102 }")
2103
2104 (define_insn "mulsidi3_internal"
2105   [(set (match_operand:DI 0 "register_operand" "=x")
2106         (mult:DI (match_operator:DI 3 "extend_operator"
2107                                     [(match_operand:SI 1 "register_operand" "d")])
2108                  (match_operator:DI 4 "extend_operator"
2109                                     [(match_operand:SI 2 "register_operand" "d")])))
2110    (clobber (match_scratch:SI 5 "=a"))]
2111   "!TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2112   "*
2113 {
2114   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2115     return \"mult\\t%1,%2\";
2116   return \"multu\\t%1,%2\";
2117 }"
2118   [(set_attr "type"     "imul")
2119    (set_attr "mode"     "SI")])
2120
2121 (define_insn "mulsidi3_64bit"
2122   [(set (match_operand:DI 0 "register_operand" "=a")
2123         (mult:DI (match_operator:DI 3 "extend_operator"
2124                                     [(match_operand:SI 1 "register_operand" "d")])
2125                  (match_operator:DI 4 "extend_operator"
2126                                     [(match_operand:SI 2 "register_operand" "d")])))
2127    (clobber (match_scratch:DI 5 "=l"))
2128    (clobber (match_scratch:DI 6 "=h"))]
2129   "TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2130   "*
2131 {
2132   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2133     return \"mult\\t%1,%2\";
2134   return \"multu\\t%1,%2\";
2135 }"
2136   [(set_attr "type"     "imul")
2137    (set_attr "mode"     "SI")])
2138
2139 ;; _highpart patterns
2140 (define_expand "smulsi3_highpart"
2141   [(set (match_operand:SI 0 "register_operand" "=h")
2142         (truncate:SI
2143          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2144                                (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2145                       (const_int 32))))]
2146   ""
2147   "
2148 {
2149   rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
2150   rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
2151 #ifndef NO_MD_PROTOTYPES
2152   rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
2153 #else
2154   rtx (*genfn) ();
2155 #endif
2156   genfn = gen_xmulsi3_highpart_internal;
2157   emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2158                        dummy, dummy2));
2159   DONE;
2160 }")
2161
2162 (define_expand "umulsi3_highpart"
2163   [(set (match_operand:SI 0 "register_operand" "=h")
2164         (truncate:SI
2165          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2166                                (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2167                       (const_int 32))))]
2168   ""
2169   "
2170 {
2171   rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
2172   rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
2173 #ifndef NO_MD_PROTOTYPES
2174   rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
2175 #else
2176   rtx (*genfn) ();
2177 #endif
2178   genfn = gen_xmulsi3_highpart_internal;
2179   emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2180                        dummy, dummy2));
2181   DONE;
2182 }")
2183
2184 (define_insn "xmulsi3_highpart_internal"
2185   [(set (match_operand:SI 0 "register_operand" "=h")
2186         (truncate:SI
2187          (match_operator:DI 5 "highpart_shift_operator"
2188                             [(mult:DI (match_operator:DI 3 "extend_operator"
2189                                                          [(match_operand:SI 1 "register_operand" "d")])
2190                                       (match_operator:DI 4 "extend_operator"
2191                                                          [(match_operand:SI 2 "register_operand" "d")]))
2192                              (const_int 32)])))
2193    (clobber (match_scratch:SI 6 "=l"))
2194    (clobber (match_scratch:SI 7 "=a"))]
2195   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
2196   "*
2197 {
2198   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2199     return \"mult\\t%1,%2\";
2200   else
2201     return \"multu\\t%1,%2\";
2202 }"
2203   [(set_attr "type"     "imul")
2204    (set_attr "mode"     "SI")])
2205
2206 (define_insn "smuldi3_highpart"
2207   [(set (match_operand:DI 0 "register_operand" "=h")
2208         (truncate:DI
2209          (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2210                                (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2211                       (const_int 64))))
2212    (clobber (match_scratch:DI 3 "=l"))
2213    (clobber (match_scratch:DI 4 "=a"))]
2214   "TARGET_64BIT"
2215   "dmult\\t%1,%2"
2216   [(set_attr "type"     "imul")
2217    (set_attr "mode"     "DI")])
2218
2219 (define_insn "umuldi3_highpart"
2220   [(set (match_operand:DI 0 "register_operand" "=h")
2221         (truncate:DI
2222          (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2223                                (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2224                       (const_int 64))))
2225    (clobber (match_scratch:DI 3 "=l"))
2226    (clobber (match_scratch:DI 4 "=a"))]
2227   "TARGET_64BIT"
2228   "dmultu\\t%1,%2"
2229   [(set_attr "type"     "imul")
2230    (set_attr "mode"     "DI")])
2231
2232 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2233 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
2234
2235 (define_insn "madsi"
2236   [(set (match_operand:SI 0 "register_operand" "+l")
2237         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2238                           (match_operand:SI 2 "register_operand" "d"))
2239                  (match_dup 0)))
2240    (clobber (match_scratch:SI 3 "=h"))
2241    (clobber (match_scratch:SI 4 "=a"))]
2242   "TARGET_MAD"
2243   "mad\\t%1,%2"
2244   [(set_attr "type"     "imul")
2245    (set_attr "mode"     "SI")])
2246
2247 (define_insn "*mul_acc_di"
2248   [(set (match_operand:DI 0 "register_operand" "+x")
2249         (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2250                            [(match_operand:SI 1 "register_operand" "d")])
2251                           (match_operator:DI 4 "extend_operator"
2252                            [(match_operand:SI 2 "register_operand" "d")]))
2253                  (match_dup 0)))
2254    (clobber (match_scratch:SI 5 "=a"))]
2255   "TARGET_MAD
2256    && ! TARGET_64BIT
2257    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2258   "*
2259 {
2260   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2261     return \"mad\\t%1,%2\";
2262   else
2263     return \"madu\\t%1,%2\";
2264 }"
2265   [(set_attr "type"     "imul")
2266    (set_attr "mode"     "SI")])
2267
2268 (define_insn "*mul_acc_64bit_di"
2269   [(set (match_operand:DI 0 "register_operand" "+a")
2270         (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2271                            [(match_operand:SI 1 "register_operand" "d")])
2272                           (match_operator:DI 4 "extend_operator"
2273                            [(match_operand:SI 2 "register_operand" "d")]))
2274                  (match_dup 0)))
2275    (clobber (match_scratch:SI 5 "=h"))
2276    (clobber (match_scratch:SI 6 "=l"))]
2277   "TARGET_MAD
2278    && TARGET_64BIT
2279    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2280   "*
2281 {
2282   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2283     return \"mad\\t%1,%2\";
2284   else
2285     return \"madu\\t%1,%2\";
2286 }"
2287   [(set_attr "type"     "imul")
2288    (set_attr "mode"     "SI")])
2289
2290 ;; Floating point multiply accumulate instructions.
2291
2292 (define_insn ""
2293   [(set (match_operand:DF 0 "register_operand" "=f")
2294         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2295                           (match_operand:DF 2 "register_operand" "f"))
2296                  (match_operand:DF 3 "register_operand" "f")))]
2297   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2298   "madd.d\\t%0,%3,%1,%2"
2299   [(set_attr "type"     "fmadd")
2300    (set_attr "mode"     "DF")])
2301
2302 (define_insn ""
2303   [(set (match_operand:SF 0 "register_operand" "=f")
2304         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2305                           (match_operand:SF 2 "register_operand" "f"))
2306                  (match_operand:SF 3 "register_operand" "f")))]
2307   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2308   "madd.s\\t%0,%3,%1,%2"
2309   [(set_attr "type"     "fmadd")
2310    (set_attr "mode"     "SF")])
2311
2312 (define_insn ""
2313   [(set (match_operand:DF 0 "register_operand" "=f")
2314         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2315                            (match_operand:DF 2 "register_operand" "f"))
2316                   (match_operand:DF 3 "register_operand" "f")))]
2317   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2318   "msub.d\\t%0,%3,%1,%2"
2319   [(set_attr "type"     "fmadd")
2320    (set_attr "mode"     "DF")])
2321
2322 (define_insn ""
2323   [(set (match_operand:SF 0 "register_operand" "=f")
2324         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2325                            (match_operand:SF 2 "register_operand" "f"))
2326                   (match_operand:SF 3 "register_operand" "f")))]
2327
2328   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2329   "msub.s\\t%0,%3,%1,%2"
2330   [(set_attr "type"     "fmadd")
2331    (set_attr "mode"     "SF")])
2332
2333 (define_insn ""
2334   [(set (match_operand:DF 0 "register_operand" "=f")
2335         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2336                                   (match_operand:DF 2 "register_operand" "f"))
2337                          (match_operand:DF 3 "register_operand" "f"))))]
2338   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2339   "nmadd.d\\t%0,%3,%1,%2"
2340   [(set_attr "type"     "fmadd")
2341    (set_attr "mode"     "DF")])
2342
2343 (define_insn ""
2344   [(set (match_operand:SF 0 "register_operand" "=f")
2345         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2346                                   (match_operand:SF 2 "register_operand" "f"))
2347                          (match_operand:SF 3 "register_operand" "f"))))]
2348   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2349   "nmadd.s\\t%0,%3,%1,%2"
2350   [(set_attr "type"     "fmadd")
2351    (set_attr "mode"     "SF")])
2352
2353 (define_insn ""
2354   [(set (match_operand:DF 0 "register_operand" "=f")
2355         (minus:DF (match_operand:DF 1 "register_operand" "f")
2356                   (mult:DF (match_operand:DF 2 "register_operand" "f")
2357                            (match_operand:DF 3 "register_operand" "f"))))]
2358   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2359   "nmsub.d\\t%0,%1,%2,%3"
2360   [(set_attr "type"     "fmadd")
2361    (set_attr "mode"     "DF")])
2362
2363 (define_insn ""
2364   [(set (match_operand:SF 0 "register_operand" "=f")
2365         (minus:SF (match_operand:SF 1 "register_operand" "f")
2366                   (mult:SF (match_operand:SF 2 "register_operand" "f")
2367                            (match_operand:SF 3 "register_operand" "f"))))]
2368   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2369   "nmsub.s\\t%0,%1,%2,%3"
2370   [(set_attr "type"     "fmadd")
2371    (set_attr "mode"     "SF")])
2372 \f
2373 ;;
2374 ;;  ....................
2375 ;;
2376 ;;      DIVISION and REMAINDER
2377 ;;
2378 ;;  ....................
2379 ;;
2380
2381 (define_insn "divdf3"
2382   [(set (match_operand:DF 0 "register_operand" "=f")
2383         (div:DF (match_operand:DF 1 "register_operand" "f")
2384                 (match_operand:DF 2 "register_operand" "f")))]
2385   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2386   "div.d\\t%0,%1,%2"
2387   [(set_attr "type"     "fdiv")
2388    (set_attr "mode"     "DF")])
2389
2390 (define_insn "divsf3"
2391   [(set (match_operand:SF 0 "register_operand" "=f")
2392         (div:SF (match_operand:SF 1 "register_operand" "f")
2393                 (match_operand:SF 2 "register_operand" "f")))]
2394   "TARGET_HARD_FLOAT"
2395   "div.s\\t%0,%1,%2"
2396   [(set_attr "type"     "fdiv")
2397    (set_attr "mode"     "SF")])
2398
2399 (define_insn ""
2400   [(set (match_operand:DF 0 "register_operand" "=f")
2401         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2402                 (match_operand:DF 2 "register_operand" "f")))]
2403   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2404   "recip.d\\t%0,%2"
2405   [(set_attr "type"     "fdiv")
2406    (set_attr "mode"     "DF")])
2407
2408 (define_insn ""
2409   [(set (match_operand:SF 0 "register_operand" "=f")
2410         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2411                 (match_operand:SF 2 "register_operand" "f")))]
2412   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2413   "recip.s\\t%0,%2"
2414   [(set_attr "type"     "fdiv")
2415    (set_attr "mode"     "SF")])
2416
2417 ;; If optimizing, prefer the divmod functions over separate div and
2418 ;; mod functions, since this will allow using one instruction for both
2419 ;; the quotient and remainder.  At present, the divmod is not moved out
2420 ;; of loops if it is constant within the loop, so allow -mdebugc to
2421 ;; use the old method of doing things.
2422
2423 ;; 64 is the multiply/divide hi register
2424 ;; 65 is the multiply/divide lo register
2425
2426 ;; ??? We can't accept constants here, because the MIPS assembler will replace
2427 ;; a divide by power of 2 with a shift, and then the remainder is no longer
2428 ;; available.
2429
2430 (define_expand "divmodsi4"
2431   [(set (match_operand:SI 0 "register_operand" "=d")
2432         (div:SI (match_operand:SI 1 "register_operand" "d")
2433                 (match_operand:SI 2 "register_operand" "d")))
2434    (set (match_operand:SI 3 "register_operand" "=d")
2435         (mod:SI (match_dup 1)
2436                 (match_dup 2)))
2437    (clobber (match_scratch:SI 4 "=l"))
2438    (clobber (match_scratch:SI 5 "=h"))
2439    (clobber (match_scratch:SI 6 "=a"))]
2440   "optimize"
2441   "
2442 {
2443   emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
2444              operands[3]));
2445   if (!TARGET_NO_CHECK_ZERO_DIV)
2446     {
2447       emit_insn (gen_div_trap (operands[2],
2448                                GEN_INT (0),
2449                                GEN_INT (0x7)));
2450     }
2451   if (TARGET_CHECK_RANGE_DIV)
2452     {
2453       emit_insn (gen_div_trap (operands[2],
2454                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2455                                GEN_INT (0x6)));
2456       emit_insn (gen_div_trap (operands[2],
2457                                copy_to_mode_reg (SImode,
2458                                                  GEN_INT
2459                                                  (trunc_int_for_mode
2460                                                   (BITMASK_HIGH, SImode))),
2461                                GEN_INT (0x6)));
2462     }
2463
2464   DONE;
2465 }")
2466
2467 (define_insn "divmodsi4_internal"
2468   [(set (match_operand:SI 0 "register_operand" "=l")
2469         (div:SI (match_operand:SI 1 "register_operand" "d")
2470                 (match_operand:SI 2 "register_operand" "d")))
2471    (set (match_operand:SI 3 "register_operand" "=h")
2472         (mod:SI (match_dup 1)
2473                 (match_dup 2)))
2474    (clobber (match_scratch:SI 4 "=a"))]
2475   "optimize"
2476   "div\\t$0,%1,%2"
2477   [(set_attr "type"     "idiv")
2478    (set_attr "mode"     "SI")])
2479
2480 (define_expand "divmoddi4"
2481   [(set (match_operand:DI 0 "register_operand" "=d")
2482         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2483                 (match_operand:DI 2 "se_register_operand" "d")))
2484    (set (match_operand:DI 3 "register_operand" "=d")
2485         (mod:DI (match_dup 1)
2486                 (match_dup 2)))
2487    (clobber (match_scratch:DI 4 "=l"))
2488    (clobber (match_scratch:DI 5 "=h"))
2489    (clobber (match_scratch:DI 6 "=a"))]
2490   "TARGET_64BIT && optimize"
2491   "
2492 {
2493   emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
2494              operands[3]));
2495   if (!TARGET_NO_CHECK_ZERO_DIV)
2496     {
2497       emit_insn (gen_div_trap (operands[2],
2498                                GEN_INT (0),
2499                                GEN_INT (0x7)));
2500     }
2501   if (TARGET_CHECK_RANGE_DIV)
2502     {
2503       emit_insn (gen_div_trap (operands[2],
2504                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2505                                GEN_INT (0x6)));
2506       emit_insn (gen_div_trap (operands[2],
2507                                copy_to_mode_reg (DImode,
2508                                                  GEN_INT (BITMASK_HIGH)),
2509                                GEN_INT (0x6)));
2510     }
2511
2512   DONE;
2513 }")
2514
2515 (define_insn "divmoddi4_internal"
2516   [(set (match_operand:DI 0 "register_operand" "=l")
2517         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2518                 (match_operand:DI 2 "se_register_operand" "d")))
2519    (set (match_operand:DI 3 "register_operand" "=h")
2520         (mod:DI (match_dup 1)
2521                 (match_dup 2)))
2522    (clobber (match_scratch:DI 4 "=a"))]
2523   "TARGET_64BIT && optimize"
2524   "ddiv\\t$0,%1,%2"
2525   [(set_attr "type"     "idiv")
2526    (set_attr "mode"     "SI")])
2527
2528 (define_expand "udivmodsi4"
2529   [(set (match_operand:SI 0 "register_operand" "=d")
2530         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2531                  (match_operand:SI 2 "register_operand" "d")))
2532    (set (match_operand:SI 3 "register_operand" "=d")
2533         (umod:SI (match_dup 1)
2534                  (match_dup 2)))
2535    (clobber (match_scratch:SI 4 "=l"))
2536    (clobber (match_scratch:SI 5 "=h"))
2537    (clobber (match_scratch:SI 6 "=a"))]
2538   "optimize"
2539   "
2540 {
2541   emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
2542                                       operands[3]));
2543   if (!TARGET_NO_CHECK_ZERO_DIV)
2544     {
2545       emit_insn (gen_div_trap (operands[2],
2546                                GEN_INT (0),
2547                                GEN_INT (0x7)));
2548     }
2549
2550   DONE;
2551 }")
2552
2553 (define_insn "udivmodsi4_internal"
2554   [(set (match_operand:SI 0 "register_operand" "=l")
2555         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2556                  (match_operand:SI 2 "register_operand" "d")))
2557    (set (match_operand:SI 3 "register_operand" "=h")
2558         (umod:SI (match_dup 1)
2559                  (match_dup 2)))
2560    (clobber (match_scratch:SI 4 "=a"))]
2561   "optimize"
2562   "divu\\t$0,%1,%2"
2563   [(set_attr "type"     "idiv")
2564    (set_attr "mode"     "SI")])
2565
2566 (define_expand "udivmoddi4"
2567   [(set (match_operand:DI 0 "register_operand" "=d")
2568         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2569                  (match_operand:DI 2 "se_register_operand" "d")))
2570    (set (match_operand:DI 3 "register_operand" "=d")
2571         (umod:DI (match_dup 1)
2572                  (match_dup 2)))
2573    (clobber (match_scratch:DI 4 "=l"))
2574    (clobber (match_scratch:DI 5 "=h"))
2575    (clobber (match_scratch:DI 6 "=a"))]
2576   "TARGET_64BIT && optimize"
2577   "
2578 {
2579   emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
2580                                       operands[3]));
2581   if (!TARGET_NO_CHECK_ZERO_DIV)
2582     {
2583       emit_insn (gen_div_trap (operands[2],
2584                                GEN_INT (0),
2585                                GEN_INT (0x7)));
2586     }
2587
2588   DONE;
2589 }")
2590
2591 (define_insn "udivmoddi4_internal"
2592   [(set (match_operand:DI 0 "register_operand" "=l")
2593         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2594                  (match_operand:DI 2 "se_register_operand" "d")))
2595    (set (match_operand:DI 3 "register_operand" "=h")
2596         (umod:DI (match_dup 1)
2597                  (match_dup 2)))
2598    (clobber (match_scratch:DI 4 "=a"))]
2599   "TARGET_64BIT && optimize"
2600   "ddivu\\t$0,%1,%2"
2601   [(set_attr "type"     "idiv")
2602    (set_attr "mode"     "SI")])
2603
2604 ;; Division trap
2605
2606 (define_expand "div_trap"
2607   [(trap_if (eq (match_operand 0 "register_operand" "d")
2608                 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2609             (match_operand 2 "immediate_operand" ""))]
2610   ""
2611   "
2612 {
2613   if (TARGET_MIPS16)
2614     emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
2615   else
2616     emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
2617   DONE;
2618 }")
2619
2620 (define_insn "div_trap_normal"
2621   [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2622                 (match_operand 1 "true_reg_or_0_operand" "d,J"))
2623             (match_operand 2 "immediate_operand" ""))]
2624   "!TARGET_MIPS16"
2625   "*
2626 {
2627   rtx link;
2628   int have_dep_anti = 0;
2629
2630   /* For divmod if one division is not needed then we don't need an extra
2631      divide by zero trap, which is anti dependent on previous trap */
2632   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2633
2634     if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2635         && GET_CODE (XEXP (link, 0)) == INSN
2636         && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2637         && which_alternative == 1)
2638       have_dep_anti = 1;
2639   if (! have_dep_anti)
2640     {
2641       if (GENERATE_BRANCHLIKELY)
2642         {
2643           if (which_alternative == 1)
2644             return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2645           else
2646             return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2647         }
2648       else
2649         {
2650           if (which_alternative == 1)
2651             return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2652           else
2653             return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2654         }
2655     }
2656   return \"\";
2657 }"
2658   [(set_attr "type" "unknown")
2659    (set_attr "length" "12")])
2660
2661
2662 ;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
2663
2664 (define_insn "div_trap_mips16"
2665   [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2666                 (match_operand 1 "true_reg_or_0_operand" "d,J"))
2667             (match_operand 2 "immediate_operand" ""))
2668    (clobber (reg:SI 24))]
2669   "TARGET_MIPS16"
2670   "*
2671 {
2672   rtx link;
2673   int have_dep_anti = 0;
2674
2675   /* For divmod if one division is not needed then we don't need an extra
2676      divide by zero trap, which is anti dependent on previous trap */
2677   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2678
2679     if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2680         && GET_CODE (XEXP (link, 0)) == INSN
2681         && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2682         && which_alternative == 1)
2683       have_dep_anti = 1;
2684   if (! have_dep_anti)
2685     {
2686       /* No branch delay slots on mips16.  */
2687       if (which_alternative == 1)
2688         return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2689       else
2690         return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2691     }
2692   return \"\";
2693 }"
2694   [(set_attr "type" "unknown")
2695    (set_attr "length" "12")])
2696
2697 (define_expand "divsi3"
2698   [(set (match_operand:SI 0 "register_operand" "=l")
2699         (div:SI (match_operand:SI 1 "register_operand" "d")
2700                 (match_operand:SI 2 "register_operand" "d")))
2701    (clobber (match_scratch:SI 3 "=h"))
2702    (clobber (match_scratch:SI 4 "=a"))]
2703   "!optimize"
2704   "
2705 {
2706   emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
2707   if (!TARGET_NO_CHECK_ZERO_DIV)
2708     {
2709       emit_insn (gen_div_trap (operands[2],
2710                                GEN_INT (0),
2711                                GEN_INT (0x7)));
2712     }
2713   if (TARGET_CHECK_RANGE_DIV)
2714     {
2715       emit_insn (gen_div_trap (operands[2],
2716                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2717                                GEN_INT (0x6)));
2718       emit_insn (gen_div_trap (operands[2],
2719                                copy_to_mode_reg (SImode,
2720                                                  GEN_INT
2721                                                  (trunc_int_for_mode
2722                                                   (BITMASK_HIGH, SImode))),
2723                                GEN_INT (0x6)));
2724     }
2725
2726   DONE;
2727 }")
2728
2729 (define_insn "divsi3_internal"
2730   [(set (match_operand:SI 0 "register_operand" "=l")
2731         (div:SI (match_operand:SI 1 "register_operand" "d")
2732                 (match_operand:SI 2 "nonmemory_operand" "di")))
2733    (clobber (match_scratch:SI 3 "=h"))
2734    (clobber (match_scratch:SI 4 "=a"))]
2735   "!optimize"
2736   "div\\t$0,%1,%2"
2737   [(set_attr "type"     "idiv")
2738    (set_attr "mode"     "SI")])
2739
2740 (define_expand "divdi3"
2741   [(set (match_operand:DI 0 "register_operand" "=l")
2742         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2743                 (match_operand:DI 2 "se_register_operand" "d")))
2744    (clobber (match_scratch:DI 3 "=h"))
2745    (clobber (match_scratch:DI 4 "=a"))]
2746   "TARGET_64BIT && !optimize"
2747   "
2748 {
2749   emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
2750   if (!TARGET_NO_CHECK_ZERO_DIV)
2751     {
2752       emit_insn (gen_div_trap (operands[2],
2753                                GEN_INT (0),
2754                                GEN_INT (0x7)));
2755     }
2756   if (TARGET_CHECK_RANGE_DIV)
2757     {
2758       emit_insn (gen_div_trap (operands[2],
2759                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2760                                GEN_INT (0x6)));
2761       emit_insn (gen_div_trap (operands[2],
2762                                copy_to_mode_reg (DImode,
2763                                                  GEN_INT (BITMASK_HIGH)),
2764                                GEN_INT (0x6)));
2765     }
2766
2767   DONE;
2768 }")
2769
2770 (define_insn "divdi3_internal"
2771   [(set (match_operand:DI 0 "register_operand" "=l")
2772         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2773                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2774    (clobber (match_scratch:SI 3 "=h"))
2775    (clobber (match_scratch:SI 4 "=a"))]
2776   "TARGET_64BIT && !optimize"
2777   "ddiv\\t$0,%1,%2"
2778   [(set_attr "type"     "idiv")
2779    (set_attr "mode"     "DI")])
2780
2781 (define_expand "modsi3"
2782   [(set (match_operand:SI 0 "register_operand" "=h")
2783         (mod:SI (match_operand:SI 1 "register_operand" "d")
2784                 (match_operand:SI 2 "register_operand" "d")))
2785    (clobber (match_scratch:SI 3 "=l"))
2786    (clobber (match_scratch:SI 4 "=a"))]
2787   "!optimize"
2788   "
2789 {
2790   emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
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   if (TARGET_CHECK_RANGE_DIV)
2798     {
2799       emit_insn (gen_div_trap (operands[2],
2800                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2801                                GEN_INT (0x6)));
2802       emit_insn (gen_div_trap (operands[2],
2803                                copy_to_mode_reg (SImode,
2804                                                  GEN_INT
2805                                                  (trunc_int_for_mode
2806                                                   (BITMASK_HIGH, SImode))),
2807                                GEN_INT (0x6)));
2808     }
2809
2810   DONE;
2811 }")
2812
2813 (define_insn "modsi3_internal"
2814   [(set (match_operand:SI 0 "register_operand" "=h")
2815         (mod:SI (match_operand:SI 1 "register_operand" "d")
2816                 (match_operand:SI 2 "nonmemory_operand" "di")))
2817    (clobber (match_scratch:SI 3 "=l"))
2818    (clobber (match_scratch:SI 4 "=a"))]
2819   "!optimize"
2820   "div\\t$0,%1,%2"
2821   [(set_attr "type"     "idiv")
2822    (set_attr "mode"     "SI")])
2823
2824 (define_expand "moddi3"
2825   [(set (match_operand:DI 0 "register_operand" "=h")
2826         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2827                 (match_operand:DI 2 "se_register_operand" "d")))
2828    (clobber (match_scratch:DI 3 "=l"))
2829    (clobber (match_scratch:DI 4 "=a"))]
2830   "TARGET_64BIT && !optimize"
2831   "
2832 {
2833   emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
2834   if (!TARGET_NO_CHECK_ZERO_DIV)
2835     {
2836       emit_insn (gen_div_trap (operands[2],
2837                                GEN_INT (0),
2838                                GEN_INT (0x7)));
2839     }
2840   if (TARGET_CHECK_RANGE_DIV)
2841     {
2842       emit_insn (gen_div_trap (operands[2],
2843                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2844                                GEN_INT (0x6)));
2845       emit_insn (gen_div_trap (operands[2],
2846                                copy_to_mode_reg (DImode,
2847                                                  GEN_INT (BITMASK_HIGH)),
2848                                GEN_INT (0x6)));
2849     }
2850
2851   DONE;
2852 }")
2853
2854 (define_insn "moddi3_internal"
2855   [(set (match_operand:DI 0 "register_operand" "=h")
2856         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2857                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2858    (clobber (match_scratch:SI 3 "=l"))
2859    (clobber (match_scratch:SI 4 "=a"))]
2860   "TARGET_64BIT && !optimize"
2861   "ddiv\\t$0,%1,%2"
2862   [(set_attr "type"     "idiv")
2863    (set_attr "mode"     "DI")])
2864
2865 (define_expand "udivsi3"
2866   [(set (match_operand:SI 0 "register_operand" "=l")
2867         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2868                  (match_operand:SI 2 "register_operand" "d")))
2869    (clobber (match_scratch:SI 3 "=h"))
2870    (clobber (match_scratch:SI 4 "=a"))]
2871   "!optimize"
2872   "
2873 {
2874   emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
2875   if (!TARGET_NO_CHECK_ZERO_DIV)
2876     {
2877       emit_insn (gen_div_trap (operands[2],
2878                                GEN_INT (0),
2879                                GEN_INT (0x7)));
2880     }
2881
2882   DONE;
2883 }")
2884
2885 (define_insn "udivsi3_internal"
2886   [(set (match_operand:SI 0 "register_operand" "=l")
2887         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2888                  (match_operand:SI 2 "nonmemory_operand" "di")))
2889    (clobber (match_scratch:SI 3 "=h"))
2890    (clobber (match_scratch:SI 4 "=a"))]
2891   "!optimize"
2892   "divu\\t$0,%1,%2"
2893   [(set_attr "type"     "idiv")
2894    (set_attr "mode"     "SI")])
2895
2896 (define_expand "udivdi3"
2897   [(set (match_operand:DI 0 "register_operand" "=l")
2898         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2899                  (match_operand:DI 2 "se_register_operand" "di")))
2900    (clobber (match_scratch:DI 3 "=h"))
2901    (clobber (match_scratch:DI 4 "=a"))]
2902   "TARGET_64BIT && !optimize"
2903   "
2904 {
2905   emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
2906   if (!TARGET_NO_CHECK_ZERO_DIV)
2907     {
2908       emit_insn (gen_div_trap (operands[2],
2909                                GEN_INT (0),
2910                                GEN_INT (0x7)));
2911     }
2912
2913   DONE;
2914 }")
2915
2916 (define_insn "udivdi3_internal"
2917   [(set (match_operand:DI 0 "register_operand" "=l")
2918         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2919                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
2920    (clobber (match_scratch:SI 3 "=h"))
2921    (clobber (match_scratch:SI 4 "=a"))]
2922   "TARGET_64BIT && !optimize"
2923   "ddivu\\t$0,%1,%2"
2924   [(set_attr "type"     "idiv")
2925    (set_attr "mode"     "DI")])
2926
2927 (define_expand "umodsi3"
2928   [(set (match_operand:SI 0 "register_operand" "=h")
2929         (umod:SI (match_operand:SI 1 "register_operand" "d")
2930                  (match_operand:SI 2 "register_operand" "d")))
2931    (clobber (match_scratch:SI 3 "=l"))
2932    (clobber (match_scratch:SI 4 "=a"))]
2933   "!optimize"
2934   "
2935 {
2936   emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
2937   if (!TARGET_NO_CHECK_ZERO_DIV)
2938     {
2939       emit_insn (gen_div_trap (operands[2],
2940                                GEN_INT (0),
2941                                GEN_INT (0x7)));
2942     }
2943
2944   DONE;
2945 }")
2946
2947 (define_insn "umodsi3_internal"
2948   [(set (match_operand:SI 0 "register_operand" "=h")
2949         (umod:SI (match_operand:SI 1 "register_operand" "d")
2950                  (match_operand:SI 2 "nonmemory_operand" "di")))
2951    (clobber (match_scratch:SI 3 "=l"))
2952    (clobber (match_scratch:SI 4 "=a"))]
2953   "!optimize"
2954   "divu\\t$0,%1,%2"
2955   [(set_attr "type"     "idiv")
2956    (set_attr "mode"     "SI")])
2957
2958 (define_expand "umoddi3"
2959   [(set (match_operand:DI 0 "register_operand" "=h")
2960         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2961                  (match_operand:DI 2 "se_register_operand" "di")))
2962    (clobber (match_scratch:DI 3 "=l"))
2963    (clobber (match_scratch:DI 4 "=a"))]
2964   "TARGET_64BIT && !optimize"
2965   "
2966 {
2967   emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
2968   if (!TARGET_NO_CHECK_ZERO_DIV)
2969     {
2970       emit_insn (gen_div_trap (operands[2],
2971                                GEN_INT (0),
2972                                GEN_INT (0x7)));
2973     }
2974
2975   DONE;
2976 }")
2977
2978 (define_insn "umoddi3_internal"
2979   [(set (match_operand:DI 0 "register_operand" "=h")
2980         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2981                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
2982    (clobber (match_scratch:SI 3 "=l"))
2983    (clobber (match_scratch:SI 4 "=a"))]
2984   "TARGET_64BIT && !optimize"
2985   "ddivu\\t$0,%1,%2"
2986   [(set_attr "type"     "idiv")
2987    (set_attr "mode"     "DI")])
2988 \f
2989 ;;
2990 ;;  ....................
2991 ;;
2992 ;;      SQUARE ROOT
2993 ;;
2994 ;;  ....................
2995
2996 (define_insn "sqrtdf2"
2997   [(set (match_operand:DF 0 "register_operand" "=f")
2998         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2999   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
3000   "sqrt.d\\t%0,%1"
3001   [(set_attr "type"     "fsqrt")
3002    (set_attr "mode"     "DF")])
3003
3004 (define_insn "sqrtsf2"
3005   [(set (match_operand:SF 0 "register_operand" "=f")
3006         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
3007   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
3008   "sqrt.s\\t%0,%1"
3009   [(set_attr "type"     "fsqrt")
3010    (set_attr "mode"     "SF")])
3011
3012 (define_insn ""
3013   [(set (match_operand:DF 0 "register_operand" "=f")
3014         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
3015                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
3016   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
3017   "rsqrt.d\\t%0,%2"
3018   [(set_attr "type"     "fsqrt")
3019    (set_attr "mode"     "DF")])
3020
3021 (define_insn ""
3022   [(set (match_operand:SF 0 "register_operand" "=f")
3023         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
3024                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
3025   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
3026   "rsqrt.s\\t%0,%2"
3027   [(set_attr "type"     "fsqrt")
3028    (set_attr "mode"     "SF")])
3029
3030 \f
3031 ;;
3032 ;;  ....................
3033 ;;
3034 ;;      ABSOLUTE VALUE
3035 ;;
3036 ;;  ....................
3037
3038 ;; Do not use the integer abs macro instruction, since that signals an
3039 ;; exception on -2147483648 (sigh).
3040
3041 (define_insn "abssi2"
3042   [(set (match_operand:SI 0 "register_operand" "=d")
3043         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
3044   "!TARGET_MIPS16"
3045   "*
3046 {
3047   dslots_jump_total++;
3048   dslots_jump_filled++;
3049   operands[2] = const0_rtx;
3050
3051   if (REGNO (operands[0]) == REGNO (operands[1]))
3052     {
3053       if (GENERATE_BRANCHLIKELY)
3054         return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
3055       else
3056         return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
3057     }
3058   else
3059     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
3060 }"
3061   [(set_attr "type"     "multi")
3062    (set_attr "mode"     "SI")
3063    (set_attr "length"   "12")])
3064
3065 (define_insn "absdi2"
3066   [(set (match_operand:DI 0 "register_operand" "=d")
3067         (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
3068   "TARGET_64BIT && !TARGET_MIPS16"
3069   "*
3070 {
3071   unsigned int regno1;
3072   dslots_jump_total++;
3073   dslots_jump_filled++;
3074   operands[2] = const0_rtx;
3075
3076   if (GET_CODE (operands[1]) == REG)
3077     regno1 = REGNO (operands[1]);
3078   else
3079     regno1 = REGNO (XEXP (operands[1], 0));
3080
3081   if (REGNO (operands[0]) == regno1)
3082     return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3083   else
3084     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3085 }"
3086   [(set_attr "type"     "multi")
3087    (set_attr "mode"     "DI")
3088    (set_attr "length"   "12")])
3089
3090 (define_insn "absdf2"
3091   [(set (match_operand:DF 0 "register_operand" "=f")
3092         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
3093   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3094   "abs.d\\t%0,%1"
3095   [(set_attr "type"     "fabs")
3096    (set_attr "mode"     "DF")])
3097
3098 (define_insn "abssf2"
3099   [(set (match_operand:SF 0 "register_operand" "=f")
3100         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
3101   "TARGET_HARD_FLOAT"
3102   "abs.s\\t%0,%1"
3103   [(set_attr "type"     "fabs")
3104    (set_attr "mode"     "SF")])
3105
3106 \f
3107 ;;
3108 ;;  ....................
3109 ;;
3110 ;;      FIND FIRST BIT INSTRUCTION
3111 ;;
3112 ;;  ....................
3113 ;;
3114
3115 (define_insn "ffssi2"
3116   [(set (match_operand:SI 0 "register_operand" "=&d")
3117         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
3118    (clobber (match_scratch:SI 2 "=&d"))
3119    (clobber (match_scratch:SI 3 "=&d"))]
3120   "!TARGET_MIPS16"
3121   "*
3122 {
3123   dslots_jump_total += 2;
3124   dslots_jump_filled += 2;
3125   operands[4] = const0_rtx;
3126
3127   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3128     return \"%(\\
3129 move\\t%0,%z4\\n\\
3130 \\tbeq\\t%1,%z4,2f\\n\\
3131 %~1:\\tand\\t%2,%1,0x0001\\n\\
3132 \\taddu\\t%0,%0,1\\n\\
3133 \\tbeq\\t%2,%z4,1b\\n\\
3134 \\tsrl\\t%1,%1,1\\n\\
3135 %~2:%)\";
3136
3137   return \"%(\\
3138 move\\t%0,%z4\\n\\
3139 \\tmove\\t%3,%1\\n\\
3140 \\tbeq\\t%3,%z4,2f\\n\\
3141 %~1:\\tand\\t%2,%3,0x0001\\n\\
3142 \\taddu\\t%0,%0,1\\n\\
3143 \\tbeq\\t%2,%z4,1b\\n\\
3144 \\tsrl\\t%3,%3,1\\n\\
3145 %~2:%)\";
3146 }"
3147   [(set_attr "type"     "multi")
3148    (set_attr "mode"     "SI")
3149    (set_attr "length"   "12")])
3150
3151 (define_insn "ffsdi2"
3152   [(set (match_operand:DI 0 "register_operand" "=&d")
3153         (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
3154    (clobber (match_scratch:DI 2 "=&d"))
3155    (clobber (match_scratch:DI 3 "=&d"))]
3156   "TARGET_64BIT && !TARGET_MIPS16"
3157   "*
3158 {
3159   dslots_jump_total += 2;
3160   dslots_jump_filled += 2;
3161   operands[4] = const0_rtx;
3162
3163   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3164     return \"%(\\
3165 move\\t%0,%z4\\n\\
3166 \\tbeq\\t%1,%z4,2f\\n\\
3167 %~1:\\tand\\t%2,%1,0x0001\\n\\
3168 \\tdaddu\\t%0,%0,1\\n\\
3169 \\tbeq\\t%2,%z4,1b\\n\\
3170 \\tdsrl\\t%1,%1,1\\n\\
3171 %~2:%)\";
3172
3173   return \"%(\\
3174 move\\t%0,%z4\\n\\
3175 \\tmove\\t%3,%1\\n\\
3176 \\tbeq\\t%3,%z4,2f\\n\\
3177 %~1:\\tand\\t%2,%3,0x0001\\n\\
3178 \\tdaddu\\t%0,%0,1\\n\\
3179 \\tbeq\\t%2,%z4,1b\\n\\
3180 \\tdsrl\\t%3,%3,1\\n\\
3181 %~2:%)\";
3182 }"
3183   [(set_attr "type"     "multi")
3184    (set_attr "mode"     "DI")
3185    (set_attr "length"   "24")])
3186
3187 \f
3188 ;;
3189 ;;  ....................
3190 ;;
3191 ;;      NEGATION and ONE'S COMPLEMENT
3192 ;;
3193 ;;  ....................
3194
3195 (define_insn "negsi2"
3196   [(set (match_operand:SI 0 "register_operand" "=d")
3197         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
3198   ""
3199   "*
3200 {
3201   if (TARGET_MIPS16)
3202     return \"neg\\t%0,%1\";
3203   operands[2] = const0_rtx;
3204   return \"subu\\t%0,%z2,%1\";
3205 }"
3206   [(set_attr "type"     "arith")
3207    (set_attr "mode"     "SI")])
3208
3209 (define_expand "negdi2"
3210   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
3211                    (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
3212               (clobber (match_dup 2))])]
3213   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3214   "
3215 {
3216   if (TARGET_64BIT)
3217     {
3218       emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
3219       DONE;
3220     }
3221
3222   operands[2] = gen_reg_rtx (SImode);
3223 }")
3224
3225 (define_insn "negdi2_internal"
3226   [(set (match_operand:DI 0 "register_operand" "=d")
3227         (neg:DI (match_operand:DI 1 "register_operand" "d")))
3228    (clobber (match_operand:SI 2 "register_operand" "=d"))]
3229   "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
3230   "*
3231 {
3232   operands[3] = const0_rtx;
3233   return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
3234 }"
3235   [(set_attr "type"     "darith")
3236    (set_attr "mode"     "DI")
3237    (set_attr "length"   "16")])
3238
3239 (define_insn "negdi2_internal_2"
3240   [(set (match_operand:DI 0 "register_operand" "=d")
3241         (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
3242   "TARGET_64BIT && !TARGET_MIPS16"
3243   "*
3244 {
3245   operands[2] = const0_rtx;
3246   return \"dsubu\\t%0,%z2,%1\";
3247 }"
3248   [(set_attr "type"     "arith")
3249    (set_attr "mode"     "DI")])
3250
3251 (define_insn "negdf2"
3252   [(set (match_operand:DF 0 "register_operand" "=f")
3253         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3254   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3255   "neg.d\\t%0,%1"
3256   [(set_attr "type"     "fneg")
3257    (set_attr "mode"     "DF")])
3258
3259 (define_insn "negsf2"
3260   [(set (match_operand:SF 0 "register_operand" "=f")
3261         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3262   "TARGET_HARD_FLOAT"
3263   "neg.s\\t%0,%1"
3264   [(set_attr "type"     "fneg")
3265    (set_attr "mode"     "SF")])
3266
3267 (define_insn "one_cmplsi2"
3268   [(set (match_operand:SI 0 "register_operand" "=d")
3269         (not:SI (match_operand:SI 1 "register_operand" "d")))]
3270   ""
3271   "*
3272 {
3273   if (TARGET_MIPS16)
3274     return \"not\\t%0,%1\";
3275   operands[2] = const0_rtx;
3276   return \"nor\\t%0,%z2,%1\";
3277 }"
3278   [(set_attr "type"     "arith")
3279    (set_attr "mode"     "SI")])
3280
3281 (define_insn "one_cmpldi2"
3282   [(set (match_operand:DI 0 "register_operand" "=d")
3283         (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
3284   ""
3285   "*
3286 {
3287   if (TARGET_MIPS16)
3288     {
3289       if (TARGET_64BIT)
3290         return \"not\\t%0,%1\";
3291       return \"not\\t%M0,%M1\;not\\t%L0,%L1\";
3292     }
3293   operands[2] = const0_rtx;
3294   if (TARGET_64BIT)
3295     return \"nor\\t%0,%z2,%1\";
3296   return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
3297 }"
3298   [(set_attr "type"     "darith")
3299    (set_attr "mode"     "DI")
3300    (set (attr "length")
3301         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3302                        (const_int 4)
3303                        (const_int 8)))])
3304
3305 (define_split
3306   [(set (match_operand:DI 0 "register_operand" "")
3307         (not:DI (match_operand:DI 1 "register_operand" "")))]
3308   "reload_completed && !TARGET_64BIT
3309    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3310    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3311    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3312
3313   [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
3314    (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))]
3315   "")
3316
3317 \f
3318 ;;
3319 ;;  ....................
3320 ;;
3321 ;;      LOGICAL
3322 ;;
3323 ;;  ....................
3324 ;;
3325
3326 ;; Many of these instructions uses trivial define_expands, because we
3327 ;; want to use a different set of constraints when TARGET_MIPS16.
3328
3329 (define_expand "andsi3"
3330   [(set (match_operand:SI 0 "register_operand" "=d,d")
3331         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3332                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3333   ""
3334   "
3335 {
3336   if (TARGET_MIPS16)
3337     {
3338       operands[1] = force_reg (SImode, operands[1]);
3339       operands[2] = force_reg (SImode, operands[2]);
3340     }
3341 }")
3342
3343 (define_insn ""
3344   [(set (match_operand:SI 0 "register_operand" "=d,d")
3345         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3346                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3347   "!TARGET_MIPS16"
3348   "@
3349    and\\t%0,%1,%2
3350    andi\\t%0,%1,%x2"
3351   [(set_attr "type"     "arith")
3352    (set_attr "mode"     "SI")])
3353
3354 (define_insn ""
3355   [(set (match_operand:SI 0 "register_operand" "=d")
3356         (and:SI (match_operand:SI 1 "register_operand" "%0")
3357                 (match_operand:SI 2 "register_operand" "d")))]
3358   "TARGET_MIPS16"
3359   "and\\t%0,%2"
3360   [(set_attr "type"     "arith")
3361    (set_attr "mode"     "SI")])
3362
3363 (define_expand "anddi3"
3364   [(set (match_operand:DI 0 "register_operand" "=d")
3365         (and:DI (match_operand:DI 1 "se_register_operand" "d")
3366                 (match_operand:DI 2 "se_register_operand" "d")))]
3367   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3368   "
3369 {
3370   if (TARGET_MIPS16)
3371     {
3372       operands[1] = force_reg (DImode, operands[1]);
3373       operands[2] = force_reg (DImode, operands[2]);
3374     }
3375 }")
3376
3377 (define_insn ""
3378   [(set (match_operand:DI 0 "register_operand" "=d")
3379         (and:DI (match_operand:DI 1 "se_register_operand" "d")
3380                 (match_operand:DI 2 "se_register_operand" "d")))]
3381   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3382   "*
3383 {
3384   if (TARGET_64BIT)
3385     return \"and\\t%0,%1,%2\";
3386   return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
3387 }"
3388   [(set_attr "type"     "darith")
3389    (set_attr "mode"     "DI")
3390    (set (attr "length")
3391         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3392                        (const_int 4)
3393                        (const_int 8)))])
3394
3395 (define_insn ""
3396   [(set (match_operand:DI 0 "register_operand" "=d")
3397         (and:DI (match_operand:DI 1 "se_register_operand" "0")
3398                 (match_operand:DI 2 "se_register_operand" "d")))]
3399   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3400   "*
3401 {
3402   if (TARGET_64BIT)
3403     return \"and\\t%0,%2\";
3404   return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
3405 }"
3406   [(set_attr "type"     "darith")
3407    (set_attr "mode"     "DI")
3408    (set (attr "length")
3409         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3410                        (const_int 4)
3411                        (const_int 8)))])
3412
3413 (define_split
3414   [(set (match_operand:DI 0 "register_operand" "")
3415         (and:DI (match_operand:DI 1 "register_operand" "")
3416                 (match_operand:DI 2 "register_operand" "")))]
3417   "reload_completed && !TARGET_64BIT
3418    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3419    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3420    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3421    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3422
3423   [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3424    (set (subreg:SI (match_dup 0) 4) (and:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3425   "")
3426
3427 (define_insn "anddi3_internal1"
3428   [(set (match_operand:DI 0 "register_operand" "=d,d")
3429         (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
3430                 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
3431   "TARGET_64BIT && !TARGET_MIPS16"
3432   "@
3433    and\\t%0,%1,%2
3434    andi\\t%0,%1,%x2"
3435   [(set_attr "type"     "arith")
3436    (set_attr "mode"     "DI")])
3437
3438 (define_expand "iorsi3"
3439   [(set (match_operand:SI 0 "register_operand" "=d,d")
3440         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3441                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3442   ""
3443   "
3444 {
3445   if (TARGET_MIPS16)
3446     {
3447       operands[1] = force_reg (SImode, operands[1]);
3448       operands[2] = force_reg (SImode, operands[2]);
3449     }
3450 }")
3451
3452 (define_insn ""
3453   [(set (match_operand:SI 0 "register_operand" "=d,d")
3454         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3455                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3456   "!TARGET_MIPS16"
3457   "@
3458    or\\t%0,%1,%2
3459    ori\\t%0,%1,%x2"
3460   [(set_attr "type"     "arith")
3461    (set_attr "mode"     "SI")])
3462
3463 (define_insn ""
3464   [(set (match_operand:SI 0 "register_operand" "=d")
3465         (ior:SI (match_operand:SI 1 "register_operand" "%0")
3466                 (match_operand:SI 2 "register_operand" "d")))]
3467   "TARGET_MIPS16"
3468   "or\\t%0,%2"
3469   [(set_attr "type"     "arith")
3470    (set_attr "mode"     "SI")])
3471
3472 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
3473 ;;; TARGET_64BIT
3474
3475 (define_expand "iordi3"
3476   [(set (match_operand:DI 0 "register_operand" "=d")
3477         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3478                 (match_operand:DI 2 "se_register_operand" "d")))]
3479   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3480   "")
3481
3482 (define_insn ""
3483   [(set (match_operand:DI 0 "register_operand" "=d")
3484         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3485                 (match_operand:DI 2 "se_register_operand" "d")))]
3486   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3487   "*
3488 {
3489   if (TARGET_64BIT)
3490     return \"or\\t%0,%1,%2\";
3491   return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
3492 }"
3493   [(set_attr "type"     "darith")
3494    (set_attr "mode"     "DI")
3495    (set (attr "length")
3496         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3497                        (const_int 4)
3498                        (const_int 8)))])
3499
3500 (define_insn ""
3501   [(set (match_operand:DI 0 "register_operand" "=d")
3502         (ior:DI (match_operand:DI 1 "se_register_operand" "0")
3503                 (match_operand:DI 2 "se_register_operand" "d")))]
3504   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3505   "*
3506 {
3507   if (TARGET_64BIT)
3508     return \"or\\t%0,%2\";
3509   return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
3510 }"
3511   [(set_attr "type"     "darith")
3512    (set_attr "mode"     "DI")
3513    (set (attr "length")
3514         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3515                        (const_int 4)
3516                        (const_int 8)))])
3517
3518 (define_split
3519   [(set (match_operand:DI 0 "register_operand" "")
3520         (ior:DI (match_operand:DI 1 "register_operand" "")
3521                 (match_operand:DI 2 "register_operand" "")))]
3522   "reload_completed && !TARGET_64BIT
3523    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3524    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3525    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3526    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3527
3528   [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3529    (set (subreg:SI (match_dup 0) 4) (ior:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3530   "")
3531
3532 (define_expand "xorsi3"
3533   [(set (match_operand:SI 0 "register_operand" "=d,d")
3534         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3535                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3536   ""
3537   "")
3538
3539 (define_insn ""
3540   [(set (match_operand:SI 0 "register_operand" "=d,d")
3541         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3542                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3543   "!TARGET_MIPS16"
3544   "@
3545    xor\\t%0,%1,%2
3546    xori\\t%0,%1,%x2"
3547   [(set_attr "type"     "arith")
3548    (set_attr "mode"     "SI")])
3549
3550 (define_insn ""
3551   [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3552         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3553                 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3554   "TARGET_MIPS16"
3555   "@
3556    xor\\t%0,%2
3557    cmpi\\t%1,%2
3558    cmp\\t%1,%2"
3559   [(set_attr "type"     "arith")
3560    (set_attr "mode"     "SI")
3561    (set_attr_alternative "length"
3562                 [(const_int 4)
3563                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3564                                (const_int 4)
3565                                (const_int 8))
3566                  (const_int 4)])])
3567
3568 ;; ??? If delete the 32-bit long long patterns, then could merge this with
3569 ;; the following xordi3_internal pattern.
3570 (define_expand "xordi3"
3571   [(set (match_operand:DI 0 "register_operand" "=d")
3572         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3573                 (match_operand:DI 2 "se_register_operand" "d")))]
3574   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3575   "")
3576
3577 (define_insn ""
3578   [(set (match_operand:DI 0 "register_operand" "=d")
3579         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3580                 (match_operand:DI 2 "se_register_operand" "d")))]
3581   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3582   "*
3583 {
3584   if (TARGET_64BIT)
3585     return \"xor\\t%0,%1,%2\";
3586   return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
3587 }"
3588   [(set_attr "type"     "darith")
3589    (set_attr "mode"     "DI")
3590    (set (attr "length")
3591         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3592                        (const_int 4)
3593                        (const_int 8)))])
3594
3595 (define_insn ""
3596   [(set (match_operand:DI 0 "register_operand" "=d")
3597         (xor:DI (match_operand:DI 1 "se_register_operand" "0")
3598                 (match_operand:DI 2 "se_register_operand" "d")))]
3599   "!TARGET_64BIT && TARGET_MIPS16"
3600   "xor\\t%M0,%M2\;xor\\t%L0,%L2"
3601   [(set_attr "type"     "darith")
3602    (set_attr "mode"     "DI")
3603    (set_attr "length"   "8")])
3604
3605 (define_insn ""
3606   [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3607         (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
3608                 (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
3609   "TARGET_64BIT && TARGET_MIPS16"
3610   "@
3611    xor\\t%0,%2
3612    cmpi\\t%1,%2
3613    cmp\\t%1,%2"
3614   [(set_attr "type"     "arith")
3615    (set_attr "mode"     "DI")
3616    (set_attr_alternative "length"
3617                 [(const_int 4)
3618                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3619                                (const_int 4)
3620                                (const_int 8))
3621                  (const_int 4)])])
3622
3623 (define_split
3624   [(set (match_operand:DI 0 "register_operand" "")
3625         (xor: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) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3634    (set (subreg:SI (match_dup 0) 4) (xor:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3635   "")
3636
3637 (define_insn "xordi3_immed"
3638   [(set (match_operand:DI 0 "register_operand" "=d")
3639         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3640                 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
3641   "TARGET_64BIT && !TARGET_MIPS16"
3642   "xori\\t%0,%1,%x2"
3643   [(set_attr "type"     "arith")
3644    (set_attr "mode"     "DI")])
3645
3646 (define_insn "*norsi3"
3647   [(set (match_operand:SI 0 "register_operand" "=d")
3648         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3649                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3650   "!TARGET_MIPS16"
3651   "nor\\t%0,%z1,%z2"
3652   [(set_attr "type"     "arith")
3653    (set_attr "mode"     "SI")])
3654
3655 (define_insn "*nordi3"
3656   [(set (match_operand:DI 0 "register_operand" "=d")
3657         (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
3658                 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
3659   "!TARGET_MIPS16"
3660   "*
3661 {
3662   if (TARGET_64BIT)
3663     return \"nor\\t%0,%z1,%z2\";
3664   return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
3665 }"
3666   [(set_attr "type"     "darith")
3667    (set_attr "mode"     "DI")
3668    (set (attr "length")
3669         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3670                        (const_int 4)
3671                        (const_int 8)))])
3672
3673 (define_split
3674   [(set (match_operand:DI 0 "register_operand" "")
3675         (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
3676                 (not:DI (match_operand:DI 2 "register_operand" ""))))]
3677   "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT
3678    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3679    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3680    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3681    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3682
3683   [(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))))
3684    (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))))]
3685   "")
3686 \f
3687 ;;
3688 ;;  ....................
3689 ;;
3690 ;;      TRUNCATION
3691 ;;
3692 ;;  ....................
3693
3694 (define_insn "truncdfsf2"
3695   [(set (match_operand:SF 0 "register_operand" "=f")
3696         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3697   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3698   "cvt.s.d\\t%0,%1"
3699   [(set_attr "type"     "fcvt")
3700    (set_attr "mode"     "SF")])
3701
3702 (define_insn "truncdisi2"
3703   [(set (match_operand:SI 0 "register_operand" "=d")
3704         (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
3705   "TARGET_64BIT"
3706   "*
3707 {
3708   if (TARGET_MIPS16)
3709     return \"dsll\\t%0,%1,32\;dsra\\t%0,32\";
3710   return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
3711 }"
3712   [(set_attr "type"     "darith")
3713    (set_attr "mode"     "SI")
3714    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3715                                       (const_int 8)
3716                                       (const_int 16)))])
3717
3718 (define_insn "truncdihi2"
3719   [(set (match_operand:HI 0 "register_operand" "=d")
3720         (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
3721   "TARGET_64BIT"
3722   "*
3723 {
3724   if (TARGET_MIPS16)
3725     return \"dsll\\t%0,%1,48\;dsra\\t%0,48\";
3726   return \"andi\\t%0,%1,0xffff\";
3727 }"
3728   [(set_attr "type"     "darith")
3729    (set_attr "mode"     "HI")
3730    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3731                                       (const_int 4)
3732                                       (const_int 16)))])
3733 (define_insn "truncdiqi2"
3734   [(set (match_operand:QI 0 "register_operand" "=d")
3735         (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
3736   "TARGET_64BIT"
3737   "*
3738 {
3739   if (TARGET_MIPS16)
3740     return \"dsll\\t%0,%1,56\;dsra\\t%0,56\";
3741   return \"andi\\t%0,%1,0x00ff\";
3742 }"
3743   [(set_attr "type"     "darith")
3744    (set_attr "mode"     "QI")
3745    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3746                                       (const_int 4)
3747                                       (const_int 16)))])
3748
3749 ;; Combiner patterns to optimize shift/truncate combinations.
3750 (define_insn ""
3751   [(set (match_operand:SI 0 "register_operand" "=d")
3752         (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3753                                   (match_operand:DI 2 "small_int" "I"))))]
3754   "TARGET_64BIT && !TARGET_MIPS16"
3755   "*
3756 {
3757   int shift_amt = INTVAL (operands[2]) & 0x3f;
3758
3759   if (shift_amt < 32)
3760     {
3761       operands[2] = GEN_INT (32 - shift_amt);
3762       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3763     }
3764   else
3765     {
3766       operands[2] = GEN_INT (shift_amt);
3767       return \"dsra\\t%0,%1,%2\";
3768     }
3769 }"
3770   [(set_attr "type"     "darith")
3771    (set_attr "mode"     "SI")
3772    (set_attr "length"   "8")])
3773
3774 (define_insn ""
3775   [(set (match_operand:SI 0 "register_operand" "=d")
3776         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3777                                   (match_operand:DI 2 "small_int" "I"))))]
3778   "TARGET_64BIT && !TARGET_MIPS16"
3779   "*
3780 {
3781   int shift_amt = INTVAL (operands[2]) & 0x3f;
3782
3783   if (shift_amt < 32)
3784     {
3785       operands[2] = GEN_INT (32 - shift_amt);
3786       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3787     }
3788   else if (shift_amt == 32)
3789     return \"dsra\\t%0,%1,32\";
3790   else
3791     {
3792       operands[2] = GEN_INT (shift_amt);
3793       return \"dsrl\\t%0,%1,%2\";
3794     }
3795 }"
3796   [(set_attr "type"     "darith")
3797    (set_attr "mode"     "SI")
3798    (set_attr "length"   "8")])
3799
3800 (define_insn ""
3801   [(set (match_operand:SI 0 "register_operand" "=d")
3802         (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
3803                                 (match_operand:DI 2 "small_int" "I"))))]
3804   "TARGET_64BIT"
3805   "*
3806 {
3807   int shift_amt = INTVAL (operands[2]) & 0x3f;
3808
3809   if (shift_amt < 32)
3810     {
3811       operands[2] = GEN_INT (32 + shift_amt);
3812       if (TARGET_MIPS16)
3813         return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\";
3814       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3815     }
3816   else
3817     return \"move\\t%0,%.\";
3818 }"
3819   [(set_attr "type"     "darith")
3820    (set_attr "mode"     "SI")
3821    (set_attr "length"   "8")])
3822
3823 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3824
3825 (define_insn ""
3826   [(set (match_operand:SI 0 "register_operand" "=d")
3827         (zero_extend:SI (truncate:HI
3828                          (match_operand:DI 1 "se_register_operand" "d"))))]
3829   "TARGET_64BIT && !TARGET_MIPS16"
3830   "andi\\t%0,%1,0xffff"
3831   [(set_attr "type"     "darith")
3832    (set_attr "mode"     "SI")])
3833
3834 (define_insn ""
3835   [(set (match_operand:SI 0 "register_operand" "=d")
3836         (zero_extend:SI (truncate:QI
3837                          (match_operand:DI 1 "se_register_operand" "d"))))]
3838   "TARGET_64BIT && !TARGET_MIPS16"
3839   "andi\\t%0,%1,0xff"
3840   [(set_attr "type"     "darith")
3841    (set_attr "mode"     "SI")])
3842
3843 (define_insn ""
3844   [(set (match_operand:HI 0 "register_operand" "=d")
3845         (zero_extend:HI (truncate:QI
3846                          (match_operand:DI 1 "se_register_operand" "d"))))]
3847   "TARGET_64BIT && !TARGET_MIPS16"
3848   "andi\\t%0,%1,0xff"
3849   [(set_attr "type"     "darith")
3850    (set_attr "mode"     "HI")])
3851 \f
3852 ;;
3853 ;;  ....................
3854 ;;
3855 ;;      ZERO EXTENSION
3856 ;;
3857 ;;  ....................
3858
3859 ;; Extension insns.
3860 ;; Those for integer source operand are ordered widest source type first.
3861
3862 (define_expand "zero_extendsidi2"
3863   [(set (match_operand:DI 0 "register_operand" "")
3864         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3865   "TARGET_64BIT"
3866   "
3867 {
3868   if ((optimize || TARGET_MIPS16) && GET_CODE (operands[1]) == MEM)
3869     operands[1] = force_not_mem (operands[1]);
3870
3871   if (GET_CODE (operands[1]) != MEM)
3872     {
3873       rtx op1   = gen_lowpart (DImode, operands[1]);
3874       rtx temp  = gen_reg_rtx (DImode);
3875       rtx shift = GEN_INT (32);
3876
3877       emit_insn (gen_ashldi3 (temp, op1, shift));
3878       emit_insn (gen_lshrdi3 (operands[0], temp, shift));
3879       DONE;
3880     }
3881 }")
3882
3883 (define_insn "zero_extendsidi2_internal"
3884   [(set (match_operand:DI 0 "register_operand" "=d,d")
3885         (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
3886   "TARGET_64BIT && !TARGET_MIPS16"
3887   "* return mips_move_1word (operands, insn, TRUE);"
3888   [(set_attr "type"     "load")
3889    (set_attr "mode"     "DI")
3890    (set_attr "length"   "4,8")])
3891
3892 (define_expand "zero_extendhisi2"
3893   [(set (match_operand:SI 0 "register_operand" "")
3894         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3895   ""
3896   "
3897 {
3898   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3899     {
3900       rtx op = gen_lowpart (SImode, operands[1]);
3901       rtx temp = force_reg (SImode, GEN_INT (0xffff));
3902
3903       emit_insn (gen_andsi3 (operands[0], op, temp));
3904       DONE;
3905     }
3906 }")
3907
3908 (define_insn ""
3909   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3910         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3911   "!TARGET_MIPS16"
3912   "*
3913 {
3914   if (which_alternative == 0)
3915     return \"andi\\t%0,%1,0xffff\";
3916   else
3917     return mips_move_1word (operands, insn, TRUE);
3918 }"
3919   [(set_attr "type"     "arith,load,load")
3920    (set_attr "mode"     "SI")
3921    (set_attr "length"   "4,4,8")])
3922
3923 (define_insn ""
3924   [(set (match_operand:SI 0 "register_operand" "=d,d")
3925         (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3926   "TARGET_MIPS16"
3927   "* return mips_move_1word (operands, insn, TRUE);"
3928   [(set_attr "type"     "load,load")
3929    (set_attr "mode"     "SI")
3930    (set_attr "length"   "4,8")])
3931
3932 (define_expand "zero_extendhidi2"
3933   [(set (match_operand:DI 0 "register_operand" "")
3934         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3935   "TARGET_64BIT"
3936   "
3937 {
3938   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3939     {
3940       rtx op = gen_lowpart (DImode, operands[1]);
3941       rtx temp = force_reg (DImode, GEN_INT (0xffff));
3942
3943       emit_insn (gen_anddi3 (operands[0], op, temp));
3944       DONE;
3945     }
3946 }")
3947
3948 (define_insn ""
3949   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3950         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3951   "TARGET_64BIT && !TARGET_MIPS16"
3952   "*
3953 {
3954   if (which_alternative == 0)
3955     return \"andi\\t%0,%1,0xffff\";
3956   else
3957     return mips_move_1word (operands, insn, TRUE);
3958 }"
3959   [(set_attr "type"     "arith,load,load")
3960    (set_attr "mode"     "DI")
3961    (set_attr "length"   "4,4,8")])
3962
3963 (define_insn ""
3964   [(set (match_operand:DI 0 "register_operand" "=d,d")
3965         (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3966   "TARGET_64BIT && TARGET_MIPS16"
3967   "* return mips_move_1word (operands, insn, TRUE);"
3968   [(set_attr "type"     "load,load")
3969    (set_attr "mode"     "DI")
3970    (set_attr "length"   "4,8")])
3971
3972 (define_expand "zero_extendqihi2"
3973   [(set (match_operand:HI 0 "register_operand" "")
3974         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3975   ""
3976   "
3977 {
3978   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3979     {
3980       rtx op0 = gen_lowpart (SImode, operands[0]);
3981       rtx op1 = gen_lowpart (SImode, operands[1]);
3982       rtx temp = force_reg (SImode, GEN_INT (0xff));
3983
3984       emit_insn (gen_andsi3 (op0, op1, temp));
3985       DONE;
3986     }
3987 }")
3988
3989 (define_insn ""
3990   [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3991         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3992   "!TARGET_MIPS16"
3993   "*
3994 {
3995   if (which_alternative == 0)
3996     return \"andi\\t%0,%1,0x00ff\";
3997   else
3998     return mips_move_1word (operands, insn, TRUE);
3999 }"
4000   [(set_attr "type"     "arith,load,load")
4001    (set_attr "mode"     "HI")
4002    (set_attr "length"   "4,4,8")])
4003
4004 (define_insn ""
4005   [(set (match_operand:HI 0 "register_operand" "=d,d")
4006         (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
4007   "TARGET_MIPS16"
4008   "* return mips_move_1word (operands, insn, TRUE);"
4009   [(set_attr "type"     "load,load")
4010    (set_attr "mode"     "HI")
4011    (set_attr "length"   "4,8")])
4012
4013 (define_expand "zero_extendqisi2"
4014   [(set (match_operand:SI 0 "register_operand" "")
4015         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4016   ""
4017   "
4018 {
4019   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4020     {
4021       rtx op = gen_lowpart (SImode, operands[1]);
4022       rtx temp = force_reg (SImode, GEN_INT (0xff));
4023
4024       emit_insn (gen_andsi3 (operands[0], op, temp));
4025       DONE;
4026     }
4027 }")
4028
4029 (define_insn ""
4030   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
4031         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
4032   "!TARGET_MIPS16"
4033   "*
4034 {
4035   if (which_alternative == 0)
4036     return \"andi\\t%0,%1,0x00ff\";
4037   else
4038     return mips_move_1word (operands, insn, TRUE);
4039 }"
4040   [(set_attr "type"     "arith,load,load")
4041    (set_attr "mode"     "SI")
4042    (set_attr "length"   "4,4,8")])
4043
4044 (define_insn ""
4045   [(set (match_operand:SI 0 "register_operand" "=d,d")
4046         (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4047   "TARGET_MIPS16"
4048   "* return mips_move_1word (operands, insn, TRUE);"
4049   [(set_attr "type"     "load,load")
4050    (set_attr "mode"     "SI")
4051    (set_attr "length"   "4,8")])
4052
4053 (define_expand "zero_extendqidi2"
4054   [(set (match_operand:DI 0 "register_operand" "")
4055         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4056   "TARGET_64BIT"
4057   "
4058 {
4059   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4060     {
4061       rtx op = gen_lowpart (DImode, operands[1]);
4062       rtx temp = force_reg (DImode, GEN_INT (0xff));
4063
4064       emit_insn (gen_anddi3 (operands[0], op, temp));
4065       DONE;
4066     }
4067 }")
4068
4069 (define_insn ""
4070   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4071         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
4072   "TARGET_64BIT && !TARGET_MIPS16"
4073   "*
4074 {
4075   if (which_alternative == 0)
4076     return \"andi\\t%0,%1,0x00ff\";
4077   else
4078     return mips_move_1word (operands, insn, TRUE);
4079 }"
4080   [(set_attr "type"     "arith,load,load")
4081    (set_attr "mode"     "DI")
4082    (set_attr "length"   "4,4,8")])
4083
4084 ;; These can be created when a paradoxical subreg operand with an implicit
4085 ;; sign_extend operator is reloaded.  Because of the subreg, this is really
4086 ;; a zero extend.
4087 ;; ??? It might be possible to eliminate the need for these patterns by adding
4088 ;; more support to reload for implicit sign_extend operators.
4089 (define_insn "*paradoxical_extendhidi2"
4090   [(set (match_operand:DI 0 "register_operand" "=d,d")
4091         (sign_extend:DI
4092          (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
4093   "TARGET_64BIT"
4094   "*
4095 {
4096   return mips_move_1word (operands, insn, TRUE);
4097 }"
4098   [(set_attr "type"     "load,load")
4099    (set_attr "mode"     "DI")
4100    (set_attr "length"   "4,8")])
4101
4102 (define_insn ""
4103   [(set (match_operand:DI 0 "register_operand" "=d,d")
4104         (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4105   "TARGET_64BIT && TARGET_MIPS16"
4106   "* return mips_move_1word (operands, insn, TRUE);"
4107   [(set_attr "type"     "load,load")
4108    (set_attr "mode"     "DI")
4109    (set_attr "length"   "4,8")])
4110 \f
4111 ;;
4112 ;;  ....................
4113 ;;
4114 ;;      SIGN EXTENSION
4115 ;;
4116 ;;  ....................
4117
4118 ;; Extension insns.
4119 ;; Those for integer source operand are ordered widest source type first.
4120
4121 ;; In 64 bit mode, 32 bit values in general registers are always
4122 ;; correctly sign extended.  That means that if the target is a
4123 ;; general register, we can sign extend from SImode to DImode just by
4124 ;; doing a move.
4125
4126 (define_insn "extendsidi2"
4127   [(set (match_operand:DI 0 "register_operand" "=d,y,d,*d,d,d")
4128         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,d,y,*x,R,m")))]
4129   "TARGET_64BIT"
4130   "* return mips_move_1word (operands, insn, FALSE);"
4131   [(set_attr "type"     "move,move,move,hilo,load,load")
4132    (set_attr "mode"     "DI")
4133    (set_attr "length"   "4,4,4,4,4,8")])
4134
4135 ;; These patterns originally accepted general_operands, however, slightly
4136 ;; better code is generated by only accepting register_operands, and then
4137 ;; letting combine generate the lh and lb insns.
4138
4139 (define_expand "extendhidi2"
4140   [(set (match_operand:DI 0 "register_operand" "")
4141         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
4142   "TARGET_64BIT"
4143   "
4144 {
4145   if (optimize && GET_CODE (operands[1]) == MEM)
4146     operands[1] = force_not_mem (operands[1]);
4147
4148   if (GET_CODE (operands[1]) != MEM)
4149     {
4150       rtx op1   = gen_lowpart (DImode, operands[1]);
4151       rtx temp  = gen_reg_rtx (DImode);
4152       rtx shift = GEN_INT (48);
4153
4154       emit_insn (gen_ashldi3 (temp, op1, shift));
4155       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4156       DONE;
4157     }
4158 }")
4159
4160 (define_insn "extendhidi2_internal"
4161   [(set (match_operand:DI 0 "register_operand" "=d,d")
4162         (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
4163   "TARGET_64BIT"
4164   "* return mips_move_1word (operands, insn, FALSE);"
4165   [(set_attr "type"     "load")
4166    (set_attr "mode"     "DI")
4167    (set_attr "length"   "4,8")])
4168
4169 (define_expand "extendhisi2"
4170   [(set (match_operand:SI 0 "register_operand" "")
4171         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4172   ""
4173   "
4174 {
4175   if (optimize && GET_CODE (operands[1]) == MEM)
4176     operands[1] = force_not_mem (operands[1]);
4177
4178   if (GET_CODE (operands[1]) != MEM)
4179     {
4180       rtx op1   = gen_lowpart (SImode, operands[1]);
4181       rtx temp  = gen_reg_rtx (SImode);
4182       rtx shift = GEN_INT (16);
4183
4184       emit_insn (gen_ashlsi3 (temp, op1, shift));
4185       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4186       DONE;
4187     }
4188 }")
4189
4190 (define_insn "extendhisi2_internal"
4191   [(set (match_operand:SI 0 "register_operand" "=d,d")
4192         (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
4193   ""
4194   "* return mips_move_1word (operands, insn, FALSE);"
4195   [(set_attr "type"     "load")
4196    (set_attr "mode"     "SI")
4197    (set_attr "length"   "4,8")])
4198
4199 (define_expand "extendqihi2"
4200   [(set (match_operand:HI 0 "register_operand" "")
4201         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
4202   ""
4203   "
4204 {
4205   if (optimize && GET_CODE (operands[1]) == MEM)
4206     operands[1] = force_not_mem (operands[1]);
4207
4208   if (GET_CODE (operands[1]) != MEM)
4209     {
4210       rtx op0   = gen_lowpart (SImode, operands[0]);
4211       rtx op1   = gen_lowpart (SImode, operands[1]);
4212       rtx temp  = gen_reg_rtx (SImode);
4213       rtx shift = GEN_INT (24);
4214
4215       emit_insn (gen_ashlsi3 (temp, op1, shift));
4216       emit_insn (gen_ashrsi3 (op0, temp, shift));
4217       DONE;
4218     }
4219 }")
4220
4221 (define_insn "extendqihi2_internal"
4222   [(set (match_operand:HI 0 "register_operand" "=d,d")
4223         (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
4224   ""
4225   "* return mips_move_1word (operands, insn, FALSE);"
4226   [(set_attr "type"     "load")
4227    (set_attr "mode"     "SI")
4228    (set_attr "length"   "4,8")])
4229
4230
4231 (define_expand "extendqisi2"
4232   [(set (match_operand:SI 0 "register_operand" "")
4233         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4234   ""
4235   "
4236 {
4237   if (optimize && GET_CODE (operands[1]) == MEM)
4238     operands[1] = force_not_mem (operands[1]);
4239
4240   if (GET_CODE (operands[1]) != MEM)
4241     {
4242       rtx op1   = gen_lowpart (SImode, operands[1]);
4243       rtx temp  = gen_reg_rtx (SImode);
4244       rtx shift = GEN_INT (24);
4245
4246       emit_insn (gen_ashlsi3 (temp, op1, shift));
4247       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4248       DONE;
4249     }
4250 }")
4251
4252 (define_insn "extendqisi2_insn"
4253   [(set (match_operand:SI 0 "register_operand" "=d,d")
4254         (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4255   ""
4256   "* return mips_move_1word (operands, insn, FALSE);"
4257   [(set_attr "type"     "load")
4258    (set_attr "mode"     "SI")
4259    (set_attr "length"   "4,8")])
4260
4261 (define_expand "extendqidi2"
4262   [(set (match_operand:DI 0 "register_operand" "")
4263         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4264   "TARGET_64BIT"
4265   "
4266 {
4267   if (optimize && GET_CODE (operands[1]) == MEM)
4268     operands[1] = force_not_mem (operands[1]);
4269
4270   if (GET_CODE (operands[1]) != MEM)
4271     {
4272       rtx op1   = gen_lowpart (DImode, operands[1]);
4273       rtx temp  = gen_reg_rtx (DImode);
4274       rtx shift = GEN_INT (56);
4275
4276       emit_insn (gen_ashldi3 (temp, op1, shift));
4277       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4278       DONE;
4279     }
4280 }")
4281
4282 (define_insn "extendqidi2_insn"
4283   [(set (match_operand:DI 0 "register_operand" "=d,d")
4284         (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4285   "TARGET_64BIT"
4286   "* return mips_move_1word (operands, insn, FALSE);"
4287   [(set_attr "type"     "load")
4288    (set_attr "mode"     "DI")
4289    (set_attr "length"   "4,8")])
4290
4291
4292 (define_insn "extendsfdf2"
4293   [(set (match_operand:DF 0 "register_operand" "=f")
4294         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
4295   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4296   "cvt.d.s\\t%0,%1"
4297   [(set_attr "type"     "fcvt")
4298    (set_attr "mode"     "DF")])
4299
4300 \f
4301
4302 ;;
4303 ;;  ....................
4304 ;;
4305 ;;      CONVERSIONS
4306 ;;
4307 ;;  ....................
4308
4309 ;; The SImode scratch register can not be shared with address regs used for
4310 ;; operand zero, because then the address in the move instruction will be
4311 ;; clobbered.  We mark the scratch register as early clobbered to prevent this.
4312
4313 ;; We need the ?X in alternative 1 so that it will be chosen only if the
4314 ;; destination is a floating point register.  Otherwise, alternative 1 can
4315 ;; have lower cost than alternative 0 (because there is one less loser), and
4316 ;; can be chosen when it won't work (because integral reloads into FP
4317 ;; registers are not supported).
4318
4319 (define_insn "fix_truncdfsi2"
4320   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,*f,R,To")
4321         (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4322    (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4323    (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
4324   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4325   "*
4326 {
4327   rtx xoperands[10];
4328
4329   if (which_alternative == 1)
4330     return \"trunc.w.d %0,%1,%2\";
4331
4332   output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
4333
4334   xoperands[0] = operands[0];
4335   xoperands[1] = operands[3];
4336   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4337   return \"\";
4338 }"
4339   [(set_attr "type"     "fcvt")
4340    (set_attr "mode"     "DF")
4341    (set_attr "length"   "44,36,40,44")])
4342
4343
4344 (define_insn "fix_truncsfsi2"
4345   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,*f,R,To")
4346         (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4347    (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4348    (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
4349   "TARGET_HARD_FLOAT"
4350   "*
4351 {
4352   rtx xoperands[10];
4353
4354   if (which_alternative == 1)
4355     return \"trunc.w.s %0,%1,%2\";
4356
4357   output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
4358
4359   xoperands[0] = operands[0];
4360   xoperands[1] = operands[3];
4361   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4362   return \"\";
4363 }"
4364   [(set_attr "type"     "fcvt")
4365    (set_attr "mode"     "SF")
4366    (set_attr "length"   "44,36,40,44")])
4367
4368
4369 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
4370 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
4371 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
4372
4373 ;;; Deleting this means that we now need two libgcc2.a libraries.  One for
4374 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
4375
4376 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
4377
4378 (define_insn "fix_truncdfdi2"
4379   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,*f,R,To")
4380         (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4381    (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4382   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4383   "*
4384 {
4385   rtx xoperands[10];
4386
4387   if (which_alternative == 1)
4388     return \"trunc.l.d %0,%1\";
4389
4390   output_asm_insn (\"trunc.l.d %2,%1\", operands);
4391
4392   xoperands[0] = operands[0];
4393   xoperands[1] = operands[2];
4394   output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
4395   return \"\";
4396 }"
4397   [(set_attr "type"     "fcvt")
4398    (set_attr "mode"     "DF")
4399    (set_attr "length"   "8,4,8,12")])
4400
4401
4402 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
4403 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
4404 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
4405 (define_insn "fix_truncsfdi2"
4406   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,*f,R,To")
4407         (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4408    (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4409   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4410   "*
4411 {
4412   rtx xoperands[10];
4413
4414   if (which_alternative == 1)
4415     return \"trunc.l.s %0,%1\";
4416
4417   output_asm_insn (\"trunc.l.s %2,%1\", operands);
4418
4419   xoperands[0] = operands[0];
4420   xoperands[1] = operands[2];
4421   output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
4422   return \"\";
4423 }"
4424   [(set_attr "type"     "fcvt")
4425    (set_attr "mode"     "SF")
4426    (set_attr "length"   "8,4,8,12")])
4427
4428
4429 (define_insn "floatsidf2"
4430   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4431         (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4432   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4433   "*
4434 {
4435   dslots_load_total++;
4436   if (GET_CODE (operands[1]) == MEM)
4437     return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
4438
4439   return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
4440 }"
4441   [(set_attr "type"     "fcvt")
4442    (set_attr "mode"     "DF")
4443    (set_attr "length"   "12,16,12")])
4444
4445
4446 (define_insn "floatdidf2"
4447   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4448         (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4449   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4450   "*
4451 {
4452   dslots_load_total++;
4453   if (GET_CODE (operands[1]) == MEM)
4454     return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
4455
4456   return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
4457 }"
4458   [(set_attr "type"     "fcvt")
4459    (set_attr "mode"     "DF")
4460    (set_attr "length"   "12,16,12")])
4461
4462
4463 (define_insn "floatsisf2"
4464   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4465         (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4466   "TARGET_HARD_FLOAT"
4467   "*
4468 {
4469   dslots_load_total++;
4470   if (GET_CODE (operands[1]) == MEM)
4471     return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
4472
4473   return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
4474 }"
4475   [(set_attr "type"     "fcvt")
4476    (set_attr "mode"     "SF")
4477    (set_attr "length"   "12,16,12")])
4478
4479
4480 (define_insn "floatdisf2"
4481   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4482         (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4483   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4484   "*
4485 {
4486   dslots_load_total++;
4487   if (GET_CODE (operands[1]) == MEM)
4488     return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
4489
4490   return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
4491 }"
4492   [(set_attr "type"     "fcvt")
4493    (set_attr "mode"     "SF")
4494    (set_attr "length"   "12,16,12")])
4495
4496
4497 (define_expand "fixuns_truncdfsi2"
4498   [(set (match_operand:SI 0 "register_operand" "")
4499         (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
4500   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4501   "
4502 {
4503   rtx reg1 = gen_reg_rtx (DFmode);
4504   rtx reg2 = gen_reg_rtx (DFmode);
4505   rtx reg3 = gen_reg_rtx (SImode);
4506   rtx label1 = gen_label_rtx ();
4507   rtx label2 = gen_label_rtx ();
4508   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, 31);
4509
4510   if (reg1)                     /* turn off complaints about unreached code */
4511     {
4512       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
4513       do_pending_stack_adjust ();
4514
4515       emit_insn (gen_cmpdf (operands[1], reg1));
4516       emit_jump_insn (gen_bge (label1));
4517
4518       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
4519       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4520                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4521       emit_barrier ();
4522
4523       emit_label (label1);
4524       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4525       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4526                                      (BITMASK_HIGH, SImode)));
4527
4528       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4529       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4530
4531       emit_label (label2);
4532
4533       /* allow REG_NOTES to be set on last insn (labels don't have enough
4534          fields, and can't be used for REG_NOTES anyway).  */
4535       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4536       DONE;
4537     }
4538 }")
4539
4540
4541 (define_expand "fixuns_truncdfdi2"
4542   [(set (match_operand:DI 0 "register_operand" "")
4543         (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
4544   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4545   "
4546 {
4547   rtx reg1 = gen_reg_rtx (DFmode);
4548   rtx reg2 = gen_reg_rtx (DFmode);
4549   rtx reg3 = gen_reg_rtx (DImode);
4550   rtx label1 = gen_label_rtx ();
4551   rtx label2 = gen_label_rtx ();
4552   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, 63);
4553
4554   if (reg1)                     /* turn off complaints about unreached code */
4555     {
4556       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
4557       do_pending_stack_adjust ();
4558
4559       emit_insn (gen_cmpdf (operands[1], reg1));
4560       emit_jump_insn (gen_bge (label1));
4561
4562       emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
4563       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4564                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4565       emit_barrier ();
4566
4567       emit_label (label1);
4568       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4569       emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4570       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4571
4572       emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4573       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4574
4575       emit_label (label2);
4576
4577       /* allow REG_NOTES to be set on last insn (labels don't have enough
4578          fields, and can't be used for REG_NOTES anyway).  */
4579       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4580       DONE;
4581     }
4582 }")
4583
4584
4585 (define_expand "fixuns_truncsfsi2"
4586   [(set (match_operand:SI 0 "register_operand" "")
4587         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4588   "TARGET_HARD_FLOAT"
4589   "
4590 {
4591   rtx reg1 = gen_reg_rtx (SFmode);
4592   rtx reg2 = gen_reg_rtx (SFmode);
4593   rtx reg3 = gen_reg_rtx (SImode);
4594   rtx label1 = gen_label_rtx ();
4595   rtx label2 = gen_label_rtx ();
4596   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, 31);
4597
4598   if (reg1)                     /* turn off complaints about unreached code */
4599     {
4600       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
4601       do_pending_stack_adjust ();
4602
4603       emit_insn (gen_cmpsf (operands[1], reg1));
4604       emit_jump_insn (gen_bge (label1));
4605
4606       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4607       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4608                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4609       emit_barrier ();
4610
4611       emit_label (label1);
4612       emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4613       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4614                                      (BITMASK_HIGH, SImode)));
4615
4616       emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4617       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4618
4619       emit_label (label2);
4620
4621       /* allow REG_NOTES to be set on last insn (labels don't have enough
4622          fields, and can't be used for REG_NOTES anyway).  */
4623       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4624       DONE;
4625     }
4626 }")
4627
4628
4629 (define_expand "fixuns_truncsfdi2"
4630   [(set (match_operand:DI 0 "register_operand" "")
4631         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4632   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4633   "
4634 {
4635   rtx reg1 = gen_reg_rtx (SFmode);
4636   rtx reg2 = gen_reg_rtx (SFmode);
4637   rtx reg3 = gen_reg_rtx (DImode);
4638   rtx label1 = gen_label_rtx ();
4639   rtx label2 = gen_label_rtx ();
4640   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, 63);
4641
4642   if (reg1)                     /* turn off complaints about unreached code */
4643     {
4644       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
4645       do_pending_stack_adjust ();
4646
4647       emit_insn (gen_cmpsf (operands[1], reg1));
4648       emit_jump_insn (gen_bge (label1));
4649
4650       emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4651       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4652                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4653       emit_barrier ();
4654
4655       emit_label (label1);
4656       emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4657       emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4658       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4659
4660       emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4661       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4662
4663       emit_label (label2);
4664
4665       /* allow REG_NOTES to be set on last insn (labels don't have enough
4666          fields, and can't be used for REG_NOTES anyway).  */
4667       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4668       DONE;
4669     }
4670 }")
4671
4672 \f
4673 ;;
4674 ;;  ....................
4675 ;;
4676 ;;      DATA MOVEMENT
4677 ;;
4678 ;;  ....................
4679
4680 ;; Bit field extract patterns which use lwl/lwr.
4681
4682 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4683 ;; It isn't clear whether this will give better code.
4684
4685 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4686 (define_expand "extv"
4687   [(set (match_operand 0 "register_operand" "")
4688         (sign_extract (match_operand:QI 1 "memory_operand" "")
4689                       (match_operand 2 "immediate_operand" "")
4690                       (match_operand 3 "immediate_operand" "")))]
4691   "!TARGET_MIPS16"
4692   "
4693 {
4694   /* If the field does not start on a byte boundary, then fail.  */
4695   if (INTVAL (operands[3]) % 8 != 0)
4696     FAIL;
4697
4698   /* MIPS I and MIPS II can only handle a 32bit field.  */
4699   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4700     FAIL;
4701
4702   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4703   if (TARGET_64BIT
4704       && INTVAL (operands[2]) != 64
4705       && INTVAL (operands[2]) != 32)
4706     FAIL;
4707
4708   /* This can happen for a 64 bit target, when extracting a value from
4709      a 64 bit union member.  extract_bit_field doesn't verify that our
4710      source matches the predicate, so we force it to be a MEM here.  */
4711   if (GET_CODE (operands[1]) != MEM)
4712     FAIL;
4713
4714   /* Change the mode to BLKmode for aliasing purposes.  */
4715   operands[1] = adjust_address (operands[1], BLKmode, 0);
4716
4717   /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value.  */
4718   if (INTVAL (operands[2]) == 64)
4719     emit_insn (gen_movdi_uld (operands[0], operands[1]));
4720   else
4721     {
4722       if (TARGET_64BIT)
4723         {
4724           operands[0] = gen_lowpart (SImode, operands[0]);
4725           if (operands[0] == NULL_RTX)
4726             FAIL;
4727         }
4728       emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4729     }
4730   DONE;
4731 }")
4732
4733 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4734 (define_expand "extzv"
4735   [(set (match_operand 0 "register_operand" "")
4736         (zero_extract (match_operand:QI 1 "memory_operand" "")
4737                       (match_operand 2 "immediate_operand" "")
4738                       (match_operand 3 "immediate_operand" "")))]
4739   "!TARGET_MIPS16"
4740   "
4741 {
4742   /* If the field does not start on a byte boundary, then fail.  */
4743   if (INTVAL (operands[3]) % 8 != 0)
4744     FAIL;
4745
4746   /* MIPS I and MIPS II can only handle a 32bit field.  */
4747   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4748     FAIL;
4749
4750   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4751   if (TARGET_64BIT
4752       && INTVAL (operands[2]) != 64
4753       && INTVAL (operands[2]) != 32)
4754     FAIL;
4755
4756   /* This can happen for a 64 bit target, when extracting a value from
4757      a 64 bit union member.  extract_bit_field doesn't verify that our
4758      source matches the predicate, so we force it to be a MEM here.  */
4759   if (GET_CODE (operands[1]) != MEM)
4760     FAIL;
4761
4762   /* Change the mode to BLKmode for aliasing purposes.  */
4763   operands[1] = adjust_address (operands[1], BLKmode, 0);
4764
4765   /* Otherwise, emit a lwl/lwr pair to load the value.  */
4766   if (INTVAL (operands[2]) == 64)
4767     emit_insn (gen_movdi_uld (operands[0], operands[1]));
4768   else
4769     {
4770       if (TARGET_64BIT)
4771         {
4772           operands[0] = gen_lowpart (SImode, operands[0]);
4773           if (operands[0] == NULL_RTX)
4774             FAIL;
4775         }
4776       emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4777     }
4778   DONE;
4779 }")
4780
4781 ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
4782 (define_expand "insv"
4783   [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4784                       (match_operand 1 "immediate_operand" "")
4785                       (match_operand 2 "immediate_operand" ""))
4786         (match_operand 3 "register_operand" ""))]
4787   "!TARGET_MIPS16"
4788   "
4789 {
4790   /* If the field does not start on a byte boundary, then fail.  */
4791   if (INTVAL (operands[2]) % 8 != 0)
4792     FAIL;
4793
4794   /* MIPS I and MIPS II can only handle a 32bit field.  */
4795   if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
4796     FAIL;
4797
4798   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4799   if (TARGET_64BIT
4800       && INTVAL (operands[1]) != 64
4801       && INTVAL (operands[1]) != 32)
4802     FAIL;
4803
4804   /* This can happen for a 64 bit target, when storing into a 32 bit union
4805      member.  store_bit_field doesn't verify that our target matches the
4806      predicate, so we force it to be a MEM here.  */
4807   if (GET_CODE (operands[0]) != MEM)
4808     FAIL;
4809
4810   /* Change the mode to BLKmode for aliasing purposes.  */
4811   operands[0] = adjust_address (operands[0], BLKmode, 0);
4812
4813   /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value.  */
4814   if (INTVAL (operands[1]) == 64)
4815     emit_insn (gen_movdi_usd (operands[0], operands[3]));
4816   else
4817     {
4818       if (TARGET_64BIT)
4819         {
4820           operands[3] = gen_lowpart (SImode, operands[3]);
4821           if (operands[3] == NULL_RTX)
4822             FAIL;
4823         }
4824       emit_insn (gen_movsi_usw (operands[0], operands[3]));
4825     }
4826   DONE;
4827 }")
4828
4829 ;; unaligned word moves generated by the bit field patterns
4830
4831 (define_insn "movsi_ulw"
4832   [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4833         (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")]
4834                    UNSPEC_ULW))]
4835   "!TARGET_MIPS16"
4836   "*
4837 {
4838   rtx offset = const0_rtx;
4839   rtx addr = XEXP (operands[1], 0);
4840   rtx mem_addr = eliminate_constant_term (addr, &offset);
4841   const char *ret;
4842
4843   if (TARGET_STATS)
4844     mips_count_memory_refs (operands[1], 2);
4845
4846   /* The stack/frame pointers are always aligned, so we can convert
4847      to the faster lw if we are referencing an aligned stack location.  */
4848
4849   if ((INTVAL (offset) & 3) == 0
4850       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4851     ret = \"lw\\t%0,%1\";
4852   else
4853     ret = \"ulw\\t%0,%1\";
4854
4855   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4856 }"
4857   [(set_attr "type"     "load,load")
4858    (set_attr "mode"     "SI")
4859    (set_attr "length"   "8,16")])
4860
4861 (define_insn "movsi_usw"
4862   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4863         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")]
4864                     UNSPEC_USW))]
4865   "!TARGET_MIPS16"
4866   "*
4867 {
4868   rtx offset = const0_rtx;
4869   rtx addr = XEXP (operands[0], 0);
4870   rtx mem_addr = eliminate_constant_term (addr, &offset);
4871
4872   if (TARGET_STATS)
4873     mips_count_memory_refs (operands[0], 2);
4874
4875   /* The stack/frame pointers are always aligned, so we can convert
4876      to the faster sw if we are referencing an aligned stack location.  */
4877
4878   if ((INTVAL (offset) & 3) == 0
4879       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4880     return \"sw\\t%z1,%0\";
4881
4882   return \"usw\\t%z1,%0\";
4883 }"
4884   [(set_attr "type"     "store")
4885    (set_attr "mode"     "SI")
4886    (set_attr "length"   "8,16")])
4887
4888 ;; Bit field extract patterns which use ldl/ldr.
4889
4890 ;; unaligned double word moves generated by the bit field patterns
4891
4892 (define_insn "movdi_uld"
4893   [(set (match_operand:DI 0 "register_operand" "=&d,&d")
4894         (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")]
4895                    UNSPEC_ULD))]
4896   ""
4897   "*
4898 {
4899   rtx offset = const0_rtx;
4900   rtx addr = XEXP (operands[1], 0);
4901   rtx mem_addr = eliminate_constant_term (addr, &offset);
4902   const char *ret;
4903
4904   if (TARGET_STATS)
4905     mips_count_memory_refs (operands[1], 2);
4906
4907   /* The stack/frame pointers are always aligned, so we can convert
4908      to the faster lw if we are referencing an aligned stack location.  */
4909
4910   if ((INTVAL (offset) & 7) == 0
4911       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4912     ret = \"ld\\t%0,%1\";
4913   else
4914     ret = \"uld\\t%0,%1\";
4915
4916   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4917 }"
4918   [(set_attr "type"     "load,load")
4919    (set_attr "mode"     "SI")
4920    (set_attr "length"   "8,16")])
4921
4922 (define_insn "movdi_usd"
4923   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4924         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")]
4925                     UNSPEC_USD))]
4926   ""
4927   "*
4928 {
4929   rtx offset = const0_rtx;
4930   rtx addr = XEXP (operands[0], 0);
4931   rtx mem_addr = eliminate_constant_term (addr, &offset);
4932
4933   if (TARGET_STATS)
4934     mips_count_memory_refs (operands[0], 2);
4935
4936   /* The stack/frame pointers are always aligned, so we can convert
4937      to the faster sw if we are referencing an aligned stack location.  */
4938
4939   if ((INTVAL (offset) & 7) == 0
4940       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4941     return \"sd\\t%z1,%0\";
4942
4943   return \"usd\\t%z1,%0\";
4944 }"
4945   [(set_attr "type"     "store")
4946    (set_attr "mode"     "SI")
4947    (set_attr "length"   "8,16")])
4948
4949 ;; These two patterns support loading addresses with two instructions instead
4950 ;; of using the macro instruction la.
4951
4952 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
4953 ;; unnecessary.
4954
4955 (define_insn "high"
4956   [(set (match_operand:SI 0 "register_operand" "=r")
4957         (high:SI (match_operand:SI 1 "immediate_operand" "")))]
4958   "mips_split_addresses && !TARGET_MIPS16"
4959   "lui\\t%0,%%hi(%1) # high"
4960   [(set_attr "type"     "move")])
4961
4962 (define_insn "low"
4963   [(set (match_operand:SI 0 "register_operand" "=r")
4964         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
4965                    (match_operand:SI 2 "immediate_operand" "")))]
4966   "mips_split_addresses && !TARGET_MIPS16"
4967   "addiu\\t%0,%1,%%lo(%2) # low"
4968   [(set_attr "type"     "arith")
4969    (set_attr "mode"     "SI")])
4970
4971 ;; 64-bit integer moves
4972
4973 ;; Unlike most other insns, the move insns can't be split with
4974 ;; different predicates, because register spilling and other parts of
4975 ;; the compiler, have memoized the insn number already.
4976
4977 (define_expand "movdi"
4978   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4979         (match_operand:DI 1 "general_operand" ""))]
4980   ""
4981   "
4982 {
4983   if (mips_split_addresses && mips_check_split (operands[1], DImode))
4984     {
4985       enum machine_mode mode = GET_MODE (operands[0]);
4986       rtx tem = ((reload_in_progress | reload_completed)
4987                  ? operands[0] : gen_reg_rtx (mode));
4988
4989       emit_insn (gen_rtx_SET (VOIDmode, tem,
4990                               gen_rtx_HIGH (mode, operands[1])));
4991
4992       operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
4993     }
4994
4995   /* If we are generating embedded PIC code, and we are referring to a
4996      symbol in the .text section, we must use an offset from the start
4997      of the function.  */
4998   if (TARGET_EMBEDDED_PIC
4999       && (GET_CODE (operands[1]) == LABEL_REF
5000           || (GET_CODE (operands[1]) == SYMBOL_REF
5001               && ! SYMBOL_REF_FLAG (operands[1]))))
5002     {
5003       rtx temp;
5004
5005       temp = embedded_pic_offset (operands[1]);
5006       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
5007                            force_reg (DImode, temp));
5008       emit_move_insn (operands[0], force_reg (DImode, temp));
5009       DONE;
5010     }
5011
5012   /* If operands[1] is a constant address illegal for pic, then we need to
5013      handle it just like LEGITIMIZE_ADDRESS does.  */
5014   if (flag_pic && pic_address_needs_scratch (operands[1]))
5015     {
5016       rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
5017       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5018
5019       if (! SMALL_INT (temp2))
5020         temp2 = force_reg (DImode, temp2);
5021
5022       emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
5023       DONE;
5024     }
5025
5026   /* On the mips16, we can handle a GP relative reference by adding in
5027      $gp.  We need to check the name to see whether this is a string
5028      constant.  */
5029   if (TARGET_MIPS16
5030       && register_operand (operands[0], DImode)
5031       && GET_CODE (operands[1]) == SYMBOL_REF
5032       && SYMBOL_REF_FLAG (operands[1]))
5033     {
5034       const char *name = XSTR (operands[1], 0);
5035
5036       if (name[0] != '*'
5037           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5038                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5039         {
5040           rtx base_reg;
5041
5042           if (reload_in_progress || reload_completed)
5043             {
5044               /* In movsi we use the constant table here.  However, in
5045                  this case, we're better off copying $28 into a
5046                  register and adding, because the constant table entry
5047                  would be 8 bytes.  */
5048               base_reg = operands[0];
5049               emit_move_insn (base_reg,
5050                               gen_rtx (CONST, DImode,
5051                                        gen_rtx (REG, DImode,
5052                                                 GP_REG_FIRST + 28)));
5053             }
5054           else
5055             {
5056               base_reg = gen_reg_rtx (Pmode);
5057               emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5058             }
5059
5060           emit_move_insn (operands[0],
5061                           gen_rtx (PLUS, Pmode, base_reg,
5062                                    mips16_gp_offset (operands[1])));
5063           DONE;
5064         }
5065     }
5066
5067   if ((reload_in_progress | reload_completed) == 0
5068       && !register_operand (operands[0], DImode)
5069       && !register_operand (operands[1], DImode)
5070       && (TARGET_MIPS16
5071           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5072                && operands[1] != CONST0_RTX (DImode))))
5073     {
5074       rtx temp = force_reg (DImode, operands[1]);
5075       emit_move_insn (operands[0], temp);
5076       DONE;
5077     }
5078 }")
5079
5080 ;; For mips16, we need a special case to handle storing $31 into
5081 ;; memory, since we don't have a constraint to match $31.  This
5082 ;; instruction can be generated by save_restore_insns.
5083
5084 (define_insn ""
5085   [(set (match_operand:DI 0 "memory_operand" "=R,m")
5086         (reg:DI 31))]
5087   "TARGET_MIPS16 && TARGET_64BIT"
5088   "*
5089 {
5090   operands[1] = gen_rtx (REG, DImode, 31);
5091   return mips_move_2words (operands, insn);
5092 }"
5093   [(set_attr "type"     "store")
5094    (set_attr "mode"     "DI")
5095    (set_attr "length"   "4,8")])
5096
5097 (define_insn "movdi_internal"
5098   [(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")
5099         (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"))]
5100   "!TARGET_64BIT && !TARGET_MIPS16
5101    && (register_operand (operands[0], DImode)
5102        || register_operand (operands[1], DImode)
5103        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5104        || operands[1] == CONST0_RTX (DImode))"
5105   "* return mips_move_2words (operands, insn); "
5106   [(set_attr "type"     "move,arith,load,load,store,store,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5107    (set_attr "mode"     "DI")
5108    (set_attr "length"   "8,16,8,16,8,16,8,8,8,8,8,8,8,8,8")])
5109
5110 (define_insn ""
5111   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
5112         (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
5113   "!TARGET_64BIT && TARGET_MIPS16
5114    && (register_operand (operands[0], DImode)
5115        || register_operand (operands[1], DImode))"
5116   "* return mips_move_2words (operands, insn);"
5117   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
5118    (set_attr "mode"     "DI")
5119    (set_attr "length"   "8,8,8,8,12,8,16,8,16,8")])
5120
5121 (define_split
5122   [(set (match_operand:DI 0 "register_operand" "")
5123         (match_operand:DI 1 "register_operand" ""))]
5124   "reload_completed && !TARGET_64BIT
5125    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5126    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
5127    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
5128
5129   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
5130    (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
5131   "")
5132
5133 (define_insn "movdi_internal2"
5134   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*x,*d,*x,*a,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5135         (match_operand:DI 1 "movdi_operand" "d,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5136   "TARGET_64BIT && !TARGET_MIPS16
5137    && (register_operand (operands[0], DImode)
5138        || se_register_operand (operands[1], DImode)
5139        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5140        || operands[1] == CONST0_RTX (DImode))"
5141   "* return mips_move_2words (operands, insn); "
5142   [(set_attr "type"     "move,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5143    (set_attr "mode"     "DI")
5144    (set_attr "length"   "4,4,8,4,8,4,8,4,4,4,8,8,8,8,8,8,8")])
5145
5146 (define_insn ""
5147   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
5148         (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
5149   "TARGET_64BIT && TARGET_MIPS16
5150    && (register_operand (operands[0], DImode)
5151        || se_register_operand (operands[1], DImode))"
5152   "* return mips_move_2words (operands, insn);"
5153   [(set_attr "type"     "move,move,move,arith,arith,arith,load,load,store,store,hilo")
5154    (set_attr "mode"     "DI")
5155    (set_attr_alternative "length"
5156                 [(const_int 4)
5157                  (const_int 4)
5158                  (const_int 4)
5159                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5160                                (const_int 4)
5161                                (const_int 8))
5162                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5163                                (const_int 8)
5164                                (const_int 12))
5165                  (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
5166                                (const_int 4)
5167                                (const_int 8))
5168                  (const_int 4)
5169                  (const_int 8)
5170                  (const_int 4)
5171                  (const_int 8)
5172                  (const_int 4)])])
5173
5174 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
5175 ;; when the original load is a 4 byte instruction but the add and the
5176 ;; load are 2 2 byte instructions.
5177
5178 (define_split
5179   [(set (match_operand:DI 0 "register_operand" "")
5180         (mem:DI (plus:DI (match_dup 0)
5181                          (match_operand:DI 1 "const_int_operand" ""))))]
5182   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
5183    && !TARGET_DEBUG_D_MODE
5184    && GET_CODE (operands[0]) == REG
5185    && M16_REG_P (REGNO (operands[0]))
5186    && GET_CODE (operands[1]) == CONST_INT
5187    && ((INTVAL (operands[1]) < 0
5188         && INTVAL (operands[1]) >= -0x10)
5189        || (INTVAL (operands[1]) >= 32 * 8
5190            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
5191        || (INTVAL (operands[1]) >= 0
5192            && INTVAL (operands[1]) < 32 * 8
5193            && (INTVAL (operands[1]) & 7) != 0))"
5194   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
5195    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
5196   "
5197 {
5198   HOST_WIDE_INT val = INTVAL (operands[1]);
5199
5200   if (val < 0)
5201     operands[2] = GEN_INT (0);
5202   else if (val >= 32 * 8)
5203     {
5204       int off = val & 7;
5205
5206       operands[1] = GEN_INT (0x8 + off);
5207       operands[2] = GEN_INT (val - off - 0x8);
5208     }
5209   else
5210     {
5211       int off = val & 7;
5212
5213       operands[1] = GEN_INT (off);
5214       operands[2] = GEN_INT (val - off);
5215     }
5216 }")
5217
5218 ;; Handle input reloads in DImode.
5219 ;; This is mainly to handle reloading HILO_REGNUM.  Note that we may
5220 ;; see it as the source or the destination, depending upon which way
5221 ;; reload handles the instruction.
5222 ;; Making the second operand TImode is a trick.  The compiler may
5223 ;; reuse the same register for operand 0 and operand 2.  Using TImode
5224 ;; gives us two registers, so we can always use the one which is not
5225 ;; used.
5226
5227 (define_expand "reload_indi"
5228   [(set (match_operand:DI 0 "register_operand" "=b")
5229         (match_operand:DI 1 "" "b"))
5230    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5231   "TARGET_64BIT"
5232   "
5233 {
5234   rtx scratch = gen_rtx_REG (DImode,
5235                              (REGNO (operands[0]) == REGNO (operands[2])
5236                               ? REGNO (operands[2]) + 1
5237                               : REGNO (operands[2])));
5238
5239   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5240     {
5241       if (GET_CODE (operands[1]) == MEM)
5242         {
5243           rtx memword, offword, hi_word, lo_word;
5244           rtx addr = find_replacement (&XEXP (operands[1], 0));
5245           rtx op1 = replace_equiv_address (operands[1], addr);
5246
5247           scratch = gen_rtx_REG (SImode, REGNO (scratch));
5248           memword = adjust_address (op1, SImode, 0);
5249           offword = adjust_address (op1, SImode, 4);
5250
5251           if (BYTES_BIG_ENDIAN)
5252             {
5253               hi_word = memword;
5254               lo_word = offword;
5255             }
5256           else
5257             {
5258               hi_word = offword;
5259               lo_word = memword;
5260             }
5261           emit_move_insn (scratch, hi_word);
5262           emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
5263           emit_move_insn (scratch, lo_word);
5264           emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
5265           emit_insn (gen_hilo_delay (operands[0]));
5266         }
5267       else
5268         {
5269           emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5270           emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
5271           emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5272           emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5273           emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5274           emit_insn (gen_hilo_delay (operands[0]));
5275         }
5276       DONE;
5277     }
5278   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5279     {
5280       emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
5281       emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5282       emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5283       emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
5284       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5285       emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5286       emit_insn (gen_hilo_delay (operands[1]));
5287       DONE;
5288     }
5289   /* This handles moves between a float register and HI/LO.  */
5290   emit_move_insn (scratch, operands[1]);
5291   emit_move_insn (operands[0], scratch);
5292   DONE;
5293 }")
5294
5295 ;; Handle output reloads in DImode.
5296
5297 ;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5298 ;; use a TImode scratch reg.
5299
5300 (define_expand "reload_outdi"
5301   [(set (match_operand:DI 0 "general_operand" "=b")
5302         (match_operand:DI 1 "se_register_operand" "b"))
5303    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5304   "TARGET_64BIT"
5305   "
5306 {
5307   rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5308
5309   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5310     {
5311       emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5312       emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5313       emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5314       emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5315       emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5316       emit_insn (gen_hilo_delay (operands[0]));
5317       DONE;
5318     }
5319   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5320     {
5321       if (GET_CODE (operands[0]) == MEM)
5322         {
5323           rtx scratch, memword, offword, hi_word, lo_word;
5324           rtx addr = find_replacement (&XEXP (operands[0], 0));
5325           rtx op0 = replace_equiv_address (operands[0], addr);
5326
5327           scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
5328           memword = adjust_address (op0, SImode, 0);
5329           offword = adjust_address (op0, SImode, 4);
5330
5331           if (BYTES_BIG_ENDIAN)
5332             {
5333               hi_word = memword;
5334               lo_word = offword;
5335             }
5336           else
5337             {
5338               hi_word = offword;
5339               lo_word = memword;
5340             }
5341           emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
5342           emit_move_insn (hi_word, scratch);
5343           emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
5344           emit_move_insn (lo_word, scratch);
5345           emit_insn (gen_hilo_delay (operands[1]));
5346         }
5347       else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
5348         {
5349           /* Handle the case where operand[0] is not a 'd' register,
5350              and hence we can not directly move from the HILO register
5351              into it.  */
5352           rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5353           emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5354           emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5355           emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5356           emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
5357           emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
5358           emit_insn (gen_iordi3 (scratch, scratch, scratch2));
5359           emit_insn (gen_movdi (operands[0], scratch));
5360           emit_insn (gen_hilo_delay (operands[1]));
5361         }
5362       else
5363         {
5364           emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5365           emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5366           emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5367           emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5368           emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5369           emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5370           emit_insn (gen_hilo_delay (operands[1]));
5371         }
5372       DONE;
5373     }
5374   /* This handles moves between a float register and HI/LO.  */
5375   emit_move_insn (scratch, operands[1]);
5376   emit_move_insn (operands[0], scratch);
5377   DONE;
5378 }")
5379
5380 ;; 32-bit Integer moves
5381
5382 (define_split
5383   [(set (match_operand:SI 0 "register_operand" "")
5384         (match_operand:SI 1 "large_int" ""))]
5385   "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
5386   [(set (match_dup 0)
5387         (match_dup 2))
5388    (set (match_dup 0)
5389         (ior:SI (match_dup 0)
5390                 (match_dup 3)))]
5391   "
5392 {
5393   operands[2] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
5394                                              & BITMASK_UPPER16,
5395                                              SImode));
5396   operands[3] = GEN_INT (INTVAL (operands[1]) & BITMASK_LOWER16);
5397 }")
5398
5399 ;; Unlike most other insns, the move insns can't be split with
5400 ;; different predicates, because register spilling and other parts of
5401 ;; the compiler, have memoized the insn number already.
5402
5403 (define_expand "movsi"
5404   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5405         (match_operand:SI 1 "general_operand" ""))]
5406   ""
5407   "
5408 {
5409   if (mips_split_addresses && mips_check_split (operands[1], SImode))
5410     {
5411       enum machine_mode mode = GET_MODE (operands[0]);
5412       rtx tem = ((reload_in_progress | reload_completed)
5413                  ? operands[0] : gen_reg_rtx (mode));
5414
5415       emit_insn (gen_rtx_SET (VOIDmode, tem,
5416                               gen_rtx_HIGH (mode, operands[1])));
5417
5418       operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
5419     }
5420
5421   /* If we are generating embedded PIC code, and we are referring to a
5422      symbol in the .text section, we must use an offset from the start
5423      of the function.  */
5424   if (TARGET_EMBEDDED_PIC
5425       && (GET_CODE (operands[1]) == LABEL_REF
5426           || (GET_CODE (operands[1]) == SYMBOL_REF
5427               && ! SYMBOL_REF_FLAG (operands[1]))))
5428     {
5429       rtx temp;
5430
5431       temp = embedded_pic_offset (operands[1]);
5432       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
5433                            force_reg (SImode, temp));
5434       emit_move_insn (operands[0], force_reg (SImode, temp));
5435       DONE;
5436     }
5437
5438   /* If operands[1] is a constant address invalid for pic, then we need to
5439      handle it just like LEGITIMIZE_ADDRESS does.  */
5440   if (flag_pic && pic_address_needs_scratch (operands[1]))
5441     {
5442       rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
5443       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5444
5445       if (! SMALL_INT (temp2))
5446         temp2 = force_reg (SImode, temp2);
5447
5448       emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, temp2));
5449       DONE;
5450     }
5451
5452   /* On the mips16, we can handle a GP relative reference by adding in
5453      $gp.  We need to check the name to see whether this is a string
5454      constant.  */
5455   if (TARGET_MIPS16
5456       && register_operand (operands[0], SImode)
5457       && GET_CODE (operands[1]) == SYMBOL_REF
5458       && SYMBOL_REF_FLAG (operands[1]))
5459     {
5460       const char *name = XSTR (operands[1], 0);
5461
5462       if (name[0] != '*'
5463           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5464                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5465         {
5466           rtx base_reg;
5467
5468           if (reload_in_progress || reload_completed)
5469             {
5470               /* We need to reload this address.  In this case we
5471                  aren't going to have a chance to combine loading the
5472                  address with the load or store.  That means that we
5473                  can either generate a 2 byte move followed by a 4
5474                  byte addition, or a 2 byte load with a 4 byte entry
5475                  in the constant table.  Since the entry in the
5476                  constant table might be shared, we're better off, on
5477                  average, loading the address from the constant table.  */
5478               emit_move_insn (operands[0],
5479                               force_const_mem (SImode, operands[1]));
5480               DONE;
5481             }
5482
5483           base_reg = gen_reg_rtx (Pmode);
5484           emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5485
5486           emit_move_insn (operands[0],
5487                           gen_rtx (PLUS, Pmode, base_reg,
5488                                    mips16_gp_offset (operands[1])));
5489           DONE;
5490         }
5491     }
5492
5493   if ((reload_in_progress | reload_completed) == 0
5494       && !register_operand (operands[0], SImode)
5495       && !register_operand (operands[1], SImode)
5496       && (TARGET_MIPS16
5497           || GET_CODE (operands[1]) != CONST_INT
5498           || INTVAL (operands[1]) != 0))
5499     {
5500       rtx temp = force_reg (SImode, operands[1]);
5501       emit_move_insn (operands[0], temp);
5502       DONE;
5503     }
5504 }")
5505
5506 ;; We can only store $ra directly into a small sp offset.  Should the
5507 ;; offset be too wide, non-constant or not sp-based, leave it up to
5508 ;; reload to choose a scratch register.
5509
5510 (define_insn ""
5511   [(set (mem:SI (plus:SI (reg:SI 29)
5512                          (match_operand:SI 0 "small_int" "n")))
5513         (reg:SI 31))]
5514   "TARGET_MIPS16"
5515   "sw\\t$31,%0($sp)"
5516   [(set_attr "type"     "store")
5517    (set_attr "mode"     "SI")
5518    (set_attr_alternative
5519     "length"
5520     [(if_then_else
5521       (lt (symbol_ref "(unsigned HOST_WIDE_INT) INTVAL (operands[0])")
5522           (const_int 1024))
5523       (const_int 4)
5524       (const_int 8))])])
5525
5526 ;; The difference between these two is whether or not ints are allowed
5527 ;; in FP registers (off by default, use -mdebugh to enable).
5528
5529 (define_insn "movsi_internal1"
5530   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x,*x,*d,*d,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5531         (match_operand:SI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,J,*d,*x,*a,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5532   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5533    && (register_operand (operands[0], SImode)
5534        || register_operand (operands[1], SImode)
5535        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5536   "* return mips_move_1word (operands, insn, FALSE);"
5537   [(set_attr "type"     "move,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5538    (set_attr "mode"     "SI")
5539    (set_attr "length"   "4,4,8,4,8,4,8,4,4,4,4,8,4,8,4,4,4,4,4,4,8,4,4,8")])
5540
5541 (define_insn "movsi_internal2"
5542   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5543         (match_operand:SI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5544   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5545    && (register_operand (operands[0], SImode)
5546        || register_operand (operands[1], SImode)
5547        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5548   "* return mips_move_1word (operands, insn, FALSE);"
5549   [(set_attr "type"     "move,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5550    (set_attr "mode"     "SI")
5551    (set_attr "length"   "4,4,8,4,8,4,8,4,4,4,4,4,4,4,4,8,4,4,8")])
5552
5553 ;; This is the mips16 movsi instruction.  We accept a small integer as
5554 ;; the source if the destination is a GP memory reference.  This is
5555 ;; because we want the combine pass to turn adding a GP reference to a
5556 ;; register into a direct GP reference, but the combine pass will pass
5557 ;; in the source as a constant if it finds an equivalent one.  If the
5558 ;; instruction is recognized, reload will force the constant back out
5559 ;; into a register.
5560
5561 (define_insn ""
5562   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d,*d")
5563         (match_operand:SI 1 "move_operand" "d,d,y,K,N,s,R,m,d,d,*x,*a"))]
5564   "TARGET_MIPS16
5565    && (register_operand (operands[0], SImode)
5566        || register_operand (operands[1], SImode)
5567        || (GET_CODE (operands[0]) == MEM
5568            && GET_CODE (XEXP (operands[0], 0)) == PLUS
5569            && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
5570            && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
5571            && GET_CODE (operands[1]) == CONST_INT
5572            && (SMALL_INT (operands[1])
5573                || SMALL_INT_UNSIGNED (operands[1]))))"
5574   "* return mips_move_1word (operands, insn, FALSE);"
5575   [(set_attr "type"     "move,move,move,arith,arith,arith,load,load,store,store,hilo,hilo")
5576    (set_attr "mode"     "SI")
5577    (set_attr_alternative "length"
5578                 [(const_int 4)
5579                  (const_int 4)
5580                  (const_int 4)
5581                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5582                                (const_int 4)
5583                                (const_int 8))
5584                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5585                                (const_int 8)
5586                                (const_int 12))
5587                  (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
5588                                (const_int 4)
5589                                (const_int 8))
5590                  (const_int 4)
5591                  (const_int 8)
5592                  (const_int 4)
5593                  (const_int 8)
5594                  (const_int 4)
5595                  (const_int 4)])])
5596
5597 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
5598 ;; when the original load is a 4 byte instruction but the add and the
5599 ;; load are 2 2 byte instructions.
5600
5601 (define_split
5602   [(set (match_operand:SI 0 "register_operand" "")
5603         (mem:SI (plus:SI (match_dup 0)
5604                          (match_operand:SI 1 "const_int_operand" ""))))]
5605   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5606    && GET_CODE (operands[0]) == REG
5607    && M16_REG_P (REGNO (operands[0]))
5608    && GET_CODE (operands[1]) == CONST_INT
5609    && ((INTVAL (operands[1]) < 0
5610         && INTVAL (operands[1]) >= -0x80)
5611        || (INTVAL (operands[1]) >= 32 * 4
5612            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5613        || (INTVAL (operands[1]) >= 0
5614            && INTVAL (operands[1]) < 32 * 4
5615            && (INTVAL (operands[1]) & 3) != 0))"
5616   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5617    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
5618   "
5619 {
5620   HOST_WIDE_INT val = INTVAL (operands[1]);
5621
5622   if (val < 0)
5623     operands[2] = GEN_INT (0);
5624   else if (val >= 32 * 4)
5625     {
5626       int off = val & 3;
5627
5628       operands[1] = GEN_INT (0x7c + off);
5629       operands[2] = GEN_INT (val - off - 0x7c);
5630     }
5631   else
5632     {
5633       int off = val & 3;
5634
5635       operands[1] = GEN_INT (off);
5636       operands[2] = GEN_INT (val - off);
5637     }
5638 }")
5639
5640 ;; On the mips16, we can split a load of certain constants into a load
5641 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
5642 ;; instructions.
5643
5644 (define_split
5645   [(set (match_operand:SI 0 "register_operand" "")
5646         (match_operand:SI 1 "const_int_operand" ""))]
5647   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5648    && GET_CODE (operands[0]) == REG
5649    && M16_REG_P (REGNO (operands[0]))
5650    && GET_CODE (operands[1]) == CONST_INT
5651    && INTVAL (operands[1]) >= 0x100
5652    && INTVAL (operands[1]) <= 0xff + 0x7f"
5653   [(set (match_dup 0) (match_dup 1))
5654    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5655   "
5656 {
5657   int val = INTVAL (operands[1]);
5658
5659   operands[1] = GEN_INT (0xff);
5660   operands[2] = GEN_INT (val - 0xff);
5661 }")
5662
5663 ;; On the mips16, we can split a load of a negative constant into a
5664 ;; load and a neg.  That's what mips_move_1word will generate anyhow.
5665
5666 (define_split
5667   [(set (match_operand:SI 0 "register_operand" "")
5668         (match_operand:SI 1 "const_int_operand" ""))]
5669   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5670    && GET_CODE (operands[0]) == REG
5671    && M16_REG_P (REGNO (operands[0]))
5672    && GET_CODE (operands[1]) == CONST_INT
5673    && INTVAL (operands[1]) < 0
5674    && INTVAL (operands[1]) > - 0x8000"
5675   [(set (match_dup 0) (match_dup 1))
5676    (set (match_dup 0) (neg:SI (match_dup 0)))]
5677   "
5678 {
5679   operands[1] = GEN_INT (- INTVAL (operands[1]));
5680 }")
5681
5682 ;; Reload HILO_REGNUM in SI mode.  This needs a scratch register in
5683 ;; order to set the sign bit correctly in the HI register.
5684
5685 (define_expand "reload_outsi"
5686   [(set (match_operand:SI 0 "general_operand" "=b")
5687         (match_operand:SI 1 "register_operand" "b"))
5688    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5689   "TARGET_64BIT || TARGET_MIPS16"
5690   "
5691 {
5692   if (TARGET_64BIT
5693       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5694     {
5695       emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
5696       emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5697       emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
5698       emit_insn (gen_hilo_delay (operands[0]));
5699       DONE;
5700     }
5701   /* Use a mult to reload LO on mips16.  ??? This is hideous.  */
5702   if (TARGET_MIPS16
5703       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5704     {
5705       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5706       /* This is gen_mulsi3_internal, but we need to fill in the
5707          scratch registers.  */
5708       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5709                           gen_rtvec (3,
5710                                      gen_rtx (SET, VOIDmode,
5711                                               operands[0],
5712                                               gen_rtx (MULT, SImode,
5713                                                        operands[1],
5714                                                        operands[2])),
5715                                      gen_rtx (CLOBBER, VOIDmode,
5716                                               gen_rtx (REG, SImode, 64)),
5717                                      gen_rtx (CLOBBER, VOIDmode,
5718                                               gen_rtx (REG, SImode, 66)))));
5719       DONE;
5720     }
5721   /* FIXME: I don't know how to get a value into the HI register.  */
5722   if (GET_CODE (operands[0]) == REG
5723       && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5724           : GP_REG_P (REGNO (operands[0]))))
5725     {
5726       emit_move_insn (operands[0], operands[1]);
5727       DONE;
5728     }
5729   /* This handles moves between a float register and HI/LO.  */
5730   emit_move_insn (operands[2], operands[1]);
5731   emit_move_insn (operands[0], operands[2]);
5732   DONE;
5733 }")
5734
5735 ;; Reload a value into HI or LO.  There is no mthi or mtlo on mips16,
5736 ;; so we use a mult.  ??? This is hideous, and we ought to figure out
5737 ;; something better.
5738
5739 ;; We use no predicate for operand1, because it may be a PLUS, and there
5740 ;; is no convenient predicate for that.
5741
5742 (define_expand "reload_insi"
5743   [(set (match_operand:SI 0 "register_operand" "=b")
5744         (match_operand:SI 1 "" "b"))
5745    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5746   "TARGET_MIPS16"
5747   "
5748 {
5749   if (TARGET_MIPS16
5750       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5751     {
5752       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5753       /* This is gen_mulsi3_internal, but we need to fill in the
5754          scratch registers.  */
5755       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5756                           gen_rtvec (3,
5757                                      gen_rtx (SET, VOIDmode,
5758                                               operands[0],
5759                                               gen_rtx (MULT, SImode,
5760                                                        operands[1],
5761                                                        operands[2])),
5762                                      gen_rtx (CLOBBER, VOIDmode,
5763                                               gen_rtx (REG, SImode, 64)),
5764                                      gen_rtx (CLOBBER, VOIDmode,
5765                                               gen_rtx (REG, SImode, 66)))));
5766       DONE;
5767     }
5768
5769   /* If this is a plus, then this must be an add of the stack pointer against
5770      either a hard register or a pseudo.  */
5771   if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5772     {
5773       rtx plus_op;
5774
5775       if (XEXP (operands[1], 0) == stack_pointer_rtx)
5776         plus_op = XEXP (operands[1], 1);
5777       else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5778         plus_op = XEXP (operands[1], 0);
5779       else
5780         abort ();
5781
5782       /* We should have a register now.  */
5783       if (GET_CODE (plus_op) != REG)
5784         abort ();
5785
5786       if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5787         {
5788           /* We have to have at least one temporary register which is not
5789              overlapping plus_op.  */
5790           if (! rtx_equal_p (plus_op, operands[0]))
5791             {
5792               emit_move_insn (operands[0], stack_pointer_rtx);
5793               emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5794             }
5795           else if (! rtx_equal_p (plus_op, operands[2]))
5796             {
5797               emit_move_insn (operands[2], stack_pointer_rtx);
5798               emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5799             }
5800           else
5801             abort ();
5802         }
5803       else
5804         {
5805           /* We need two registers in this case.  */
5806           if (! rtx_equal_p (operands[0], operands[2]))
5807             {
5808               emit_move_insn (operands[0], stack_pointer_rtx);
5809               emit_move_insn (operands[2], plus_op);
5810               emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5811             }
5812           else
5813             abort ();
5814         }
5815       DONE;
5816     }
5817
5818   /* FIXME: I don't know how to get a value into the HI register.  */
5819   emit_move_insn (operands[0], operands[1]);
5820   DONE;
5821 }")
5822
5823 ;; This insn is for the unspec delay for HILO.
5824
5825 (define_insn "hilo_delay"
5826   [(unspec [(match_operand 0 "register_operand" "=b")] UNSPEC_HILO_DELAY)]
5827   ""
5828   ""
5829   [(set_attr "type" "nop")
5830    (set_attr "mode" "none")
5831    (set_attr "can_delay" "no")])
5832
5833 ;; This insn handles moving CCmode values.  It's really just a
5834 ;; slightly simplified copy of movsi_internal2, with additional cases
5835 ;; to move a condition register to a general register and to move
5836 ;; between the general registers and the floating point registers.
5837
5838 (define_insn "movcc"
5839   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
5840         (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
5841   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5842   "* return mips_move_1word (operands, insn, FALSE);"
5843   [(set_attr "type"     "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
5844    (set_attr "mode"     "SI")
5845    (set_attr "length"   "8,4,4,8,4,8,4,4,4,4,8,4,8")])
5846
5847 ;; Reload condition code registers.  These need scratch registers.
5848
5849 (define_expand "reload_incc"
5850   [(set (match_operand:CC 0 "register_operand" "=z")
5851         (match_operand:CC 1 "general_operand" "z"))
5852    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5853   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5854   "
5855 {
5856   rtx source;
5857   rtx fp1, fp2;
5858   int regno;
5859
5860   /* This is called when are copying some value into a condition code
5861      register.  Operand 0 is the condition code register.  Operand 1
5862      is the source.  Operand 2 is a scratch register; we use TFmode
5863      because we actually need two floating point registers.  */
5864   if (! ST_REG_P (true_regnum (operands[0]))
5865       || ! FP_REG_P (true_regnum (operands[2])))
5866     abort ();
5867
5868   /* We need to get the source in SFmode so that the insn is
5869      recognized.  */
5870   if (GET_CODE (operands[1]) == MEM)
5871     source = adjust_address (operands[1], SFmode, 0);
5872   else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
5873     source = gen_rtx_REG (SFmode, true_regnum (operands[1]));
5874   else
5875     source = operands[1];
5876
5877   /* FP1 and FP2 are the two halves of the TFmode scratch operand.  They
5878      will be single registers in 64-bit mode and register pairs in 32-bit
5879      mode.  SOURCE is loaded into FP1 and zero is loaded into FP2.  */
5880   regno = REGNO (operands[2]);
5881   fp1 = gen_rtx_REG (SFmode, regno);
5882   fp2 = gen_rtx_REG (SFmode, regno + HARD_REGNO_NREGS (regno, DFmode));
5883
5884   emit_insn (gen_move_insn (fp1, source));
5885   emit_insn (gen_move_insn (fp2, gen_rtx_REG (SFmode, 0)));
5886   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5887                           gen_rtx_LT (CCmode, fp2, fp1)));
5888
5889   DONE;
5890 }")
5891
5892 (define_expand "reload_outcc"
5893   [(set (match_operand:CC 0 "general_operand" "=z")
5894         (match_operand:CC 1 "register_operand" "z"))
5895    (clobber (match_operand:CC 2 "register_operand" "=&d"))]
5896   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5897   "
5898 {
5899   /* This is called when we are copying a condition code register out
5900      to save it somewhere.  Operand 0 should be the location we are
5901      going to save it to.  Operand 1 should be the condition code
5902      register.  Operand 2 should be a scratch general purpose register
5903      created for us by reload.  The mips_secondary_reload_class
5904      function should have told reload that we don't need a scratch
5905      register if the destination is a general purpose register anyhow.  */
5906   if (ST_REG_P (true_regnum (operands[0]))
5907       || GP_REG_P (true_regnum (operands[0]))
5908       || ! ST_REG_P (true_regnum (operands[1]))
5909       || ! GP_REG_P (true_regnum (operands[2])))
5910     abort ();
5911
5912   /* All we have to do is copy the value from the condition code to
5913      the data register, which movcc can handle, and then store the
5914      value into the real final destination.  */
5915   emit_insn (gen_move_insn (operands[2], operands[1]));
5916   emit_insn (gen_move_insn (operands[0], operands[2]));
5917
5918   DONE;
5919 }")
5920
5921 ;; MIPS4 supports loading and storing a floating point register from
5922 ;; the sum of two general registers.  We use two versions for each of
5923 ;; these four instructions: one where the two general registers are
5924 ;; SImode, and one where they are DImode.  This is because general
5925 ;; registers will be in SImode when they hold 32 bit values, but,
5926 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5927 ;; instructions will still work correctly.
5928
5929 ;; ??? Perhaps it would be better to support these instructions by
5930 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
5931 ;; these instructions can only be used to load and store floating
5932 ;; point registers, that would probably cause trouble in reload.
5933
5934 (define_insn ""
5935   [(set (match_operand:SF 0 "register_operand" "=f")
5936         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5937                          (match_operand:SI 2 "register_operand" "d"))))]
5938   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5939   "lwxc1\\t%0,%1(%2)"
5940   [(set_attr "type"     "load")
5941    (set_attr "mode"     "SF")])
5942
5943 (define_insn ""
5944   [(set (match_operand:SF 0 "register_operand" "=f")
5945         (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5946                          (match_operand:DI 2 "se_register_operand" "d"))))]
5947   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5948   "lwxc1\\t%0,%1(%2)"
5949   [(set_attr "type"     "load")
5950    (set_attr "mode"     "SF")])
5951
5952 (define_insn ""
5953   [(set (match_operand:DF 0 "register_operand" "=f")
5954         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5955                          (match_operand:SI 2 "register_operand" "d"))))]
5956   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5957   "ldxc1\\t%0,%1(%2)"
5958   [(set_attr "type"     "load")
5959    (set_attr "mode"     "DF")])
5960
5961 (define_insn ""
5962   [(set (match_operand:DF 0 "register_operand" "=f")
5963         (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5964                          (match_operand:DI 2 "se_register_operand" "d"))))]
5965   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5966   "ldxc1\\t%0,%1(%2)"
5967   [(set_attr "type"     "load")
5968    (set_attr "mode"     "DF")])
5969
5970 (define_insn ""
5971   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5972                          (match_operand:SI 2 "register_operand" "d")))
5973         (match_operand:SF 0 "register_operand" "f"))]
5974   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5975   "swxc1\\t%0,%1(%2)"
5976   [(set_attr "type"     "store")
5977    (set_attr "mode"     "SF")])
5978
5979 (define_insn ""
5980   [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5981                          (match_operand:DI 2 "se_register_operand" "d")))
5982         (match_operand:SF 0 "register_operand" "f"))]
5983   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5984   "swxc1\\t%0,%1(%2)"
5985   [(set_attr "type"     "store")
5986    (set_attr "mode"     "SF")])
5987
5988 (define_insn ""
5989   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5990                          (match_operand:SI 2 "register_operand" "d")))
5991         (match_operand:DF 0 "register_operand" "f"))]
5992   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5993   "sdxc1\\t%0,%1(%2)"
5994   [(set_attr "type"     "store")
5995    (set_attr "mode"     "DF")])
5996
5997 (define_insn ""
5998   [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5999                          (match_operand:DI 2 "se_register_operand" "d")))
6000         (match_operand:DF 0 "register_operand" "f"))]
6001   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6002   "sdxc1\\t%0,%1(%2)"
6003   [(set_attr "type"     "store")
6004    (set_attr "mode"     "DF")])
6005
6006 ;; 16-bit Integer moves
6007
6008 ;; Unlike most other insns, the move insns can't be split with
6009 ;; different predicates, because register spilling and other parts of
6010 ;; the compiler, have memoized the insn number already.
6011 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6012
6013 (define_expand "movhi"
6014   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6015         (match_operand:HI 1 "general_operand" ""))]
6016   ""
6017   "
6018 {
6019   if ((reload_in_progress | reload_completed) == 0
6020       && !register_operand (operands[0], HImode)
6021       && !register_operand (operands[1], HImode)
6022       && (TARGET_MIPS16
6023           || (GET_CODE (operands[1]) != CONST_INT
6024           || INTVAL (operands[1]) != 0)))
6025     {
6026       rtx temp = force_reg (HImode, operands[1]);
6027       emit_move_insn (operands[0], temp);
6028       DONE;
6029     }
6030 }")
6031
6032 ;; The difference between these two is whether or not ints are allowed
6033 ;; in FP registers (off by default, use -mdebugh to enable).
6034
6035 (define_insn "movhi_internal1"
6036   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
6037         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6038   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6039    && (register_operand (operands[0], HImode)
6040        || register_operand (operands[1], HImode)
6041        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6042   "* return mips_move_1word (operands, insn, TRUE);"
6043   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6044    (set_attr "mode"     "HI")
6045    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,4")])
6046
6047 (define_insn "movhi_internal2"
6048   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
6049         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
6050   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6051    && (register_operand (operands[0], HImode)
6052        || register_operand (operands[1], HImode)
6053        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6054   "* return mips_move_1word (operands, insn, TRUE);"
6055   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
6056    (set_attr "mode"     "HI")
6057    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4")])
6058
6059 (define_insn ""
6060   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6061         (match_operand:HI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
6062   "TARGET_MIPS16
6063    && (register_operand (operands[0], HImode)
6064        || register_operand (operands[1], HImode))"
6065   "* return mips_move_1word (operands, insn, TRUE);"
6066   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
6067    (set_attr "mode"     "HI")
6068    (set_attr_alternative "length"
6069                 [(const_int 4)
6070                  (const_int 4)
6071                  (const_int 4)
6072                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6073                                (const_int 4)
6074                                (const_int 8))
6075                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6076                                (const_int 8)
6077                                (const_int 12))
6078                  (const_int 4)
6079                  (const_int 8)
6080                  (const_int 4)
6081                  (const_int 8)
6082                  (const_int 4)])])
6083
6084
6085 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
6086 ;; when the original load is a 4 byte instruction but the add and the
6087 ;; load are 2 2 byte instructions.
6088
6089 (define_split
6090   [(set (match_operand:HI 0 "register_operand" "")
6091         (mem:HI (plus:SI (match_dup 0)
6092                          (match_operand:SI 1 "const_int_operand" ""))))]
6093   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6094    && GET_CODE (operands[0]) == REG
6095    && M16_REG_P (REGNO (operands[0]))
6096    && GET_CODE (operands[1]) == CONST_INT
6097    && ((INTVAL (operands[1]) < 0
6098         && INTVAL (operands[1]) >= -0x80)
6099        || (INTVAL (operands[1]) >= 32 * 2
6100            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
6101        || (INTVAL (operands[1]) >= 0
6102            && INTVAL (operands[1]) < 32 * 2
6103            && (INTVAL (operands[1]) & 1) != 0))"
6104   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6105    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
6106   "
6107 {
6108   HOST_WIDE_INT val = INTVAL (operands[1]);
6109
6110   if (val < 0)
6111     operands[2] = GEN_INT (0);
6112   else if (val >= 32 * 2)
6113     {
6114       int off = val & 1;
6115
6116       operands[1] = GEN_INT (0x7e + off);
6117       operands[2] = GEN_INT (val - off - 0x7e);
6118     }
6119   else
6120     {
6121       int off = val & 1;
6122
6123       operands[1] = GEN_INT (off);
6124       operands[2] = GEN_INT (val - off);
6125     }
6126 }")
6127
6128 ;; 8-bit Integer moves
6129
6130 ;; Unlike most other insns, the move insns can't be split with
6131 ;; different predicates, because register spilling and other parts of
6132 ;; the compiler, have memoized the insn number already.
6133 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6134
6135 (define_expand "movqi"
6136   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6137         (match_operand:QI 1 "general_operand" ""))]
6138   ""
6139   "
6140 {
6141   if ((reload_in_progress | reload_completed) == 0
6142       && !register_operand (operands[0], QImode)
6143       && !register_operand (operands[1], QImode)
6144       && (TARGET_MIPS16
6145           || (GET_CODE (operands[1]) != CONST_INT
6146           || INTVAL (operands[1]) != 0)))
6147     {
6148       rtx temp = force_reg (QImode, operands[1]);
6149       emit_move_insn (operands[0], temp);
6150       DONE;
6151     }
6152 }")
6153
6154 ;; The difference between these two is whether or not ints are allowed
6155 ;; in FP registers (off by default, use -mdebugh to enable).
6156
6157 (define_insn "movqi_internal1"
6158   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
6159         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6160   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6161    && (register_operand (operands[0], QImode)
6162        || register_operand (operands[1], QImode)
6163        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6164   "* return mips_move_1word (operands, insn, TRUE);"
6165   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6166    (set_attr "mode"     "QI")
6167    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,4")])
6168
6169 (define_insn "movqi_internal2"
6170   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
6171         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
6172   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6173    && (register_operand (operands[0], QImode)
6174        || register_operand (operands[1], QImode)
6175        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6176   "* return mips_move_1word (operands, insn, TRUE);"
6177   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
6178    (set_attr "mode"     "QI")
6179    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4")])
6180
6181 (define_insn ""
6182   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6183         (match_operand:QI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
6184   "TARGET_MIPS16
6185    && (register_operand (operands[0], QImode)
6186        || register_operand (operands[1], QImode))"
6187   "* return mips_move_1word (operands, insn, TRUE);"
6188   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
6189    (set_attr "mode"     "QI")
6190    (set_attr_alternative "length"
6191                 [(const_int 4)
6192                  (const_int 4)
6193                  (const_int 4)
6194                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6195                                (const_int 4)
6196                                (const_int 8))
6197                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6198                                (const_int 8)
6199                                (const_int 12))
6200                  (const_int 4)
6201                  (const_int 8)
6202                  (const_int 4)
6203                  (const_int 8)
6204                  (const_int 4)])])
6205
6206
6207 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
6208 ;; when the original load is a 4 byte instruction but the add and the
6209 ;; load are 2 2 byte instructions.
6210
6211 (define_split
6212   [(set (match_operand:QI 0 "register_operand" "")
6213         (mem:QI (plus:SI (match_dup 0)
6214                          (match_operand:SI 1 "const_int_operand" ""))))]
6215   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6216    && GET_CODE (operands[0]) == REG
6217    && M16_REG_P (REGNO (operands[0]))
6218    && GET_CODE (operands[1]) == CONST_INT
6219    && ((INTVAL (operands[1]) < 0
6220         && INTVAL (operands[1]) >= -0x80)
6221        || (INTVAL (operands[1]) >= 32
6222            && INTVAL (operands[1]) <= 31 + 0x7f))"
6223   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6224    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
6225   "
6226 {
6227   HOST_WIDE_INT val = INTVAL (operands[1]);
6228
6229   if (val < 0)
6230     operands[2] = GEN_INT (0);
6231   else
6232     {
6233       operands[1] = GEN_INT (0x7f);
6234       operands[2] = GEN_INT (val - 0x7f);
6235     }
6236 }")
6237
6238 ;; 32-bit floating point moves
6239
6240 (define_expand "movsf"
6241   [(set (match_operand:SF 0 "nonimmediate_operand" "")
6242         (match_operand:SF 1 "general_operand" ""))]
6243   ""
6244   "
6245 {
6246   if ((reload_in_progress | reload_completed) == 0
6247       && !register_operand (operands[0], SFmode)
6248       && !register_operand (operands[1], SFmode)
6249       && (TARGET_MIPS16
6250           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6251                && operands[1] != CONST0_RTX (SFmode))))
6252     {
6253       rtx temp = force_reg (SFmode, operands[1]);
6254       emit_move_insn (operands[0], temp);
6255       DONE;
6256     }
6257 }")
6258
6259 (define_insn "movsf_internal1"
6260   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
6261         (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
6262   "TARGET_HARD_FLOAT
6263    && (register_operand (operands[0], SFmode)
6264        || register_operand (operands[1], SFmode)
6265        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6266        || operands[1] == CONST0_RTX (SFmode))"
6267   "* return mips_move_1word (operands, insn, FALSE);"
6268   [(set_attr "type"     "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
6269    (set_attr "mode"     "SF")
6270    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,8,4,8")])
6271
6272
6273 (define_insn "movsf_internal2"
6274   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
6275         (match_operand:SF 1 "general_operand" "      Gd,R,Fm,d,d"))]
6276   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
6277    && (register_operand (operands[0], SFmode)
6278        || register_operand (operands[1], SFmode)
6279        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6280        || operands[1] == CONST0_RTX (SFmode))"
6281   "* return mips_move_1word (operands, insn, FALSE);"
6282   [(set_attr "type"     "move,load,load,store,store")
6283    (set_attr "mode"     "SF")
6284    (set_attr "length"   "4,4,8,4,8")])
6285
6286 (define_insn ""
6287   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
6288         (match_operand:SF 1 "general_operand"      "d,d,y,R,Fm,d,d"))]
6289   "TARGET_MIPS16
6290    && (register_operand (operands[0], SFmode)
6291        || register_operand (operands[1], SFmode))"
6292   "* return mips_move_1word (operands, insn, FALSE);"
6293   [(set_attr "type"     "move,move,move,load,load,store,store")
6294    (set_attr "mode"     "SF")
6295    (set_attr "length"   "4,4,4,4,8,4,8")])
6296
6297
6298 ;; 64-bit floating point moves
6299
6300 (define_expand "movdf"
6301   [(set (match_operand:DF 0 "nonimmediate_operand" "")
6302         (match_operand:DF 1 "general_operand" ""))]
6303   ""
6304   "
6305 {
6306   if ((reload_in_progress | reload_completed) == 0
6307       && !register_operand (operands[0], DFmode)
6308       && !register_operand (operands[1], DFmode)
6309       && (TARGET_MIPS16
6310           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6311                && operands[1] != CONST0_RTX (DFmode))))
6312     {
6313       rtx temp = force_reg (DFmode, operands[1]);
6314       emit_move_insn (operands[0], temp);
6315       DONE;
6316     }
6317 }")
6318
6319 (define_insn "movdf_internal1"
6320   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,To,f,*f,*d,*d,*d,*d,*R,*T")
6321         (match_operand:DF 1 "general_operand" "f,R,To,fG,fG,F,*d,*f,*d*G,*R,*T*F,*d,*d"))]
6322   "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
6323    && TARGET_DOUBLE_FLOAT
6324    && (register_operand (operands[0], DFmode)
6325        || register_operand (operands[1], DFmode)
6326        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6327        || operands[1] == CONST0_RTX (DFmode))"
6328   "* return mips_move_2words (operands, insn); "
6329   [(set_attr "type"     "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
6330    (set_attr "mode"     "DF")
6331    (set_attr "length"   "4,8,16,8,16,16,8,8,8,8,16,8,16")])
6332
6333 (define_insn "movdf_internal1a"
6334   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,*d,*d,*d,*To,*R,*d")
6335         (match_operand:DF 1 "general_operand"      " f,To,f,G,f,G,*F,*To,*R,*d,*d,*d"))]
6336   "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
6337    && TARGET_DOUBLE_FLOAT
6338    && (register_operand (operands[0], DFmode)
6339        || register_operand (operands[1], DFmode)
6340        || (GET_CODE (operands [0]) == MEM
6341            && ((GET_CODE (operands[1]) == CONST_INT
6342                 && INTVAL (operands[1]) == 0)
6343                || operands[1] == CONST0_RTX (DFmode))))"
6344   "* return mips_move_2words (operands, insn); "
6345   [(set_attr "type"     "move,load,store,store,store,store,load,load,load,store,store,move")
6346    (set_attr "mode"     "DF")
6347    (set_attr "length"   "4,8,4,4,8,8,8,8,4,8,4,4")])
6348
6349 (define_insn "movdf_internal2"
6350   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To,d,f,f")
6351         (match_operand:DF 1 "general_operand" "dG,R,ToF,d,d,f,d,f"))]
6352   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
6353    && (register_operand (operands[0], DFmode)
6354        || register_operand (operands[1], DFmode)
6355        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6356        || operands[1] == CONST0_RTX (DFmode))"
6357   "* return mips_move_2words (operands, insn); "
6358   [(set_attr "type"     "move,load,load,store,store,xfer,load,move")
6359    (set_attr "mode"     "DF")
6360    (set_attr "length"   "8,8,16,8,16,8,8,4")])
6361
6362 (define_insn ""
6363   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
6364         (match_operand:DF 1 "general_operand" "d,d,y,R,ToF,d,d"))]
6365   "TARGET_MIPS16
6366    && (register_operand (operands[0], DFmode)
6367        || register_operand (operands[1], DFmode))"
6368   "* return mips_move_2words (operands, insn);"
6369   [(set_attr "type"     "move,move,move,load,load,store,store")
6370    (set_attr "mode"     "DF")
6371    (set_attr "length"   "8,8,8,8,16,8,16")])
6372
6373 (define_split
6374   [(set (match_operand:DF 0 "register_operand" "")
6375         (match_operand:DF 1 "register_operand" ""))]
6376   "reload_completed && !TARGET_64BIT
6377    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6378    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6379    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
6380   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
6381    (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
6382   "")
6383
6384 ;; Instructions to load the global pointer register.
6385 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
6386 ;; uses in front of it.  All symbol_refs implicitly use the gp reg.
6387
6388 (define_insn "loadgp"
6389   [(set (reg:DI 28)
6390         (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
6391                              (match_operand:DI 1 "register_operand" "")]
6392                             UNSPEC_LOADGP))
6393    (clobber (reg:DI 1))]
6394   ""
6395   "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
6396   [(set_attr "type"     "move")
6397    (set_attr "mode"     "DI")
6398    (set_attr "length"   "12")])
6399 \f
6400 ;; Block moves, see mips.c for more details.
6401 ;; Argument 0 is the destination
6402 ;; Argument 1 is the source
6403 ;; Argument 2 is the length
6404 ;; Argument 3 is the alignment
6405
6406 (define_expand "movstrsi"
6407   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6408                    (match_operand:BLK 1 "general_operand" ""))
6409               (use (match_operand:SI 2 "arith32_operand" ""))
6410               (use (match_operand:SI 3 "immediate_operand" ""))])]
6411   "!TARGET_MIPS16"
6412   "
6413 {
6414   if (operands[0])              /* avoid unused code messages */
6415     {
6416       expand_block_move (operands);
6417       DONE;
6418     }
6419 }")
6420
6421 ;; Insn generated by block moves
6422
6423 (define_insn "movstrsi_internal"
6424   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6425         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6426    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6427    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6428    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6429    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6430    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6431    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6432    (use (const_int 0))]                                 ;; normal block move
6433   ""
6434   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6435   [(set_attr "type"     "store")
6436    (set_attr "mode"     "none")
6437    (set_attr "length"   "80")])
6438
6439 ;; We need mips16 versions, because an offset from the stack pointer
6440 ;; is not offsettable, since the stack pointer can only handle 4 and 8
6441 ;; byte loads.
6442
6443 (define_insn ""
6444   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6445         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6446    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6447    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6448    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6449    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6450    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6451    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6452    (use (const_int 0))]                                 ;; normal block move
6453   "TARGET_MIPS16"
6454   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6455   [(set_attr "type"     "multi")
6456    (set_attr "mode"     "none")
6457    (set_attr "length"   "80")])
6458
6459 ;; Split a block move into 2 parts, the first part is everything
6460 ;; except for the last move, and the second part is just the last
6461 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
6462 ;; fill a delay slot.  This also prevents a bug in delayed branches
6463 ;; from showing up, which reuses one of the registers in our clobbers.
6464
6465 (define_split
6466   [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6467         (mem:BLK (match_operand:SI 1 "register_operand" "")))
6468    (clobber (match_operand:SI 4 "register_operand" ""))
6469    (clobber (match_operand:SI 5 "register_operand" ""))
6470    (clobber (match_operand:SI 6 "register_operand" ""))
6471    (clobber (match_operand:SI 7 "register_operand" ""))
6472    (use (match_operand:SI 2 "small_int" ""))
6473    (use (match_operand:SI 3 "small_int" ""))
6474    (use (const_int 0))]
6475
6476   "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
6477
6478   ;; All but the last move
6479   [(parallel [(set (mem:BLK (match_dup 0))
6480                    (mem:BLK (match_dup 1)))
6481               (clobber (match_dup 4))
6482               (clobber (match_dup 5))
6483               (clobber (match_dup 6))
6484               (clobber (match_dup 7))
6485               (use (match_dup 2))
6486               (use (match_dup 3))
6487               (use (const_int 1))])
6488
6489    ;; The last store, so it can fill a delay slot
6490    (parallel [(set (mem:BLK (match_dup 0))
6491                    (mem:BLK (match_dup 1)))
6492               (clobber (match_dup 4))
6493               (clobber (match_dup 5))
6494               (clobber (match_dup 6))
6495               (clobber (match_dup 7))
6496               (use (match_dup 2))
6497               (use (match_dup 3))
6498               (use (const_int 2))])]
6499
6500   "")
6501
6502 (define_insn "movstrsi_internal2"
6503   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6504         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6505    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6506    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6507    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6508    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6509    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6510    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6511    (use (const_int 1))]                                 ;; all but last store
6512   ""
6513   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6514   [(set_attr "type"     "store")
6515    (set_attr "mode"     "none")
6516    (set_attr "length"   "80")])
6517
6518 (define_insn ""
6519   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6520         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6521    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6522    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6523    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6524    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6525    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6526    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6527    (use (const_int 1))]                                 ;; all but last store
6528   "TARGET_MIPS16"
6529   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6530   [(set_attr "type"     "multi")
6531    (set_attr "mode"     "none")
6532    (set_attr "length"   "80")])
6533
6534 (define_insn "movstrsi_internal3"
6535   [(set (match_operand:BLK 0 "memory_operand" "=Ro")    ;; destination
6536         (match_operand:BLK 1 "memory_operand" "Ro"))    ;; source
6537    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6538    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6539    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6540    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6541    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6542    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6543    (use (const_int 2))]                                 ;; just last store of block move
6544   ""
6545   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6546   [(set_attr "type"     "store")
6547    (set_attr "mode"     "none")])
6548 \f
6549 ;;
6550 ;;  ....................
6551 ;;
6552 ;;      SHIFTS
6553 ;;
6554 ;;  ....................
6555
6556 ;; Many of these instructions uses trivial define_expands, because we
6557 ;; want to use a different set of constraints when TARGET_MIPS16.
6558
6559 (define_expand "ashlsi3"
6560   [(set (match_operand:SI 0 "register_operand" "=d")
6561         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6562                    (match_operand:SI 2 "arith_operand" "dI")))]
6563   ""
6564   "
6565 {
6566   /* On the mips16, a shift of more than 8 is a four byte instruction,
6567      so, for a shift between 8 and 16, it is just as fast to do two
6568      shifts of 8 or less.  If there is a lot of shifting going on, we
6569      may win in CSE.  Otherwise combine will put the shifts back
6570      together again.  This can be called by function_arg, so we must
6571      be careful not to allocate a new register if we've reached the
6572      reload pass.  */
6573   if (TARGET_MIPS16
6574       && optimize
6575       && GET_CODE (operands[2]) == CONST_INT
6576       && INTVAL (operands[2]) > 8
6577       && INTVAL (operands[2]) <= 16
6578       && ! reload_in_progress
6579       && ! reload_completed)
6580     {
6581       rtx temp = gen_reg_rtx (SImode);
6582
6583       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6584       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6585                                         GEN_INT (INTVAL (operands[2]) - 8)));
6586       DONE;
6587     }
6588 }")
6589
6590 (define_insn "ashlsi3_internal1"
6591   [(set (match_operand:SI 0 "register_operand" "=d")
6592         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6593                    (match_operand:SI 2 "arith_operand" "dI")))]
6594   "!TARGET_MIPS16"
6595   "*
6596 {
6597   if (GET_CODE (operands[2]) == CONST_INT)
6598     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6599
6600   return \"sll\\t%0,%1,%2\";
6601 }"
6602   [(set_attr "type"     "arith")
6603    (set_attr "mode"     "SI")])
6604
6605 (define_insn "ashlsi3_internal2"
6606   [(set (match_operand:SI 0 "register_operand" "=d,d")
6607         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6608                    (match_operand:SI 2 "arith_operand" "d,I")))]
6609   "TARGET_MIPS16"
6610   "*
6611 {
6612   if (which_alternative == 0)
6613     return \"sll\\t%0,%2\";
6614
6615   if (GET_CODE (operands[2]) == CONST_INT)
6616     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6617
6618   return \"sll\\t%0,%1,%2\";
6619 }"
6620   [(set_attr "type"     "arith")
6621    (set_attr "mode"     "SI")
6622    (set_attr_alternative "length"
6623                 [(const_int 4)
6624                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6625                                (const_int 4)
6626                                (const_int 8))])])
6627
6628 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6629
6630 (define_split
6631   [(set (match_operand:SI 0 "register_operand" "")
6632         (ashift:SI (match_operand:SI 1 "register_operand" "")
6633                    (match_operand:SI 2 "const_int_operand" "")))]
6634   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6635    && GET_CODE (operands[2]) == CONST_INT
6636    && INTVAL (operands[2]) > 8
6637    && INTVAL (operands[2]) <= 16"
6638   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6639    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6640 "
6641 {
6642   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6643 }")
6644
6645 (define_expand "ashldi3"
6646   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6647                    (ashift:DI (match_operand:DI 1 "se_register_operand" "")
6648                               (match_operand:SI 2 "arith_operand" "")))
6649               (clobber (match_dup  3))])]
6650   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6651   "
6652 {
6653   if (TARGET_64BIT)
6654     {
6655       /* On the mips16, a shift of more than 8 is a four byte
6656          instruction, so, for a shift between 8 and 16, it is just as
6657          fast to do two shifts of 8 or less.  If there is a lot of
6658          shifting going on, we may win in CSE.  Otherwise combine will
6659          put the shifts back together again.  This can be called by
6660          function_arg, so we must be careful not to allocate a new
6661          register if we've reached the reload pass.  */
6662       if (TARGET_MIPS16
6663           && optimize
6664           && GET_CODE (operands[2]) == CONST_INT
6665           && INTVAL (operands[2]) > 8
6666           && INTVAL (operands[2]) <= 16
6667           && ! reload_in_progress
6668           && ! reload_completed)
6669         {
6670           rtx temp = gen_reg_rtx (DImode);
6671
6672           emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6673           emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6674                                             GEN_INT (INTVAL (operands[2]) - 8)));
6675           DONE;
6676         }
6677
6678       emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6679                                         operands[2]));
6680       DONE;
6681     }
6682
6683   operands[3] = gen_reg_rtx (SImode);
6684 }")
6685
6686
6687 (define_insn "ashldi3_internal"
6688   [(set (match_operand:DI 0 "register_operand" "=&d")
6689         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6690                    (match_operand:SI 2 "register_operand" "d")))
6691    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6692   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6693   "*
6694 {
6695   operands[4] = const0_rtx;
6696   dslots_jump_total += 3;
6697   dslots_jump_filled += 2;
6698
6699   return \"sll\\t%3,%2,26\\n\\
6700 \\tbgez\\t%3,1f\\n\\
6701 \\tsll\\t%M0,%L1,%2\\n\\
6702 \\t%(b\\t3f\\n\\
6703 \\tmove\\t%L0,%z4%)\\n\\
6704 \\n\\
6705 %~1:\\n\\
6706 \\t%(beq\\t%3,%z4,2f\\n\\
6707 \\tsll\\t%M0,%M1,%2%)\\n\\
6708 \\n\\
6709 \\tsubu\\t%3,%z4,%2\\n\\
6710 \\tsrl\\t%3,%L1,%3\\n\\
6711 \\tor\\t%M0,%M0,%3\\n\\
6712 %~2:\\n\\
6713 \\tsll\\t%L0,%L1,%2\\n\\
6714 %~3:\";
6715 }"
6716   [(set_attr "type"     "darith")
6717    (set_attr "mode"     "SI")
6718    (set_attr "length"   "48")])
6719
6720
6721 (define_insn "ashldi3_internal2"
6722   [(set (match_operand:DI 0 "register_operand" "=d")
6723         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6724                    (match_operand:SI 2 "small_int" "IJK")))
6725    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6726   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6727    && (INTVAL (operands[2]) & 32) != 0"
6728   "*
6729 {
6730   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6731   operands[4] = const0_rtx;
6732   return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6733 }"
6734   [(set_attr "type"     "darith")
6735    (set_attr "mode"     "DI")
6736    (set_attr "length"   "8")])
6737
6738
6739 (define_split
6740   [(set (match_operand:DI 0 "register_operand" "")
6741         (ashift:DI (match_operand:DI 1 "register_operand" "")
6742                    (match_operand:SI 2 "small_int" "")))
6743    (clobber (match_operand:SI 3 "register_operand" ""))]
6744   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6745    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6746    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6747    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6748    && (INTVAL (operands[2]) & 32) != 0"
6749
6750   [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6751    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6752
6753   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6754
6755
6756 (define_split
6757   [(set (match_operand:DI 0 "register_operand" "")
6758         (ashift:DI (match_operand:DI 1 "register_operand" "")
6759                    (match_operand:SI 2 "small_int" "")))
6760    (clobber (match_operand:SI 3 "register_operand" ""))]
6761   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6762    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6763    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6764    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6765    && (INTVAL (operands[2]) & 32) != 0"
6766
6767   [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6768    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
6769
6770   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6771
6772
6773 (define_insn "ashldi3_internal3"
6774   [(set (match_operand:DI 0 "register_operand" "=d")
6775         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6776                    (match_operand:SI 2 "small_int" "IJK")))
6777    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6778   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6779    && (INTVAL (operands[2]) & 63) < 32
6780    && (INTVAL (operands[2]) & 63) != 0"
6781   "*
6782 {
6783   int amount = INTVAL (operands[2]);
6784
6785   operands[2] = GEN_INT (amount & 31);
6786   operands[4] = const0_rtx;
6787   operands[5] = GEN_INT ((-amount) & 31);
6788
6789   return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6790 }"
6791   [(set_attr "type"     "darith")
6792    (set_attr "mode"     "DI")
6793    (set_attr "length"   "16")])
6794
6795
6796 (define_split
6797   [(set (match_operand:DI 0 "register_operand" "")
6798         (ashift:DI (match_operand:DI 1 "register_operand" "")
6799                    (match_operand:SI 2 "small_int" "")))
6800    (clobber (match_operand:SI 3 "register_operand" ""))]
6801   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6802    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6803    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6804    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6805    && (INTVAL (operands[2]) & 63) < 32
6806    && (INTVAL (operands[2]) & 63) != 0"
6807
6808   [(set (subreg:SI (match_dup 0) 4)
6809         (ashift:SI (subreg:SI (match_dup 1) 4)
6810                    (match_dup 2)))
6811
6812    (set (match_dup 3)
6813         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6814                      (match_dup 4)))
6815
6816    (set (subreg:SI (match_dup 0) 4)
6817         (ior:SI (subreg:SI (match_dup 0) 4)
6818                 (match_dup 3)))
6819
6820    (set (subreg:SI (match_dup 0) 0)
6821         (ashift:SI (subreg:SI (match_dup 1) 0)
6822                    (match_dup 2)))]
6823   "
6824 {
6825   int amount = INTVAL (operands[2]);
6826   operands[2] = GEN_INT (amount & 31);
6827   operands[4] = GEN_INT ((-amount) & 31);
6828 }")
6829
6830
6831 (define_split
6832   [(set (match_operand:DI 0 "register_operand" "")
6833         (ashift:DI (match_operand:DI 1 "register_operand" "")
6834                    (match_operand:SI 2 "small_int" "")))
6835    (clobber (match_operand:SI 3 "register_operand" ""))]
6836   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6837    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6838    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6839    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6840    && (INTVAL (operands[2]) & 63) < 32
6841    && (INTVAL (operands[2]) & 63) != 0"
6842
6843   [(set (subreg:SI (match_dup 0) 0)
6844         (ashift:SI (subreg:SI (match_dup 1) 0)
6845                    (match_dup 2)))
6846
6847    (set (match_dup 3)
6848         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6849                      (match_dup 4)))
6850
6851    (set (subreg:SI (match_dup 0) 0)
6852         (ior:SI (subreg:SI (match_dup 0) 0)
6853                 (match_dup 3)))
6854
6855    (set (subreg:SI (match_dup 0) 4)
6856         (ashift:SI (subreg:SI (match_dup 1) 4)
6857                    (match_dup 2)))]
6858   "
6859 {
6860   int amount = INTVAL (operands[2]);
6861   operands[2] = GEN_INT (amount & 31);
6862   operands[4] = GEN_INT ((-amount) & 31);
6863 }")
6864
6865
6866 (define_insn "ashldi3_internal4"
6867   [(set (match_operand:DI 0 "register_operand" "=d")
6868         (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6869                    (match_operand:SI 2 "arith_operand" "dI")))]
6870   "TARGET_64BIT && !TARGET_MIPS16"
6871   "*
6872 {
6873   if (GET_CODE (operands[2]) == CONST_INT)
6874     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6875
6876   return \"dsll\\t%0,%1,%2\";
6877 }"
6878   [(set_attr "type"     "arith")
6879    (set_attr "mode"     "DI")])
6880
6881 (define_insn ""
6882   [(set (match_operand:DI 0 "register_operand" "=d,d")
6883         (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
6884                    (match_operand:SI 2 "arith_operand" "d,I")))]
6885   "TARGET_64BIT && TARGET_MIPS16"
6886   "*
6887 {
6888   if (which_alternative == 0)
6889     return \"dsll\\t%0,%2\";
6890
6891   if (GET_CODE (operands[2]) == CONST_INT)
6892     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6893
6894   return \"dsll\\t%0,%1,%2\";
6895 }"
6896   [(set_attr "type"     "arith")
6897    (set_attr "mode"     "DI")
6898    (set_attr_alternative "length"
6899                 [(const_int 4)
6900                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6901                                (const_int 4)
6902                                (const_int 8))])])
6903
6904
6905 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6906
6907 (define_split
6908   [(set (match_operand:DI 0 "register_operand" "")
6909         (ashift:DI (match_operand:DI 1 "register_operand" "")
6910                    (match_operand:SI 2 "const_int_operand" "")))]
6911   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
6912    && reload_completed
6913    && GET_CODE (operands[2]) == CONST_INT
6914    && INTVAL (operands[2]) > 8
6915    && INTVAL (operands[2]) <= 16"
6916   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6917    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6918 "
6919 {
6920   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6921 }")
6922
6923 (define_expand "ashrsi3"
6924   [(set (match_operand:SI 0 "register_operand" "=d")
6925         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6926                      (match_operand:SI 2 "arith_operand" "dI")))]
6927   ""
6928   "
6929 {
6930   /* On the mips16, a shift of more than 8 is a four byte instruction,
6931      so, for a shift between 8 and 16, it is just as fast to do two
6932      shifts of 8 or less.  If there is a lot of shifting going on, we
6933      may win in CSE.  Otherwise combine will put the shifts back
6934      together again.  */
6935   if (TARGET_MIPS16
6936       && optimize
6937       && GET_CODE (operands[2]) == CONST_INT
6938       && INTVAL (operands[2]) > 8
6939       && INTVAL (operands[2]) <= 16)
6940     {
6941       rtx temp = gen_reg_rtx (SImode);
6942
6943       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6944       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6945                                         GEN_INT (INTVAL (operands[2]) - 8)));
6946       DONE;
6947     }
6948 }")
6949
6950 (define_insn "ashrsi3_internal1"
6951   [(set (match_operand:SI 0 "register_operand" "=d")
6952         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6953                      (match_operand:SI 2 "arith_operand" "dI")))]
6954   "!TARGET_MIPS16"
6955   "*
6956 {
6957   if (GET_CODE (operands[2]) == CONST_INT)
6958     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6959
6960   return \"sra\\t%0,%1,%2\";
6961 }"
6962   [(set_attr "type"     "arith")
6963    (set_attr "mode"     "SI")])
6964
6965 (define_insn "ashrsi3_internal2"
6966   [(set (match_operand:SI 0 "register_operand" "=d,d")
6967         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6968                      (match_operand:SI 2 "arith_operand" "d,I")))]
6969   "TARGET_MIPS16"
6970   "*
6971 {
6972   if (which_alternative == 0)
6973     return \"sra\\t%0,%2\";
6974
6975   if (GET_CODE (operands[2]) == CONST_INT)
6976     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6977
6978   return \"sra\\t%0,%1,%2\";
6979 }"
6980   [(set_attr "type"     "arith")
6981    (set_attr "mode"     "SI")
6982    (set_attr_alternative "length"
6983                 [(const_int 4)
6984                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6985                                (const_int 4)
6986                                (const_int 8))])])
6987
6988
6989 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6990
6991 (define_split
6992   [(set (match_operand:SI 0 "register_operand" "")
6993         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6994                      (match_operand:SI 2 "const_int_operand" "")))]
6995   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6996    && GET_CODE (operands[2]) == CONST_INT
6997    && INTVAL (operands[2]) > 8
6998    && INTVAL (operands[2]) <= 16"
6999   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
7000    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
7001 "
7002 {
7003   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7004 }")
7005
7006 (define_expand "ashrdi3"
7007   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7008                    (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7009                                 (match_operand:SI 2 "arith_operand" "")))
7010               (clobber (match_dup  3))])]
7011   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7012   "
7013 {
7014   if (TARGET_64BIT)
7015     {
7016       /* On the mips16, a shift of more than 8 is a four byte
7017          instruction, so, for a shift between 8 and 16, it is just as
7018          fast to do two shifts of 8 or less.  If there is a lot of
7019          shifting going on, we may win in CSE.  Otherwise combine will
7020          put the shifts back together again.  */
7021       if (TARGET_MIPS16
7022           && optimize
7023           && GET_CODE (operands[2]) == CONST_INT
7024           && INTVAL (operands[2]) > 8
7025           && INTVAL (operands[2]) <= 16)
7026         {
7027           rtx temp = gen_reg_rtx (DImode);
7028
7029           emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7030           emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
7031                                             GEN_INT (INTVAL (operands[2]) - 8)));
7032           DONE;
7033         }
7034
7035       emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
7036                                         operands[2]));
7037       DONE;
7038     }
7039
7040   operands[3] = gen_reg_rtx (SImode);
7041 }")
7042
7043
7044 (define_insn "ashrdi3_internal"
7045   [(set (match_operand:DI 0 "register_operand" "=&d")
7046         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7047                      (match_operand:SI 2 "register_operand" "d")))
7048    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7049   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7050   "*
7051 {
7052   operands[4] = const0_rtx;
7053   dslots_jump_total += 3;
7054   dslots_jump_filled += 2;
7055
7056   return \"sll\\t%3,%2,26\\n\\
7057 \\tbgez\\t%3,1f\\n\\
7058 \\tsra\\t%L0,%M1,%2\\n\\
7059 \\t%(b\\t3f\\n\\
7060 \\tsra\\t%M0,%M1,31%)\\n\\
7061 \\n\\
7062 %~1:\\n\\
7063 \\t%(beq\\t%3,%z4,2f\\n\\
7064 \\tsrl\\t%L0,%L1,%2%)\\n\\
7065 \\n\\
7066 \\tsubu\\t%3,%z4,%2\\n\\
7067 \\tsll\\t%3,%M1,%3\\n\\
7068 \\tor\\t%L0,%L0,%3\\n\\
7069 %~2:\\n\\
7070 \\tsra\\t%M0,%M1,%2\\n\\
7071 %~3:\";
7072 }"
7073   [(set_attr "type"     "darith")
7074    (set_attr "mode"     "DI")
7075    (set_attr "length"   "48")])
7076
7077
7078 (define_insn "ashrdi3_internal2"
7079   [(set (match_operand:DI 0 "register_operand" "=d")
7080         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7081                      (match_operand:SI 2 "small_int" "IJK")))
7082    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7083   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
7084   "*
7085 {
7086   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7087   return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
7088 }"
7089   [(set_attr "type"     "darith")
7090    (set_attr "mode"     "DI")
7091    (set_attr "length"   "8")])
7092
7093
7094 (define_split
7095   [(set (match_operand:DI 0 "register_operand" "")
7096         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7097                      (match_operand:SI 2 "small_int" "")))
7098    (clobber (match_operand:SI 3 "register_operand" ""))]
7099   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7100    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7101    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7102    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7103    && (INTVAL (operands[2]) & 32) != 0"
7104
7105   [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7106    (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
7107
7108   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7109
7110
7111 (define_split
7112   [(set (match_operand:DI 0 "register_operand" "")
7113         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7114                      (match_operand:SI 2 "small_int" "")))
7115    (clobber (match_operand:SI 3 "register_operand" ""))]
7116   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7117    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7118    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7119    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7120    && (INTVAL (operands[2]) & 32) != 0"
7121
7122   [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7123    (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
7124
7125   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7126
7127
7128 (define_insn "ashrdi3_internal3"
7129   [(set (match_operand:DI 0 "register_operand" "=d")
7130         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7131                      (match_operand:SI 2 "small_int" "IJK")))
7132    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7133   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7134    && (INTVAL (operands[2]) & 63) < 32
7135    && (INTVAL (operands[2]) & 63) != 0"
7136   "*
7137 {
7138   int amount = INTVAL (operands[2]);
7139
7140   operands[2] = GEN_INT (amount & 31);
7141   operands[4] = GEN_INT ((-amount) & 31);
7142
7143   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
7144 }"
7145   [(set_attr "type"     "darith")
7146    (set_attr "mode"     "DI")
7147    (set_attr "length"   "16")])
7148
7149
7150 (define_split
7151   [(set (match_operand:DI 0 "register_operand" "")
7152         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7153                      (match_operand:SI 2 "small_int" "")))
7154    (clobber (match_operand:SI 3 "register_operand" ""))]
7155   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7156    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7157    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7158    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7159    && (INTVAL (operands[2]) & 63) < 32
7160    && (INTVAL (operands[2]) & 63) != 0"
7161
7162   [(set (subreg:SI (match_dup 0) 0)
7163         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7164                      (match_dup 2)))
7165
7166    (set (match_dup 3)
7167         (ashift:SI (subreg:SI (match_dup 1) 4)
7168                    (match_dup 4)))
7169
7170    (set (subreg:SI (match_dup 0) 0)
7171         (ior:SI (subreg:SI (match_dup 0) 0)
7172                 (match_dup 3)))
7173
7174    (set (subreg:SI (match_dup 0) 4)
7175         (ashiftrt:SI (subreg:SI (match_dup 1) 4)
7176                      (match_dup 2)))]
7177   "
7178 {
7179   int amount = INTVAL (operands[2]);
7180   operands[2] = GEN_INT (amount & 31);
7181   operands[4] = GEN_INT ((-amount) & 31);
7182 }")
7183
7184
7185 (define_split
7186   [(set (match_operand:DI 0 "register_operand" "")
7187         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7188                      (match_operand:SI 2 "small_int" "")))
7189    (clobber (match_operand:SI 3 "register_operand" ""))]
7190   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7191    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7192    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7193    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7194    && (INTVAL (operands[2]) & 63) < 32
7195    && (INTVAL (operands[2]) & 63) != 0"
7196
7197   [(set (subreg:SI (match_dup 0) 4)
7198         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7199                      (match_dup 2)))
7200
7201    (set (match_dup 3)
7202         (ashift:SI (subreg:SI (match_dup 1) 0)
7203                    (match_dup 4)))
7204
7205    (set (subreg:SI (match_dup 0) 4)
7206         (ior:SI (subreg:SI (match_dup 0) 4)
7207                 (match_dup 3)))
7208
7209    (set (subreg:SI (match_dup 0) 0)
7210         (ashiftrt:SI (subreg:SI (match_dup 1) 0)
7211                      (match_dup 2)))]
7212   "
7213 {
7214   int amount = INTVAL (operands[2]);
7215   operands[2] = GEN_INT (amount & 31);
7216   operands[4] = GEN_INT ((-amount) & 31);
7217 }")
7218
7219
7220 (define_insn "ashrdi3_internal4"
7221   [(set (match_operand:DI 0 "register_operand" "=d")
7222         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7223                      (match_operand:SI 2 "arith_operand" "dI")))]
7224   "TARGET_64BIT && !TARGET_MIPS16"
7225   "*
7226 {
7227   if (GET_CODE (operands[2]) == CONST_INT)
7228     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7229
7230   return \"dsra\\t%0,%1,%2\";
7231 }"
7232   [(set_attr "type"     "arith")
7233    (set_attr "mode"     "DI")])
7234
7235 (define_insn ""
7236   [(set (match_operand:DI 0 "register_operand" "=d,d")
7237         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7238                      (match_operand:SI 2 "arith_operand" "d,I")))]
7239   "TARGET_64BIT && TARGET_MIPS16"
7240   "*
7241 {
7242   if (GET_CODE (operands[2]) == CONST_INT)
7243     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7244
7245   return \"dsra\\t%0,%2\";
7246 }"
7247   [(set_attr "type"     "arith")
7248    (set_attr "mode"     "DI")
7249    (set_attr_alternative "length"
7250                 [(const_int 4)
7251                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7252                                (const_int 4)
7253                                (const_int 8))])])
7254
7255 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7256
7257 (define_split
7258   [(set (match_operand:DI 0 "register_operand" "")
7259         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7260                      (match_operand:SI 2 "const_int_operand" "")))]
7261   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
7262    && reload_completed
7263    && GET_CODE (operands[2]) == CONST_INT
7264    && INTVAL (operands[2]) > 8
7265    && INTVAL (operands[2]) <= 16"
7266   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7267    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7268 "
7269 {
7270   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7271 }")
7272
7273 (define_expand "lshrsi3"
7274   [(set (match_operand:SI 0 "register_operand" "=d")
7275         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7276                      (match_operand:SI 2 "arith_operand" "dI")))]
7277   ""
7278   "
7279 {
7280   /* On the mips16, a shift of more than 8 is a four byte instruction,
7281      so, for a shift between 8 and 16, it is just as fast to do two
7282      shifts of 8 or less.  If there is a lot of shifting going on, we
7283      may win in CSE.  Otherwise combine will put the shifts back
7284      together again.  */
7285   if (TARGET_MIPS16
7286       && optimize
7287       && GET_CODE (operands[2]) == CONST_INT
7288       && INTVAL (operands[2]) > 8
7289       && INTVAL (operands[2]) <= 16)
7290     {
7291       rtx temp = gen_reg_rtx (SImode);
7292
7293       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7294       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7295                                         GEN_INT (INTVAL (operands[2]) - 8)));
7296       DONE;
7297     }
7298 }")
7299
7300 (define_insn "lshrsi3_internal1"
7301   [(set (match_operand:SI 0 "register_operand" "=d")
7302         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7303                      (match_operand:SI 2 "arith_operand" "dI")))]
7304   "!TARGET_MIPS16"
7305   "*
7306 {
7307   if (GET_CODE (operands[2]) == CONST_INT)
7308     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7309
7310   return \"srl\\t%0,%1,%2\";
7311 }"
7312   [(set_attr "type"     "arith")
7313    (set_attr "mode"     "SI")])
7314
7315 (define_insn "lshrsi3_internal2"
7316   [(set (match_operand:SI 0 "register_operand" "=d,d")
7317         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7318                      (match_operand:SI 2 "arith_operand" "d,I")))]
7319   "TARGET_MIPS16"
7320   "*
7321 {
7322   if (which_alternative == 0)
7323     return \"srl\\t%0,%2\";
7324
7325   if (GET_CODE (operands[2]) == CONST_INT)
7326     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7327
7328   return \"srl\\t%0,%1,%2\";
7329 }"
7330   [(set_attr "type"     "arith")
7331    (set_attr "mode"     "SI")
7332    (set_attr_alternative "length"
7333                 [(const_int 4)
7334                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7335                                (const_int 4)
7336                                (const_int 8))])])
7337
7338
7339 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7340
7341 (define_split
7342   [(set (match_operand:SI 0 "register_operand" "")
7343         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7344                      (match_operand:SI 2 "const_int_operand" "")))]
7345   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7346    && GET_CODE (operands[2]) == CONST_INT
7347    && INTVAL (operands[2]) > 8
7348    && INTVAL (operands[2]) <= 16"
7349   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7350    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7351 "
7352 {
7353   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7354 }")
7355
7356 ;; If we load a byte on the mips16 as a bitfield, the resulting
7357 ;; sequence of instructions is too complicated for combine, because it
7358 ;; involves four instructions: a load, a shift, a constant load into a
7359 ;; register, and an and (the key problem here is that the mips16 does
7360 ;; not have and immediate).  We recognize a shift of a load in order
7361 ;; to make it simple enough for combine to understand.
7362
7363 (define_insn ""
7364   [(set (match_operand:SI 0 "register_operand" "=d,d")
7365         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
7366                      (match_operand:SI 2 "immediate_operand" "I,I")))]
7367   "TARGET_MIPS16"
7368   "lw\\t%0,%1\;srl\\t%0,%2"
7369   [(set_attr "type"     "load")
7370    (set_attr "mode"     "SI")
7371    (set_attr_alternative "length"
7372                 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7373                                (const_int 8)
7374                                (const_int 12))
7375                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7376                                (const_int 12)
7377                                (const_int 16))])])
7378
7379 (define_split
7380   [(set (match_operand:SI 0 "register_operand" "")
7381         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7382                      (match_operand:SI 2 "immediate_operand" "")))]
7383   "TARGET_MIPS16 && !TARGET_DEBUG_D_MODE"
7384   [(set (match_dup 0) (match_dup 1))
7385    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7386   "")
7387
7388 (define_expand "lshrdi3"
7389   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7390                    (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7391                                 (match_operand:SI 2 "arith_operand" "")))
7392               (clobber (match_dup  3))])]
7393   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7394   "
7395 {
7396   if (TARGET_64BIT)
7397     {
7398       /* On the mips16, a shift of more than 8 is a four byte
7399          instruction, so, for a shift between 8 and 16, it is just as
7400          fast to do two shifts of 8 or less.  If there is a lot of
7401          shifting going on, we may win in CSE.  Otherwise combine will
7402          put the shifts back together again.  */
7403       if (TARGET_MIPS16
7404           && optimize
7405           && GET_CODE (operands[2]) == CONST_INT
7406           && INTVAL (operands[2]) > 8
7407           && INTVAL (operands[2]) <= 16)
7408         {
7409           rtx temp = gen_reg_rtx (DImode);
7410
7411           emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7412           emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7413                                             GEN_INT (INTVAL (operands[2]) - 8)));
7414           DONE;
7415         }
7416
7417       emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7418                                         operands[2]));
7419       DONE;
7420     }
7421
7422   operands[3] = gen_reg_rtx (SImode);
7423 }")
7424
7425
7426 (define_insn "lshrdi3_internal"
7427   [(set (match_operand:DI 0 "register_operand" "=&d")
7428         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7429                      (match_operand:SI 2 "register_operand" "d")))
7430    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7431   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7432   "*
7433 {
7434   operands[4] = const0_rtx;
7435   dslots_jump_total += 3;
7436   dslots_jump_filled += 2;
7437
7438   return \"sll\\t%3,%2,26\\n\\
7439 \\tbgez\\t%3,1f\\n\\
7440 \\tsrl\\t%L0,%M1,%2\\n\\
7441 \\t%(b\\t3f\\n\\
7442 \\tmove\\t%M0,%z4%)\\n\\
7443 \\n\\
7444 %~1:\\n\\
7445 \\t%(beq\\t%3,%z4,2f\\n\\
7446 \\tsrl\\t%L0,%L1,%2%)\\n\\
7447 \\n\\
7448 \\tsubu\\t%3,%z4,%2\\n\\
7449 \\tsll\\t%3,%M1,%3\\n\\
7450 \\tor\\t%L0,%L0,%3\\n\\
7451 %~2:\\n\\
7452 \\tsrl\\t%M0,%M1,%2\\n\\
7453 %~3:\";
7454 }"
7455   [(set_attr "type"     "darith")
7456    (set_attr "mode"     "DI")
7457    (set_attr "length"   "48")])
7458
7459
7460 (define_insn "lshrdi3_internal2"
7461   [(set (match_operand:DI 0 "register_operand" "=d")
7462         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7463                      (match_operand:SI 2 "small_int" "IJK")))
7464    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7465   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7466    && (INTVAL (operands[2]) & 32) != 0"
7467   "*
7468 {
7469   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7470   operands[4] = const0_rtx;
7471   return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7472 }"
7473   [(set_attr "type"     "darith")
7474    (set_attr "mode"     "DI")
7475    (set_attr "length"   "8")])
7476
7477
7478 (define_split
7479   [(set (match_operand:DI 0 "register_operand" "")
7480         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7481                      (match_operand:SI 2 "small_int" "")))
7482    (clobber (match_operand:SI 3 "register_operand" ""))]
7483   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7484    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7485    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7486    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7487    && (INTVAL (operands[2]) & 32) != 0"
7488
7489   [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7490    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
7491
7492   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7493
7494
7495 (define_split
7496   [(set (match_operand:DI 0 "register_operand" "")
7497         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7498                      (match_operand:SI 2 "small_int" "")))
7499    (clobber (match_operand:SI 3 "register_operand" ""))]
7500   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7501    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7502    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7503    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7504    && (INTVAL (operands[2]) & 32) != 0"
7505
7506   [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7507    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7508
7509   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7510
7511
7512 (define_insn "lshrdi3_internal3"
7513   [(set (match_operand:DI 0 "register_operand" "=d")
7514         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7515                    (match_operand:SI 2 "small_int" "IJK")))
7516    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7517   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7518    && (INTVAL (operands[2]) & 63) < 32
7519    && (INTVAL (operands[2]) & 63) != 0"
7520   "*
7521 {
7522   int amount = INTVAL (operands[2]);
7523
7524   operands[2] = GEN_INT (amount & 31);
7525   operands[4] = GEN_INT ((-amount) & 31);
7526
7527   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7528 }"
7529   [(set_attr "type"     "darith")
7530    (set_attr "mode"     "DI")
7531    (set_attr "length"   "16")])
7532
7533
7534 (define_split
7535   [(set (match_operand:DI 0 "register_operand" "")
7536         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7537                      (match_operand:SI 2 "small_int" "")))
7538    (clobber (match_operand:SI 3 "register_operand" ""))]
7539   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7540    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7541    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7542    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7543    && (INTVAL (operands[2]) & 63) < 32
7544    && (INTVAL (operands[2]) & 63) != 0"
7545
7546   [(set (subreg:SI (match_dup 0) 0)
7547         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7548                      (match_dup 2)))
7549
7550    (set (match_dup 3)
7551         (ashift:SI (subreg:SI (match_dup 1) 4)
7552                    (match_dup 4)))
7553
7554    (set (subreg:SI (match_dup 0) 0)
7555         (ior:SI (subreg:SI (match_dup 0) 0)
7556                 (match_dup 3)))
7557
7558    (set (subreg:SI (match_dup 0) 4)
7559         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7560                      (match_dup 2)))]
7561   "
7562 {
7563   int amount = INTVAL (operands[2]);
7564   operands[2] = GEN_INT (amount & 31);
7565   operands[4] = GEN_INT ((-amount) & 31);
7566 }")
7567
7568
7569 (define_split
7570   [(set (match_operand:DI 0 "register_operand" "")
7571         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7572                      (match_operand:SI 2 "small_int" "")))
7573    (clobber (match_operand:SI 3 "register_operand" ""))]
7574   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7575    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7576    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7577    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7578    && (INTVAL (operands[2]) & 63) < 32
7579    && (INTVAL (operands[2]) & 63) != 0"
7580
7581   [(set (subreg:SI (match_dup 0) 4)
7582         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7583                      (match_dup 2)))
7584
7585    (set (match_dup 3)
7586         (ashift:SI (subreg:SI (match_dup 1) 0)
7587                    (match_dup 4)))
7588
7589    (set (subreg:SI (match_dup 0) 4)
7590         (ior:SI (subreg:SI (match_dup 0) 4)
7591                 (match_dup 3)))
7592
7593    (set (subreg:SI (match_dup 0) 0)
7594         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7595                      (match_dup 2)))]
7596   "
7597 {
7598   int amount = INTVAL (operands[2]);
7599   operands[2] = GEN_INT (amount & 31);
7600   operands[4] = GEN_INT ((-amount) & 31);
7601 }")
7602
7603
7604 (define_insn "lshrdi3_internal4"
7605   [(set (match_operand:DI 0 "register_operand" "=d")
7606         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7607                      (match_operand:SI 2 "arith_operand" "dI")))]
7608   "TARGET_64BIT && !TARGET_MIPS16"
7609   "*
7610 {
7611   if (GET_CODE (operands[2]) == CONST_INT)
7612     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7613
7614   return \"dsrl\\t%0,%1,%2\";
7615 }"
7616   [(set_attr "type"     "arith")
7617    (set_attr "mode"     "DI")])
7618
7619 (define_insn ""
7620   [(set (match_operand:DI 0 "register_operand" "=d,d")
7621         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7622                      (match_operand:SI 2 "arith_operand" "d,I")))]
7623   "TARGET_64BIT && TARGET_MIPS16"
7624   "*
7625 {
7626   if (GET_CODE (operands[2]) == CONST_INT)
7627     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7628
7629   return \"dsrl\\t%0,%2\";
7630 }"
7631   [(set_attr "type"     "arith")
7632    (set_attr "mode"     "DI")
7633    (set_attr_alternative "length"
7634                 [(const_int 4)
7635                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7636                                (const_int 4)
7637                                (const_int 8))])])
7638
7639 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7640
7641 (define_split
7642   [(set (match_operand:DI 0 "register_operand" "")
7643         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7644                      (match_operand:SI 2 "const_int_operand" "")))]
7645   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7646    && GET_CODE (operands[2]) == CONST_INT
7647    && INTVAL (operands[2]) > 8
7648    && INTVAL (operands[2]) <= 16"
7649   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7650    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7651 "
7652 {
7653   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7654 }")
7655
7656 \f
7657 ;;
7658 ;;  ....................
7659 ;;
7660 ;;      COMPARISONS
7661 ;;
7662 ;;  ....................
7663
7664 ;; Flow here is rather complex:
7665 ;;
7666 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the
7667 ;;      arguments into the branch_cmp array, and the type into
7668 ;;      branch_type.  No RTL is generated.
7669 ;;
7670 ;;  2)  The appropriate branch define_expand is called, which then
7671 ;;      creates the appropriate RTL for the comparison and branch.
7672 ;;      Different CC modes are used, based on what type of branch is
7673 ;;      done, so that we can constrain things appropriately.  There
7674 ;;      are assumptions in the rest of GCC that break if we fold the
7675 ;;      operands into the branchs for integer operations, and use cc0
7676 ;;      for floating point, so we use the fp status register instead.
7677 ;;      If needed, an appropriate temporary is created to hold the
7678 ;;      of the integer compare.
7679
7680 (define_expand "cmpsi"
7681   [(set (cc0)
7682         (compare:CC (match_operand:SI 0 "register_operand" "")
7683                     (match_operand:SI 1 "arith_operand" "")))]
7684   ""
7685   "
7686 {
7687   if (operands[0])              /* avoid unused code message */
7688     {
7689       branch_cmp[0] = operands[0];
7690       branch_cmp[1] = operands[1];
7691       branch_type = CMP_SI;
7692       DONE;
7693     }
7694 }")
7695
7696 (define_expand "tstsi"
7697   [(set (cc0)
7698         (match_operand:SI 0 "register_operand" ""))]
7699   ""
7700   "
7701 {
7702   if (operands[0])              /* avoid unused code message */
7703     {
7704       branch_cmp[0] = operands[0];
7705       branch_cmp[1] = const0_rtx;
7706       branch_type = CMP_SI;
7707       DONE;
7708     }
7709 }")
7710
7711 (define_expand "cmpdi"
7712   [(set (cc0)
7713         (compare:CC (match_operand:DI 0 "se_register_operand" "")
7714                     (match_operand:DI 1 "se_arith_operand" "")))]
7715   "TARGET_64BIT"
7716   "
7717 {
7718   if (operands[0])              /* avoid unused code message */
7719     {
7720       branch_cmp[0] = operands[0];
7721       branch_cmp[1] = operands[1];
7722       branch_type = CMP_DI;
7723       DONE;
7724     }
7725 }")
7726
7727 (define_expand "tstdi"
7728   [(set (cc0)
7729         (match_operand:DI 0 "se_register_operand" ""))]
7730   "TARGET_64BIT"
7731   "
7732 {
7733   if (operands[0])              /* avoid unused code message */
7734     {
7735       branch_cmp[0] = operands[0];
7736       branch_cmp[1] = const0_rtx;
7737       branch_type = CMP_DI;
7738       DONE;
7739     }
7740 }")
7741
7742 (define_expand "cmpdf"
7743   [(set (cc0)
7744         (compare:CC (match_operand:DF 0 "register_operand" "")
7745                     (match_operand:DF 1 "register_operand" "")))]
7746   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7747   "
7748 {
7749   if (operands[0])              /* avoid unused code message */
7750     {
7751       branch_cmp[0] = operands[0];
7752       branch_cmp[1] = operands[1];
7753       branch_type = CMP_DF;
7754       DONE;
7755     }
7756 }")
7757
7758 (define_expand "cmpsf"
7759   [(set (cc0)
7760         (compare:CC (match_operand:SF 0 "register_operand" "")
7761                     (match_operand:SF 1 "register_operand" "")))]
7762   "TARGET_HARD_FLOAT"
7763   "
7764 {
7765   if (operands[0])              /* avoid unused code message */
7766     {
7767       branch_cmp[0] = operands[0];
7768       branch_cmp[1] = operands[1];
7769       branch_type = CMP_SF;
7770       DONE;
7771     }
7772 }")
7773
7774 \f
7775 ;;
7776 ;;  ....................
7777 ;;
7778 ;;      CONDITIONAL BRANCHES
7779 ;;
7780 ;;  ....................
7781
7782 ;; Conditional branches on floating-point equality tests.
7783
7784 (define_insn "branch_fp"
7785   [(set (pc)
7786         (if_then_else
7787          (match_operator:CC 0 "cmp_op"
7788                             [(match_operand:CC 2 "register_operand" "z")
7789                              (const_int 0)])
7790          (label_ref (match_operand 1 "" ""))
7791          (pc)))]
7792   "TARGET_HARD_FLOAT"
7793   "*
7794 {
7795   return mips_output_conditional_branch (insn,
7796                                          operands,
7797                                          /*two_operands_p=*/0,
7798                                          /*float_p=*/1,
7799                                          /*inverted_p=*/0,
7800                                          get_attr_length (insn));
7801 }"
7802   [(set_attr "type"     "branch")
7803    (set_attr "mode"     "none")])
7804
7805 (define_insn "branch_fp_inverted"
7806   [(set (pc)
7807         (if_then_else
7808          (match_operator:CC 0 "cmp_op"
7809                             [(match_operand:CC 2 "register_operand" "z")
7810                              (const_int 0)])
7811          (pc)
7812          (label_ref (match_operand 1 "" ""))))]
7813   "TARGET_HARD_FLOAT"
7814   "*
7815 {
7816   return mips_output_conditional_branch (insn,
7817                                          operands,
7818                                          /*two_operands_p=*/0,
7819                                          /*float_p=*/1,
7820                                          /*inverted_p=*/1,
7821                                          get_attr_length (insn));
7822 }"
7823   [(set_attr "type"     "branch")
7824    (set_attr "mode"     "none")])
7825
7826 ;; Conditional branches on comparisons with zero.
7827
7828 (define_insn "branch_zero"
7829   [(set (pc)
7830         (if_then_else
7831          (match_operator:SI 0 "cmp_op"
7832                             [(match_operand:SI 2 "register_operand" "d")
7833                              (const_int 0)])
7834         (label_ref (match_operand 1 "" ""))
7835         (pc)))]
7836   "!TARGET_MIPS16"
7837   "*
7838 {
7839   return mips_output_conditional_branch (insn,
7840                                          operands,
7841                                          /*two_operands_p=*/0,
7842                                          /*float_p=*/0,
7843                                          /*inverted_p=*/0,
7844                                          get_attr_length (insn));
7845 }"
7846   [(set_attr "type"     "branch")
7847    (set_attr "mode"     "none")])
7848
7849 (define_insn "branch_zero_inverted"
7850   [(set (pc)
7851         (if_then_else
7852          (match_operator:SI 0 "cmp_op"
7853                             [(match_operand:SI 2 "register_operand" "d")
7854                              (const_int 0)])
7855         (pc)
7856         (label_ref (match_operand 1 "" ""))))]
7857   "!TARGET_MIPS16"
7858   "*
7859 {
7860   return mips_output_conditional_branch (insn,
7861                                          operands,
7862                                          /*two_operands_p=*/0,
7863                                          /*float_p=*/0,
7864                                          /*inverted_p=*/1,
7865                                          get_attr_length (insn));
7866 }"
7867   [(set_attr "type"     "branch")
7868    (set_attr "mode"     "none")])
7869
7870 (define_insn "branch_zero_di"
7871   [(set (pc)
7872         (if_then_else
7873          (match_operator:DI 0 "cmp_op"
7874                             [(match_operand:DI 2 "se_register_operand" "d")
7875                              (const_int 0)])
7876         (label_ref (match_operand 1 "" ""))
7877         (pc)))]
7878   "!TARGET_MIPS16"
7879   "*
7880 {
7881   return mips_output_conditional_branch (insn,
7882                                          operands,
7883                                          /*two_operands_p=*/0,
7884                                          /*float_p=*/0,
7885                                          /*inverted_p=*/0,
7886                                          get_attr_length (insn));
7887 }"
7888   [(set_attr "type"     "branch")
7889    (set_attr "mode"     "none")])
7890
7891 (define_insn "branch_zero_di_inverted"
7892   [(set (pc)
7893         (if_then_else
7894          (match_operator:DI 0 "cmp_op"
7895                             [(match_operand:DI 2 "se_register_operand" "d")
7896                              (const_int 0)])
7897         (pc)
7898         (label_ref (match_operand 1 "" ""))))]
7899   "!TARGET_MIPS16"
7900   "*
7901 {
7902   return mips_output_conditional_branch (insn,
7903                                          operands,
7904                                          /*two_operands_p=*/0,
7905                                          /*float_p=*/0,
7906                                          /*inverted_p=*/1,
7907                                          get_attr_length (insn));
7908 }"
7909   [(set_attr "type"     "branch")
7910    (set_attr "mode"     "none")])
7911
7912 ;; Conditional branch on equality comparision.
7913
7914 (define_insn "branch_equality"
7915   [(set (pc)
7916         (if_then_else
7917          (match_operator:SI 0 "equality_op"
7918                             [(match_operand:SI 2 "register_operand" "d")
7919                              (match_operand:SI 3 "register_operand" "d")])
7920          (label_ref (match_operand 1 "" ""))
7921          (pc)))]
7922   "!TARGET_MIPS16"
7923   "*
7924 {
7925   return mips_output_conditional_branch (insn,
7926                                          operands,
7927                                          /*two_operands_p=*/1,
7928                                          /*float_p=*/0,
7929                                          /*inverted_p=*/0,
7930                                          get_attr_length (insn));
7931 }"
7932   [(set_attr "type"     "branch")
7933    (set_attr "mode"     "none")])
7934
7935 (define_insn "branch_equality_di"
7936   [(set (pc)
7937         (if_then_else
7938          (match_operator:DI 0 "equality_op"
7939                             [(match_operand:DI 2 "se_register_operand" "d")
7940                              (match_operand:DI 3 "se_register_operand" "d")])
7941         (label_ref (match_operand 1 "" ""))
7942         (pc)))]
7943   "!TARGET_MIPS16"
7944   "*
7945 {
7946   return mips_output_conditional_branch (insn,
7947                                          operands,
7948                                          /*two_operands_p=*/1,
7949                                          /*float_p=*/0,
7950                                          /*inverted_p=*/0,
7951                                          get_attr_length (insn));
7952 }"
7953   [(set_attr "type"     "branch")
7954    (set_attr "mode"     "none")])
7955
7956 (define_insn "branch_equality_inverted"
7957   [(set (pc)
7958         (if_then_else
7959          (match_operator:SI 0 "equality_op"
7960                             [(match_operand:SI 2 "register_operand" "d")
7961                              (match_operand:SI 3 "register_operand" "d")])
7962          (pc)
7963          (label_ref (match_operand 1 "" ""))))]
7964   "!TARGET_MIPS16"
7965   "*
7966 {
7967   return mips_output_conditional_branch (insn,
7968                                          operands,
7969                                          /*two_operands_p=*/1,
7970                                          /*float_p=*/0,
7971                                          /*inverted_p=*/1,
7972                                          get_attr_length (insn));
7973 }"
7974   [(set_attr "type"     "branch")
7975    (set_attr "mode"     "none")])
7976
7977 (define_insn "branch_equality_di_inverted"
7978   [(set (pc)
7979         (if_then_else
7980          (match_operator:DI 0 "equality_op"
7981                             [(match_operand:DI 2 "se_register_operand" "d")
7982                              (match_operand:DI 3 "se_register_operand" "d")])
7983         (pc)
7984         (label_ref (match_operand 1 "" ""))))]
7985   "!TARGET_MIPS16"
7986   "*
7987 {
7988   return mips_output_conditional_branch (insn,
7989                                          operands,
7990                                          /*two_operands_p=*/1,
7991                                          /*float_p=*/0,
7992                                          /*inverted_p=*/1,
7993                                          get_attr_length (insn));
7994 }"
7995   [(set_attr "type"     "branch")
7996    (set_attr "mode"     "none")])
7997
7998 ;; MIPS16 branches
7999
8000 (define_insn ""
8001   [(set (pc)
8002         (if_then_else (match_operator:SI 0 "equality_op"
8003                                          [(match_operand:SI 1 "register_operand" "d,t")
8004                                           (const_int 0)])
8005         (match_operand 2 "pc_or_label_operand" "")
8006         (match_operand 3 "pc_or_label_operand" "")))]
8007   "TARGET_MIPS16"
8008   "*
8009 {
8010   if (operands[2] != pc_rtx)
8011     {
8012       if (which_alternative == 0)
8013         return \"%*b%C0z\\t%1,%2\";
8014       else
8015         return \"%*bt%C0z\\t%2\";
8016     }
8017   else
8018     {
8019       if (which_alternative == 0)
8020         return \"%*b%N0z\\t%1,%3\";
8021       else
8022         return \"%*bt%N0z\\t%3\";
8023     }
8024 }"
8025   [(set_attr "type"     "branch")
8026    (set_attr "mode"     "none")
8027    (set_attr "length"   "8")])
8028
8029 (define_insn ""
8030   [(set (pc)
8031         (if_then_else (match_operator:DI 0 "equality_op"
8032                                          [(match_operand:DI 1 "se_register_operand" "d,t")
8033                                           (const_int 0)])
8034         (match_operand 2 "pc_or_label_operand" "")
8035         (match_operand 3 "pc_or_label_operand" "")))]
8036   "TARGET_MIPS16"
8037   "*
8038 {
8039   if (operands[2] != pc_rtx)
8040     {
8041       if (which_alternative == 0)
8042         return \"%*b%C0z\\t%1,%2\";
8043       else
8044         return \"%*bt%C0z\\t%2\";
8045     }
8046   else
8047     {
8048       if (which_alternative == 0)
8049         return \"%*b%N0z\\t%1,%3\";
8050       else
8051         return \"%*bt%N0z\\t%3\";
8052     }
8053 }"
8054   [(set_attr "type"     "branch")
8055    (set_attr "mode"     "none")
8056    (set_attr "length"   "8")])
8057
8058 (define_expand "beq"
8059   [(set (pc)
8060         (if_then_else (eq:CC (cc0)
8061                              (const_int 0))
8062                       (label_ref (match_operand 0 "" ""))
8063                       (pc)))]
8064   ""
8065   "
8066 {
8067   if (operands[0])              /* avoid unused code warning */
8068     {
8069       gen_conditional_branch (operands, EQ);
8070       DONE;
8071     }
8072 }")
8073
8074 (define_expand "bne"
8075   [(set (pc)
8076         (if_then_else (ne:CC (cc0)
8077                              (const_int 0))
8078                       (label_ref (match_operand 0 "" ""))
8079                       (pc)))]
8080   ""
8081   "
8082 {
8083   if (operands[0])              /* avoid unused code warning */
8084     {
8085       gen_conditional_branch (operands, NE);
8086       DONE;
8087     }
8088 }")
8089
8090 (define_expand "bgt"
8091   [(set (pc)
8092         (if_then_else (gt:CC (cc0)
8093                              (const_int 0))
8094                       (label_ref (match_operand 0 "" ""))
8095                       (pc)))]
8096   ""
8097   "
8098 {
8099   if (operands[0])              /* avoid unused code warning */
8100     {
8101       gen_conditional_branch (operands, GT);
8102       DONE;
8103     }
8104 }")
8105
8106 (define_expand "bge"
8107   [(set (pc)
8108         (if_then_else (ge:CC (cc0)
8109                              (const_int 0))
8110                       (label_ref (match_operand 0 "" ""))
8111                       (pc)))]
8112   ""
8113   "
8114 {
8115   if (operands[0])              /* avoid unused code warning */
8116     {
8117       gen_conditional_branch (operands, GE);
8118       DONE;
8119     }
8120 }")
8121
8122 (define_expand "blt"
8123   [(set (pc)
8124         (if_then_else (lt:CC (cc0)
8125                              (const_int 0))
8126                       (label_ref (match_operand 0 "" ""))
8127                       (pc)))]
8128   ""
8129   "
8130 {
8131   if (operands[0])              /* avoid unused code warning */
8132     {
8133       gen_conditional_branch (operands, LT);
8134       DONE;
8135     }
8136 }")
8137
8138 (define_expand "ble"
8139   [(set (pc)
8140         (if_then_else (le:CC (cc0)
8141                              (const_int 0))
8142                       (label_ref (match_operand 0 "" ""))
8143                       (pc)))]
8144   ""
8145   "
8146 {
8147   if (operands[0])              /* avoid unused code warning */
8148     {
8149       gen_conditional_branch (operands, LE);
8150       DONE;
8151     }
8152 }")
8153
8154 (define_expand "bgtu"
8155   [(set (pc)
8156         (if_then_else (gtu:CC (cc0)
8157                               (const_int 0))
8158                       (label_ref (match_operand 0 "" ""))
8159                       (pc)))]
8160   ""
8161   "
8162 {
8163   if (operands[0])              /* avoid unused code warning */
8164     {
8165       gen_conditional_branch (operands, GTU);
8166       DONE;
8167     }
8168 }")
8169
8170 (define_expand "bgeu"
8171   [(set (pc)
8172         (if_then_else (geu:CC (cc0)
8173                               (const_int 0))
8174                       (label_ref (match_operand 0 "" ""))
8175                       (pc)))]
8176   ""
8177   "
8178 {
8179   if (operands[0])              /* avoid unused code warning */
8180     {
8181       gen_conditional_branch (operands, GEU);
8182       DONE;
8183     }
8184 }")
8185
8186
8187 (define_expand "bltu"
8188   [(set (pc)
8189         (if_then_else (ltu:CC (cc0)
8190                               (const_int 0))
8191                       (label_ref (match_operand 0 "" ""))
8192                       (pc)))]
8193   ""
8194   "
8195 {
8196   if (operands[0])              /* avoid unused code warning */
8197     {
8198       gen_conditional_branch (operands, LTU);
8199       DONE;
8200     }
8201 }")
8202
8203 (define_expand "bleu"
8204   [(set (pc)
8205         (if_then_else (leu:CC (cc0)
8206                               (const_int 0))
8207                       (label_ref (match_operand 0 "" ""))
8208                       (pc)))]
8209   ""
8210   "
8211 {
8212   if (operands[0])              /* avoid unused code warning */
8213     {
8214       gen_conditional_branch (operands, LEU);
8215       DONE;
8216     }
8217 }")
8218
8219 \f
8220 ;;
8221 ;;  ....................
8222 ;;
8223 ;;      SETTING A REGISTER FROM A COMPARISON
8224 ;;
8225 ;;  ....................
8226
8227 (define_expand "seq"
8228   [(set (match_operand:SI 0 "register_operand" "=d")
8229         (eq:SI (match_dup 1)
8230                (match_dup 2)))]
8231   ""
8232   "
8233 {
8234   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8235     FAIL;
8236
8237   /* set up operands from compare.  */
8238   operands[1] = branch_cmp[0];
8239   operands[2] = branch_cmp[1];
8240
8241   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8242     {
8243       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8244       DONE;
8245     }
8246
8247   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8248     operands[2] = force_reg (SImode, operands[2]);
8249
8250   /* fall through and generate default code */
8251 }")
8252
8253
8254 (define_insn "seq_si_zero"
8255   [(set (match_operand:SI 0 "register_operand" "=d")
8256         (eq:SI (match_operand:SI 1 "register_operand" "d")
8257                (const_int 0)))]
8258   "!TARGET_MIPS16"
8259   "sltu\\t%0,%1,1"
8260   [(set_attr "type"     "arith")
8261    (set_attr "mode"     "SI")])
8262
8263 (define_insn ""
8264   [(set (match_operand:SI 0 "register_operand" "=t")
8265         (eq:SI (match_operand:SI 1 "register_operand" "d")
8266                (const_int 0)))]
8267   "TARGET_MIPS16"
8268   "sltu\\t%1,1"
8269   [(set_attr "type"     "arith")
8270    (set_attr "mode"     "SI")])
8271
8272 (define_insn "seq_di_zero"
8273   [(set (match_operand:DI 0 "register_operand" "=d")
8274         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8275                (const_int 0)))]
8276   "TARGET_64BIT && !TARGET_MIPS16"
8277   "sltu\\t%0,%1,1"
8278   [(set_attr "type"     "arith")
8279    (set_attr "mode"     "DI")])
8280
8281 (define_insn ""
8282   [(set (match_operand:DI 0 "register_operand" "=t")
8283         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8284                (const_int 0)))]
8285   "TARGET_64BIT && TARGET_MIPS16"
8286   "sltu\\t%1,1"
8287   [(set_attr "type"     "arith")
8288    (set_attr "mode"     "DI")])
8289
8290 (define_insn "seq_si"
8291   [(set (match_operand:SI 0 "register_operand" "=d,d")
8292         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8293                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8294   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8295   "@
8296    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8297    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8298   [(set_attr "type"     "arith")
8299    (set_attr "mode"     "SI")
8300    (set_attr "length"   "8")])
8301
8302 (define_split
8303   [(set (match_operand:SI 0 "register_operand" "")
8304         (eq:SI (match_operand:SI 1 "register_operand" "")
8305                (match_operand:SI 2 "uns_arith_operand" "")))]
8306   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8307     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8308   [(set (match_dup 0)
8309         (xor:SI (match_dup 1)
8310                 (match_dup 2)))
8311    (set (match_dup 0)
8312         (ltu:SI (match_dup 0)
8313                 (const_int 1)))]
8314   "")
8315
8316 (define_insn "seq_di"
8317   [(set (match_operand:DI 0 "register_operand" "=d,d")
8318         (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8319                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8320   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8321   "@
8322    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8323    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8324   [(set_attr "type"     "arith")
8325    (set_attr "mode"     "DI")
8326    (set_attr "length"   "8")])
8327
8328 (define_split
8329   [(set (match_operand:DI 0 "register_operand" "")
8330         (eq:DI (match_operand:DI 1 "se_register_operand" "")
8331                (match_operand:DI 2 "se_uns_arith_operand" "")))]
8332   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8333     && !TARGET_MIPS16
8334     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8335   [(set (match_dup 0)
8336         (xor:DI (match_dup 1)
8337                 (match_dup 2)))
8338    (set (match_dup 0)
8339         (ltu:DI (match_dup 0)
8340                 (const_int 1)))]
8341   "")
8342
8343 ;; On the mips16 the default code is better than using sltu.
8344
8345 (define_expand "sne"
8346   [(set (match_operand:SI 0 "register_operand" "=d")
8347         (ne:SI (match_dup 1)
8348                (match_dup 2)))]
8349   "!TARGET_MIPS16"
8350   "
8351 {
8352   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8353     FAIL;
8354
8355   /* set up operands from compare.  */
8356   operands[1] = branch_cmp[0];
8357   operands[2] = branch_cmp[1];
8358
8359   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
8360     {
8361       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8362       DONE;
8363     }
8364
8365   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8366     operands[2] = force_reg (SImode, operands[2]);
8367
8368   /* fall through and generate default code */
8369 }")
8370
8371 (define_insn "sne_si_zero"
8372   [(set (match_operand:SI 0 "register_operand" "=d")
8373         (ne:SI (match_operand:SI 1 "register_operand" "d")
8374                (const_int 0)))]
8375   "!TARGET_MIPS16"
8376   "sltu\\t%0,%.,%1"
8377   [(set_attr "type"     "arith")
8378    (set_attr "mode"     "SI")])
8379
8380 (define_insn "sne_di_zero"
8381   [(set (match_operand:DI 0 "register_operand" "=d")
8382         (ne:DI (match_operand:DI 1 "se_register_operand" "d")
8383                (const_int 0)))]
8384   "TARGET_64BIT && !TARGET_MIPS16"
8385   "sltu\\t%0,%.,%1"
8386   [(set_attr "type"     "arith")
8387    (set_attr "mode"     "DI")])
8388
8389 (define_insn "sne_si"
8390   [(set (match_operand:SI 0 "register_operand" "=d,d")
8391         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8392                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8393   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8394   "@
8395     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8396     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8397   [(set_attr "type"     "arith")
8398    (set_attr "mode"     "SI")
8399    (set_attr "length"   "8")])
8400
8401 (define_split
8402   [(set (match_operand:SI 0 "register_operand" "")
8403         (ne:SI (match_operand:SI 1 "register_operand" "")
8404                (match_operand:SI 2 "uns_arith_operand" "")))]
8405   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8406     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8407   [(set (match_dup 0)
8408         (xor:SI (match_dup 1)
8409                 (match_dup 2)))
8410    (set (match_dup 0)
8411         (gtu:SI (match_dup 0)
8412                 (const_int 0)))]
8413   "")
8414
8415 (define_insn "sne_di"
8416   [(set (match_operand:DI 0 "register_operand" "=d,d")
8417         (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8418                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8419   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8420   "@
8421     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8422     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8423   [(set_attr "type"     "arith")
8424    (set_attr "mode"     "DI")
8425    (set_attr "length"   "8")])
8426
8427 (define_split
8428   [(set (match_operand:DI 0 "register_operand" "")
8429         (ne:DI (match_operand:DI 1 "se_register_operand" "")
8430                (match_operand:DI 2 "se_uns_arith_operand" "")))]
8431   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8432     && !TARGET_MIPS16
8433     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8434   [(set (match_dup 0)
8435         (xor:DI (match_dup 1)
8436                 (match_dup 2)))
8437    (set (match_dup 0)
8438         (gtu:DI (match_dup 0)
8439                 (const_int 0)))]
8440   "")
8441
8442 (define_expand "sgt"
8443   [(set (match_operand:SI 0 "register_operand" "=d")
8444         (gt:SI (match_dup 1)
8445                (match_dup 2)))]
8446   ""
8447   "
8448 {
8449   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8450     FAIL;
8451
8452   /* set up operands from compare.  */
8453   operands[1] = branch_cmp[0];
8454   operands[2] = branch_cmp[1];
8455
8456   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8457     {
8458       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8459       DONE;
8460     }
8461
8462   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8463     operands[2] = force_reg (SImode, operands[2]);
8464
8465   /* fall through and generate default code */
8466 }")
8467
8468 (define_insn "sgt_si"
8469   [(set (match_operand:SI 0 "register_operand" "=d")
8470         (gt:SI (match_operand:SI 1 "register_operand" "d")
8471                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8472   "!TARGET_MIPS16"
8473   "slt\\t%0,%z2,%1"
8474   [(set_attr "type"     "arith")
8475    (set_attr "mode"     "SI")])
8476
8477 (define_insn ""
8478   [(set (match_operand:SI 0 "register_operand" "=t")
8479         (gt:SI (match_operand:SI 1 "register_operand" "d")
8480                (match_operand:SI 2 "register_operand" "d")))]
8481   "TARGET_MIPS16"
8482   "slt\\t%2,%1"
8483   [(set_attr "type"     "arith")
8484    (set_attr "mode"     "SI")])
8485
8486 (define_insn "sgt_di"
8487   [(set (match_operand:DI 0 "register_operand" "=d")
8488         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8489                (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8490   "TARGET_64BIT && !TARGET_MIPS16"
8491   "slt\\t%0,%z2,%1"
8492   [(set_attr "type"     "arith")
8493    (set_attr "mode"     "DI")])
8494
8495 (define_insn ""
8496   [(set (match_operand:DI 0 "register_operand" "=d")
8497         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8498                (match_operand:DI 2 "se_register_operand" "d")))]
8499   "TARGET_64BIT && TARGET_MIPS16"
8500   "slt\\t%2,%1"
8501   [(set_attr "type"     "arith")
8502    (set_attr "mode"     "DI")])
8503
8504 (define_expand "sge"
8505   [(set (match_operand:SI 0 "register_operand" "=d")
8506         (ge:SI (match_dup 1)
8507                (match_dup 2)))]
8508   ""
8509   "
8510 {
8511   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8512     FAIL;
8513
8514   /* set up operands from compare.  */
8515   operands[1] = branch_cmp[0];
8516   operands[2] = branch_cmp[1];
8517
8518   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8519     {
8520       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8521       DONE;
8522     }
8523
8524   /* fall through and generate default code */
8525 }")
8526
8527 (define_insn "sge_si"
8528   [(set (match_operand:SI 0 "register_operand" "=d")
8529         (ge:SI (match_operand:SI 1 "register_operand" "d")
8530                (match_operand:SI 2 "arith_operand" "dI")))]
8531   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8532   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8533   [(set_attr "type"     "arith")
8534    (set_attr "mode"     "SI")
8535    (set_attr "length"   "8")])
8536
8537 (define_split
8538   [(set (match_operand:SI 0 "register_operand" "")
8539         (ge:SI (match_operand:SI 1 "register_operand" "")
8540                (match_operand:SI 2 "arith_operand" "")))]
8541   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8542   [(set (match_dup 0)
8543         (lt:SI (match_dup 1)
8544                (match_dup 2)))
8545    (set (match_dup 0)
8546         (xor:SI (match_dup 0)
8547                 (const_int 1)))]
8548   "")
8549
8550 (define_insn "sge_di"
8551   [(set (match_operand:DI 0 "register_operand" "=d")
8552         (ge:DI (match_operand:DI 1 "se_register_operand" "d")
8553                (match_operand:DI 2 "se_arith_operand" "dI")))]
8554   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8555   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8556   [(set_attr "type"     "arith")
8557    (set_attr "mode"     "DI")
8558    (set_attr "length"   "8")])
8559
8560 (define_split
8561   [(set (match_operand:DI 0 "register_operand" "")
8562         (ge:DI (match_operand:DI 1 "se_register_operand" "")
8563                (match_operand:DI 2 "se_arith_operand" "")))]
8564   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8565    && !TARGET_MIPS16"
8566   [(set (match_dup 0)
8567         (lt:DI (match_dup 1)
8568                (match_dup 2)))
8569    (set (match_dup 0)
8570         (xor:DI (match_dup 0)
8571                 (const_int 1)))]
8572   "")
8573
8574 (define_expand "slt"
8575   [(set (match_operand:SI 0 "register_operand" "=d")
8576         (lt:SI (match_dup 1)
8577                (match_dup 2)))]
8578   ""
8579   "
8580 {
8581   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8582     FAIL;
8583
8584   /* set up operands from compare.  */
8585   operands[1] = branch_cmp[0];
8586   operands[2] = branch_cmp[1];
8587
8588   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8589     {
8590       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8591       DONE;
8592     }
8593
8594   /* fall through and generate default code */
8595 }")
8596
8597 (define_insn "slt_si"
8598   [(set (match_operand:SI 0 "register_operand" "=d")
8599         (lt:SI (match_operand:SI 1 "register_operand" "d")
8600                (match_operand:SI 2 "arith_operand" "dI")))]
8601   "!TARGET_MIPS16"
8602   "slt\\t%0,%1,%2"
8603   [(set_attr "type"     "arith")
8604    (set_attr "mode"     "SI")])
8605
8606 (define_insn ""
8607   [(set (match_operand:SI 0 "register_operand" "=t,t")
8608         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8609                (match_operand:SI 2 "arith_operand" "d,I")))]
8610   "TARGET_MIPS16"
8611   "slt\\t%1,%2"
8612   [(set_attr "type"     "arith")
8613    (set_attr "mode"     "SI")
8614    (set_attr_alternative "length"
8615                 [(const_int 4)
8616                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8617                                (const_int 4)
8618                                (const_int 8))])])
8619
8620 (define_insn "slt_di"
8621   [(set (match_operand:DI 0 "register_operand" "=d")
8622         (lt:DI (match_operand:DI 1 "se_register_operand" "d")
8623                (match_operand:DI 2 "se_arith_operand" "dI")))]
8624   "TARGET_64BIT && !TARGET_MIPS16"
8625   "slt\\t%0,%1,%2"
8626   [(set_attr "type"     "arith")
8627    (set_attr "mode"     "DI")])
8628
8629 (define_insn ""
8630   [(set (match_operand:DI 0 "register_operand" "=t,t")
8631         (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
8632                (match_operand:DI 2 "se_arith_operand" "d,I")))]
8633   "TARGET_64BIT && TARGET_MIPS16"
8634   "slt\\t%1,%2"
8635   [(set_attr "type"     "arith")
8636    (set_attr "mode"     "DI")
8637    (set_attr_alternative "length"
8638                 [(const_int 4)
8639                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8640                                (const_int 4)
8641                                (const_int 8))])])
8642
8643 (define_expand "sle"
8644   [(set (match_operand:SI 0 "register_operand" "=d")
8645         (le:SI (match_dup 1)
8646                (match_dup 2)))]
8647   ""
8648   "
8649 {
8650   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8651     FAIL;
8652
8653   /* set up operands from compare.  */
8654   operands[1] = branch_cmp[0];
8655   operands[2] = branch_cmp[1];
8656
8657   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8658     {
8659       gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8660       DONE;
8661     }
8662
8663   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8664     operands[2] = force_reg (SImode, operands[2]);
8665
8666   /* fall through and generate default code */
8667 }")
8668
8669 (define_insn "sle_si_const"
8670   [(set (match_operand:SI 0 "register_operand" "=d")
8671         (le:SI (match_operand:SI 1 "register_operand" "d")
8672                (match_operand:SI 2 "small_int" "I")))]
8673   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8674   "*
8675 {
8676   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8677   return \"slt\\t%0,%1,%2\";
8678 }"
8679   [(set_attr "type"     "arith")
8680    (set_attr "mode"     "SI")])
8681
8682 (define_insn ""
8683   [(set (match_operand:SI 0 "register_operand" "=t")
8684         (le:SI (match_operand:SI 1 "register_operand" "d")
8685                (match_operand:SI 2 "small_int" "I")))]
8686   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8687   "*
8688 {
8689   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8690   return \"slt\\t%1,%2\";
8691 }"
8692   [(set_attr "type"     "arith")
8693    (set_attr "mode"     "SI")
8694    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8695                                       (const_int 4)
8696                                       (const_int 8)))])
8697
8698 (define_insn "sle_di_const"
8699   [(set (match_operand:DI 0 "register_operand" "=d")
8700         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8701                (match_operand:DI 2 "small_int" "I")))]
8702   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8703   "*
8704 {
8705   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8706   return \"slt\\t%0,%1,%2\";
8707 }"
8708   [(set_attr "type"     "arith")
8709    (set_attr "mode"     "DI")])
8710
8711 (define_insn ""
8712   [(set (match_operand:DI 0 "register_operand" "=t")
8713         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8714                (match_operand:DI 2 "small_int" "I")))]
8715   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8716   "*
8717 {
8718   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8719   return \"slt\\t%1,%2\";
8720 }"
8721   [(set_attr "type"     "arith")
8722    (set_attr "mode"     "DI")
8723    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8724                                       (const_int 4)
8725                                       (const_int 8)))])
8726
8727 (define_insn "sle_si_reg"
8728   [(set (match_operand:SI 0 "register_operand" "=d")
8729         (le:SI (match_operand:SI 1 "register_operand" "d")
8730                (match_operand:SI 2 "register_operand" "d")))]
8731   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8732   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8733   [(set_attr "type"     "arith")
8734    (set_attr "mode"     "SI")
8735    (set_attr "length"   "8")])
8736
8737 (define_split
8738   [(set (match_operand:SI 0 "register_operand" "")
8739         (le:SI (match_operand:SI 1 "register_operand" "")
8740                (match_operand:SI 2 "register_operand" "")))]
8741   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8742   [(set (match_dup 0)
8743         (lt:SI (match_dup 2)
8744                (match_dup 1)))
8745    (set (match_dup 0)
8746         (xor:SI (match_dup 0)
8747                 (const_int 1)))]
8748   "")
8749
8750 (define_insn "sle_di_reg"
8751   [(set (match_operand:DI 0 "register_operand" "=d")
8752         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8753                (match_operand:DI 2 "se_register_operand" "d")))]
8754   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8755   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8756   [(set_attr "type"     "arith")
8757    (set_attr "mode"     "DI")
8758    (set_attr "length"   "8")])
8759
8760 (define_split
8761   [(set (match_operand:DI 0 "register_operand" "")
8762         (le:DI (match_operand:DI 1 "se_register_operand" "")
8763                (match_operand:DI 2 "se_register_operand" "")))]
8764   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8765    && !TARGET_MIPS16"
8766   [(set (match_dup 0)
8767         (lt:DI (match_dup 2)
8768                (match_dup 1)))
8769    (set (match_dup 0)
8770         (xor:DI (match_dup 0)
8771                 (const_int 1)))]
8772   "")
8773
8774 (define_expand "sgtu"
8775   [(set (match_operand:SI 0 "register_operand" "=d")
8776         (gtu:SI (match_dup 1)
8777                 (match_dup 2)))]
8778   ""
8779   "
8780 {
8781   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8782     FAIL;
8783
8784   /* set up operands from compare.  */
8785   operands[1] = branch_cmp[0];
8786   operands[2] = branch_cmp[1];
8787
8788   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8789     {
8790       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8791       DONE;
8792     }
8793
8794   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8795     operands[2] = force_reg (SImode, operands[2]);
8796
8797   /* fall through and generate default code */
8798 }")
8799
8800 (define_insn "sgtu_si"
8801   [(set (match_operand:SI 0 "register_operand" "=d")
8802         (gtu:SI (match_operand:SI 1 "register_operand" "d")
8803                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8804   ""
8805   "sltu\\t%0,%z2,%1"
8806   [(set_attr "type"     "arith")
8807    (set_attr "mode"     "SI")])
8808
8809 (define_insn ""
8810   [(set (match_operand:SI 0 "register_operand" "=t")
8811         (gtu:SI (match_operand:SI 1 "register_operand" "d")
8812                 (match_operand:SI 2 "register_operand" "d")))]
8813   ""
8814   "sltu\\t%2,%1"
8815   [(set_attr "type"     "arith")
8816    (set_attr "mode"     "SI")])
8817
8818 (define_insn "sgtu_di"
8819   [(set (match_operand:DI 0 "register_operand" "=d")
8820         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8821                 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8822   "TARGET_64BIT"
8823   "sltu\\t%0,%z2,%1"
8824   [(set_attr "type"     "arith")
8825    (set_attr "mode"     "DI")])
8826
8827 (define_insn ""
8828   [(set (match_operand:DI 0 "register_operand" "=t")
8829         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8830                 (match_operand:DI 2 "se_register_operand" "d")))]
8831   "TARGET_64BIT"
8832   "sltu\\t%2,%1"
8833   [(set_attr "type"     "arith")
8834    (set_attr "mode"     "DI")])
8835
8836 (define_expand "sgeu"
8837   [(set (match_operand:SI 0 "register_operand" "=d")
8838         (geu:SI (match_dup 1)
8839                 (match_dup 2)))]
8840   ""
8841   "
8842 {
8843   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8844     FAIL;
8845
8846   /* set up operands from compare.  */
8847   operands[1] = branch_cmp[0];
8848   operands[2] = branch_cmp[1];
8849
8850   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8851     {
8852       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8853       DONE;
8854     }
8855
8856   /* fall through and generate default code */
8857 }")
8858
8859 (define_insn "sgeu_si"
8860   [(set (match_operand:SI 0 "register_operand" "=d")
8861         (geu:SI (match_operand:SI 1 "register_operand" "d")
8862                 (match_operand:SI 2 "arith_operand" "dI")))]
8863   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8864   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8865   [(set_attr "type"     "arith")
8866    (set_attr "mode"     "SI")
8867    (set_attr "length"   "8")])
8868
8869 (define_split
8870   [(set (match_operand:SI 0 "register_operand" "")
8871         (geu:SI (match_operand:SI 1 "register_operand" "")
8872                 (match_operand:SI 2 "arith_operand" "")))]
8873   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8874   [(set (match_dup 0)
8875         (ltu:SI (match_dup 1)
8876                 (match_dup 2)))
8877    (set (match_dup 0)
8878         (xor:SI (match_dup 0)
8879                 (const_int 1)))]
8880   "")
8881
8882 (define_insn "sgeu_di"
8883   [(set (match_operand:DI 0 "register_operand" "=d")
8884         (geu:DI (match_operand:DI 1 "se_register_operand" "d")
8885                 (match_operand:DI 2 "se_arith_operand" "dI")))]
8886   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8887   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8888   [(set_attr "type"     "arith")
8889    (set_attr "mode"     "DI")
8890    (set_attr "length"   "8")])
8891
8892 (define_split
8893   [(set (match_operand:DI 0 "register_operand" "")
8894         (geu:DI (match_operand:DI 1 "se_register_operand" "")
8895                 (match_operand:DI 2 "se_arith_operand" "")))]
8896   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8897    && !TARGET_MIPS16"
8898   [(set (match_dup 0)
8899         (ltu:DI (match_dup 1)
8900                 (match_dup 2)))
8901    (set (match_dup 0)
8902         (xor:DI (match_dup 0)
8903                 (const_int 1)))]
8904   "")
8905
8906 (define_expand "sltu"
8907   [(set (match_operand:SI 0 "register_operand" "=d")
8908         (ltu:SI (match_dup 1)
8909                 (match_dup 2)))]
8910   ""
8911   "
8912 {
8913   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8914     FAIL;
8915
8916   /* set up operands from compare.  */
8917   operands[1] = branch_cmp[0];
8918   operands[2] = branch_cmp[1];
8919
8920   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8921     {
8922       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8923       DONE;
8924     }
8925
8926   /* fall through and generate default code */
8927 }")
8928
8929 (define_insn "sltu_si"
8930   [(set (match_operand:SI 0 "register_operand" "=d")
8931         (ltu:SI (match_operand:SI 1 "register_operand" "d")
8932                 (match_operand:SI 2 "arith_operand" "dI")))]
8933   "!TARGET_MIPS16"
8934   "sltu\\t%0,%1,%2"
8935   [(set_attr "type"     "arith")
8936    (set_attr "mode"     "SI")])
8937
8938 (define_insn ""
8939   [(set (match_operand:SI 0 "register_operand" "=t,t")
8940         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8941                 (match_operand:SI 2 "arith_operand" "d,I")))]
8942   "TARGET_MIPS16"
8943   "sltu\\t%1,%2"
8944   [(set_attr "type"     "arith")
8945    (set_attr "mode"     "SI")
8946    (set_attr_alternative "length"
8947                 [(const_int 4)
8948                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8949                                (const_int 4)
8950                                (const_int 8))])])
8951
8952 (define_insn "sltu_di"
8953   [(set (match_operand:DI 0 "register_operand" "=d")
8954         (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
8955                 (match_operand:DI 2 "se_arith_operand" "dI")))]
8956   "TARGET_64BIT && !TARGET_MIPS16"
8957   "sltu\\t%0,%1,%2"
8958   [(set_attr "type"     "arith")
8959    (set_attr "mode"     "DI")])
8960
8961 (define_insn ""
8962   [(set (match_operand:DI 0 "register_operand" "=t,t")
8963         (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
8964                 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8965   "TARGET_64BIT && TARGET_MIPS16"
8966   "sltu\\t%1,%2"
8967   [(set_attr "type"     "arith")
8968    (set_attr "mode"     "DI")
8969    (set_attr_alternative "length"
8970                 [(const_int 4)
8971                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8972                                (const_int 4)
8973                                (const_int 8))])])
8974
8975 (define_expand "sleu"
8976   [(set (match_operand:SI 0 "register_operand" "=d")
8977         (leu:SI (match_dup 1)
8978                 (match_dup 2)))]
8979   ""
8980   "
8981 {
8982   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8983     FAIL;
8984
8985   /* set up operands from compare.  */
8986   operands[1] = branch_cmp[0];
8987   operands[2] = branch_cmp[1];
8988
8989   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8990     {
8991       gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
8992       DONE;
8993     }
8994
8995   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8996     operands[2] = force_reg (SImode, operands[2]);
8997
8998   /* fall through and generate default code */
8999 }")
9000
9001 (define_insn "sleu_si_const"
9002   [(set (match_operand:SI 0 "register_operand" "=d")
9003         (leu:SI (match_operand:SI 1 "register_operand" "d")
9004                 (match_operand:SI 2 "small_int" "I")))]
9005   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9006   "*
9007 {
9008   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9009   return \"sltu\\t%0,%1,%2\";
9010 }"
9011   [(set_attr "type"     "arith")
9012    (set_attr "mode"     "SI")])
9013
9014 (define_insn ""
9015   [(set (match_operand:SI 0 "register_operand" "=t")
9016         (leu:SI (match_operand:SI 1 "register_operand" "d")
9017                 (match_operand:SI 2 "small_int" "I")))]
9018   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9019   "*
9020 {
9021   operands[2] = GEN_INT (INTVAL (operands[2])+1);
9022   return \"sltu\\t%1,%2\";
9023 }"
9024   [(set_attr "type"     "arith")
9025    (set_attr "mode"     "SI")
9026    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9027                                       (const_int 4)
9028                                       (const_int 8)))])
9029
9030 (define_insn "sleu_di_const"
9031   [(set (match_operand:DI 0 "register_operand" "=d")
9032         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9033                 (match_operand:DI 2 "small_int" "I")))]
9034   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9035   "*
9036 {
9037   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9038   return \"sltu\\t%0,%1,%2\";
9039 }"
9040   [(set_attr "type"     "arith")
9041    (set_attr "mode"     "DI")])
9042
9043 (define_insn ""
9044   [(set (match_operand:DI 0 "register_operand" "=t")
9045         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9046                 (match_operand:DI 2 "small_int" "I")))]
9047   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9048   "*
9049 {
9050   operands[2] = GEN_INT (INTVAL (operands[2])+1);
9051   return \"sltu\\t%1,%2\";
9052 }"
9053   [(set_attr "type"     "arith")
9054    (set_attr "mode"     "DI")
9055    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9056                                       (const_int 4)
9057                                       (const_int 8)))])
9058
9059 (define_insn "sleu_si_reg"
9060   [(set (match_operand:SI 0 "register_operand" "=d")
9061         (leu:SI (match_operand:SI 1 "register_operand" "d")
9062                 (match_operand:SI 2 "register_operand" "d")))]
9063   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9064   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9065   [(set_attr "type"     "arith")
9066    (set_attr "mode"     "SI")
9067    (set_attr "length"   "8")])
9068
9069 (define_split
9070   [(set (match_operand:SI 0 "register_operand" "")
9071         (leu:SI (match_operand:SI 1 "register_operand" "")
9072                 (match_operand:SI 2 "register_operand" "")))]
9073   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
9074   [(set (match_dup 0)
9075         (ltu:SI (match_dup 2)
9076                 (match_dup 1)))
9077    (set (match_dup 0)
9078         (xor:SI (match_dup 0)
9079                 (const_int 1)))]
9080   "")
9081
9082 (define_insn "sleu_di_reg"
9083   [(set (match_operand:DI 0 "register_operand" "=d")
9084         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9085                 (match_operand:DI 2 "se_register_operand" "d")))]
9086   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9087   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9088   [(set_attr "type"     "arith")
9089    (set_attr "mode"     "DI")
9090    (set_attr "length"   "8")])
9091
9092 (define_split
9093   [(set (match_operand:DI 0 "register_operand" "")
9094         (leu:DI (match_operand:DI 1 "se_register_operand" "")
9095                 (match_operand:DI 2 "se_register_operand" "")))]
9096   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9097    && !TARGET_MIPS16"
9098   [(set (match_dup 0)
9099         (ltu:DI (match_dup 2)
9100                 (match_dup 1)))
9101    (set (match_dup 0)
9102         (xor:DI (match_dup 0)
9103                 (const_int 1)))]
9104   "")
9105
9106 \f
9107 ;;
9108 ;;  ....................
9109 ;;
9110 ;;      FLOATING POINT COMPARISONS
9111 ;;
9112 ;;  ....................
9113
9114 (define_insn "seq_df"
9115   [(set (match_operand:CC 0 "register_operand" "=z")
9116         (eq:CC (match_operand:DF 1 "register_operand" "f")
9117                (match_operand:DF 2 "register_operand" "f")))]
9118   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9119   "*
9120 {
9121   return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9122 }"
9123  [(set_attr "type"      "fcmp")
9124   (set_attr "mode"      "FPSW")])
9125
9126 (define_insn "slt_df"
9127   [(set (match_operand:CC 0 "register_operand" "=z")
9128         (lt:CC (match_operand:DF 1 "register_operand" "f")
9129                (match_operand:DF 2 "register_operand" "f")))]
9130   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9131   "*
9132 {
9133   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9134 }"
9135  [(set_attr "type"      "fcmp")
9136   (set_attr "mode"      "FPSW")])
9137
9138 (define_insn "sle_df"
9139   [(set (match_operand:CC 0 "register_operand" "=z")
9140         (le:CC (match_operand:DF 1 "register_operand" "f")
9141                (match_operand:DF 2 "register_operand" "f")))]
9142   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9143   "*
9144 {
9145   return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9146 }"
9147  [(set_attr "type"      "fcmp")
9148   (set_attr "mode"      "FPSW")])
9149
9150 (define_insn "sgt_df"
9151   [(set (match_operand:CC 0 "register_operand" "=z")
9152         (gt:CC (match_operand:DF 1 "register_operand" "f")
9153                (match_operand:DF 2 "register_operand" "f")))]
9154   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9155   "*
9156 {
9157   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9158 }"
9159  [(set_attr "type"      "fcmp")
9160   (set_attr "mode"      "FPSW")])
9161
9162 (define_insn "sge_df"
9163   [(set (match_operand:CC 0 "register_operand" "=z")
9164         (ge:CC (match_operand:DF 1 "register_operand" "f")
9165                (match_operand:DF 2 "register_operand" "f")))]
9166   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9167   "*
9168 {
9169   return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9170 }"
9171  [(set_attr "type"      "fcmp")
9172   (set_attr "mode"      "FPSW")])
9173
9174 (define_insn "seq_sf"
9175   [(set (match_operand:CC 0 "register_operand" "=z")
9176         (eq:CC (match_operand:SF 1 "register_operand" "f")
9177                (match_operand:SF 2 "register_operand" "f")))]
9178   "TARGET_HARD_FLOAT"
9179   "*
9180 {
9181   return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9182 }"
9183  [(set_attr "type"      "fcmp")
9184   (set_attr "mode"      "FPSW")])
9185
9186 (define_insn "slt_sf"
9187   [(set (match_operand:CC 0 "register_operand" "=z")
9188         (lt:CC (match_operand:SF 1 "register_operand" "f")
9189                (match_operand:SF 2 "register_operand" "f")))]
9190   "TARGET_HARD_FLOAT"
9191   "*
9192 {
9193   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9194 }"
9195  [(set_attr "type"      "fcmp")
9196   (set_attr "mode"      "FPSW")])
9197
9198 (define_insn "sle_sf"
9199   [(set (match_operand:CC 0 "register_operand" "=z")
9200         (le:CC (match_operand:SF 1 "register_operand" "f")
9201                (match_operand:SF 2 "register_operand" "f")))]
9202   "TARGET_HARD_FLOAT"
9203   "*
9204 {
9205   return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9206 }"
9207  [(set_attr "type"      "fcmp")
9208   (set_attr "mode"      "FPSW")])
9209
9210 (define_insn "sgt_sf"
9211   [(set (match_operand:CC 0 "register_operand" "=z")
9212         (gt:CC (match_operand:SF 1 "register_operand" "f")
9213                (match_operand:SF 2 "register_operand" "f")))]
9214   "TARGET_HARD_FLOAT"
9215   "*
9216 {
9217   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9218 }"
9219  [(set_attr "type"      "fcmp")
9220   (set_attr "mode"      "FPSW")])
9221
9222 (define_insn "sge_sf"
9223   [(set (match_operand:CC 0 "register_operand" "=z")
9224         (ge:CC (match_operand:SF 1 "register_operand" "f")
9225                (match_operand:SF 2 "register_operand" "f")))]
9226   "TARGET_HARD_FLOAT"
9227   "*
9228 {
9229   return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9230 }"
9231  [(set_attr "type"      "fcmp")
9232   (set_attr "mode"      "FPSW")])
9233
9234 \f
9235 ;;
9236 ;;  ....................
9237 ;;
9238 ;;      UNCONDITIONAL BRANCHES
9239 ;;
9240 ;;  ....................
9241
9242 ;; Unconditional branches.
9243
9244 (define_insn "jump"
9245   [(set (pc)
9246         (label_ref (match_operand 0 "" "")))]
9247   "!TARGET_MIPS16"
9248   "*
9249 {
9250   if (GET_CODE (operands[0]) == REG)
9251     return \"%*j\\t%0\";
9252   /* ??? I don't know why this is necessary.  This works around an
9253      assembler problem that appears when a label is defined, then referenced
9254      in a switch table, then used in a `j' instruction.  */
9255   else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
9256     return \"%*b\\t%l0\";
9257   else
9258     return \"%*j\\t%l0\";
9259 }"
9260   [(set_attr "type"     "jump")
9261    (set_attr "mode"     "none")])
9262
9263 ;; We need a different insn for the mips16, because a mips16 branch
9264 ;; does not have a delay slot.
9265
9266 (define_insn ""
9267   [(set (pc)
9268         (label_ref (match_operand 0 "" "")))]
9269   "TARGET_MIPS16 && GET_CODE (operands[0]) != REG"
9270   "b\\t%l0"
9271   [(set_attr "type"     "branch")
9272    (set_attr "mode"     "none")
9273    (set_attr "length"   "8")])
9274
9275 (define_expand "indirect_jump"
9276   [(set (pc) (match_operand 0 "register_operand" "d"))]
9277   ""
9278   "
9279 {
9280   rtx dest;
9281
9282   if (operands[0])              /* eliminate unused code warnings */
9283     {
9284       dest = operands[0];
9285       if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9286         operands[0] = copy_to_mode_reg (Pmode, dest);
9287
9288       if (!(Pmode == DImode))
9289         emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9290       else
9291         emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9292
9293       DONE;
9294     }
9295 }")
9296
9297 (define_insn "indirect_jump_internal1"
9298   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
9299   "!(Pmode == DImode)"
9300   "%*j\\t%0"
9301   [(set_attr "type"     "jump")
9302    (set_attr "mode"     "none")])
9303
9304 (define_insn "indirect_jump_internal2"
9305   [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
9306   "Pmode == DImode"
9307   "%*j\\t%0"
9308   [(set_attr "type"     "jump")
9309    (set_attr "mode"     "none")])
9310
9311 (define_expand "tablejump"
9312   [(set (pc)
9313         (match_operand 0 "register_operand" "d"))
9314    (use (label_ref (match_operand 1 "" "")))]
9315   ""
9316   "
9317 {
9318   if (operands[0])              /* eliminate unused code warnings */
9319     {
9320       if (TARGET_MIPS16)
9321         {
9322           if (GET_MODE (operands[0]) != HImode)
9323             abort ();
9324           if (!(Pmode == DImode))
9325             emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
9326           else
9327             emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
9328           DONE;
9329         }
9330
9331       if (GET_MODE (operands[0]) != Pmode)
9332         abort ();
9333
9334       if (! flag_pic)
9335         {
9336           if (!(Pmode == DImode))
9337             emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9338           else
9339             emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
9340         }
9341       else
9342         {
9343           if (!(Pmode == DImode))
9344             emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
9345           else
9346             emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
9347         }
9348
9349       DONE;
9350     }
9351 }")
9352
9353 (define_insn "tablejump_internal1"
9354   [(set (pc)
9355         (match_operand:SI 0 "register_operand" "d"))
9356    (use (label_ref (match_operand 1 "" "")))]
9357   "!(Pmode == DImode)"
9358   "%*j\\t%0"
9359   [(set_attr "type"     "jump")
9360    (set_attr "mode"     "none")])
9361
9362 (define_insn "tablejump_internal2"
9363   [(set (pc)
9364         (match_operand:DI 0 "se_register_operand" "d"))
9365    (use (label_ref (match_operand 1 "" "")))]
9366   "Pmode == DImode"
9367   "%*j\\t%0"
9368   [(set_attr "type"     "jump")
9369    (set_attr "mode"     "none")])
9370
9371 (define_expand "tablejump_internal3"
9372   [(parallel [(set (pc)
9373                    (plus:SI (match_operand:SI 0 "register_operand" "d")
9374                             (label_ref:SI (match_operand 1 "" ""))))
9375               (use (label_ref:SI (match_dup 1)))])]
9376   ""
9377   "")
9378
9379 (define_expand "tablejump_mips161"
9380   [(set (pc) (plus:SI (sign_extend:SI
9381                        (match_operand:HI 0 "register_operand" "d"))
9382                       (label_ref:SI (match_operand 1 "" ""))))]
9383   "TARGET_MIPS16 && !(Pmode == DImode)"
9384   "
9385 {
9386   if (operands[0])      /* eliminate unused code warnings.  */
9387     {
9388       rtx t1, t2, t3;
9389
9390       t1 = gen_reg_rtx (SImode);
9391       t2 = gen_reg_rtx (SImode);
9392       t3 = gen_reg_rtx (SImode);
9393       emit_insn (gen_extendhisi2 (t1, operands[0]));
9394       emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
9395       emit_insn (gen_addsi3 (t3, t1, t2));
9396       emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
9397       DONE;
9398     }
9399 }")
9400
9401 (define_expand "tablejump_mips162"
9402   [(set (pc) (plus:DI (sign_extend:DI
9403                        (match_operand:HI 0 "register_operand" "d"))
9404                       (label_ref:DI (match_operand 1 "" ""))))]
9405   "TARGET_MIPS16 && Pmode == DImode"
9406   "
9407 {
9408   if (operands[0])      /* eliminate unused code warnings.  */
9409     {
9410       rtx t1, t2, t3;
9411
9412       t1 = gen_reg_rtx (DImode);
9413       t2 = gen_reg_rtx (DImode);
9414       t3 = gen_reg_rtx (DImode);
9415       emit_insn (gen_extendhidi2 (t1, operands[0]));
9416       emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
9417       emit_insn (gen_adddi3 (t3, t1, t2));
9418       emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
9419       DONE;
9420     }
9421 }")
9422
9423 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
9424 ;;; it is not valid.  ??? With the USE, the condition tests may not be required
9425 ;;; any longer.
9426
9427 ;;; ??? The length depends on the ABI.  It is two for o32, and one for n32.
9428 ;;; We just use the conservative number here.
9429
9430 (define_insn ""
9431   [(set (pc)
9432         (plus:SI (match_operand:SI 0 "register_operand" "d")
9433                  (label_ref:SI (match_operand 1 "" ""))))
9434    (use (label_ref:SI (match_dup 1)))]
9435   "!(Pmode == DImode) && next_active_insn (insn) != 0
9436    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9437    && PREV_INSN (next_active_insn (insn)) == operands[1]"
9438   "*
9439 {
9440   /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic.  */
9441   if (mips_abi == ABI_32 || mips_abi == ABI_O64)
9442     output_asm_insn (\".cpadd\\t%0\", operands);
9443   return \"%*j\\t%0\";
9444 }"
9445   [(set_attr "type"     "jump")
9446    (set_attr "mode"     "none")
9447    (set_attr "length"   "8")])
9448
9449 (define_expand "tablejump_internal4"
9450   [(parallel [(set (pc)
9451                    (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9452                             (label_ref:DI (match_operand 1 "" ""))))
9453               (use (label_ref:DI (match_dup 1)))])]
9454   ""
9455   "")
9456
9457 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
9458 ;;; it is not valid.  ??? With the USE, the condition tests may not be required
9459 ;;; any longer.
9460
9461 (define_insn ""
9462   [(set (pc)
9463         (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9464                  (label_ref:DI (match_operand 1 "" ""))))
9465    (use (label_ref:DI (match_dup 1)))]
9466   "Pmode == DImode && next_active_insn (insn) != 0
9467    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9468    && PREV_INSN (next_active_insn (insn)) == operands[1]"
9469   "%*j\\t%0"
9470   [(set_attr "type"     "jump")
9471    (set_attr "mode"     "none")])
9472
9473 ;; Implement a switch statement when generating embedded PIC code.
9474 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
9475
9476 (define_expand "casesi"
9477   [(set (match_dup 5)
9478         (minus:SI (match_operand:SI 0 "register_operand" "d")
9479                   (match_operand:SI 1 "arith_operand" "dI")))
9480    (set (cc0)
9481         (compare:CC (match_dup 5)
9482                     (match_operand:SI 2 "arith_operand" "")))
9483    (set (pc)
9484         (if_then_else (gtu (cc0)
9485                            (const_int 0))
9486                       (label_ref (match_operand 4 "" ""))
9487                       (pc)))
9488    (parallel
9489     [(set (pc)
9490           (mem:SI (plus:SI (mult:SI (match_dup 5)
9491                                     (const_int 4))
9492                            (label_ref (match_operand 3 "" "")))))
9493      (clobber (match_scratch:SI 6 ""))
9494      (clobber (reg:SI 31))])]
9495   "TARGET_EMBEDDED_PIC"
9496   "
9497 {
9498   if (operands[0])
9499     {
9500       rtx reg = gen_reg_rtx (SImode);
9501
9502       /* If the index is too large, go to the default label.  */
9503       emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9504       emit_insn (gen_cmpsi (reg, operands[2]));
9505       emit_insn (gen_bgtu (operands[4]));
9506
9507       /* Do the PIC jump.  */
9508       if (Pmode != DImode)
9509         emit_jump_insn (gen_casesi_internal (reg, operands[3],
9510                                              gen_reg_rtx (SImode)));
9511       else
9512         emit_jump_insn (gen_casesi_internal_di (reg, operands[3],
9513                                                 gen_reg_rtx (DImode)));
9514
9515       DONE;
9516     }
9517 }")
9518
9519 ;; An embedded PIC switch statement looks like this:
9520 ;;      bal     $LS1
9521 ;;      sll     $reg,$index,2
9522 ;; $LS1:
9523 ;;      addu    $reg,$reg,$31
9524 ;;      lw      $reg,$L1-$LS1($reg)
9525 ;;      addu    $reg,$reg,$31
9526 ;;      j       $reg
9527 ;; $L1:
9528 ;;      .word   case1-$LS1
9529 ;;      .word   case2-$LS1
9530 ;;      ...
9531
9532 (define_insn "casesi_internal"
9533   [(set (pc)
9534         (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9535                                   (const_int 4))
9536                          (label_ref (match_operand 1 "" "")))))
9537    (clobber (match_operand:SI 2 "register_operand" "=d"))
9538    (clobber (reg:SI 31))]
9539   "TARGET_EMBEDDED_PIC"
9540   "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9541 lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2"
9542   [(set_attr "type"     "jump")
9543    (set_attr "mode"     "none")
9544    (set_attr "length"   "24")])
9545
9546 ;; This code assumes that the table index will never be >= 29 bits wide,
9547 ;; which allows the 'sign extend' from SI to DI be a no-op.
9548 (define_insn "casesi_internal_di"
9549   [(set (pc)
9550         (mem:DI (plus:DI (sign_extend:DI
9551                           (mult:SI (match_operand:SI 0 "register_operand" "d")
9552                                   (const_int 8)))
9553                          (label_ref (match_operand 1 "" "")))))
9554    (clobber (match_operand:DI 2 "register_operand" "=d"))
9555    (clobber (reg:DI 31))]
9556   "TARGET_EMBEDDED_PIC"
9557   "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
9558 ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
9559   [(set_attr "type"     "jump")
9560    (set_attr "mode"     "none")
9561    (set_attr "length"   "24")])
9562
9563 ;; For o32/n32/n64, we save the gp in the jmp_buf as well.  While it is
9564 ;; possible to either pull it off the stack (in the o32 case) or recalculate
9565 ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9566 ;; this is easy.
9567
9568 (define_expand "builtin_setjmp_setup"
9569   [(unspec [(match_operand 0 "register_operand" "r")] UNSPEC_SETJMP)]
9570   "TARGET_ABICALLS"
9571   "
9572 {
9573   if (Pmode == DImode)
9574     emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9575   else
9576     emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9577   DONE;
9578 }")
9579
9580 (define_expand "builtin_setjmp_setup_32"
9581   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9582                    (const_int 12)))
9583       (reg:SI 28))]
9584   "TARGET_ABICALLS && ! (Pmode == DImode)"
9585   "")
9586
9587 (define_expand "builtin_setjmp_setup_64"
9588   [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9589                    (const_int 24)))
9590       (reg:DI 28))]
9591   "TARGET_ABICALLS && Pmode == DImode"
9592   "")
9593
9594 ;; For o32/n32/n64, we need to arrange for longjmp to put the
9595 ;; target address in t9 so that we can use it for loading $gp.
9596
9597 (define_expand "builtin_longjmp"
9598   [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPEC_LONGJMP)]
9599   "TARGET_ABICALLS"
9600   "
9601 {
9602   /* The elements of the buffer are, in order:  */
9603   int W = (Pmode == DImode ? 8 : 4);
9604   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9605   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9606   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9607   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9608   rtx pv = gen_rtx_REG (Pmode, 25);
9609   rtx gp = gen_rtx_REG (Pmode, 28);
9610
9611   /* This bit is the same as expand_builtin_longjmp.  */
9612   emit_move_insn (hard_frame_pointer_rtx, fp);
9613   emit_move_insn (pv, lab);
9614   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9615   emit_move_insn (gp, gpv);
9616   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9617   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9618   emit_insn (gen_rtx_USE (VOIDmode, gp));
9619   emit_indirect_jump (pv);
9620   DONE;
9621 }")
9622 \f
9623 ;;
9624 ;;  ....................
9625 ;;
9626 ;;      Function prologue/epilogue
9627 ;;
9628 ;;  ....................
9629 ;;
9630
9631 (define_expand "prologue"
9632   [(const_int 1)]
9633   ""
9634   "
9635 {
9636   if (mips_isa >= 0)            /* avoid unused code warnings */
9637     {
9638       mips_expand_prologue ();
9639       DONE;
9640     }
9641 }")
9642
9643 ;; Block any insns from being moved before this point, since the
9644 ;; profiling call to mcount can use various registers that aren't
9645 ;; saved or used to pass arguments.
9646
9647 (define_insn "blockage"
9648   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
9649   ""
9650   ""
9651   [(set_attr "type"     "unknown")
9652    (set_attr "mode"     "none")
9653    (set_attr "length"   "0")])
9654
9655 (define_expand "epilogue"
9656   [(const_int 2)]
9657   ""
9658   "
9659 {
9660   if (mips_isa >= 0)            /* avoid unused code warnings */
9661     {
9662       mips_expand_epilogue ();
9663       DONE;
9664     }
9665 }")
9666
9667 ;; Trivial return.  Make it look like a normal return insn as that
9668 ;; allows jump optimizations to work better .
9669 (define_insn "return"
9670   [(return)]
9671   "mips_can_use_return_insn ()"
9672   "%*j\\t$31"
9673   [(set_attr "type"     "jump")
9674    (set_attr "mode"     "none")])
9675
9676 ;; Normal return.
9677
9678 (define_insn "return_internal"
9679   [(use (match_operand 0 "pmode_register_operand" ""))
9680    (return)]
9681   ""
9682   "*
9683 {
9684   return \"%*j\\t%0\";
9685 }"
9686   [(set_attr "type"     "jump")
9687    (set_attr "mode"     "none")])
9688
9689 ;; When generating embedded PIC code we need to get the address of the
9690 ;; current function.  This specialized instruction does just that.
9691
9692 (define_insn "get_fnaddr"
9693   [(set (match_operand 0 "register_operand" "=d")
9694         (unspec [(match_operand 1 "" "")] UNSPEC_GET_FNADDR))
9695    (clobber (reg:SI 31))]
9696   "TARGET_EMBEDDED_PIC
9697    && GET_CODE (operands[1]) == SYMBOL_REF"
9698   "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
9699   [(set_attr "type"     "call")
9700    (set_attr "mode"     "none")
9701    (set_attr "length"   "16")])
9702
9703 ;; This is used in compiling the unwind routines.
9704 (define_expand "eh_return"
9705   [(use (match_operand 0 "general_operand" ""))
9706    (use (match_operand 1 "general_operand" ""))]
9707   ""
9708   "
9709 {
9710   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
9711
9712   if (GET_MODE (operands[1]) != gpr_mode)
9713     operands[1] = convert_to_mode (gpr_mode, operands[1], 0);
9714   if (TARGET_64BIT)
9715     emit_insn (gen_eh_set_lr_di (operands[1]));
9716   else
9717     emit_insn (gen_eh_set_lr_si (operands[1]));
9718
9719   emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]);
9720   DONE;
9721 }")
9722
9723 ;; Clobber the return address on the stack.  We can't expand this
9724 ;; until we know where it will be put in the stack frame.
9725
9726 (define_insn "eh_set_lr_si"
9727   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9728    (clobber (match_scratch:SI 1 "=&r"))]
9729   "! TARGET_64BIT"
9730   "#")
9731
9732 (define_insn "eh_set_lr_di"
9733   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9734    (clobber (match_scratch:DI 1 "=&r"))]
9735   "TARGET_64BIT"
9736   "#")
9737
9738 (define_split
9739   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9740    (clobber (match_scratch 1 ""))]
9741   "reload_completed && !TARGET_DEBUG_D_MODE"
9742   [(const_int 0)]
9743   "
9744 {
9745   HOST_WIDE_INT gp_offset;
9746   rtx base;
9747
9748   compute_frame_size (get_frame_size ());
9749   if (((current_frame_info.mask >> 31) & 1) == 0)
9750     abort ();
9751   gp_offset = current_frame_info.gp_sp_offset;
9752
9753   if (gp_offset < 32768)
9754     base = stack_pointer_rtx;
9755   else
9756     {
9757       base = operands[1];
9758       emit_move_insn (base, GEN_INT (gp_offset));
9759       if (Pmode == DImode)
9760         emit_insn (gen_adddi3 (base, base, stack_pointer_rtx));
9761       else
9762         emit_insn (gen_addsi3 (base, base, stack_pointer_rtx));
9763       gp_offset = 0;
9764     }
9765   emit_move_insn (gen_rtx_MEM (GET_MODE (operands[0]),
9766                                plus_constant (base, gp_offset)),
9767                   operands[0]);
9768   DONE;
9769 }")
9770
9771 (define_insn "exception_receiver"
9772   [(unspec_volatile [(const_int 0)] UNSPEC_EH_RECEIVER)]
9773   "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
9774   "*
9775 {
9776   rtx loc;
9777
9778   operands[0] = pic_offset_table_rtx;
9779   if (frame_pointer_needed)
9780     loc = hard_frame_pointer_rtx;
9781   else
9782     loc = stack_pointer_rtx;
9783   loc = plus_constant (loc, current_frame_info.args_size);
9784   operands[1] = gen_rtx_MEM (Pmode, loc);
9785
9786   return mips_move_1word (operands, insn, 0);
9787 }"
9788   [(set_attr "type"   "load")
9789    (set_attr "length" "8")])
9790 \f
9791 ;;
9792 ;;  ....................
9793 ;;
9794 ;;      FUNCTION CALLS
9795 ;;
9796 ;;  ....................
9797
9798 ;; calls.c now passes a third argument, make saber happy
9799
9800 (define_expand "call"
9801   [(parallel [(call (match_operand 0 "memory_operand" "m")
9802                     (match_operand 1 "" "i"))
9803               (clobber (reg:SI 31))
9804               (use (match_operand 2 "" ""))             ;; next_arg_reg
9805               (use (match_operand 3 "" ""))])]          ;; struct_value_size_rtx
9806   ""
9807   "
9808 {
9809   rtx addr;
9810
9811   if (operands[0])              /* eliminate unused code warnings */
9812     {
9813       addr = XEXP (operands[0], 0);
9814       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9815           || ! call_insn_operand (addr, VOIDmode))
9816         XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
9817
9818       /* In order to pass small structures by value in registers
9819          compatibly with the MIPS compiler, we need to shift the value
9820          into the high part of the register.  Function_arg has encoded
9821          a PARALLEL rtx, holding a vector of adjustments to be made
9822          as the next_arg_reg variable, so we split up the insns,
9823          and emit them separately.  */
9824
9825       if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
9826         {
9827           rtvec adjust = XVEC (operands[2], 0);
9828           int num = GET_NUM_ELEM (adjust);
9829           int i;
9830
9831           for (i = 0; i < num; i++)
9832             emit_insn (RTVEC_ELT (adjust, i));
9833         }
9834
9835       if (TARGET_MIPS16
9836           && mips16_hard_float
9837           && operands[2] != 0
9838           && (int) GET_MODE (operands[2]) != 0)
9839         {
9840           if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
9841                                       (int) GET_MODE (operands[2])))
9842             DONE;
9843         }
9844
9845       emit_call_insn (gen_call_internal0 (operands[0], operands[1],
9846                                           gen_rtx_REG (SImode,
9847                                                        GP_REG_FIRST + 31)));
9848       DONE;
9849     }
9850 }")
9851
9852 (define_expand "call_internal0"
9853   [(parallel [(call (match_operand 0 "" "")
9854                     (match_operand 1 "" ""))
9855               (clobber (match_operand:SI 2 "" ""))])]
9856   ""
9857   "")
9858
9859 ;; We need to recognize reg:SI 31 specially for the mips16, because we
9860 ;; don't have a constraint letter for it.
9861
9862 (define_insn ""
9863   [(call (mem (match_operand 0 "call_insn_operand" "ei"))
9864          (match_operand 1 "" "i"))
9865    (clobber (match_operand:SI 2 "register_operand" "=y"))]
9866   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9867    && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9868   "%*jal\\t%0"
9869   [(set_attr "type"     "call")
9870    (set_attr "mode"     "none")
9871    (set_attr "length"   "8")])
9872
9873 (define_insn "call_internal1"
9874   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9875          (match_operand 1 "" "i"))
9876    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9877   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9878   "*
9879 {
9880   register rtx target = operands[0];
9881
9882   if (GET_CODE (target) == CONST_INT)
9883     return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
9884   else if (CONSTANT_ADDRESS_P (target))
9885     return \"%*jal\\t%0\";
9886   else
9887     return \"%*jal\\t%2,%0\";
9888 }"
9889   [(set_attr "type"     "call")
9890    (set_attr "mode"     "none")])
9891
9892 (define_insn "call_internal2"
9893   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9894          (match_operand 1 "" "i"))
9895    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9896   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9897   "*
9898 {
9899   register rtx target = operands[0];
9900
9901   if (GET_CODE (target) == CONST_INT)
9902     return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
9903   else if (CONSTANT_ADDRESS_P (target))
9904     {
9905       if (GET_MODE (target) == SImode)
9906         return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
9907       else
9908         return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
9909     }
9910   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9911     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9912   else
9913     return \"jal\\t%2,%0\";
9914 }"
9915   [(set_attr "type"     "call")
9916    (set_attr "mode"     "none")
9917    (set_attr "length"   "8")])
9918
9919 (define_insn "call_internal3a"
9920   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9921          (match_operand 1 "" "i"))
9922    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9923   "!TARGET_MIPS16
9924    && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9925   "%*jal\\t%2,%0"
9926   [(set_attr "type"     "call")
9927    (set_attr "mode"     "none")])
9928
9929 (define_insn "call_internal3b"
9930   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9931          (match_operand 1 "" "i"))
9932    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9933   "!TARGET_MIPS16
9934    && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9935   "%*jal\\t%2,%0"
9936   [(set_attr "type"     "call")
9937    (set_attr "mode"     "none")
9938    (set_attr "length"   "1")])
9939
9940 (define_insn "call_internal3c"
9941   [(call (mem:SI (match_operand:SI 0 "register_operand" "e"))
9942          (match_operand 1 "" "i"))
9943    (clobber (match_operand:SI 2 "register_operand" "=y"))]
9944   "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
9945    && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9946   "%*jal\\t%2,%0"
9947   [(set_attr "type"     "call")
9948    (set_attr "mode"     "none")])
9949
9950 (define_insn "call_internal4a"
9951   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9952          (match_operand 1 "" "i"))
9953    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9954   "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
9955   "*
9956 {
9957   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9958     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9959   else
9960     return \"jal\\t%2,%0\";
9961 }"
9962   [(set_attr "type"     "call")
9963    (set_attr "mode"     "none")
9964    (set_attr "length"   "8")])
9965
9966 (define_insn "call_internal4b"
9967   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9968          (match_operand 1 "" "i"))
9969    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9970   "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
9971   "*
9972 {
9973   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9974     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9975   else
9976     return \"jal\\t%2,%0\";
9977 }"
9978   [(set_attr "type"     "call")
9979    (set_attr "mode"     "none")
9980    (set_attr "length"   "8")])
9981
9982 ;; calls.c now passes a fourth argument, make saber happy
9983
9984 (define_expand "call_value"
9985   [(parallel [(set (match_operand 0 "register_operand" "=df")
9986                    (call (match_operand 1 "memory_operand" "m")
9987                          (match_operand 2 "" "i")))
9988               (clobber (reg:SI 31))
9989               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
9990   ""
9991   "
9992 {
9993   rtx addr;
9994
9995   if (operands[0])              /* eliminate unused code warning */
9996     {
9997       addr = XEXP (operands[1], 0);
9998       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9999           || ! call_insn_operand (addr, VOIDmode))
10000         XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
10001
10002       /* In order to pass small structures by value in registers
10003          compatibly with the MIPS compiler, we need to shift the value
10004          into the high part of the register.  Function_arg has encoded
10005          a PARALLEL rtx, holding a vector of adjustments to be made
10006          as the next_arg_reg variable, so we split up the insns,
10007          and emit them separately.  */
10008
10009       if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
10010         {
10011           rtvec adjust = XVEC (operands[3], 0);
10012           int num = GET_NUM_ELEM (adjust);
10013           int i;
10014
10015           for (i = 0; i < num; i++)
10016             emit_insn (RTVEC_ELT (adjust, i));
10017         }
10018
10019       if (TARGET_MIPS16
10020           && mips16_hard_float
10021           && ((operands[3] != 0
10022                && (int) GET_MODE (operands[3]) != 0)
10023               || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
10024         {
10025           if (build_mips16_call_stub (operands[0], operands[1], operands[2],
10026                                       (operands[3] == 0 ? 0
10027                                        : (int) GET_MODE (operands[3]))))
10028             DONE;
10029         }
10030
10031       /* Handle Irix6 function calls that have multiple non-contiguous
10032          results.  */
10033       if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
10034         {
10035           emit_call_insn (gen_call_value_multiple_internal0
10036                           (XEXP (XVECEXP (operands[0], 0, 0), 0),
10037                            operands[1], operands[2],
10038                            XEXP (XVECEXP (operands[0], 0, 1), 0),
10039                            gen_rtx_REG (SImode, GP_REG_FIRST + 31)));
10040           DONE;
10041         }
10042
10043       /* We have a call returning a DImode structure in an FP reg.
10044          Strip off the now unnecessary PARALLEL.  */
10045       if (GET_CODE (operands[0]) == PARALLEL)
10046         operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
10047
10048       emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
10049                                                 gen_rtx_REG (SImode,
10050                                                              GP_REG_FIRST + 31)));
10051
10052       DONE;
10053     }
10054 }")
10055
10056 (define_expand "call_value_internal0"
10057   [(parallel [(set (match_operand 0 "" "")
10058                    (call (match_operand 1 "" "")
10059                          (match_operand 2 "" "")))
10060               (clobber (match_operand:SI 3 "" ""))])]
10061   ""
10062   "")
10063
10064 ;; Recognize $31 specially on the mips16, because we don't have a
10065 ;; constraint letter for it.
10066
10067 (define_insn ""
10068   [(set (match_operand 0 "register_operand" "=d")
10069         (call (mem (match_operand 1 "call_insn_operand" "ei"))
10070               (match_operand 2 "" "i")))
10071    (clobber (match_operand:SI 3 "register_operand" "=y"))]
10072   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
10073    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10074   "%*jal\\t%1"
10075   [(set_attr "type"     "call")
10076    (set_attr "mode"     "none")
10077    (set_attr "length"   "8")])
10078
10079 (define_insn "call_value_internal1"
10080   [(set (match_operand 0 "register_operand" "=df")
10081         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10082               (match_operand 2 "" "i")))
10083    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10084   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10085   "*
10086 {
10087   register rtx target = operands[1];
10088
10089   if (GET_CODE (target) == CONST_INT)
10090     return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
10091   else if (CONSTANT_ADDRESS_P (target))
10092     return \"%*jal\\t%1\";
10093   else
10094     return \"%*jal\\t%3,%1\";
10095 }"
10096   [(set_attr "type"     "call")
10097    (set_attr "mode"     "none")])
10098
10099 (define_insn "call_value_internal2"
10100   [(set (match_operand 0 "register_operand" "=df")
10101         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10102               (match_operand 2 "" "i")))
10103    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10104   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10105   "*
10106 {
10107   register rtx target = operands[1];
10108
10109   if (GET_CODE (target) == CONST_INT)
10110     return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
10111   else if (CONSTANT_ADDRESS_P (target))
10112     {
10113       if (GET_MODE (target) == SImode)
10114         return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
10115       else
10116         return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
10117     }
10118   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10119     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10120   else
10121     return \"jal\\t%3,%1\";
10122 }"
10123   [(set_attr "type"     "call")
10124    (set_attr "mode"     "none")
10125    (set_attr "length"   "8")])
10126
10127 (define_insn "call_value_internal3a"
10128   [(set (match_operand 0 "register_operand" "=df")
10129         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10130               (match_operand 2 "" "i")))
10131    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10132   "!TARGET_MIPS16
10133    && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10134   "%*jal\\t%3,%1"
10135   [(set_attr "type"     "call")
10136    (set_attr "mode"     "none")])
10137
10138 (define_insn "call_value_internal3b"
10139   [(set (match_operand 0 "register_operand" "=df")
10140         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10141               (match_operand 2 "" "i")))
10142    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10143   "!TARGET_MIPS16
10144    && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10145   "%*jal\\t%3,%1"
10146   [(set_attr "type"     "call")
10147    (set_attr "mode"     "none")])
10148
10149 (define_insn "call_value_internal3c"
10150   [(set (match_operand 0 "register_operand" "=df")
10151         (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
10152               (match_operand 2 "" "i")))
10153    (clobber (match_operand:SI 3 "register_operand" "=y"))]
10154   "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
10155    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10156   "%*jal\\t%3,%1"
10157   [(set_attr "type"     "call")
10158    (set_attr "mode"     "none")])
10159
10160 (define_insn "call_value_internal4a"
10161   [(set (match_operand 0 "register_operand" "=df")
10162         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10163               (match_operand 2 "" "i")))
10164    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10165   "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
10166   "*
10167 {
10168   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10169     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10170   else
10171     return \"jal\\t%3,%1\";
10172 }"
10173   [(set_attr "type"     "call")
10174    (set_attr "mode"     "none")
10175    (set_attr "length"   "8")])
10176
10177 (define_insn "call_value_internal4b"
10178   [(set (match_operand 0 "register_operand" "=df")
10179         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10180               (match_operand 2 "" "i")))
10181    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10182   "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
10183   "*
10184 {
10185   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10186     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10187   else
10188     return \"jal\\t%3,%1\";
10189 }"
10190   [(set_attr "type"     "call")
10191    (set_attr "mode"     "none")
10192    (set_attr "length"   "8")])
10193
10194 (define_expand "call_value_multiple_internal0"
10195   [(parallel [(set (match_operand 0 "" "")
10196                    (call (match_operand 1 "" "")
10197                          (match_operand 2 "" "")))
10198               (set (match_operand 3 "" "")
10199                    (call (match_dup 1)
10200                          (match_dup 2)))
10201               (clobber (match_operand:SI 4 "" ""))])]
10202   ""
10203   "")
10204
10205 ;; ??? May eventually need all 6 versions of the call patterns with multiple
10206 ;; return values.
10207
10208 (define_insn "call_value_multiple_internal1"
10209   [(set (match_operand 0 "register_operand" "=df")
10210         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10211               (match_operand 2 "" "i")))
10212    (set (match_operand 3 "register_operand" "=df")
10213         (call (mem (match_dup 1))
10214               (match_dup 2)))
10215   (clobber (match_operand:SI 4 "register_operand" "=d"))]
10216   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10217   "*
10218 {
10219   register rtx target = operands[1];
10220
10221   if (GET_CODE (target) == CONST_INT)
10222     return \"%[li\\t%@,%1\\n\\t%*jal\\t%4,%@%]\";
10223   else if (CONSTANT_ADDRESS_P (target))
10224     return \"%*jal\\t%1\";
10225   else
10226     return \"%*jal\\t%4,%1\";
10227 }"
10228   [(set_attr "type"     "call")
10229    (set_attr "mode"     "none")])
10230
10231 (define_insn "call_value_multiple_internal2"
10232   [(set (match_operand 0 "register_operand" "=df")
10233         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10234               (match_operand 2 "" "i")))
10235    (set (match_operand 3 "register_operand" "=df")
10236         (call (mem (match_dup 1))
10237               (match_dup 2)))
10238    (clobber (match_operand:SI 4 "register_operand" "=d"))]
10239   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10240   "*
10241 {
10242   register rtx target = operands[1];
10243
10244   if (GET_CODE (target) == CONST_INT)
10245     return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
10246   else if (CONSTANT_ADDRESS_P (target))
10247     {
10248       if (GET_MODE (target) == SImode)
10249         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10250       else
10251         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10252     }
10253   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10254     return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
10255   else
10256     return \"jal\\t%4,%1\";
10257 }"
10258   [(set_attr "type"     "call")
10259    (set_attr "mode"     "none")
10260    (set_attr "length"   "8")])
10261
10262
10263 ;; Call subroutine returning any type.
10264
10265 (define_expand "untyped_call"
10266   [(parallel [(call (match_operand 0 "" "")
10267                     (const_int 0))
10268               (match_operand 1 "" "")
10269               (match_operand 2 "" "")])]
10270   ""
10271   "
10272 {
10273   if (operands[0])              /* silence statement not reached warnings */
10274     {
10275       int i;
10276
10277       emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
10278
10279       for (i = 0; i < XVECLEN (operands[2], 0); i++)
10280         {
10281           rtx set = XVECEXP (operands[2], 0, i);
10282           emit_move_insn (SET_DEST (set), SET_SRC (set));
10283         }
10284
10285       emit_insn (gen_blockage ());
10286       DONE;
10287     }
10288 }")
10289 \f
10290 ;;
10291 ;;  ....................
10292 ;;
10293 ;;      MISC.
10294 ;;
10295 ;;  ....................
10296 ;;
10297
10298 (define_insn "nop"
10299   [(const_int 0)]
10300   ""
10301   "%(nop%)"
10302   [(set_attr "type"     "nop")
10303    (set_attr "mode"     "none")])
10304
10305 ;; The MIPS chip does not seem to require stack probes.
10306 ;;
10307 ;; (define_expand "probe"
10308 ;;   [(set (match_dup 0)
10309 ;;      (match_dup 1))]
10310 ;;   ""
10311 ;;   "
10312 ;; {
10313 ;;   operands[0] = gen_reg_rtx (SImode);
10314 ;;   operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
10315 ;;   MEM_VOLATILE_P (operands[1]) = TRUE;
10316 ;;
10317 ;;   /* fall through and generate default code */
10318 ;; }")
10319 ;;
10320 \f
10321 ;;
10322 ;; MIPS4 Conditional move instructions.
10323
10324 (define_insn ""
10325   [(set (match_operand:SI 0 "register_operand" "=d,d")
10326         (if_then_else:SI
10327          (match_operator 4 "equality_op"
10328                          [(match_operand:SI 1 "register_operand" "d,d")
10329                           (const_int 0)])
10330          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10331          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10332   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10333   "@
10334     mov%B4\\t%0,%z2,%1
10335     mov%b4\\t%0,%z3,%1"
10336   [(set_attr "type" "move")
10337    (set_attr "mode" "SI")])
10338
10339 (define_insn ""
10340   [(set (match_operand:SI 0 "register_operand" "=d,d")
10341         (if_then_else:SI
10342          (match_operator 4 "equality_op"
10343                          [(match_operand:DI 1 "se_register_operand" "d,d")
10344                           (const_int 0)])
10345          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10346          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10347   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10348   "@
10349     mov%B4\\t%0,%z2,%1
10350     mov%b4\\t%0,%z3,%1"
10351   [(set_attr "type" "move")
10352    (set_attr "mode" "SI")])
10353
10354 (define_insn ""
10355   [(set (match_operand:SI 0 "register_operand" "=d,d")
10356         (if_then_else:SI
10357          (match_operator 3 "equality_op" [(match_operand:CC 4
10358                                                             "register_operand"
10359                                                             "z,z")
10360                                           (const_int 0)])
10361          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
10362          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
10363   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10364   "@
10365     mov%T3\\t%0,%z1,%4
10366     mov%t3\\t%0,%z2,%4"
10367   [(set_attr "type" "move")
10368    (set_attr "mode" "SI")])
10369
10370 (define_insn ""
10371   [(set (match_operand:DI 0 "register_operand" "=d,d")
10372         (if_then_else:DI
10373          (match_operator 4 "equality_op"
10374                          [(match_operand:SI 1 "register_operand" "d,d")
10375                           (const_int 0)])
10376          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10377          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10378   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10379   "@
10380     mov%B4\\t%0,%z2,%1
10381     mov%b4\\t%0,%z3,%1"
10382   [(set_attr "type" "move")
10383    (set_attr "mode" "DI")])
10384
10385 (define_insn ""
10386   [(set (match_operand:DI 0 "register_operand" "=d,d")
10387         (if_then_else:DI
10388          (match_operator 4 "equality_op"
10389                          [(match_operand:DI 1 "se_register_operand" "d,d")
10390                           (const_int 0)])
10391          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10392          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10393   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10394   "@
10395     mov%B4\\t%0,%z2,%1
10396     mov%b4\\t%0,%z3,%1"
10397   [(set_attr "type" "move")
10398    (set_attr "mode" "DI")])
10399
10400 (define_insn ""
10401   [(set (match_operand:DI 0 "register_operand" "=d,d")
10402         (if_then_else:DI
10403          (match_operator 3 "equality_op" [(match_operand:CC 4
10404                                                             "register_operand"
10405                                                             "z,z")
10406                                           (const_int 0)])
10407          (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
10408          (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
10409   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
10410   "@
10411     mov%T3\\t%0,%z1,%4
10412     mov%t3\\t%0,%z2,%4"
10413   [(set_attr "type" "move")
10414    (set_attr "mode" "DI")])
10415
10416 (define_insn ""
10417   [(set (match_operand:SF 0 "register_operand" "=f,f")
10418         (if_then_else:SF
10419          (match_operator 4 "equality_op"
10420                          [(match_operand:SI 1 "register_operand" "d,d")
10421                           (const_int 0)])
10422          (match_operand:SF 2 "register_operand" "f,0")
10423          (match_operand:SF 3 "register_operand" "0,f")))]
10424   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10425   "@
10426     mov%B4.s\\t%0,%2,%1
10427     mov%b4.s\\t%0,%3,%1"
10428   [(set_attr "type" "move")
10429    (set_attr "mode" "SF")])
10430
10431 (define_insn ""
10432   [(set (match_operand:SF 0 "register_operand" "=f,f")
10433         (if_then_else:SF
10434          (match_operator 4 "equality_op"
10435                          [(match_operand:DI 1 "se_register_operand" "d,d")
10436                           (const_int 0)])
10437          (match_operand:SF 2 "register_operand" "f,0")
10438          (match_operand:SF 3 "register_operand" "0,f")))]
10439   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10440   "@
10441     mov%B4.s\\t%0,%2,%1
10442     mov%b4.s\\t%0,%3,%1"
10443   [(set_attr "type" "move")
10444    (set_attr "mode" "SF")])
10445
10446 (define_insn ""
10447   [(set (match_operand:SF 0 "register_operand" "=f,f")
10448         (if_then_else:SF
10449          (match_operator 3 "equality_op" [(match_operand:CC 4
10450                                                             "register_operand"
10451                                                             "z,z")
10452                                           (const_int 0)])
10453          (match_operand:SF 1 "register_operand" "f,0")
10454          (match_operand:SF 2 "register_operand" "0,f")))]
10455   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10456   "@
10457     mov%T3.s\\t%0,%1,%4
10458     mov%t3.s\\t%0,%2,%4"
10459   [(set_attr "type" "move")
10460    (set_attr "mode" "SF")])
10461
10462 (define_insn ""
10463   [(set (match_operand:DF 0 "register_operand" "=f,f")
10464         (if_then_else:DF
10465          (match_operator 4 "equality_op"
10466                          [(match_operand:SI 1 "register_operand" "d,d")
10467                           (const_int 0)])
10468          (match_operand:DF 2 "register_operand" "f,0")
10469          (match_operand:DF 3 "register_operand" "0,f")))]
10470   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10471   "@
10472     mov%B4.d\\t%0,%2,%1
10473     mov%b4.d\\t%0,%3,%1"
10474   [(set_attr "type" "move")
10475    (set_attr "mode" "DF")])
10476
10477 (define_insn ""
10478   [(set (match_operand:DF 0 "register_operand" "=f,f")
10479         (if_then_else:DF
10480          (match_operator 4 "equality_op"
10481                          [(match_operand:DI 1 "se_register_operand" "d,d")
10482                           (const_int 0)])
10483          (match_operand:DF 2 "register_operand" "f,0")
10484          (match_operand:DF 3 "register_operand" "0,f")))]
10485   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10486   "@
10487     mov%B4.d\\t%0,%2,%1
10488     mov%b4.d\\t%0,%3,%1"
10489   [(set_attr "type" "move")
10490    (set_attr "mode" "DF")])
10491
10492 (define_insn ""
10493   [(set (match_operand:DF 0 "register_operand" "=f,f")
10494         (if_then_else:DF
10495          (match_operator 3 "equality_op" [(match_operand:CC 4
10496                                                             "register_operand"
10497                                                             "z,z")
10498                                           (const_int 0)])
10499          (match_operand:DF 1 "register_operand" "f,0")
10500          (match_operand:DF 2 "register_operand" "0,f")))]
10501   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10502   "@
10503     mov%T3.d\\t%0,%1,%4
10504     mov%t3.d\\t%0,%2,%4"
10505   [(set_attr "type" "move")
10506    (set_attr "mode" "DF")])
10507
10508 ;; These are the main define_expand's used to make conditional moves.
10509
10510 (define_expand "movsicc"
10511   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10512    (set (match_operand:SI 0 "register_operand" "")
10513         (if_then_else:SI (match_dup 5)
10514                          (match_operand:SI 2 "reg_or_0_operand" "")
10515                          (match_operand:SI 3 "reg_or_0_operand" "")))]
10516   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10517   "
10518 {
10519   gen_conditional_move (operands);
10520   DONE;
10521 }")
10522
10523 (define_expand "movdicc"
10524   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10525    (set (match_operand:DI 0 "register_operand" "")
10526         (if_then_else:DI (match_dup 5)
10527                          (match_operand:DI 2 "se_reg_or_0_operand" "")
10528                          (match_operand:DI 3 "se_reg_or_0_operand" "")))]
10529   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10530   "
10531 {
10532   if (mips_isa == 32)
10533     FAIL;
10534   gen_conditional_move (operands);
10535   DONE;
10536 }")
10537
10538 (define_expand "movsfcc"
10539   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10540    (set (match_operand:SF 0 "register_operand" "")
10541         (if_then_else:SF (match_dup 5)
10542                          (match_operand:SF 2 "register_operand" "")
10543                          (match_operand:SF 3 "register_operand" "")))]
10544   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10545   "
10546 {
10547   gen_conditional_move (operands);
10548   DONE;
10549 }")
10550
10551 (define_expand "movdfcc"
10552   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10553    (set (match_operand:DF 0 "register_operand" "")
10554         (if_then_else:DF (match_dup 5)
10555                          (match_operand:DF 2 "register_operand" "")
10556                          (match_operand:DF 3 "register_operand" "")))]
10557   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10558   "
10559 {
10560   gen_conditional_move (operands);
10561   DONE;
10562 }")
10563 \f
10564 ;;
10565 ;;  ....................
10566 ;;
10567 ;;      mips16 inline constant tables
10568 ;;
10569 ;;  ....................
10570 ;;
10571
10572 (define_insn "consttable_qi"
10573   [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")]
10574                     UNSPEC_CONSTTABLE_QI)]
10575   "TARGET_MIPS16"
10576   "*
10577 {
10578   assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
10579   return \"\";
10580 }"
10581   [(set_attr "type"     "unknown")
10582    (set_attr "mode"     "QI")
10583    (set_attr "length"   "8")])
10584
10585 (define_insn "consttable_hi"
10586   [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")]
10587                     UNSPEC_CONSTTABLE_HI)]
10588   "TARGET_MIPS16"
10589   "*
10590 {
10591   assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10592   return \"\";
10593 }"
10594   [(set_attr "type"     "unknown")
10595    (set_attr "mode"     "HI")
10596    (set_attr "length"   "8")])
10597
10598 (define_insn "consttable_si"
10599   [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")]
10600                     UNSPEC_CONSTTABLE_SI)]
10601   "TARGET_MIPS16"
10602   "*
10603 {
10604   assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10605   return \"\";
10606 }"
10607   [(set_attr "type"     "unknown")
10608    (set_attr "mode"     "SI")
10609    (set_attr "length"   "8")])
10610
10611 (define_insn "consttable_di"
10612   [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")]
10613                     UNSPEC_CONSTTABLE_DI)]
10614   "TARGET_MIPS16"
10615   "*
10616 {
10617   assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10618   return \"\";
10619 }"
10620   [(set_attr "type"     "unknown")
10621    (set_attr "mode"     "DI")
10622    (set_attr "length"   "16")])
10623
10624 (define_insn "consttable_sf"
10625   [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")]
10626                     UNSPEC_CONSTTABLE_SF)]
10627   "TARGET_MIPS16"
10628   "*
10629 {
10630   REAL_VALUE_TYPE d;
10631
10632   if (GET_CODE (operands[0]) != CONST_DOUBLE)
10633     abort ();
10634   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10635   assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10636   return \"\";
10637 }"
10638   [(set_attr "type"     "unknown")
10639    (set_attr "mode"     "SF")
10640    (set_attr "length"   "8")])
10641
10642 (define_insn "consttable_df"
10643   [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")]
10644                     UNSPEC_CONSTTABLE_DF)]
10645   "TARGET_MIPS16"
10646   "*
10647 {
10648   REAL_VALUE_TYPE d;
10649
10650   if (GET_CODE (operands[0]) != CONST_DOUBLE)
10651     abort ();
10652   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10653   assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10654   return \"\";
10655 }"
10656   [(set_attr "type"     "unknown")
10657    (set_attr "mode"     "DF")
10658    (set_attr "length"   "16")])
10659
10660 (define_insn "align_2"
10661   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_2)]
10662   "TARGET_MIPS16"
10663   ".align 1"
10664   [(set_attr "type"     "unknown")
10665    (set_attr "mode"     "HI")
10666    (set_attr "length"   "8")])
10667
10668 (define_insn "align_4"
10669   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_4)]
10670   "TARGET_MIPS16"
10671   ".align 2"
10672   [(set_attr "type"     "unknown")
10673    (set_attr "mode"     "SI")
10674    (set_attr "length"   "8")])
10675
10676 (define_insn "align_8"
10677   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_8)]
10678   "TARGET_MIPS16"
10679   ".align 3"
10680   [(set_attr "type"     "unknown")
10681    (set_attr "mode"     "DI")
10682    (set_attr "length"   "12")])
10683 \f
10684 ;;
10685 ;;  ....................
10686 ;;
10687 ;;      mips16 peepholes
10688 ;;
10689 ;;  ....................
10690 ;;
10691
10692 ;; On the mips16, reload will sometimes decide that a pseudo register
10693 ;; should go into $24, and then later on have to reload that register.
10694 ;; When that happens, we get a load of a general register followed by
10695 ;; a move from the general register to $24 followed by a branch.
10696 ;; These peepholes catch the common case, and fix it to just use the
10697 ;; general register for the branch.
10698
10699 (define_peephole
10700   [(set (match_operand:SI 0 "register_operand" "=t")
10701         (match_operand:SI 1 "register_operand" "d"))
10702    (set (pc)
10703         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10704                                                           (const_int 0)])
10705                       (match_operand 3 "pc_or_label_operand" "")
10706                       (match_operand 4 "pc_or_label_operand" "")))]
10707   "TARGET_MIPS16
10708    && GET_CODE (operands[0]) == REG
10709    && REGNO (operands[0]) == 24
10710    && dead_or_set_p (insn, operands[0])
10711    && GET_CODE (operands[1]) == REG
10712    && M16_REG_P (REGNO (operands[1]))"
10713   "*
10714 {
10715   if (operands[3] != pc_rtx)
10716     return \"%*b%C2z\\t%1,%3\";
10717   else
10718     return \"%*b%N2z\\t%1,%4\";
10719 }"
10720   [(set_attr "type"     "branch")
10721    (set_attr "mode"     "none")
10722    (set_attr "length"   "8")])
10723
10724 (define_peephole
10725   [(set (match_operand:DI 0 "register_operand" "=t")
10726         (match_operand:DI 1 "register_operand" "d"))
10727    (set (pc)
10728         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10729                                                           (const_int 0)])
10730                       (match_operand 3 "pc_or_label_operand" "")
10731                       (match_operand 4 "pc_or_label_operand" "")))]
10732   "TARGET_MIPS16 && TARGET_64BIT
10733    && GET_CODE (operands[0]) == REG
10734    && REGNO (operands[0]) == 24
10735    && dead_or_set_p (insn, operands[0])
10736    && GET_CODE (operands[1]) == REG
10737    && M16_REG_P (REGNO (operands[1]))"
10738   "*
10739 {
10740   if (operands[3] != pc_rtx)
10741     return \"%*b%C2z\\t%1,%3\";
10742   else
10743     return \"%*b%N2z\\t%1,%4\";
10744 }"
10745   [(set_attr "type"     "branch")
10746    (set_attr "mode"     "none")
10747    (set_attr "length"   "8")])
10748
10749 ;; We can also have the reverse reload: reload will spill $24 into
10750 ;; another register, and then do a branch on that register when it
10751 ;; could have just stuck with $24.
10752
10753 (define_peephole
10754   [(set (match_operand:SI 0 "register_operand" "=d")
10755         (match_operand:SI 1 "register_operand" "t"))
10756    (set (pc)
10757         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10758                                                           (const_int 0)])
10759                       (match_operand 3 "pc_or_label_operand" "")
10760                       (match_operand 4 "pc_or_label_operand" "")))]
10761   "TARGET_MIPS16
10762    && GET_CODE (operands[1]) == REG
10763    && REGNO (operands[1]) == 24
10764    && GET_CODE (operands[0]) == REG
10765    && M16_REG_P (REGNO (operands[0]))
10766    && dead_or_set_p (insn, operands[0])"
10767   "*
10768 {
10769   if (operands[3] != pc_rtx)
10770     return \"%*bt%C2z\\t%3\";
10771   else
10772     return \"%*bt%N2z\\t%4\";
10773 }"
10774   [(set_attr "type"     "branch")
10775    (set_attr "mode"     "none")
10776    (set_attr "length"   "8")])
10777
10778 (define_peephole
10779   [(set (match_operand:DI 0 "register_operand" "=d")
10780         (match_operand:DI 1 "register_operand" "t"))
10781    (set (pc)
10782         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10783                                                           (const_int 0)])
10784                       (match_operand 3 "pc_or_label_operand" "")
10785                       (match_operand 4 "pc_or_label_operand" "")))]
10786   "TARGET_MIPS16 && TARGET_64BIT
10787    && GET_CODE (operands[1]) == REG
10788    && REGNO (operands[1]) == 24
10789    && GET_CODE (operands[0]) == REG
10790    && M16_REG_P (REGNO (operands[0]))
10791    && dead_or_set_p (insn, operands[0])"
10792   "*
10793 {
10794   if (operands[3] != pc_rtx)
10795     return \"%*bt%C2z\\t%3\";
10796   else
10797     return \"%*bt%N2z\\t%4\";
10798 }"
10799   [(set_attr "type"     "branch")
10800    (set_attr "mode"     "none")
10801    (set_attr "length"   "8")])
10802
10803 ;; For the rare case where we need to load an address into a register
10804 ;; that can not be recognized by the normal movsi/addsi instructions.
10805 ;; I have no idea how many insns this can actually generate.  It should
10806 ;; be rare, so over-estimating as 10 instructions should not have any
10807 ;; real performance impact.
10808 (define_insn "leasi"
10809   [(set (match_operand:SI 0 "register_operand" "=d")
10810         (match_operand:SI 1 "address_operand" "p"))]
10811   "Pmode == SImode"
10812   "la %0,%a1"
10813   [(set_attr "type"     "arith")
10814    (set_attr "mode"     "SI")
10815    (set_attr "length"   "40")])
10816
10817 ;; Similarly for targets where we have 64bit pointers.
10818 (define_insn "leadi"
10819   [(set (match_operand:DI 0 "register_operand" "=d")
10820         (match_operand:DI 1 "address_operand" "p"))]
10821   "Pmode == DImode"
10822   "la %0,%a1"
10823   [(set_attr "type"     "arith")
10824    (set_attr "mode"     "DI")
10825    (set_attr "length"   "40")])