2002-05-09 Hassan Aurag <aurag@cae.com>
[official-gcc.git] / gcc / config / mips / mips.md
blobbbce30eb3bf83786dc5054c6d5d013c18cb0a968
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.
9 ;; This file is part of GNU CC.
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.
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.
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.
26 ;; ??? Currently does not have define_function_unit support for the R8000.
27 ;; Must include new entries for fmadd in addition to existing entries.
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)])
53 ;; ....................
55 ;;      Attributes
57 ;; ....................
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
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"))
89 ;; Main data type used by the insn
90 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
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.
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)))
110 ;; Attribute describing the processor.  This attribute must match exactly
111 ;; with the processor_type enumeration in mips.h.
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"))))
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")))
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")))
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")))
150 ;; Attribute defining whether or not we can use the branch-likely instructions
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"))))
159 ;; Describe a user's asm statement.
160 (define_asm_attributes
161   [(set_attr "type" "multi")])
163 ;; whether or not generating calls to position independent functions
164 (define_attr "abicalls" "no,yes"
165   (const (symbol_ref "mips_abicalls_attr")))
169 ;; .........................
171 ;;      Delay slots, can't describe load/fcmp/xfer delay slots here
173 ;; .........................
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")))])
183 (define_delay (eq_attr "type" "jump")
184   [(eq_attr "can_delay" "yes")
185    (nil)
186    (nil)])
188 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
189   [(eq_attr "can_delay" "yes")
190    (nil)
191    (nil)])
195 ;; .........................
197 ;;      Functional units
199 ;; .........................
201 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
202 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
204 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
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)
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)
216 (define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
218 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
220 (define_function_unit "imuldiv"  1 0
221   (eq_attr "type" "hilo")
222   1 3)
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)
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.
235 (define_function_unit "imuldiv" 1 0
236   (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
237   1 5)
239 (define_function_unit "imuldiv"  1 0
240   (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
241   12 12)
243 (define_function_unit "imuldiv"  1 0
244   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
245   10 10)
247 (define_function_unit "imuldiv"  1 0
248   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
249   4 4)
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)
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)
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)
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)
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)
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)
281 (define_function_unit "imuldiv"  1 0
282   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
283   35 35)
285 (define_function_unit "imuldiv"  1 0
286   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
287   42 42)
289 (define_function_unit "imuldiv"  1 0
290   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
291   36 36)
293 (define_function_unit "imuldiv"  1 0
294   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
295   69 69)
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)
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)
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)
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)
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)
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)
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.
334 (define_function_unit "adder" 1 1
335   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
336   3 0)
338 (define_function_unit "adder" 1 1
339   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
340   2 0)
342 (define_function_unit "adder" 1 1
343   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
344   1 0)
346 (define_function_unit "adder" 1 1
347   (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
348   4 0)
350 (define_function_unit "adder" 1 1
351   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
352   2 0)
354 (define_function_unit "adder" 1 1
355   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
356   3 0)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
482 ;; R4300 FP instruction classes treated as part of the "imuldiv"
483 ;; functional unit:
485 (define_function_unit "imuldiv" 1 0
486   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
487   3 3)
489 (define_function_unit "imuldiv" 1 0
490   (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
491   1 1)
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)
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)
509 ;; The following functional units do not use the cpu type, and use
510 ;; much less memory in genattrtab.c.
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)
515 ;; (define_function_unit "fp_comp"  1 0 (eq_attr "type" "fcmp")                                2 0)
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)
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)
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)
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)
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)
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)
536 ;;  ....................
538 ;;      CONDITIONAL TRAPS
540 ;;  ....................
543 (define_insn "trap"
544   [(trap_if (const_int 1) (const_int 0))]
545   ""
546   "*
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\";
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   "
563   mips_gen_conditional_trap (operands);
564   DONE;
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.
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")
580 ;;  ....................
582 ;;      ADDITION
584 ;;  ....................
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")])
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")])
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   "
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]);
621   /* If a large stack adjustment was forced into a register, we may be
622      asked to generate rtx such as:
624         (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
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);
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     }
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")])
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.
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)))])
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)))])
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   "*
702   if (REGNO (operands[0]) == REGNO (operands[1]))
703     return \"addu\\t%0,%2\";
704   return \"addu\\t%0,%1,%2\";
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)])])
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.
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   "
740   HOST_WIDE_INT val = INTVAL (operands[1]);
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     }
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   "
773   HOST_WIDE_INT val = INTVAL (operands[2]);
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     }
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   "
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]);
804   /* If a large stack adjustment was forced into a register, we may be
805      asked to generate rtx such as:
807         (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
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);
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     }
825   if (TARGET_64BIT)
826     {
827       emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
828                                         operands[2]));
829       DONE;
830     }
832   operands[3] = gen_reg_rtx (SImode);
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   "*
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\";
848   [(set_attr "type"     "darith")
849    (set_attr "mode"     "DI")
850    (set_attr "length"   "16")])
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]))"
865   [(set (subreg:SI (match_dup 0) 0)
866         (plus:SI (subreg:SI (match_dup 1) 0)
867                  (subreg:SI (match_dup 2) 0)))
869    (set (match_dup 3)
870         (ltu:SI (subreg:SI (match_dup 0) 0)
871                 (subreg:SI (match_dup 2) 0)))
873    (set (subreg:SI (match_dup 0) 4)
874         (plus:SI (subreg:SI (match_dup 1) 4)
875                  (subreg:SI (match_dup 2) 4)))
877    (set (subreg:SI (match_dup 0) 4)
878         (plus:SI (subreg:SI (match_dup 0) 4)
879                  (match_dup 3)))]
880   "")
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]))"
895   [(set (subreg:SI (match_dup 0) 4)
896         (plus:SI (subreg:SI (match_dup 1) 4)
897                  (subreg:SI (match_dup 2) 4)))
899    (set (match_dup 3)
900         (ltu:SI (subreg:SI (match_dup 0) 4)
901                 (subreg:SI (match_dup 2) 4)))
903    (set (subreg:SI (match_dup 0) 0)
904         (plus:SI (subreg:SI (match_dup 1) 0)
905                  (subreg:SI (match_dup 2) 0)))
907    (set (subreg:SI (match_dup 0) 0)
908         (plus:SI (subreg:SI (match_dup 0) 0)
909                  (match_dup 3)))]
910   "")
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")])
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"
940   [(set (subreg:SI (match_dup 0) 0)
941         (plus:SI (subreg:SI (match_dup 1) 0)
942                  (match_dup 2)))
944    (set (match_dup 3)
945         (ltu:SI (subreg:SI (match_dup 0) 0)
946                 (match_dup 2)))
948    (set (subreg:SI (match_dup 0) 4)
949         (plus:SI (subreg:SI (match_dup 1) 4)
950                  (match_dup 3)))]
951   "")
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"
964   [(set (subreg:SI (match_dup 0) 4)
965         (plus:SI (subreg:SI (match_dup 1) 4)
966                  (match_dup 2)))
968    (set (match_dup 3)
969         (ltu:SI (subreg:SI (match_dup 0) 4)
970                 (match_dup 2)))
972    (set (subreg:SI (match_dup 0) 0)
973         (plus:SI (subreg:SI (match_dup 1) 0)
974                  (match_dup 3)))]
975   "")
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   "*
988   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
989     ? \"dsubu\\t%0,%z1,%n2\"
990     : \"daddu\\t%0,%z1,%2\";
992   [(set_attr "type"     "darith")
993    (set_attr "mode"     "DI")])
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.
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)))])
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)))])
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   "*
1042   if (REGNO (operands[0]) == REGNO (operands[1]))
1043     return \"daddu\\t%0,%2\";
1044   return \"daddu\\t%0,%1,%2\";
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)])])
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.
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   "
1080   HOST_WIDE_INT val = INTVAL (operands[1]);
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     }
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   "
1113   HOST_WIDE_INT val = INTVAL (operands[2]);
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     }
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   "*
1138   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1139     ? \"subu\\t%0,%z1,%n2\"
1140     : \"addu\\t%0,%z1,%2\";
1142   [(set_attr "type"     "arith")
1143    (set_attr "mode"     "SI")])
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   "*
1152   if (REGNO (operands[0]) == REGNO (operands[1]))
1153     return \"addu\\t%0,%2\";
1154   return \"addu\\t%0,%1,%2\";
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)])])
1169 ;;  ....................
1171 ;;      SUBTRACTION
1173 ;;  ....................
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")])
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")])
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   "
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]);
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")])
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.
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)))])
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)))])
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   "*
1258   if (REGNO (operands[0]) == REGNO (operands[1]))
1259     return \"subu\\t%0,%2\";
1260   return \"subu\\t%0,%1,%2\";
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)])])
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.
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   "
1295   HOST_WIDE_INT val = INTVAL (operands[1]);
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     }
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   "
1328   HOST_WIDE_INT val = INTVAL (operands[2]);
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     }
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   "
1350   if (TARGET_64BIT)
1351     {
1352       emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1353                                         operands[2]));
1354       DONE;
1355     }
1357   operands[3] = gen_reg_rtx (SImode);
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")])
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]))"
1382   [(set (match_dup 3)
1383         (ltu:SI (subreg:SI (match_dup 1) 0)
1384                 (subreg:SI (match_dup 2) 0)))
1386    (set (subreg:SI (match_dup 0) 0)
1387         (minus:SI (subreg:SI (match_dup 1) 0)
1388                   (subreg:SI (match_dup 2) 0)))
1390    (set (subreg:SI (match_dup 0) 4)
1391         (minus:SI (subreg:SI (match_dup 1) 4)
1392                   (subreg:SI (match_dup 2) 4)))
1394    (set (subreg:SI (match_dup 0) 4)
1395         (minus:SI (subreg:SI (match_dup 0) 4)
1396                   (match_dup 3)))]
1397   "")
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]))"
1410   [(set (match_dup 3)
1411         (ltu:SI (subreg:SI (match_dup 1) 4)
1412                 (subreg:SI (match_dup 2) 4)))
1414    (set (subreg:SI (match_dup 0) 4)
1415         (minus:SI (subreg:SI (match_dup 1) 4)
1416                   (subreg:SI (match_dup 2) 4)))
1418    (set (subreg:SI (match_dup 0) 0)
1419         (minus:SI (subreg:SI (match_dup 1) 0)
1420                   (subreg:SI (match_dup 2) 0)))
1422    (set (subreg:SI (match_dup 0) 0)
1423         (minus:SI (subreg:SI (match_dup 0) 0)
1424                   (match_dup 3)))]
1425   "")
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")])
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"
1453   [(set (match_dup 3)
1454         (ltu:SI (subreg:SI (match_dup 1) 0)
1455                 (match_dup 2)))
1457    (set (subreg:SI (match_dup 0) 0)
1458         (minus:SI (subreg:SI (match_dup 1) 0)
1459                   (match_dup 2)))
1461    (set (subreg:SI (match_dup 0) 4)
1462         (minus:SI (subreg:SI (match_dup 1) 4)
1463                   (match_dup 3)))]
1464   "")
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"
1477   [(set (match_dup 3)
1478         (ltu:SI (subreg:SI (match_dup 1) 4)
1479                 (match_dup 2)))
1481    (set (subreg:SI (match_dup 0) 4)
1482         (minus:SI (subreg:SI (match_dup 1) 4)
1483                   (match_dup 2)))
1485    (set (subreg:SI (match_dup 0) 0)
1486         (minus:SI (subreg:SI (match_dup 1) 0)
1487                   (match_dup 3)))]
1488   "")
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   "*
1498   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1499     ? \"daddu\\t%0,%z1,%n2\"
1500     : \"dsubu\\t%0,%z1,%2\";
1502   [(set_attr "type"     "darith")
1503    (set_attr "mode"     "DI")])
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.
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)))])
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)))])
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   "*
1544   if (REGNO (operands[0]) == REGNO (operands[1]))
1545     return \"dsubu\\t%0,%2\";
1546   return \"dsubu\\t%0,%1,%2\";
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)])])
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.
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   "
1581   HOST_WIDE_INT val = INTVAL (operands[1]);
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     }
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   "
1614   HOST_WIDE_INT val = INTVAL (operands[2]);
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     }
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   "*
1636   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1637     ? \"addu\\t%0,%z1,%n2\"
1638     : \"subu\\t%0,%z1,%2\";
1640   [(set_attr "type"     "arith")
1641    (set_attr "mode"     "DI")])
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   "*
1652   if (REGNO (operands[0]) == REGNO (operands[1]))
1653     return \"subu\\t%0,%2\";
1654   return \"subu\\t%0,%1,%2\";
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)])])
1670 ;;  ....................
1672 ;;      MULTIPLICATION
1674 ;;  ....................
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.
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   "
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;
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")])
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   "*
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 \"\";
1716   [(set_attr "type"     "fmul")
1717    (set_attr "mode"     "DF")
1718    (set_attr "length"   "8")])  ;; mul.d + nop
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   "
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;
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")])
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   "*
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 \"\";
1755   [(set_attr "type"     "fmul")
1756    (set_attr "mode"     "SF")
1757    (set_attr "length"   "8")])  ;; mul.s + nop
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.
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   "
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;
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   "*
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\";
1801   [(set_attr "type"     "imul")
1802    (set_attr "mode"     "SI")])
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")])
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   "*
1825   rtx xoperands[10];
1827   xoperands[0] = operands[0];
1828   xoperands[1] = gen_rtx_REG (SImode, LO_REGNUM);
1830   output_asm_insn (\"mult\\t%1,%2\", operands);
1831   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1832   return \"\";
1834   [(set_attr "type"     "imul")
1835    (set_attr "mode"     "SI")
1836    (set_attr "length"   "12")])         ;; mult + mflo + delay
1838 ;; Multiply-accumulate patterns
1840 ;; For processors that can copy the output to a general register:
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.
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   "*
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];
1871   [(set_attr "type"     "imul,imul,multi")
1872    (set_attr "mode"     "SI")
1873    (set_attr "length"   "4,4,8")])
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   "")
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   "")
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   "*
1931   if (which_alternative != 0)
1932     return \"#\";
1933   return \"msub\\t%2,%3\";
1935   [(set_attr "type"     "imul,imul,multi")
1936    (set_attr "mode"     "SI")
1937    (set_attr "length"   "4,8,8")])
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   "")
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   "")
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   "")
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"
2012   "
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;
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.
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")])
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   "*
2047   if (GENERATE_MULT3_DI)
2048     output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
2049   else
2050     {
2051       rtx xoperands[10];
2053       xoperands[0] = operands[0];
2054       xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM);
2056       output_asm_insn (\"dmult\\t%1,%2\", operands);
2057       output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2058     }
2059   return \"\";
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
2068 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
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   "
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;
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   "
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;
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   "*
2114   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2115     return \"mult\\t%1,%2\";
2116   return \"multu\\t%1,%2\";
2118   [(set_attr "type"     "imul")
2119    (set_attr "mode"     "SI")])
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   "*
2132   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2133     return \"mult\\t%1,%2\";
2134   return \"multu\\t%1,%2\";
2136   [(set_attr "type"     "imul")
2137    (set_attr "mode"     "SI")])
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   "
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;
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   "
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;
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   "*
2198   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2199     return \"mult\\t%1,%2\";
2200   else
2201     return \"multu\\t%1,%2\";
2203   [(set_attr "type"     "imul")
2204    (set_attr "mode"     "SI")])
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")])
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")])
2232 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2233 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
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")])
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   "*
2260   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2261     return \"mad\\t%1,%2\";
2262   else
2263     return \"madu\\t%1,%2\";
2265   [(set_attr "type"     "imul")
2266    (set_attr "mode"     "SI")])
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   "*
2282   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2283     return \"mad\\t%1,%2\";
2284   else
2285     return \"madu\\t%1,%2\";
2287   [(set_attr "type"     "imul")
2288    (set_attr "mode"     "SI")])
2290 ;; Floating point multiply accumulate instructions.
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")])
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")])
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")])
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")))]
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")])
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")])
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")])
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")])
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")])
2374 ;;  ....................
2376 ;;      DIVISION and REMAINDER
2378 ;;  ....................
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")])
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")])
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")])
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")])
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.
2423 ;; 64 is the multiply/divide hi register
2424 ;; 65 is the multiply/divide lo register
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.
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   "
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     }
2464   DONE;
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")])
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   "
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     }
2512   DONE;
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")])
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   "
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     }
2550   DONE;
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")])
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   "
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     }
2588   DONE;
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")])
2604 ;; Division trap
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   "
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;
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   "*
2627   rtx link;
2628   int have_dep_anti = 0;
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))
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 \"\";
2658   [(set_attr "type" "unknown")
2659    (set_attr "length" "12")])
2662 ;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
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   "*
2672   rtx link;
2673   int have_dep_anti = 0;
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))
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 \"\";
2694   [(set_attr "type" "unknown")
2695    (set_attr "length" "12")])
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   "
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     }
2726   DONE;
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")])
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   "
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     }
2767   DONE;
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")])
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   "
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     }
2810   DONE;
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")])
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   "
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     }
2851   DONE;
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")])
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   "
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     }
2882   DONE;
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")])
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   "
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     }
2913   DONE;
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")])
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   "
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     }
2944   DONE;
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")])
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   "
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     }
2975   DONE;
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")])
2990 ;;  ....................
2992 ;;      SQUARE ROOT
2994 ;;  ....................
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")])
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")])
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")])
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")])
3032 ;;  ....................
3034 ;;      ABSOLUTE VALUE
3036 ;;  ....................
3038 ;; Do not use the integer abs macro instruction, since that signals an
3039 ;; exception on -2147483648 (sigh).
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   "*
3047   dslots_jump_total++;
3048   dslots_jump_filled++;
3049   operands[2] = const0_rtx;
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:%)\";
3061   [(set_attr "type"     "multi")
3062    (set_attr "mode"     "SI")
3063    (set_attr "length"   "12")])
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   "*
3071   unsigned int regno1;
3072   dslots_jump_total++;
3073   dslots_jump_filled++;
3074   operands[2] = const0_rtx;
3076   if (GET_CODE (operands[1]) == REG)
3077     regno1 = REGNO (operands[1]);
3078   else
3079     regno1 = REGNO (XEXP (operands[1], 0));
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:%)\";
3086   [(set_attr "type"     "multi")
3087    (set_attr "mode"     "DI")
3088    (set_attr "length"   "12")])
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")])
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")])
3108 ;;  ....................
3110 ;;      FIND FIRST BIT INSTRUCTION
3112 ;;  ....................
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   "*
3123   dslots_jump_total += 2;
3124   dslots_jump_filled += 2;
3125   operands[4] = const0_rtx;
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:%)\";
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:%)\";
3147   [(set_attr "type"     "multi")
3148    (set_attr "mode"     "SI")
3149    (set_attr "length"   "12")])
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   "*
3159   dslots_jump_total += 2;
3160   dslots_jump_filled += 2;
3161   operands[4] = const0_rtx;
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:%)\";
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:%)\";
3183   [(set_attr "type"     "multi")
3184    (set_attr "mode"     "DI")
3185    (set_attr "length"   "24")])
3189 ;;  ....................
3191 ;;      NEGATION and ONE'S COMPLEMENT
3193 ;;  ....................
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   "*
3201   if (TARGET_MIPS16)
3202     return \"neg\\t%0,%1\";
3203   operands[2] = const0_rtx;
3204   return \"subu\\t%0,%z2,%1\";
3206   [(set_attr "type"     "arith")
3207    (set_attr "mode"     "SI")])
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   "
3216   if (TARGET_64BIT)
3217     {
3218       emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
3219       DONE;
3220     }
3222   operands[2] = gen_reg_rtx (SImode);
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   "*
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\";
3235   [(set_attr "type"     "darith")
3236    (set_attr "mode"     "DI")
3237    (set_attr "length"   "16")])
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   "*
3245   operands[2] = const0_rtx;
3246   return \"dsubu\\t%0,%z2,%1\";
3248   [(set_attr "type"     "arith")
3249    (set_attr "mode"     "DI")])
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")])
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")])
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   "*
3273   if (TARGET_MIPS16)
3274     return \"not\\t%0,%1\";
3275   operands[2] = const0_rtx;
3276   return \"nor\\t%0,%z2,%1\";
3278   [(set_attr "type"     "arith")
3279    (set_attr "mode"     "SI")])
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   "*
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\";
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)))])
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]))"
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   "")
3319 ;;  ....................
3321 ;;      LOGICAL
3323 ;;  ....................
3326 ;; Many of these instructions uses trivial define_expands, because we
3327 ;; want to use a different set of constraints when TARGET_MIPS16.
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   "
3336   if (TARGET_MIPS16)
3337     {
3338       operands[1] = force_reg (SImode, operands[1]);
3339       operands[2] = force_reg (SImode, operands[2]);
3340     }
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")])
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")])
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   "
3370   if (TARGET_MIPS16)
3371     {
3372       operands[1] = force_reg (DImode, operands[1]);
3373       operands[2] = force_reg (DImode, operands[2]);
3374     }
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   "*
3384   if (TARGET_64BIT)
3385     return \"and\\t%0,%1,%2\";
3386   return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
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)))])
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   "*
3402   if (TARGET_64BIT)
3403     return \"and\\t%0,%2\";
3404   return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
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)))])
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]))"
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   "")
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")])
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   "
3445   if (TARGET_MIPS16)
3446     {
3447       operands[1] = force_reg (SImode, operands[1]);
3448       operands[2] = force_reg (SImode, operands[2]);
3449     }
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")])
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")])
3472 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
3473 ;;; TARGET_64BIT
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   "")
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   "*
3489   if (TARGET_64BIT)
3490     return \"or\\t%0,%1,%2\";
3491   return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
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)))])
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   "*
3507   if (TARGET_64BIT)
3508     return \"or\\t%0,%2\";
3509   return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
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)))])
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]))"
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   "")
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   "")
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")])
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)])])
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   "")
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   "*
3584   if (TARGET_64BIT)
3585     return \"xor\\t%0,%1,%2\";
3586   return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
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)))])
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")])
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)])])
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]))"
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   "")
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")])
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")])
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   "*
3662   if (TARGET_64BIT)
3663     return \"nor\\t%0,%z1,%z2\";
3664   return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
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)))])
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]))"
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   "")
3688 ;;  ....................
3690 ;;      TRUNCATION
3692 ;;  ....................
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")])
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   "*
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\";
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)))])
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   "*
3724   if (TARGET_MIPS16)
3725     return \"dsll\\t%0,%1,48\;dsra\\t%0,48\";
3726   return \"andi\\t%0,%1,0xffff\";
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   "*
3739   if (TARGET_MIPS16)
3740     return \"dsll\\t%0,%1,56\;dsra\\t%0,56\";
3741   return \"andi\\t%0,%1,0x00ff\";
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)))])
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   "*
3757   int shift_amt = INTVAL (operands[2]) & 0x3f;
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     }
3770   [(set_attr "type"     "darith")
3771    (set_attr "mode"     "SI")
3772    (set_attr "length"   "8")])
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   "*
3781   int shift_amt = INTVAL (operands[2]) & 0x3f;
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     }
3796   [(set_attr "type"     "darith")
3797    (set_attr "mode"     "SI")
3798    (set_attr "length"   "8")])
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   "*
3807   int shift_amt = INTVAL (operands[2]) & 0x3f;
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,%.\";
3819   [(set_attr "type"     "darith")
3820    (set_attr "mode"     "SI")
3821    (set_attr "length"   "8")])
3823 ;; Combiner patterns to optimize truncate/zero_extend combinations.
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")])
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")])
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")])
3853 ;;  ....................
3855 ;;      ZERO EXTENSION
3857 ;;  ....................
3859 ;; Extension insns.
3860 ;; Those for integer source operand are ordered widest source type first.
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   "
3868   if ((optimize || TARGET_MIPS16) && GET_CODE (operands[1]) == MEM)
3869     operands[1] = force_not_mem (operands[1]);
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);
3877       emit_insn (gen_ashldi3 (temp, op1, shift));
3878       emit_insn (gen_lshrdi3 (operands[0], temp, shift));
3879       DONE;
3880     }
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")])
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   "
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));
3903       emit_insn (gen_andsi3 (operands[0], op, temp));
3904       DONE;
3905     }
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   "*
3914   if (which_alternative == 0)
3915     return \"andi\\t%0,%1,0xffff\";
3916   else
3917     return mips_move_1word (operands, insn, TRUE);
3919   [(set_attr "type"     "arith,load,load")
3920    (set_attr "mode"     "SI")
3921    (set_attr "length"   "4,4,8")])
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")])
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   "
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));
3943       emit_insn (gen_anddi3 (operands[0], op, temp));
3944       DONE;
3945     }
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   "*
3954   if (which_alternative == 0)
3955     return \"andi\\t%0,%1,0xffff\";
3956   else
3957     return mips_move_1word (operands, insn, TRUE);
3959   [(set_attr "type"     "arith,load,load")
3960    (set_attr "mode"     "DI")
3961    (set_attr "length"   "4,4,8")])
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")])
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   "
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));
3984       emit_insn (gen_andsi3 (op0, op1, temp));
3985       DONE;
3986     }
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   "*
3995   if (which_alternative == 0)
3996     return \"andi\\t%0,%1,0x00ff\";
3997   else
3998     return mips_move_1word (operands, insn, TRUE);
4000   [(set_attr "type"     "arith,load,load")
4001    (set_attr "mode"     "HI")
4002    (set_attr "length"   "4,4,8")])
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")])
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   "
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));
4024       emit_insn (gen_andsi3 (operands[0], op, temp));
4025       DONE;
4026     }
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   "*
4035   if (which_alternative == 0)
4036     return \"andi\\t%0,%1,0x00ff\";
4037   else
4038     return mips_move_1word (operands, insn, TRUE);
4040   [(set_attr "type"     "arith,load,load")
4041    (set_attr "mode"     "SI")
4042    (set_attr "length"   "4,4,8")])
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")])
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   "
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));
4064       emit_insn (gen_anddi3 (operands[0], op, temp));
4065       DONE;
4066     }
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   "*
4075   if (which_alternative == 0)
4076     return \"andi\\t%0,%1,0x00ff\";
4077   else
4078     return mips_move_1word (operands, insn, TRUE);
4080   [(set_attr "type"     "arith,load,load")
4081    (set_attr "mode"     "DI")
4082    (set_attr "length"   "4,4,8")])
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   "*
4096   return mips_move_1word (operands, insn, TRUE);
4098   [(set_attr "type"     "load,load")
4099    (set_attr "mode"     "DI")
4100    (set_attr "length"   "4,8")])
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")])
4112 ;;  ....................
4114 ;;      SIGN EXTENSION
4116 ;;  ....................
4118 ;; Extension insns.
4119 ;; Those for integer source operand are ordered widest source type first.
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.
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")])
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.
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   "
4145   if (optimize && GET_CODE (operands[1]) == MEM)
4146     operands[1] = force_not_mem (operands[1]);
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);
4154       emit_insn (gen_ashldi3 (temp, op1, shift));
4155       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4156       DONE;
4157     }
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")])
4169 (define_expand "extendhisi2"
4170   [(set (match_operand:SI 0 "register_operand" "")
4171         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4172   ""
4173   "
4175   if (optimize && GET_CODE (operands[1]) == MEM)
4176     operands[1] = force_not_mem (operands[1]);
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);
4184       emit_insn (gen_ashlsi3 (temp, op1, shift));
4185       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4186       DONE;
4187     }
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")])
4199 (define_expand "extendqihi2"
4200   [(set (match_operand:HI 0 "register_operand" "")
4201         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
4202   ""
4203   "
4205   if (optimize && GET_CODE (operands[1]) == MEM)
4206     operands[1] = force_not_mem (operands[1]);
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);
4215       emit_insn (gen_ashlsi3 (temp, op1, shift));
4216       emit_insn (gen_ashrsi3 (op0, temp, shift));
4217       DONE;
4218     }
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")])
4231 (define_expand "extendqisi2"
4232   [(set (match_operand:SI 0 "register_operand" "")
4233         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4234   ""
4235   "
4237   if (optimize && GET_CODE (operands[1]) == MEM)
4238     operands[1] = force_not_mem (operands[1]);
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);
4246       emit_insn (gen_ashlsi3 (temp, op1, shift));
4247       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4248       DONE;
4249     }
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")])
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   "
4267   if (optimize && GET_CODE (operands[1]) == MEM)
4268     operands[1] = force_not_mem (operands[1]);
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);
4276       emit_insn (gen_ashldi3 (temp, op1, shift));
4277       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4278       DONE;
4279     }
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")])
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")])
4303 ;;  ....................
4305 ;;      CONVERSIONS
4307 ;;  ....................
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.
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).
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   "*
4327   rtx xoperands[10];
4329   if (which_alternative == 1)
4330     return \"trunc.w.d %0,%1,%2\";
4332   output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
4334   xoperands[0] = operands[0];
4335   xoperands[1] = operands[3];
4336   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4337   return \"\";
4339   [(set_attr "type"     "fcvt")
4340    (set_attr "mode"     "DF")
4341    (set_attr "length"   "44,36,40,44")])
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   "*
4352   rtx xoperands[10];
4354   if (which_alternative == 1)
4355     return \"trunc.w.s %0,%1,%2\";
4357   output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
4359   xoperands[0] = operands[0];
4360   xoperands[1] = operands[3];
4361   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4362   return \"\";
4364   [(set_attr "type"     "fcvt")
4365    (set_attr "mode"     "SF")
4366    (set_attr "length"   "44,36,40,44")])
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.
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.
4376 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
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   "*
4385   rtx xoperands[10];
4387   if (which_alternative == 1)
4388     return \"trunc.l.d %0,%1\";
4390   output_asm_insn (\"trunc.l.d %2,%1\", operands);
4392   xoperands[0] = operands[0];
4393   xoperands[1] = operands[2];
4394   output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
4395   return \"\";
4397   [(set_attr "type"     "fcvt")
4398    (set_attr "mode"     "DF")
4399    (set_attr "length"   "8,4,8,12")])
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   "*
4412   rtx xoperands[10];
4414   if (which_alternative == 1)
4415     return \"trunc.l.s %0,%1\";
4417   output_asm_insn (\"trunc.l.s %2,%1\", operands);
4419   xoperands[0] = operands[0];
4420   xoperands[1] = operands[2];
4421   output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
4422   return \"\";
4424   [(set_attr "type"     "fcvt")
4425    (set_attr "mode"     "SF")
4426    (set_attr "length"   "8,4,8,12")])
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   "*
4435   dslots_load_total++;
4436   if (GET_CODE (operands[1]) == MEM)
4437     return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
4439   return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
4441   [(set_attr "type"     "fcvt")
4442    (set_attr "mode"     "DF")
4443    (set_attr "length"   "12,16,12")])
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   "*
4452   dslots_load_total++;
4453   if (GET_CODE (operands[1]) == MEM)
4454     return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
4456   return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
4458   [(set_attr "type"     "fcvt")
4459    (set_attr "mode"     "DF")
4460    (set_attr "length"   "12,16,12")])
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   "*
4469   dslots_load_total++;
4470   if (GET_CODE (operands[1]) == MEM)
4471     return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
4473   return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
4475   [(set_attr "type"     "fcvt")
4476    (set_attr "mode"     "SF")
4477    (set_attr "length"   "12,16,12")])
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   "*
4486   dslots_load_total++;
4487   if (GET_CODE (operands[1]) == MEM)
4488     return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
4490   return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
4492   [(set_attr "type"     "fcvt")
4493    (set_attr "mode"     "SF")
4494    (set_attr "length"   "12,16,12")])
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   "
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);
4510   if (reg1)                     /* turn off complaints about unreached code */
4511     {
4512       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4513       do_pending_stack_adjust ();
4515       emit_insn (gen_cmpdf (operands[1], reg1));
4516       emit_jump_insn (gen_bge (label1));
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 ();
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)));
4528       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4529       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4531       emit_label (label2);
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     }
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   "
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);
4554   if (reg1)                     /* turn off complaints about unreached code */
4555     {
4556       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4557       do_pending_stack_adjust ();
4559       emit_insn (gen_cmpdf (operands[1], reg1));
4560       emit_jump_insn (gen_bge (label1));
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 ();
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)));
4572       emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4573       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4575       emit_label (label2);
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     }
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   "
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);
4598   if (reg1)                     /* turn off complaints about unreached code */
4599     {
4600       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4601       do_pending_stack_adjust ();
4603       emit_insn (gen_cmpsf (operands[1], reg1));
4604       emit_jump_insn (gen_bge (label1));
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 ();
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)));
4616       emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4617       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4619       emit_label (label2);
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     }
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   "
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);
4642   if (reg1)                     /* turn off complaints about unreached code */
4643     {
4644       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4645       do_pending_stack_adjust ();
4647       emit_insn (gen_cmpsf (operands[1], reg1));
4648       emit_jump_insn (gen_bge (label1));
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 ();
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)));
4660       emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4661       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4663       emit_label (label2);
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     }
4674 ;;  ....................
4676 ;;      DATA MOVEMENT
4678 ;;  ....................
4680 ;; Bit field extract patterns which use lwl/lwr.
4682 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4683 ;; It isn't clear whether this will give better code.
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   "
4694   /* If the field does not start on a byte boundary, then fail.  */
4695   if (INTVAL (operands[3]) % 8 != 0)
4696     FAIL;
4698   /* MIPS I and MIPS II can only handle a 32bit field.  */
4699   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4700     FAIL;
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;
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;
4714   /* Change the mode to BLKmode for aliasing purposes.  */
4715   operands[1] = adjust_address (operands[1], BLKmode, 0);
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;
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   "
4742   /* If the field does not start on a byte boundary, then fail.  */
4743   if (INTVAL (operands[3]) % 8 != 0)
4744     FAIL;
4746   /* MIPS I and MIPS II can only handle a 32bit field.  */
4747   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4748     FAIL;
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;
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;
4762   /* Change the mode to BLKmode for aliasing purposes.  */
4763   operands[1] = adjust_address (operands[1], BLKmode, 0);
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;
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   "
4790   /* If the field does not start on a byte boundary, then fail.  */
4791   if (INTVAL (operands[2]) % 8 != 0)
4792     FAIL;
4794   /* MIPS I and MIPS II can only handle a 32bit field.  */
4795   if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
4796     FAIL;
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;
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;
4810   /* Change the mode to BLKmode for aliasing purposes.  */
4811   operands[0] = adjust_address (operands[0], BLKmode, 0);
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;
4829 ;; unaligned word moves generated by the bit field patterns
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   "*
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;
4843   if (TARGET_STATS)
4844     mips_count_memory_refs (operands[1], 2);
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.  */
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\";
4855   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4857   [(set_attr "type"     "load,load")
4858    (set_attr "mode"     "SI")
4859    (set_attr "length"   "8,16")])
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   "*
4868   rtx offset = const0_rtx;
4869   rtx addr = XEXP (operands[0], 0);
4870   rtx mem_addr = eliminate_constant_term (addr, &offset);
4872   if (TARGET_STATS)
4873     mips_count_memory_refs (operands[0], 2);
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.  */
4878   if ((INTVAL (offset) & 3) == 0
4879       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4880     return \"sw\\t%z1,%0\";
4882   return \"usw\\t%z1,%0\";
4884   [(set_attr "type"     "store")
4885    (set_attr "mode"     "SI")
4886    (set_attr "length"   "8,16")])
4888 ;; Bit field extract patterns which use ldl/ldr.
4890 ;; unaligned double word moves generated by the bit field patterns
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   "*
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;
4904   if (TARGET_STATS)
4905     mips_count_memory_refs (operands[1], 2);
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.  */
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\";
4916   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4918   [(set_attr "type"     "load,load")
4919    (set_attr "mode"     "SI")
4920    (set_attr "length"   "8,16")])
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   "*
4929   rtx offset = const0_rtx;
4930   rtx addr = XEXP (operands[0], 0);
4931   rtx mem_addr = eliminate_constant_term (addr, &offset);
4933   if (TARGET_STATS)
4934     mips_count_memory_refs (operands[0], 2);
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.  */
4939   if ((INTVAL (offset) & 7) == 0
4940       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4941     return \"sd\\t%1,%0\";
4943   return \"usd\\t%z1,%0\";
4945   [(set_attr "type"     "store")
4946    (set_attr "mode"     "SI")
4947    (set_attr "length"   "8,16")])
4949 ;; These two patterns support loading addresses with two instructions instead
4950 ;; of using the macro instruction la.
4952 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
4953 ;; unnecessary.
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")])
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")])
4971 ;; 64-bit integer moves
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.
4977 (define_expand "movdi"
4978   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4979         (match_operand:DI 1 "general_operand" ""))]
4980   ""
4981   "
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));
4989       emit_insn (gen_rtx_SET (VOIDmode, tem,
4990                               gen_rtx_HIGH (mode, operands[1])));
4992       operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
4993     }
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;
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     }
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);
5019       if (! SMALL_INT (temp2))
5020         temp2 = force_reg (DImode, temp2);
5022       emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
5023       DONE;
5024     }
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);
5036       if (name[0] != '*'
5037           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5038                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5039         {
5040           rtx base_reg;
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             }
5060           emit_move_insn (operands[0],
5061                           gen_rtx (PLUS, Pmode, base_reg,
5062                                    mips16_gp_offset (operands[1])));
5063           DONE;
5064         }
5065     }
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     }
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.
5084 (define_insn ""
5085   [(set (match_operand:DI 0 "memory_operand" "=R,m")
5086         (reg:DI 31))]
5087   "TARGET_MIPS16 && TARGET_64BIT"
5088   "*
5090   operands[1] = gen_rtx (REG, DImode, 31);
5091   return mips_move_2words (operands, insn);
5093   [(set_attr "type"     "store")
5094    (set_attr "mode"     "DI")
5095    (set_attr "length"   "4,8")])
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")])
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")])
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]))"
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   "")
5133 (define_insn "movdi_internal2"
5134   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,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,S,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,load,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,8,4,8,4,8,4,8,4,4,4,8,8,8,8,8,8,8")])
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)])])
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.
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   "
5198   HOST_WIDE_INT val = INTVAL (operands[1]);
5200   if (val < 0)
5201     operands[2] = GEN_INT (0);
5202   else if (val >= 32 * 8)
5203     {
5204       int off = val & 7;
5206       operands[1] = GEN_INT (0x8 + off);
5207       operands[2] = GEN_INT (val - off - 0x8);
5208     }
5209   else
5210     {
5211       int off = val & 7;
5213       operands[1] = GEN_INT (off);
5214       operands[2] = GEN_INT (val - off);
5215     }
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.
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   "
5234   rtx scratch = gen_rtx_REG (DImode,
5235                              (REGNO (operands[0]) == REGNO (operands[2])
5236                               ? REGNO (operands[2]) + 1
5237                               : REGNO (operands[2])));
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);
5247           scratch = gen_rtx_REG (SImode, REGNO (scratch));
5248           memword = adjust_address (op1, SImode, 0);
5249           offword = adjust_address (op1, SImode, 4);
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;
5295 ;; Handle output reloads in DImode.
5297 ;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5298 ;; use a TImode scratch reg.
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   "
5307   rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
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);
5327           scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
5328           memword = adjust_address (op0, SImode, 0);
5329           offword = adjust_address (op0, SImode, 4);
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;
5380 ;; 32-bit Integer moves
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   "
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);
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.
5403 (define_expand "movsi"
5404   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5405         (match_operand:SI 1 "general_operand" ""))]
5406   ""
5407   "
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));
5415       emit_insn (gen_rtx_SET (VOIDmode, tem,
5416                               gen_rtx_HIGH (mode, operands[1])));
5418       operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
5419     }
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;
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     }
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);
5445       if (! SMALL_INT (temp2))
5446         temp2 = force_reg (SImode, temp2);
5448       emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, temp2));
5449       DONE;
5450     }
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);
5462       if (name[0] != '*'
5463           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5464                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5465         {
5466           rtx base_reg;
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             }
5483           base_reg = gen_reg_rtx (Pmode);
5484           emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5486           emit_move_insn (operands[0],
5487                           gen_rtx (PLUS, Pmode, base_reg,
5488                                    mips16_gp_offset (operands[1])));
5489           DONE;
5490         }
5491     }
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     }
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.
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))])])
5526 ;; The difference between these two is whether or not ints are allowed
5527 ;; in FP registers (off by default, use -mdebugh to enable).
5529 (define_insn "movsi_internal1"
5530   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,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,S,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,load,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,8,4,8,4,8,4,8,4,4,4,4,8,4,8,4,4,4,4,4,4,8,4,4,8")])
5541 (define_insn "movsi_internal2"
5542   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,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,S,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,load,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,8,4,8,4,8,4,8,4,4,4,4,4,4,4,4,8,4,4,8")])
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.
5561 (define_insn ""
5562   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,d,R,m,*d,*d")
5563         (match_operand:SI 1 "move_operand" "d,d,y,S,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,load,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                  (const_int 8)
5582                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5583                                (const_int 4)
5584                                (const_int 8))
5585                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5586                                (const_int 8)
5587                                (const_int 12))
5588                  (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
5589                                (const_int 4)
5590                                (const_int 8))
5591                  (const_int 4)
5592                  (const_int 8)
5593                  (const_int 4)
5594                  (const_int 8)
5595                  (const_int 4)
5596                  (const_int 4)])])
5598 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
5599 ;; when the original load is a 4 byte instruction but the add and the
5600 ;; load are 2 2 byte instructions.
5602 (define_split
5603   [(set (match_operand:SI 0 "register_operand" "")
5604         (mem:SI (plus:SI (match_dup 0)
5605                          (match_operand:SI 1 "const_int_operand" ""))))]
5606   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5607    && GET_CODE (operands[0]) == REG
5608    && M16_REG_P (REGNO (operands[0]))
5609    && GET_CODE (operands[1]) == CONST_INT
5610    && ((INTVAL (operands[1]) < 0
5611         && INTVAL (operands[1]) >= -0x80)
5612        || (INTVAL (operands[1]) >= 32 * 4
5613            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5614        || (INTVAL (operands[1]) >= 0
5615            && INTVAL (operands[1]) < 32 * 4
5616            && (INTVAL (operands[1]) & 3) != 0))"
5617   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5618    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
5619   "
5621   HOST_WIDE_INT val = INTVAL (operands[1]);
5623   if (val < 0)
5624     operands[2] = GEN_INT (0);
5625   else if (val >= 32 * 4)
5626     {
5627       int off = val & 3;
5629       operands[1] = GEN_INT (0x7c + off);
5630       operands[2] = GEN_INT (val - off - 0x7c);
5631     }
5632   else
5633     {
5634       int off = val & 3;
5636       operands[1] = GEN_INT (off);
5637       operands[2] = GEN_INT (val - off);
5638     }
5641 ;; On the mips16, we can split a load of certain constants into a load
5642 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
5643 ;; instructions.
5645 (define_split
5646   [(set (match_operand:SI 0 "register_operand" "")
5647         (match_operand:SI 1 "const_int_operand" ""))]
5648   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5649    && GET_CODE (operands[0]) == REG
5650    && M16_REG_P (REGNO (operands[0]))
5651    && GET_CODE (operands[1]) == CONST_INT
5652    && INTVAL (operands[1]) >= 0x100
5653    && INTVAL (operands[1]) <= 0xff + 0x7f"
5654   [(set (match_dup 0) (match_dup 1))
5655    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5656   "
5658   int val = INTVAL (operands[1]);
5660   operands[1] = GEN_INT (0xff);
5661   operands[2] = GEN_INT (val - 0xff);
5664 ;; On the mips16, we can split a load of a negative constant into a
5665 ;; load and a neg.  That's what mips_move_1word will generate anyhow.
5667 (define_split
5668   [(set (match_operand:SI 0 "register_operand" "")
5669         (match_operand:SI 1 "const_int_operand" ""))]
5670   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5671    && GET_CODE (operands[0]) == REG
5672    && M16_REG_P (REGNO (operands[0]))
5673    && GET_CODE (operands[1]) == CONST_INT
5674    && INTVAL (operands[1]) < 0
5675    && INTVAL (operands[1]) > - 0x8000"
5676   [(set (match_dup 0) (match_dup 1))
5677    (set (match_dup 0) (neg:SI (match_dup 0)))]
5678   "
5680   operands[1] = GEN_INT (- INTVAL (operands[1]));
5683 ;; Reload HILO_REGNUM in SI mode.  This needs a scratch register in
5684 ;; order to set the sign bit correctly in the HI register.
5686 (define_expand "reload_outsi"
5687   [(set (match_operand:SI 0 "general_operand" "=b")
5688         (match_operand:SI 1 "register_operand" "b"))
5689    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5690   "TARGET_64BIT || TARGET_MIPS16"
5691   "
5693   if (TARGET_64BIT
5694       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5695     {
5696       emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
5697       emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5698       emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
5699       emit_insn (gen_hilo_delay (operands[0]));
5700       DONE;
5701     }
5702   /* Use a mult to reload LO on mips16.  ??? This is hideous.  */
5703   if (TARGET_MIPS16
5704       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5705     {
5706       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5707       /* This is gen_mulsi3_internal, but we need to fill in the
5708          scratch registers.  */
5709       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5710                           gen_rtvec (3,
5711                                      gen_rtx (SET, VOIDmode,
5712                                               operands[0],
5713                                               gen_rtx (MULT, SImode,
5714                                                        operands[1],
5715                                                        operands[2])),
5716                                      gen_rtx (CLOBBER, VOIDmode,
5717                                               gen_rtx (REG, SImode, 64)),
5718                                      gen_rtx (CLOBBER, VOIDmode,
5719                                               gen_rtx (REG, SImode, 66)))));
5720       DONE;
5721     }
5722   /* FIXME: I don't know how to get a value into the HI register.  */
5723   if (GET_CODE (operands[0]) == REG
5724       && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5725           : GP_REG_P (REGNO (operands[0]))))
5726     {
5727       emit_move_insn (operands[0], operands[1]);
5728       DONE;
5729     }
5730   /* This handles moves between a float register and HI/LO.  */
5731   emit_move_insn (operands[2], operands[1]);
5732   emit_move_insn (operands[0], operands[2]);
5733   DONE;
5736 ;; Reload a value into HI or LO.  There is no mthi or mtlo on mips16,
5737 ;; so we use a mult.  ??? This is hideous, and we ought to figure out
5738 ;; something better.
5740 ;; We use no predicate for operand1, because it may be a PLUS, and there
5741 ;; is no convenient predicate for that.
5743 (define_expand "reload_insi"
5744   [(set (match_operand:SI 0 "register_operand" "=b")
5745         (match_operand:SI 1 "" "b"))
5746    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5747   "TARGET_MIPS16"
5748   "
5750   if (TARGET_MIPS16
5751       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5752     {
5753       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5754       /* This is gen_mulsi3_internal, but we need to fill in the
5755          scratch registers.  */
5756       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5757                           gen_rtvec (3,
5758                                      gen_rtx (SET, VOIDmode,
5759                                               operands[0],
5760                                               gen_rtx (MULT, SImode,
5761                                                        operands[1],
5762                                                        operands[2])),
5763                                      gen_rtx (CLOBBER, VOIDmode,
5764                                               gen_rtx (REG, SImode, 64)),
5765                                      gen_rtx (CLOBBER, VOIDmode,
5766                                               gen_rtx (REG, SImode, 66)))));
5767       DONE;
5768     }
5770   /* If this is a plus, then this must be an add of the stack pointer against
5771      either a hard register or a pseudo.  */
5772   if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5773     {
5774       rtx plus_op;
5776       if (XEXP (operands[1], 0) == stack_pointer_rtx)
5777         plus_op = XEXP (operands[1], 1);
5778       else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5779         plus_op = XEXP (operands[1], 0);
5780       else
5781         abort ();
5783       /* We should have a register now.  */
5784       if (GET_CODE (plus_op) != REG)
5785         abort ();
5787       if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5788         {
5789           /* We have to have at least one temporary register which is not
5790              overlapping plus_op.  */
5791           if (! rtx_equal_p (plus_op, operands[0]))
5792             {
5793               emit_move_insn (operands[0], stack_pointer_rtx);
5794               emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5795             }
5796           else if (! rtx_equal_p (plus_op, operands[2]))
5797             {
5798               emit_move_insn (operands[2], stack_pointer_rtx);
5799               emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5800             }
5801           else
5802             abort ();
5803         }
5804       else
5805         {
5806           /* We need two registers in this case.  */
5807           if (! rtx_equal_p (operands[0], operands[2]))
5808             {
5809               emit_move_insn (operands[0], stack_pointer_rtx);
5810               emit_move_insn (operands[2], plus_op);
5811               emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5812             }
5813           else
5814             abort ();
5815         }
5816       DONE;
5817     }
5819   /* FIXME: I don't know how to get a value into the HI register.  */
5820   emit_move_insn (operands[0], operands[1]);
5821   DONE;
5824 ;; This insn is for the unspec delay for HILO.
5826 (define_insn "hilo_delay"
5827   [(unspec [(match_operand 0 "register_operand" "=b")] UNSPEC_HILO_DELAY)]
5828   ""
5829   ""
5830   [(set_attr "type" "nop")
5831    (set_attr "mode" "none")
5832    (set_attr "can_delay" "no")])
5834 ;; This insn handles moving CCmode values.  It's really just a
5835 ;; slightly simplified copy of movsi_internal2, with additional cases
5836 ;; to move a condition register to a general register and to move
5837 ;; between the general registers and the floating point registers.
5839 (define_insn "movcc"
5840   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
5841         (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
5842   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5843   "* return mips_move_1word (operands, insn, FALSE);"
5844   [(set_attr "type"     "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
5845    (set_attr "mode"     "SI")
5846    (set_attr "length"   "8,4,4,8,4,8,4,4,4,4,8,4,8")])
5848 ;; Reload condition code registers.  These need scratch registers.
5850 (define_expand "reload_incc"
5851   [(set (match_operand:CC 0 "register_operand" "=z")
5852         (match_operand:CC 1 "general_operand" "z"))
5853    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5854   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5855   "
5857   rtx source;
5858   rtx fp1, fp2;
5859   int regno;
5861   /* This is called when are copying some value into a condition code
5862      register.  Operand 0 is the condition code register.  Operand 1
5863      is the source.  Operand 2 is a scratch register; we use TFmode
5864      because we actually need two floating point registers.  */
5865   if (! ST_REG_P (true_regnum (operands[0]))
5866       || ! FP_REG_P (true_regnum (operands[2])))
5867     abort ();
5869   /* We need to get the source in SFmode so that the insn is
5870      recognized.  */
5871   if (GET_CODE (operands[1]) == MEM)
5872     source = adjust_address (operands[1], SFmode, 0);
5873   else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
5874     source = gen_rtx_REG (SFmode, true_regnum (operands[1]));
5875   else
5876     source = operands[1];
5878   /* FP1 and FP2 are the two halves of the TFmode scratch operand.  They
5879      will be single registers in 64-bit mode and register pairs in 32-bit
5880      mode.  SOURCE is loaded into FP1 and zero is loaded into FP2.  */
5881   regno = REGNO (operands[2]);
5882   fp1 = gen_rtx_REG (SFmode, regno);
5883   fp2 = gen_rtx_REG (SFmode, regno + HARD_REGNO_NREGS (regno, DFmode));
5885   emit_insn (gen_move_insn (fp1, source));
5886   emit_insn (gen_move_insn (fp2, gen_rtx_REG (SFmode, 0)));
5887   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5888                           gen_rtx_LT (CCmode, fp2, fp1)));
5890   DONE;
5893 (define_expand "reload_outcc"
5894   [(set (match_operand:CC 0 "general_operand" "=z")
5895         (match_operand:CC 1 "register_operand" "z"))
5896    (clobber (match_operand:CC 2 "register_operand" "=&d"))]
5897   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5898   "
5900   /* This is called when we are copying a condition code register out
5901      to save it somewhere.  Operand 0 should be the location we are
5902      going to save it to.  Operand 1 should be the condition code
5903      register.  Operand 2 should be a scratch general purpose register
5904      created for us by reload.  The mips_secondary_reload_class
5905      function should have told reload that we don't need a scratch
5906      register if the destination is a general purpose register anyhow.  */
5907   if (ST_REG_P (true_regnum (operands[0]))
5908       || GP_REG_P (true_regnum (operands[0]))
5909       || ! ST_REG_P (true_regnum (operands[1]))
5910       || ! GP_REG_P (true_regnum (operands[2])))
5911     abort ();
5913   /* All we have to do is copy the value from the condition code to
5914      the data register, which movcc can handle, and then store the
5915      value into the real final destination.  */
5916   emit_insn (gen_move_insn (operands[2], operands[1]));
5917   emit_insn (gen_move_insn (operands[0], operands[2]));
5919   DONE;
5922 ;; MIPS4 supports loading and storing a floating point register from
5923 ;; the sum of two general registers.  We use two versions for each of
5924 ;; these four instructions: one where the two general registers are
5925 ;; SImode, and one where they are DImode.  This is because general
5926 ;; registers will be in SImode when they hold 32 bit values, but,
5927 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5928 ;; instructions will still work correctly.
5930 ;; ??? Perhaps it would be better to support these instructions by
5931 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
5932 ;; these instructions can only be used to load and store floating
5933 ;; point registers, that would probably cause trouble in reload.
5935 (define_insn ""
5936   [(set (match_operand:SF 0 "register_operand" "=f")
5937         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5938                          (match_operand:SI 2 "register_operand" "d"))))]
5939   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5940   "lwxc1\\t%0,%1(%2)"
5941   [(set_attr "type"     "load")
5942    (set_attr "mode"     "SF")])
5944 (define_insn ""
5945   [(set (match_operand:SF 0 "register_operand" "=f")
5946         (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5947                          (match_operand:DI 2 "se_register_operand" "d"))))]
5948   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5949   "lwxc1\\t%0,%1(%2)"
5950   [(set_attr "type"     "load")
5951    (set_attr "mode"     "SF")])
5953 (define_insn ""
5954   [(set (match_operand:DF 0 "register_operand" "=f")
5955         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5956                          (match_operand:SI 2 "register_operand" "d"))))]
5957   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5958   "ldxc1\\t%0,%1(%2)"
5959   [(set_attr "type"     "load")
5960    (set_attr "mode"     "DF")])
5962 (define_insn ""
5963   [(set (match_operand:DF 0 "register_operand" "=f")
5964         (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5965                          (match_operand:DI 2 "se_register_operand" "d"))))]
5966   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5967   "ldxc1\\t%0,%1(%2)"
5968   [(set_attr "type"     "load")
5969    (set_attr "mode"     "DF")])
5971 (define_insn ""
5972   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5973                          (match_operand:SI 2 "register_operand" "d")))
5974         (match_operand:SF 0 "register_operand" "f"))]
5975   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5976   "swxc1\\t%0,%1(%2)"
5977   [(set_attr "type"     "store")
5978    (set_attr "mode"     "SF")])
5980 (define_insn ""
5981   [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5982                          (match_operand:DI 2 "se_register_operand" "d")))
5983         (match_operand:SF 0 "register_operand" "f"))]
5984   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5985   "swxc1\\t%0,%1(%2)"
5986   [(set_attr "type"     "store")
5987    (set_attr "mode"     "SF")])
5989 (define_insn ""
5990   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5991                          (match_operand:SI 2 "register_operand" "d")))
5992         (match_operand:DF 0 "register_operand" "f"))]
5993   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5994   "sdxc1\\t%0,%1(%2)"
5995   [(set_attr "type"     "store")
5996    (set_attr "mode"     "DF")])
5998 (define_insn ""
5999   [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
6000                          (match_operand:DI 2 "se_register_operand" "d")))
6001         (match_operand:DF 0 "register_operand" "f"))]
6002   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6003   "sdxc1\\t%0,%1(%2)"
6004   [(set_attr "type"     "store")
6005    (set_attr "mode"     "DF")])
6007 ;; 16-bit Integer moves
6009 ;; Unlike most other insns, the move insns can't be split with
6010 ;; different predicates, because register spilling and other parts of
6011 ;; the compiler, have memoized the insn number already.
6012 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6014 (define_expand "movhi"
6015   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6016         (match_operand:HI 1 "general_operand" ""))]
6017   ""
6018   "
6020   if ((reload_in_progress | reload_completed) == 0
6021       && !register_operand (operands[0], HImode)
6022       && !register_operand (operands[1], HImode)
6023       && (TARGET_MIPS16
6024           || (GET_CODE (operands[1]) != CONST_INT
6025           || INTVAL (operands[1]) != 0)))
6026     {
6027       rtx temp = force_reg (HImode, operands[1]);
6028       emit_move_insn (operands[0], temp);
6029       DONE;
6030     }
6033 ;; The difference between these two is whether or not ints are allowed
6034 ;; in FP registers (off by default, use -mdebugh to enable).
6036 (define_insn "movhi_internal1"
6037   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
6038         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6039   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6040    && (register_operand (operands[0], HImode)
6041        || register_operand (operands[1], HImode)
6042        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6043   "* return mips_move_1word (operands, insn, TRUE);"
6044   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6045    (set_attr "mode"     "HI")
6046    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,4")])
6048 (define_insn "movhi_internal2"
6049   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
6050         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
6051   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6052    && (register_operand (operands[0], HImode)
6053        || register_operand (operands[1], HImode)
6054        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6055   "* return mips_move_1word (operands, insn, TRUE);"
6056   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
6057    (set_attr "mode"     "HI")
6058    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4")])
6060 (define_insn ""
6061   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6062         (match_operand:HI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
6063   "TARGET_MIPS16
6064    && (register_operand (operands[0], HImode)
6065        || register_operand (operands[1], HImode))"
6066   "* return mips_move_1word (operands, insn, TRUE);"
6067   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
6068    (set_attr "mode"     "HI")
6069    (set_attr_alternative "length"
6070                 [(const_int 4)
6071                  (const_int 4)
6072                  (const_int 4)
6073                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6074                                (const_int 4)
6075                                (const_int 8))
6076                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6077                                (const_int 8)
6078                                (const_int 12))
6079                  (const_int 4)
6080                  (const_int 8)
6081                  (const_int 4)
6082                  (const_int 8)
6083                  (const_int 4)])])
6086 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
6087 ;; when the original load is a 4 byte instruction but the add and the
6088 ;; load are 2 2 byte instructions.
6090 (define_split
6091   [(set (match_operand:HI 0 "register_operand" "")
6092         (mem:HI (plus:SI (match_dup 0)
6093                          (match_operand:SI 1 "const_int_operand" ""))))]
6094   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6095    && GET_CODE (operands[0]) == REG
6096    && M16_REG_P (REGNO (operands[0]))
6097    && GET_CODE (operands[1]) == CONST_INT
6098    && ((INTVAL (operands[1]) < 0
6099         && INTVAL (operands[1]) >= -0x80)
6100        || (INTVAL (operands[1]) >= 32 * 2
6101            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
6102        || (INTVAL (operands[1]) >= 0
6103            && INTVAL (operands[1]) < 32 * 2
6104            && (INTVAL (operands[1]) & 1) != 0))"
6105   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6106    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
6107   "
6109   HOST_WIDE_INT val = INTVAL (operands[1]);
6111   if (val < 0)
6112     operands[2] = GEN_INT (0);
6113   else if (val >= 32 * 2)
6114     {
6115       int off = val & 1;
6117       operands[1] = GEN_INT (0x7e + off);
6118       operands[2] = GEN_INT (val - off - 0x7e);
6119     }
6120   else
6121     {
6122       int off = val & 1;
6124       operands[1] = GEN_INT (off);
6125       operands[2] = GEN_INT (val - off);
6126     }
6129 ;; 8-bit Integer moves
6131 ;; Unlike most other insns, the move insns can't be split with
6132 ;; different predicates, because register spilling and other parts of
6133 ;; the compiler, have memoized the insn number already.
6134 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6136 (define_expand "movqi"
6137   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6138         (match_operand:QI 1 "general_operand" ""))]
6139   ""
6140   "
6142   if ((reload_in_progress | reload_completed) == 0
6143       && !register_operand (operands[0], QImode)
6144       && !register_operand (operands[1], QImode)
6145       && (TARGET_MIPS16
6146           || (GET_CODE (operands[1]) != CONST_INT
6147           || INTVAL (operands[1]) != 0)))
6148     {
6149       rtx temp = force_reg (QImode, operands[1]);
6150       emit_move_insn (operands[0], temp);
6151       DONE;
6152     }
6155 ;; The difference between these two is whether or not ints are allowed
6156 ;; in FP registers (off by default, use -mdebugh to enable).
6158 (define_insn "movqi_internal1"
6159   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
6160         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6161   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6162    && (register_operand (operands[0], QImode)
6163        || register_operand (operands[1], QImode)
6164        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6165   "* return mips_move_1word (operands, insn, TRUE);"
6166   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6167    (set_attr "mode"     "QI")
6168    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,4")])
6170 (define_insn "movqi_internal2"
6171   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
6172         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
6173   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6174    && (register_operand (operands[0], QImode)
6175        || register_operand (operands[1], QImode)
6176        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6177   "* return mips_move_1word (operands, insn, TRUE);"
6178   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
6179    (set_attr "mode"     "QI")
6180    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4")])
6182 (define_insn ""
6183   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6184         (match_operand:QI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
6185   "TARGET_MIPS16
6186    && (register_operand (operands[0], QImode)
6187        || register_operand (operands[1], QImode))"
6188   "* return mips_move_1word (operands, insn, TRUE);"
6189   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
6190    (set_attr "mode"     "QI")
6191    (set_attr_alternative "length"
6192                 [(const_int 4)
6193                  (const_int 4)
6194                  (const_int 4)
6195                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6196                                (const_int 4)
6197                                (const_int 8))
6198                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6199                                (const_int 8)
6200                                (const_int 12))
6201                  (const_int 4)
6202                  (const_int 8)
6203                  (const_int 4)
6204                  (const_int 8)
6205                  (const_int 4)])])
6208 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
6209 ;; when the original load is a 4 byte instruction but the add and the
6210 ;; load are 2 2 byte instructions.
6212 (define_split
6213   [(set (match_operand:QI 0 "register_operand" "")
6214         (mem:QI (plus:SI (match_dup 0)
6215                          (match_operand:SI 1 "const_int_operand" ""))))]
6216   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6217    && GET_CODE (operands[0]) == REG
6218    && M16_REG_P (REGNO (operands[0]))
6219    && GET_CODE (operands[1]) == CONST_INT
6220    && ((INTVAL (operands[1]) < 0
6221         && INTVAL (operands[1]) >= -0x80)
6222        || (INTVAL (operands[1]) >= 32
6223            && INTVAL (operands[1]) <= 31 + 0x7f))"
6224   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6225    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
6226   "
6228   HOST_WIDE_INT val = INTVAL (operands[1]);
6230   if (val < 0)
6231     operands[2] = GEN_INT (0);
6232   else
6233     {
6234       operands[1] = GEN_INT (0x7f);
6235       operands[2] = GEN_INT (val - 0x7f);
6236     }
6239 ;; 32-bit floating point moves
6241 (define_expand "movsf"
6242   [(set (match_operand:SF 0 "nonimmediate_operand" "")
6243         (match_operand:SF 1 "general_operand" ""))]
6244   ""
6245   "
6247   if ((reload_in_progress | reload_completed) == 0
6248       && !register_operand (operands[0], SFmode)
6249       && !register_operand (operands[1], SFmode)
6250       && (TARGET_MIPS16
6251           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6252                && operands[1] != CONST0_RTX (SFmode))))
6253     {
6254       rtx temp = force_reg (SFmode, operands[1]);
6255       emit_move_insn (operands[0], temp);
6256       DONE;
6257     }
6260 (define_insn "movsf_internal1"
6261   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
6262         (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
6263   "TARGET_HARD_FLOAT
6264    && (register_operand (operands[0], SFmode)
6265        || register_operand (operands[1], SFmode)
6266        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6267        || operands[1] == CONST0_RTX (SFmode))"
6268   "* return mips_move_1word (operands, insn, FALSE);"
6269   [(set_attr "type"     "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
6270    (set_attr "mode"     "SF")
6271    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,8,4,8")])
6274 (define_insn "movsf_internal2"
6275   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
6276         (match_operand:SF 1 "general_operand" "      Gd,R,Fm,d,d"))]
6277   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
6278    && (register_operand (operands[0], SFmode)
6279        || register_operand (operands[1], SFmode)
6280        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6281        || operands[1] == CONST0_RTX (SFmode))"
6282   "* return mips_move_1word (operands, insn, FALSE);"
6283   [(set_attr "type"     "move,load,load,store,store")
6284    (set_attr "mode"     "SF")
6285    (set_attr "length"   "4,4,8,4,8")])
6287 (define_insn ""
6288   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
6289         (match_operand:SF 1 "general_operand"      "d,d,y,R,Fm,d,d"))]
6290   "TARGET_MIPS16
6291    && (register_operand (operands[0], SFmode)
6292        || register_operand (operands[1], SFmode))"
6293   "* return mips_move_1word (operands, insn, FALSE);"
6294   [(set_attr "type"     "move,move,move,load,load,store,store")
6295    (set_attr "mode"     "SF")
6296    (set_attr "length"   "4,4,4,4,8,4,8")])
6299 ;; 64-bit floating point moves
6301 (define_expand "movdf"
6302   [(set (match_operand:DF 0 "nonimmediate_operand" "")
6303         (match_operand:DF 1 "general_operand" ""))]
6304   ""
6305   "
6307   if ((reload_in_progress | reload_completed) == 0
6308       && !register_operand (operands[0], DFmode)
6309       && !register_operand (operands[1], DFmode)
6310       && (TARGET_MIPS16
6311           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6312                && operands[1] != CONST0_RTX (DFmode))))
6313     {
6314       rtx temp = force_reg (DFmode, operands[1]);
6315       emit_move_insn (operands[0], temp);
6316       DONE;
6317     }
6320 (define_insn "movdf_internal1"
6321   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,To,f,*f,*d,*d,*d,*d,*R,*T")
6322         (match_operand:DF 1 "general_operand" "f,R,To,fG,fG,F,*d,*f,*d*G,*R,*T*F,*d,*d"))]
6323   "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
6324    && TARGET_DOUBLE_FLOAT
6325    && (register_operand (operands[0], DFmode)
6326        || register_operand (operands[1], DFmode)
6327        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6328        || operands[1] == CONST0_RTX (DFmode))"
6329   "* return mips_move_2words (operands, insn); "
6330   [(set_attr "type"     "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
6331    (set_attr "mode"     "DF")
6332    (set_attr "length"   "4,8,16,8,16,16,8,8,8,8,16,8,16")])
6334 (define_insn "movdf_internal1a"
6335   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,*d,*d,*d,*To,*R,*d")
6336         (match_operand:DF 1 "general_operand"      " f,To,f,G,f,G,*F,*To,*R,*d,*d,*d"))]
6337   "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
6338    && TARGET_DOUBLE_FLOAT
6339    && (register_operand (operands[0], DFmode)
6340        || register_operand (operands[1], DFmode)
6341        || (GET_CODE (operands [0]) == MEM
6342            && ((GET_CODE (operands[1]) == CONST_INT
6343                 && INTVAL (operands[1]) == 0)
6344                || operands[1] == CONST0_RTX (DFmode))))"
6345   "* return mips_move_2words (operands, insn); "
6346   [(set_attr "type"     "move,load,store,store,store,store,load,load,load,store,store,move")
6347    (set_attr "mode"     "DF")
6348    (set_attr "length"   "4,8,4,4,8,8,8,8,4,8,4,4")])
6350 (define_insn "movdf_internal2"
6351   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To,d,f,f")
6352         (match_operand:DF 1 "general_operand" "dG,R,ToF,d,d,f,d,f"))]
6353   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
6354    && (register_operand (operands[0], DFmode)
6355        || register_operand (operands[1], DFmode)
6356        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6357        || operands[1] == CONST0_RTX (DFmode))"
6358   "* return mips_move_2words (operands, insn); "
6359   [(set_attr "type"     "move,load,load,store,store,xfer,load,move")
6360    (set_attr "mode"     "DF")
6361    (set_attr "length"   "8,8,16,8,16,8,8,4")])
6363 (define_insn ""
6364   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
6365         (match_operand:DF 1 "general_operand" "d,d,y,R,ToF,d,d"))]
6366   "TARGET_MIPS16
6367    && (register_operand (operands[0], DFmode)
6368        || register_operand (operands[1], DFmode))"
6369   "* return mips_move_2words (operands, insn);"
6370   [(set_attr "type"     "move,move,move,load,load,store,store")
6371    (set_attr "mode"     "DF")
6372    (set_attr "length"   "8,8,8,8,16,8,16")])
6374 (define_split
6375   [(set (match_operand:DF 0 "register_operand" "")
6376         (match_operand:DF 1 "register_operand" ""))]
6377   "reload_completed && !TARGET_64BIT
6378    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6379    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6380    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
6381   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
6382    (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
6383   "")
6385 ;; Instructions to load the global pointer register.
6386 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
6387 ;; uses in front of it.  All symbol_refs implicitly use the gp reg.
6389 (define_insn "loadgp"
6390   [(set (reg:DI 28)
6391         (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
6392                              (match_operand:DI 1 "register_operand" "")]
6393                             UNSPEC_LOADGP))
6394    (clobber (reg:DI 1))]
6395   ""
6396   "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
6397   [(set_attr "type"     "move")
6398    (set_attr "mode"     "DI")
6399    (set_attr "length"   "12")])
6401 ;; Block moves, see mips.c for more details.
6402 ;; Argument 0 is the destination
6403 ;; Argument 1 is the source
6404 ;; Argument 2 is the length
6405 ;; Argument 3 is the alignment
6407 (define_expand "movstrsi"
6408   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6409                    (match_operand:BLK 1 "general_operand" ""))
6410               (use (match_operand:SI 2 "arith32_operand" ""))
6411               (use (match_operand:SI 3 "immediate_operand" ""))])]
6412   "!TARGET_MIPS16"
6413   "
6415   if (operands[0])              /* avoid unused code messages */
6416     {
6417       expand_block_move (operands);
6418       DONE;
6419     }
6422 ;; Insn generated by block moves
6424 (define_insn "movstrsi_internal"
6425   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6426         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6427    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6428    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6429    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6430    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6431    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6432    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6433    (use (const_int 0))]                                 ;; normal block move
6434   ""
6435   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6436   [(set_attr "type"     "store")
6437    (set_attr "mode"     "none")
6438    (set_attr "length"   "80")])
6440 ;; We need mips16 versions, because an offset from the stack pointer
6441 ;; is not offsettable, since the stack pointer can only handle 4 and 8
6442 ;; byte loads.
6444 (define_insn ""
6445   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6446         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6447    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6448    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6449    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6450    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6451    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6452    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6453    (use (const_int 0))]                                 ;; normal block move
6454   "TARGET_MIPS16"
6455   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6456   [(set_attr "type"     "multi")
6457    (set_attr "mode"     "none")
6458    (set_attr "length"   "80")])
6460 ;; Split a block move into 2 parts, the first part is everything
6461 ;; except for the last move, and the second part is just the last
6462 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
6463 ;; fill a delay slot.  This also prevents a bug in delayed branches
6464 ;; from showing up, which reuses one of the registers in our clobbers.
6466 (define_split
6467   [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6468         (mem:BLK (match_operand:SI 1 "register_operand" "")))
6469    (clobber (match_operand:SI 4 "register_operand" ""))
6470    (clobber (match_operand:SI 5 "register_operand" ""))
6471    (clobber (match_operand:SI 6 "register_operand" ""))
6472    (clobber (match_operand:SI 7 "register_operand" ""))
6473    (use (match_operand:SI 2 "small_int" ""))
6474    (use (match_operand:SI 3 "small_int" ""))
6475    (use (const_int 0))]
6477   "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
6479   ;; All but the last move
6480   [(parallel [(set (mem:BLK (match_dup 0))
6481                    (mem:BLK (match_dup 1)))
6482               (clobber (match_dup 4))
6483               (clobber (match_dup 5))
6484               (clobber (match_dup 6))
6485               (clobber (match_dup 7))
6486               (use (match_dup 2))
6487               (use (match_dup 3))
6488               (use (const_int 1))])
6490    ;; The last store, so it can fill a delay slot
6491    (parallel [(set (mem:BLK (match_dup 0))
6492                    (mem:BLK (match_dup 1)))
6493               (clobber (match_dup 4))
6494               (clobber (match_dup 5))
6495               (clobber (match_dup 6))
6496               (clobber (match_dup 7))
6497               (use (match_dup 2))
6498               (use (match_dup 3))
6499               (use (const_int 2))])]
6501   "")
6503 (define_insn "movstrsi_internal2"
6504   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6505         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6506    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6507    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6508    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6509    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6510    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6511    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6512    (use (const_int 1))]                                 ;; all but last store
6513   ""
6514   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6515   [(set_attr "type"     "store")
6516    (set_attr "mode"     "none")
6517    (set_attr "length"   "80")])
6519 (define_insn ""
6520   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6521         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6522    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6523    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6524    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6525    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6526    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6527    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6528    (use (const_int 1))]                                 ;; all but last store
6529   "TARGET_MIPS16"
6530   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6531   [(set_attr "type"     "multi")
6532    (set_attr "mode"     "none")
6533    (set_attr "length"   "80")])
6535 (define_insn "movstrsi_internal3"
6536   [(set (match_operand:BLK 0 "memory_operand" "=Ro")    ;; destination
6537         (match_operand:BLK 1 "memory_operand" "Ro"))    ;; source
6538    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6539    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6540    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6541    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6542    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6543    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6544    (use (const_int 2))]                                 ;; just last store of block move
6545   ""
6546   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6547   [(set_attr "type"     "store")
6548    (set_attr "mode"     "none")])
6551 ;;  ....................
6553 ;;      SHIFTS
6555 ;;  ....................
6557 ;; Many of these instructions uses trivial define_expands, because we
6558 ;; want to use a different set of constraints when TARGET_MIPS16.
6560 (define_expand "ashlsi3"
6561   [(set (match_operand:SI 0 "register_operand" "=d")
6562         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6563                    (match_operand:SI 2 "arith_operand" "dI")))]
6564   ""
6565   "
6567   /* On the mips16, a shift of more than 8 is a four byte instruction,
6568      so, for a shift between 8 and 16, it is just as fast to do two
6569      shifts of 8 or less.  If there is a lot of shifting going on, we
6570      may win in CSE.  Otherwise combine will put the shifts back
6571      together again.  This can be called by function_arg, so we must
6572      be careful not to allocate a new register if we've reached the
6573      reload pass.  */
6574   if (TARGET_MIPS16
6575       && optimize
6576       && GET_CODE (operands[2]) == CONST_INT
6577       && INTVAL (operands[2]) > 8
6578       && INTVAL (operands[2]) <= 16
6579       && ! reload_in_progress
6580       && ! reload_completed)
6581     {
6582       rtx temp = gen_reg_rtx (SImode);
6584       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6585       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6586                                         GEN_INT (INTVAL (operands[2]) - 8)));
6587       DONE;
6588     }
6591 (define_insn "ashlsi3_internal1"
6592   [(set (match_operand:SI 0 "register_operand" "=d")
6593         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6594                    (match_operand:SI 2 "arith_operand" "dI")))]
6595   "!TARGET_MIPS16"
6596   "*
6598   if (GET_CODE (operands[2]) == CONST_INT)
6599     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6601   return \"sll\\t%0,%1,%2\";
6603   [(set_attr "type"     "arith")
6604    (set_attr "mode"     "SI")])
6606 (define_insn "ashlsi3_internal2"
6607   [(set (match_operand:SI 0 "register_operand" "=d,d")
6608         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6609                    (match_operand:SI 2 "arith_operand" "d,I")))]
6610   "TARGET_MIPS16"
6611   "*
6613   if (which_alternative == 0)
6614     return \"sll\\t%0,%2\";
6616   if (GET_CODE (operands[2]) == CONST_INT)
6617     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6619   return \"sll\\t%0,%1,%2\";
6621   [(set_attr "type"     "arith")
6622    (set_attr "mode"     "SI")
6623    (set_attr_alternative "length"
6624                 [(const_int 4)
6625                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6626                                (const_int 4)
6627                                (const_int 8))])])
6629 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6631 (define_split
6632   [(set (match_operand:SI 0 "register_operand" "")
6633         (ashift:SI (match_operand:SI 1 "register_operand" "")
6634                    (match_operand:SI 2 "const_int_operand" "")))]
6635   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6636    && GET_CODE (operands[2]) == CONST_INT
6637    && INTVAL (operands[2]) > 8
6638    && INTVAL (operands[2]) <= 16"
6639   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6640    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6643   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6646 (define_expand "ashldi3"
6647   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6648                    (ashift:DI (match_operand:DI 1 "se_register_operand" "")
6649                               (match_operand:SI 2 "arith_operand" "")))
6650               (clobber (match_dup  3))])]
6651   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6652   "
6654   if (TARGET_64BIT)
6655     {
6656       /* On the mips16, a shift of more than 8 is a four byte
6657          instruction, so, for a shift between 8 and 16, it is just as
6658          fast to do two shifts of 8 or less.  If there is a lot of
6659          shifting going on, we may win in CSE.  Otherwise combine will
6660          put the shifts back together again.  This can be called by
6661          function_arg, so we must be careful not to allocate a new
6662          register if we've reached the reload pass.  */
6663       if (TARGET_MIPS16
6664           && optimize
6665           && GET_CODE (operands[2]) == CONST_INT
6666           && INTVAL (operands[2]) > 8
6667           && INTVAL (operands[2]) <= 16
6668           && ! reload_in_progress
6669           && ! reload_completed)
6670         {
6671           rtx temp = gen_reg_rtx (DImode);
6673           emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6674           emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6675                                             GEN_INT (INTVAL (operands[2]) - 8)));
6676           DONE;
6677         }
6679       emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6680                                         operands[2]));
6681       DONE;
6682     }
6684   operands[3] = gen_reg_rtx (SImode);
6688 (define_insn "ashldi3_internal"
6689   [(set (match_operand:DI 0 "register_operand" "=&d")
6690         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6691                    (match_operand:SI 2 "register_operand" "d")))
6692    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6693   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6694   "*
6696   operands[4] = const0_rtx;
6697   dslots_jump_total += 3;
6698   dslots_jump_filled += 2;
6700   return \"sll\\t%3,%2,26\\n\\
6701 \\tbgez\\t%3,1f\\n\\
6702 \\tsll\\t%M0,%L1,%2\\n\\
6703 \\t%(b\\t3f\\n\\
6704 \\tmove\\t%L0,%z4%)\\n\\
6705 \\n\\
6706 %~1:\\n\\
6707 \\t%(beq\\t%3,%z4,2f\\n\\
6708 \\tsll\\t%M0,%M1,%2%)\\n\\
6709 \\n\\
6710 \\tsubu\\t%3,%z4,%2\\n\\
6711 \\tsrl\\t%3,%L1,%3\\n\\
6712 \\tor\\t%M0,%M0,%3\\n\\
6713 %~2:\\n\\
6714 \\tsll\\t%L0,%L1,%2\\n\\
6715 %~3:\";
6717   [(set_attr "type"     "darith")
6718    (set_attr "mode"     "SI")
6719    (set_attr "length"   "48")])
6722 (define_insn "ashldi3_internal2"
6723   [(set (match_operand:DI 0 "register_operand" "=d")
6724         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6725                    (match_operand:SI 2 "small_int" "IJK")))
6726    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6727   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6728    && (INTVAL (operands[2]) & 32) != 0"
6729   "*
6731   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6732   operands[4] = const0_rtx;
6733   return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6735   [(set_attr "type"     "darith")
6736    (set_attr "mode"     "DI")
6737    (set_attr "length"   "8")])
6740 (define_split
6741   [(set (match_operand:DI 0 "register_operand" "")
6742         (ashift:DI (match_operand:DI 1 "register_operand" "")
6743                    (match_operand:SI 2 "small_int" "")))
6744    (clobber (match_operand:SI 3 "register_operand" ""))]
6745   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6746    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6747    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6748    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6749    && (INTVAL (operands[2]) & 32) != 0"
6751   [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6752    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6754   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6757 (define_split
6758   [(set (match_operand:DI 0 "register_operand" "")
6759         (ashift:DI (match_operand:DI 1 "register_operand" "")
6760                    (match_operand:SI 2 "small_int" "")))
6761    (clobber (match_operand:SI 3 "register_operand" ""))]
6762   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6763    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6764    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6765    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6766    && (INTVAL (operands[2]) & 32) != 0"
6768   [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6769    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
6771   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6774 (define_insn "ashldi3_internal3"
6775   [(set (match_operand:DI 0 "register_operand" "=d")
6776         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6777                    (match_operand:SI 2 "small_int" "IJK")))
6778    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6779   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6780    && (INTVAL (operands[2]) & 63) < 32
6781    && (INTVAL (operands[2]) & 63) != 0"
6782   "*
6784   int amount = INTVAL (operands[2]);
6786   operands[2] = GEN_INT (amount & 31);
6787   operands[4] = const0_rtx;
6788   operands[5] = GEN_INT ((-amount) & 31);
6790   return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6792   [(set_attr "type"     "darith")
6793    (set_attr "mode"     "DI")
6794    (set_attr "length"   "16")])
6797 (define_split
6798   [(set (match_operand:DI 0 "register_operand" "")
6799         (ashift:DI (match_operand:DI 1 "register_operand" "")
6800                    (match_operand:SI 2 "small_int" "")))
6801    (clobber (match_operand:SI 3 "register_operand" ""))]
6802   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6803    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6804    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6805    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6806    && (INTVAL (operands[2]) & 63) < 32
6807    && (INTVAL (operands[2]) & 63) != 0"
6809   [(set (subreg:SI (match_dup 0) 4)
6810         (ashift:SI (subreg:SI (match_dup 1) 4)
6811                    (match_dup 2)))
6813    (set (match_dup 3)
6814         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6815                      (match_dup 4)))
6817    (set (subreg:SI (match_dup 0) 4)
6818         (ior:SI (subreg:SI (match_dup 0) 4)
6819                 (match_dup 3)))
6821    (set (subreg:SI (match_dup 0) 0)
6822         (ashift:SI (subreg:SI (match_dup 1) 0)
6823                    (match_dup 2)))]
6824   "
6826   int amount = INTVAL (operands[2]);
6827   operands[2] = GEN_INT (amount & 31);
6828   operands[4] = GEN_INT ((-amount) & 31);
6832 (define_split
6833   [(set (match_operand:DI 0 "register_operand" "")
6834         (ashift:DI (match_operand:DI 1 "register_operand" "")
6835                    (match_operand:SI 2 "small_int" "")))
6836    (clobber (match_operand:SI 3 "register_operand" ""))]
6837   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6838    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6839    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6840    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6841    && (INTVAL (operands[2]) & 63) < 32
6842    && (INTVAL (operands[2]) & 63) != 0"
6844   [(set (subreg:SI (match_dup 0) 0)
6845         (ashift:SI (subreg:SI (match_dup 1) 0)
6846                    (match_dup 2)))
6848    (set (match_dup 3)
6849         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6850                      (match_dup 4)))
6852    (set (subreg:SI (match_dup 0) 0)
6853         (ior:SI (subreg:SI (match_dup 0) 0)
6854                 (match_dup 3)))
6856    (set (subreg:SI (match_dup 0) 4)
6857         (ashift:SI (subreg:SI (match_dup 1) 4)
6858                    (match_dup 2)))]
6859   "
6861   int amount = INTVAL (operands[2]);
6862   operands[2] = GEN_INT (amount & 31);
6863   operands[4] = GEN_INT ((-amount) & 31);
6867 (define_insn "ashldi3_internal4"
6868   [(set (match_operand:DI 0 "register_operand" "=d")
6869         (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6870                    (match_operand:SI 2 "arith_operand" "dI")))]
6871   "TARGET_64BIT && !TARGET_MIPS16"
6872   "*
6874   if (GET_CODE (operands[2]) == CONST_INT)
6875     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6877   return \"dsll\\t%0,%1,%2\";
6879   [(set_attr "type"     "arith")
6880    (set_attr "mode"     "DI")])
6882 (define_insn ""
6883   [(set (match_operand:DI 0 "register_operand" "=d,d")
6884         (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
6885                    (match_operand:SI 2 "arith_operand" "d,I")))]
6886   "TARGET_64BIT && TARGET_MIPS16"
6887   "*
6889   if (which_alternative == 0)
6890     return \"dsll\\t%0,%2\";
6892   if (GET_CODE (operands[2]) == CONST_INT)
6893     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6895   return \"dsll\\t%0,%1,%2\";
6897   [(set_attr "type"     "arith")
6898    (set_attr "mode"     "DI")
6899    (set_attr_alternative "length"
6900                 [(const_int 4)
6901                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6902                                (const_int 4)
6903                                (const_int 8))])])
6906 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6908 (define_split
6909   [(set (match_operand:DI 0 "register_operand" "")
6910         (ashift:DI (match_operand:DI 1 "register_operand" "")
6911                    (match_operand:SI 2 "const_int_operand" "")))]
6912   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
6913    && reload_completed
6914    && GET_CODE (operands[2]) == CONST_INT
6915    && INTVAL (operands[2]) > 8
6916    && INTVAL (operands[2]) <= 16"
6917   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6918    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6921   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6924 (define_expand "ashrsi3"
6925   [(set (match_operand:SI 0 "register_operand" "=d")
6926         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6927                      (match_operand:SI 2 "arith_operand" "dI")))]
6928   ""
6929   "
6931   /* On the mips16, a shift of more than 8 is a four byte instruction,
6932      so, for a shift between 8 and 16, it is just as fast to do two
6933      shifts of 8 or less.  If there is a lot of shifting going on, we
6934      may win in CSE.  Otherwise combine will put the shifts back
6935      together again.  */
6936   if (TARGET_MIPS16
6937       && optimize
6938       && GET_CODE (operands[2]) == CONST_INT
6939       && INTVAL (operands[2]) > 8
6940       && INTVAL (operands[2]) <= 16)
6941     {
6942       rtx temp = gen_reg_rtx (SImode);
6944       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6945       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6946                                         GEN_INT (INTVAL (operands[2]) - 8)));
6947       DONE;
6948     }
6951 (define_insn "ashrsi3_internal1"
6952   [(set (match_operand:SI 0 "register_operand" "=d")
6953         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6954                      (match_operand:SI 2 "arith_operand" "dI")))]
6955   "!TARGET_MIPS16"
6956   "*
6958   if (GET_CODE (operands[2]) == CONST_INT)
6959     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6961   return \"sra\\t%0,%1,%2\";
6963   [(set_attr "type"     "arith")
6964    (set_attr "mode"     "SI")])
6966 (define_insn "ashrsi3_internal2"
6967   [(set (match_operand:SI 0 "register_operand" "=d,d")
6968         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6969                      (match_operand:SI 2 "arith_operand" "d,I")))]
6970   "TARGET_MIPS16"
6971   "*
6973   if (which_alternative == 0)
6974     return \"sra\\t%0,%2\";
6976   if (GET_CODE (operands[2]) == CONST_INT)
6977     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6979   return \"sra\\t%0,%1,%2\";
6981   [(set_attr "type"     "arith")
6982    (set_attr "mode"     "SI")
6983    (set_attr_alternative "length"
6984                 [(const_int 4)
6985                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6986                                (const_int 4)
6987                                (const_int 8))])])
6990 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6992 (define_split
6993   [(set (match_operand:SI 0 "register_operand" "")
6994         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6995                      (match_operand:SI 2 "const_int_operand" "")))]
6996   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6997    && GET_CODE (operands[2]) == CONST_INT
6998    && INTVAL (operands[2]) > 8
6999    && INTVAL (operands[2]) <= 16"
7000   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
7001    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
7004   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7007 (define_expand "ashrdi3"
7008   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7009                    (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7010                                 (match_operand:SI 2 "arith_operand" "")))
7011               (clobber (match_dup  3))])]
7012   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7013   "
7015   if (TARGET_64BIT)
7016     {
7017       /* On the mips16, a shift of more than 8 is a four byte
7018          instruction, so, for a shift between 8 and 16, it is just as
7019          fast to do two shifts of 8 or less.  If there is a lot of
7020          shifting going on, we may win in CSE.  Otherwise combine will
7021          put the shifts back together again.  */
7022       if (TARGET_MIPS16
7023           && optimize
7024           && GET_CODE (operands[2]) == CONST_INT
7025           && INTVAL (operands[2]) > 8
7026           && INTVAL (operands[2]) <= 16)
7027         {
7028           rtx temp = gen_reg_rtx (DImode);
7030           emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7031           emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
7032                                             GEN_INT (INTVAL (operands[2]) - 8)));
7033           DONE;
7034         }
7036       emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
7037                                         operands[2]));
7038       DONE;
7039     }
7041   operands[3] = gen_reg_rtx (SImode);
7045 (define_insn "ashrdi3_internal"
7046   [(set (match_operand:DI 0 "register_operand" "=&d")
7047         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7048                      (match_operand:SI 2 "register_operand" "d")))
7049    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7050   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7051   "*
7053   operands[4] = const0_rtx;
7054   dslots_jump_total += 3;
7055   dslots_jump_filled += 2;
7057   return \"sll\\t%3,%2,26\\n\\
7058 \\tbgez\\t%3,1f\\n\\
7059 \\tsra\\t%L0,%M1,%2\\n\\
7060 \\t%(b\\t3f\\n\\
7061 \\tsra\\t%M0,%M1,31%)\\n\\
7062 \\n\\
7063 %~1:\\n\\
7064 \\t%(beq\\t%3,%z4,2f\\n\\
7065 \\tsrl\\t%L0,%L1,%2%)\\n\\
7066 \\n\\
7067 \\tsubu\\t%3,%z4,%2\\n\\
7068 \\tsll\\t%3,%M1,%3\\n\\
7069 \\tor\\t%L0,%L0,%3\\n\\
7070 %~2:\\n\\
7071 \\tsra\\t%M0,%M1,%2\\n\\
7072 %~3:\";
7074   [(set_attr "type"     "darith")
7075    (set_attr "mode"     "DI")
7076    (set_attr "length"   "48")])
7079 (define_insn "ashrdi3_internal2"
7080   [(set (match_operand:DI 0 "register_operand" "=d")
7081         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7082                      (match_operand:SI 2 "small_int" "IJK")))
7083    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7084   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
7085   "*
7087   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7088   return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
7090   [(set_attr "type"     "darith")
7091    (set_attr "mode"     "DI")
7092    (set_attr "length"   "8")])
7095 (define_split
7096   [(set (match_operand:DI 0 "register_operand" "")
7097         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7098                      (match_operand:SI 2 "small_int" "")))
7099    (clobber (match_operand:SI 3 "register_operand" ""))]
7100   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7101    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7102    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7103    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7104    && (INTVAL (operands[2]) & 32) != 0"
7106   [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7107    (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
7109   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7112 (define_split
7113   [(set (match_operand:DI 0 "register_operand" "")
7114         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7115                      (match_operand:SI 2 "small_int" "")))
7116    (clobber (match_operand:SI 3 "register_operand" ""))]
7117   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7118    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7119    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7120    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7121    && (INTVAL (operands[2]) & 32) != 0"
7123   [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7124    (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
7126   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7129 (define_insn "ashrdi3_internal3"
7130   [(set (match_operand:DI 0 "register_operand" "=d")
7131         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7132                      (match_operand:SI 2 "small_int" "IJK")))
7133    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7134   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7135    && (INTVAL (operands[2]) & 63) < 32
7136    && (INTVAL (operands[2]) & 63) != 0"
7137   "*
7139   int amount = INTVAL (operands[2]);
7141   operands[2] = GEN_INT (amount & 31);
7142   operands[4] = GEN_INT ((-amount) & 31);
7144   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
7146   [(set_attr "type"     "darith")
7147    (set_attr "mode"     "DI")
7148    (set_attr "length"   "16")])
7151 (define_split
7152   [(set (match_operand:DI 0 "register_operand" "")
7153         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7154                      (match_operand:SI 2 "small_int" "")))
7155    (clobber (match_operand:SI 3 "register_operand" ""))]
7156   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7157    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7158    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7159    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7160    && (INTVAL (operands[2]) & 63) < 32
7161    && (INTVAL (operands[2]) & 63) != 0"
7163   [(set (subreg:SI (match_dup 0) 0)
7164         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7165                      (match_dup 2)))
7167    (set (match_dup 3)
7168         (ashift:SI (subreg:SI (match_dup 1) 4)
7169                    (match_dup 4)))
7171    (set (subreg:SI (match_dup 0) 0)
7172         (ior:SI (subreg:SI (match_dup 0) 0)
7173                 (match_dup 3)))
7175    (set (subreg:SI (match_dup 0) 4)
7176         (ashiftrt:SI (subreg:SI (match_dup 1) 4)
7177                      (match_dup 2)))]
7178   "
7180   int amount = INTVAL (operands[2]);
7181   operands[2] = GEN_INT (amount & 31);
7182   operands[4] = GEN_INT ((-amount) & 31);
7186 (define_split
7187   [(set (match_operand:DI 0 "register_operand" "")
7188         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7189                      (match_operand:SI 2 "small_int" "")))
7190    (clobber (match_operand:SI 3 "register_operand" ""))]
7191   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7192    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7193    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7194    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7195    && (INTVAL (operands[2]) & 63) < 32
7196    && (INTVAL (operands[2]) & 63) != 0"
7198   [(set (subreg:SI (match_dup 0) 4)
7199         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7200                      (match_dup 2)))
7202    (set (match_dup 3)
7203         (ashift:SI (subreg:SI (match_dup 1) 0)
7204                    (match_dup 4)))
7206    (set (subreg:SI (match_dup 0) 4)
7207         (ior:SI (subreg:SI (match_dup 0) 4)
7208                 (match_dup 3)))
7210    (set (subreg:SI (match_dup 0) 0)
7211         (ashiftrt:SI (subreg:SI (match_dup 1) 0)
7212                      (match_dup 2)))]
7213   "
7215   int amount = INTVAL (operands[2]);
7216   operands[2] = GEN_INT (amount & 31);
7217   operands[4] = GEN_INT ((-amount) & 31);
7221 (define_insn "ashrdi3_internal4"
7222   [(set (match_operand:DI 0 "register_operand" "=d")
7223         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7224                      (match_operand:SI 2 "arith_operand" "dI")))]
7225   "TARGET_64BIT && !TARGET_MIPS16"
7226   "*
7228   if (GET_CODE (operands[2]) == CONST_INT)
7229     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7231   return \"dsra\\t%0,%1,%2\";
7233   [(set_attr "type"     "arith")
7234    (set_attr "mode"     "DI")])
7236 (define_insn ""
7237   [(set (match_operand:DI 0 "register_operand" "=d,d")
7238         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7239                      (match_operand:SI 2 "arith_operand" "d,I")))]
7240   "TARGET_64BIT && TARGET_MIPS16"
7241   "*
7243   if (GET_CODE (operands[2]) == CONST_INT)
7244     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7246   return \"dsra\\t%0,%2\";
7248   [(set_attr "type"     "arith")
7249    (set_attr "mode"     "DI")
7250    (set_attr_alternative "length"
7251                 [(const_int 4)
7252                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7253                                (const_int 4)
7254                                (const_int 8))])])
7256 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7258 (define_split
7259   [(set (match_operand:DI 0 "register_operand" "")
7260         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7261                      (match_operand:SI 2 "const_int_operand" "")))]
7262   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
7263    && reload_completed
7264    && GET_CODE (operands[2]) == CONST_INT
7265    && INTVAL (operands[2]) > 8
7266    && INTVAL (operands[2]) <= 16"
7267   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7268    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7271   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7274 (define_expand "lshrsi3"
7275   [(set (match_operand:SI 0 "register_operand" "=d")
7276         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7277                      (match_operand:SI 2 "arith_operand" "dI")))]
7278   ""
7279   "
7281   /* On the mips16, a shift of more than 8 is a four byte instruction,
7282      so, for a shift between 8 and 16, it is just as fast to do two
7283      shifts of 8 or less.  If there is a lot of shifting going on, we
7284      may win in CSE.  Otherwise combine will put the shifts back
7285      together again.  */
7286   if (TARGET_MIPS16
7287       && optimize
7288       && GET_CODE (operands[2]) == CONST_INT
7289       && INTVAL (operands[2]) > 8
7290       && INTVAL (operands[2]) <= 16)
7291     {
7292       rtx temp = gen_reg_rtx (SImode);
7294       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7295       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7296                                         GEN_INT (INTVAL (operands[2]) - 8)));
7297       DONE;
7298     }
7301 (define_insn "lshrsi3_internal1"
7302   [(set (match_operand:SI 0 "register_operand" "=d")
7303         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7304                      (match_operand:SI 2 "arith_operand" "dI")))]
7305   "!TARGET_MIPS16"
7306   "*
7308   if (GET_CODE (operands[2]) == CONST_INT)
7309     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7311   return \"srl\\t%0,%1,%2\";
7313   [(set_attr "type"     "arith")
7314    (set_attr "mode"     "SI")])
7316 (define_insn "lshrsi3_internal2"
7317   [(set (match_operand:SI 0 "register_operand" "=d,d")
7318         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7319                      (match_operand:SI 2 "arith_operand" "d,I")))]
7320   "TARGET_MIPS16"
7321   "*
7323   if (which_alternative == 0)
7324     return \"srl\\t%0,%2\";
7326   if (GET_CODE (operands[2]) == CONST_INT)
7327     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7329   return \"srl\\t%0,%1,%2\";
7331   [(set_attr "type"     "arith")
7332    (set_attr "mode"     "SI")
7333    (set_attr_alternative "length"
7334                 [(const_int 4)
7335                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7336                                (const_int 4)
7337                                (const_int 8))])])
7340 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7342 (define_split
7343   [(set (match_operand:SI 0 "register_operand" "")
7344         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7345                      (match_operand:SI 2 "const_int_operand" "")))]
7346   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7347    && GET_CODE (operands[2]) == CONST_INT
7348    && INTVAL (operands[2]) > 8
7349    && INTVAL (operands[2]) <= 16"
7350   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7351    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7354   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7357 ;; If we load a byte on the mips16 as a bitfield, the resulting
7358 ;; sequence of instructions is too complicated for combine, because it
7359 ;; involves four instructions: a load, a shift, a constant load into a
7360 ;; register, and an and (the key problem here is that the mips16 does
7361 ;; not have and immediate).  We recognize a shift of a load in order
7362 ;; to make it simple enough for combine to understand.
7364 (define_insn ""
7365   [(set (match_operand:SI 0 "register_operand" "=d,d")
7366         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
7367                      (match_operand:SI 2 "immediate_operand" "I,I")))]
7368   "TARGET_MIPS16"
7369   "lw\\t%0,%1\;srl\\t%0,%2"
7370   [(set_attr "type"     "load")
7371    (set_attr "mode"     "SI")
7372    (set_attr_alternative "length"
7373                 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7374                                (const_int 8)
7375                                (const_int 12))
7376                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7377                                (const_int 12)
7378                                (const_int 16))])])
7380 (define_split
7381   [(set (match_operand:SI 0 "register_operand" "")
7382         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7383                      (match_operand:SI 2 "immediate_operand" "")))]
7384   "TARGET_MIPS16 && !TARGET_DEBUG_D_MODE"
7385   [(set (match_dup 0) (match_dup 1))
7386    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7387   "")
7389 (define_expand "lshrdi3"
7390   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7391                    (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7392                                 (match_operand:SI 2 "arith_operand" "")))
7393               (clobber (match_dup  3))])]
7394   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7395   "
7397   if (TARGET_64BIT)
7398     {
7399       /* On the mips16, a shift of more than 8 is a four byte
7400          instruction, so, for a shift between 8 and 16, it is just as
7401          fast to do two shifts of 8 or less.  If there is a lot of
7402          shifting going on, we may win in CSE.  Otherwise combine will
7403          put the shifts back together again.  */
7404       if (TARGET_MIPS16
7405           && optimize
7406           && GET_CODE (operands[2]) == CONST_INT
7407           && INTVAL (operands[2]) > 8
7408           && INTVAL (operands[2]) <= 16)
7409         {
7410           rtx temp = gen_reg_rtx (DImode);
7412           emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7413           emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7414                                             GEN_INT (INTVAL (operands[2]) - 8)));
7415           DONE;
7416         }
7418       emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7419                                         operands[2]));
7420       DONE;
7421     }
7423   operands[3] = gen_reg_rtx (SImode);
7427 (define_insn "lshrdi3_internal"
7428   [(set (match_operand:DI 0 "register_operand" "=&d")
7429         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7430                      (match_operand:SI 2 "register_operand" "d")))
7431    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7432   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7433   "*
7435   operands[4] = const0_rtx;
7436   dslots_jump_total += 3;
7437   dslots_jump_filled += 2;
7439   return \"sll\\t%3,%2,26\\n\\
7440 \\tbgez\\t%3,1f\\n\\
7441 \\tsrl\\t%L0,%M1,%2\\n\\
7442 \\t%(b\\t3f\\n\\
7443 \\tmove\\t%M0,%z4%)\\n\\
7444 \\n\\
7445 %~1:\\n\\
7446 \\t%(beq\\t%3,%z4,2f\\n\\
7447 \\tsrl\\t%L0,%L1,%2%)\\n\\
7448 \\n\\
7449 \\tsubu\\t%3,%z4,%2\\n\\
7450 \\tsll\\t%3,%M1,%3\\n\\
7451 \\tor\\t%L0,%L0,%3\\n\\
7452 %~2:\\n\\
7453 \\tsrl\\t%M0,%M1,%2\\n\\
7454 %~3:\";
7456   [(set_attr "type"     "darith")
7457    (set_attr "mode"     "DI")
7458    (set_attr "length"   "48")])
7461 (define_insn "lshrdi3_internal2"
7462   [(set (match_operand:DI 0 "register_operand" "=d")
7463         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7464                      (match_operand:SI 2 "small_int" "IJK")))
7465    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7466   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7467    && (INTVAL (operands[2]) & 32) != 0"
7468   "*
7470   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7471   operands[4] = const0_rtx;
7472   return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7474   [(set_attr "type"     "darith")
7475    (set_attr "mode"     "DI")
7476    (set_attr "length"   "8")])
7479 (define_split
7480   [(set (match_operand:DI 0 "register_operand" "")
7481         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7482                      (match_operand:SI 2 "small_int" "")))
7483    (clobber (match_operand:SI 3 "register_operand" ""))]
7484   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7485    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7486    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7487    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7488    && (INTVAL (operands[2]) & 32) != 0"
7490   [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7491    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
7493   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7496 (define_split
7497   [(set (match_operand:DI 0 "register_operand" "")
7498         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7499                      (match_operand:SI 2 "small_int" "")))
7500    (clobber (match_operand:SI 3 "register_operand" ""))]
7501   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7502    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7503    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7504    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7505    && (INTVAL (operands[2]) & 32) != 0"
7507   [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7508    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7510   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7513 (define_insn "lshrdi3_internal3"
7514   [(set (match_operand:DI 0 "register_operand" "=d")
7515         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7516                    (match_operand:SI 2 "small_int" "IJK")))
7517    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7518   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7519    && (INTVAL (operands[2]) & 63) < 32
7520    && (INTVAL (operands[2]) & 63) != 0"
7521   "*
7523   int amount = INTVAL (operands[2]);
7525   operands[2] = GEN_INT (amount & 31);
7526   operands[4] = GEN_INT ((-amount) & 31);
7528   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7530   [(set_attr "type"     "darith")
7531    (set_attr "mode"     "DI")
7532    (set_attr "length"   "16")])
7535 (define_split
7536   [(set (match_operand:DI 0 "register_operand" "")
7537         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7538                      (match_operand:SI 2 "small_int" "")))
7539    (clobber (match_operand:SI 3 "register_operand" ""))]
7540   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7541    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7542    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7543    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7544    && (INTVAL (operands[2]) & 63) < 32
7545    && (INTVAL (operands[2]) & 63) != 0"
7547   [(set (subreg:SI (match_dup 0) 0)
7548         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7549                      (match_dup 2)))
7551    (set (match_dup 3)
7552         (ashift:SI (subreg:SI (match_dup 1) 4)
7553                    (match_dup 4)))
7555    (set (subreg:SI (match_dup 0) 0)
7556         (ior:SI (subreg:SI (match_dup 0) 0)
7557                 (match_dup 3)))
7559    (set (subreg:SI (match_dup 0) 4)
7560         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7561                      (match_dup 2)))]
7562   "
7564   int amount = INTVAL (operands[2]);
7565   operands[2] = GEN_INT (amount & 31);
7566   operands[4] = GEN_INT ((-amount) & 31);
7570 (define_split
7571   [(set (match_operand:DI 0 "register_operand" "")
7572         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7573                      (match_operand:SI 2 "small_int" "")))
7574    (clobber (match_operand:SI 3 "register_operand" ""))]
7575   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7576    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7577    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7578    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7579    && (INTVAL (operands[2]) & 63) < 32
7580    && (INTVAL (operands[2]) & 63) != 0"
7582   [(set (subreg:SI (match_dup 0) 4)
7583         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7584                      (match_dup 2)))
7586    (set (match_dup 3)
7587         (ashift:SI (subreg:SI (match_dup 1) 0)
7588                    (match_dup 4)))
7590    (set (subreg:SI (match_dup 0) 4)
7591         (ior:SI (subreg:SI (match_dup 0) 4)
7592                 (match_dup 3)))
7594    (set (subreg:SI (match_dup 0) 0)
7595         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7596                      (match_dup 2)))]
7597   "
7599   int amount = INTVAL (operands[2]);
7600   operands[2] = GEN_INT (amount & 31);
7601   operands[4] = GEN_INT ((-amount) & 31);
7605 (define_insn "lshrdi3_internal4"
7606   [(set (match_operand:DI 0 "register_operand" "=d")
7607         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7608                      (match_operand:SI 2 "arith_operand" "dI")))]
7609   "TARGET_64BIT && !TARGET_MIPS16"
7610   "*
7612   if (GET_CODE (operands[2]) == CONST_INT)
7613     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7615   return \"dsrl\\t%0,%1,%2\";
7617   [(set_attr "type"     "arith")
7618    (set_attr "mode"     "DI")])
7620 (define_insn ""
7621   [(set (match_operand:DI 0 "register_operand" "=d,d")
7622         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7623                      (match_operand:SI 2 "arith_operand" "d,I")))]
7624   "TARGET_64BIT && TARGET_MIPS16"
7625   "*
7627   if (GET_CODE (operands[2]) == CONST_INT)
7628     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7630   return \"dsrl\\t%0,%2\";
7632   [(set_attr "type"     "arith")
7633    (set_attr "mode"     "DI")
7634    (set_attr_alternative "length"
7635                 [(const_int 4)
7636                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7637                                (const_int 4)
7638                                (const_int 8))])])
7640 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7642 (define_split
7643   [(set (match_operand:DI 0 "register_operand" "")
7644         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7645                      (match_operand:SI 2 "const_int_operand" "")))]
7646   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7647    && GET_CODE (operands[2]) == CONST_INT
7648    && INTVAL (operands[2]) > 8
7649    && INTVAL (operands[2]) <= 16"
7650   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7651    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7654   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7659 ;;  ....................
7661 ;;      COMPARISONS
7663 ;;  ....................
7665 ;; Flow here is rather complex:
7667 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the
7668 ;;      arguments into the branch_cmp array, and the type into
7669 ;;      branch_type.  No RTL is generated.
7671 ;;  2)  The appropriate branch define_expand is called, which then
7672 ;;      creates the appropriate RTL for the comparison and branch.
7673 ;;      Different CC modes are used, based on what type of branch is
7674 ;;      done, so that we can constrain things appropriately.  There
7675 ;;      are assumptions in the rest of GCC that break if we fold the
7676 ;;      operands into the branchs for integer operations, and use cc0
7677 ;;      for floating point, so we use the fp status register instead.
7678 ;;      If needed, an appropriate temporary is created to hold the
7679 ;;      of the integer compare.
7681 (define_expand "cmpsi"
7682   [(set (cc0)
7683         (compare:CC (match_operand:SI 0 "register_operand" "")
7684                     (match_operand:SI 1 "arith_operand" "")))]
7685   ""
7686   "
7688   if (operands[0])              /* avoid unused code message */
7689     {
7690       branch_cmp[0] = operands[0];
7691       branch_cmp[1] = operands[1];
7692       branch_type = CMP_SI;
7693       DONE;
7694     }
7697 (define_expand "tstsi"
7698   [(set (cc0)
7699         (match_operand:SI 0 "register_operand" ""))]
7700   ""
7701   "
7703   if (operands[0])              /* avoid unused code message */
7704     {
7705       branch_cmp[0] = operands[0];
7706       branch_cmp[1] = const0_rtx;
7707       branch_type = CMP_SI;
7708       DONE;
7709     }
7712 (define_expand "cmpdi"
7713   [(set (cc0)
7714         (compare:CC (match_operand:DI 0 "se_register_operand" "")
7715                     (match_operand:DI 1 "se_arith_operand" "")))]
7716   "TARGET_64BIT"
7717   "
7719   if (operands[0])              /* avoid unused code message */
7720     {
7721       branch_cmp[0] = operands[0];
7722       branch_cmp[1] = operands[1];
7723       branch_type = CMP_DI;
7724       DONE;
7725     }
7728 (define_expand "tstdi"
7729   [(set (cc0)
7730         (match_operand:DI 0 "se_register_operand" ""))]
7731   "TARGET_64BIT"
7732   "
7734   if (operands[0])              /* avoid unused code message */
7735     {
7736       branch_cmp[0] = operands[0];
7737       branch_cmp[1] = const0_rtx;
7738       branch_type = CMP_DI;
7739       DONE;
7740     }
7743 (define_expand "cmpdf"
7744   [(set (cc0)
7745         (compare:CC (match_operand:DF 0 "register_operand" "")
7746                     (match_operand:DF 1 "register_operand" "")))]
7747   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7748   "
7750   if (operands[0])              /* avoid unused code message */
7751     {
7752       branch_cmp[0] = operands[0];
7753       branch_cmp[1] = operands[1];
7754       branch_type = CMP_DF;
7755       DONE;
7756     }
7759 (define_expand "cmpsf"
7760   [(set (cc0)
7761         (compare:CC (match_operand:SF 0 "register_operand" "")
7762                     (match_operand:SF 1 "register_operand" "")))]
7763   "TARGET_HARD_FLOAT"
7764   "
7766   if (operands[0])              /* avoid unused code message */
7767     {
7768       branch_cmp[0] = operands[0];
7769       branch_cmp[1] = operands[1];
7770       branch_type = CMP_SF;
7771       DONE;
7772     }
7777 ;;  ....................
7779 ;;      CONDITIONAL BRANCHES
7781 ;;  ....................
7783 ;; Conditional branches on floating-point equality tests.
7785 (define_insn "branch_fp"
7786   [(set (pc)
7787         (if_then_else
7788          (match_operator:CC 0 "cmp_op"
7789                             [(match_operand:CC 2 "register_operand" "z")
7790                              (const_int 0)])
7791          (label_ref (match_operand 1 "" ""))
7792          (pc)))]
7793   "TARGET_HARD_FLOAT"
7794   "*
7796   return mips_output_conditional_branch (insn,
7797                                          operands,
7798                                          /*two_operands_p=*/0,
7799                                          /*float_p=*/1,
7800                                          /*inverted_p=*/0,
7801                                          get_attr_length (insn));
7803   [(set_attr "type"     "branch")
7804    (set_attr "mode"     "none")])
7806 (define_insn "branch_fp_inverted"
7807   [(set (pc)
7808         (if_then_else
7809          (match_operator:CC 0 "cmp_op"
7810                             [(match_operand:CC 2 "register_operand" "z")
7811                              (const_int 0)])
7812          (pc)
7813          (label_ref (match_operand 1 "" ""))))]
7814   "TARGET_HARD_FLOAT"
7815   "*
7817   return mips_output_conditional_branch (insn,
7818                                          operands,
7819                                          /*two_operands_p=*/0,
7820                                          /*float_p=*/1,
7821                                          /*inverted_p=*/1,
7822                                          get_attr_length (insn));
7824   [(set_attr "type"     "branch")
7825    (set_attr "mode"     "none")])
7827 ;; Conditional branches on comparisons with zero.
7829 (define_insn "branch_zero"
7830   [(set (pc)
7831         (if_then_else
7832          (match_operator:SI 0 "cmp_op"
7833                             [(match_operand:SI 2 "register_operand" "d")
7834                              (const_int 0)])
7835         (label_ref (match_operand 1 "" ""))
7836         (pc)))]
7837   "!TARGET_MIPS16"
7838   "*
7840   return mips_output_conditional_branch (insn,
7841                                          operands,
7842                                          /*two_operands_p=*/0,
7843                                          /*float_p=*/0,
7844                                          /*inverted_p=*/0,
7845                                          get_attr_length (insn));
7847   [(set_attr "type"     "branch")
7848    (set_attr "mode"     "none")])
7850 (define_insn "branch_zero_inverted"
7851   [(set (pc)
7852         (if_then_else
7853          (match_operator:SI 0 "cmp_op"
7854                             [(match_operand:SI 2 "register_operand" "d")
7855                              (const_int 0)])
7856         (pc)
7857         (label_ref (match_operand 1 "" ""))))]
7858   "!TARGET_MIPS16"
7859   "*
7861   return mips_output_conditional_branch (insn,
7862                                          operands,
7863                                          /*two_operands_p=*/0,
7864                                          /*float_p=*/0,
7865                                          /*inverted_p=*/1,
7866                                          get_attr_length (insn));
7868   [(set_attr "type"     "branch")
7869    (set_attr "mode"     "none")])
7871 (define_insn "branch_zero_di"
7872   [(set (pc)
7873         (if_then_else
7874          (match_operator:DI 0 "cmp_op"
7875                             [(match_operand:DI 2 "se_register_operand" "d")
7876                              (const_int 0)])
7877         (label_ref (match_operand 1 "" ""))
7878         (pc)))]
7879   "!TARGET_MIPS16"
7880   "*
7882   return mips_output_conditional_branch (insn,
7883                                          operands,
7884                                          /*two_operands_p=*/0,
7885                                          /*float_p=*/0,
7886                                          /*inverted_p=*/0,
7887                                          get_attr_length (insn));
7889   [(set_attr "type"     "branch")
7890    (set_attr "mode"     "none")])
7892 (define_insn "branch_zero_di_inverted"
7893   [(set (pc)
7894         (if_then_else
7895          (match_operator:DI 0 "cmp_op"
7896                             [(match_operand:DI 2 "se_register_operand" "d")
7897                              (const_int 0)])
7898         (pc)
7899         (label_ref (match_operand 1 "" ""))))]
7900   "!TARGET_MIPS16"
7901   "*
7903   return mips_output_conditional_branch (insn,
7904                                          operands,
7905                                          /*two_operands_p=*/0,
7906                                          /*float_p=*/0,
7907                                          /*inverted_p=*/1,
7908                                          get_attr_length (insn));
7910   [(set_attr "type"     "branch")
7911    (set_attr "mode"     "none")])
7913 ;; Conditional branch on equality comparision.
7915 (define_insn "branch_equality"
7916   [(set (pc)
7917         (if_then_else
7918          (match_operator:SI 0 "equality_op"
7919                             [(match_operand:SI 2 "register_operand" "d")
7920                              (match_operand:SI 3 "register_operand" "d")])
7921          (label_ref (match_operand 1 "" ""))
7922          (pc)))]
7923   "!TARGET_MIPS16"
7924   "*
7926   return mips_output_conditional_branch (insn,
7927                                          operands,
7928                                          /*two_operands_p=*/1,
7929                                          /*float_p=*/0,
7930                                          /*inverted_p=*/0,
7931                                          get_attr_length (insn));
7933   [(set_attr "type"     "branch")
7934    (set_attr "mode"     "none")])
7936 (define_insn "branch_equality_di"
7937   [(set (pc)
7938         (if_then_else
7939          (match_operator:DI 0 "equality_op"
7940                             [(match_operand:DI 2 "se_register_operand" "d")
7941                              (match_operand:DI 3 "se_register_operand" "d")])
7942         (label_ref (match_operand 1 "" ""))
7943         (pc)))]
7944   "!TARGET_MIPS16"
7945   "*
7947   return mips_output_conditional_branch (insn,
7948                                          operands,
7949                                          /*two_operands_p=*/1,
7950                                          /*float_p=*/0,
7951                                          /*inverted_p=*/0,
7952                                          get_attr_length (insn));
7954   [(set_attr "type"     "branch")
7955    (set_attr "mode"     "none")])
7957 (define_insn "branch_equality_inverted"
7958   [(set (pc)
7959         (if_then_else
7960          (match_operator:SI 0 "equality_op"
7961                             [(match_operand:SI 2 "register_operand" "d")
7962                              (match_operand:SI 3 "register_operand" "d")])
7963          (pc)
7964          (label_ref (match_operand 1 "" ""))))]
7965   "!TARGET_MIPS16"
7966   "*
7968   return mips_output_conditional_branch (insn,
7969                                          operands,
7970                                          /*two_operands_p=*/1,
7971                                          /*float_p=*/0,
7972                                          /*inverted_p=*/1,
7973                                          get_attr_length (insn));
7975   [(set_attr "type"     "branch")
7976    (set_attr "mode"     "none")])
7978 (define_insn "branch_equality_di_inverted"
7979   [(set (pc)
7980         (if_then_else
7981          (match_operator:DI 0 "equality_op"
7982                             [(match_operand:DI 2 "se_register_operand" "d")
7983                              (match_operand:DI 3 "se_register_operand" "d")])
7984         (pc)
7985         (label_ref (match_operand 1 "" ""))))]
7986   "!TARGET_MIPS16"
7987   "*
7989   return mips_output_conditional_branch (insn,
7990                                          operands,
7991                                          /*two_operands_p=*/1,
7992                                          /*float_p=*/0,
7993                                          /*inverted_p=*/1,
7994                                          get_attr_length (insn));
7996   [(set_attr "type"     "branch")
7997    (set_attr "mode"     "none")])
7999 ;; MIPS16 branches
8001 (define_insn ""
8002   [(set (pc)
8003         (if_then_else (match_operator:SI 0 "equality_op"
8004                                          [(match_operand:SI 1 "register_operand" "d,t")
8005                                           (const_int 0)])
8006         (match_operand 2 "pc_or_label_operand" "")
8007         (match_operand 3 "pc_or_label_operand" "")))]
8008   "TARGET_MIPS16"
8009   "*
8011   if (operands[2] != pc_rtx)
8012     {
8013       if (which_alternative == 0)
8014         return \"%*b%C0z\\t%1,%2\";
8015       else
8016         return \"%*bt%C0z\\t%2\";
8017     }
8018   else
8019     {
8020       if (which_alternative == 0)
8021         return \"%*b%N0z\\t%1,%3\";
8022       else
8023         return \"%*bt%N0z\\t%3\";
8024     }
8026   [(set_attr "type"     "branch")
8027    (set_attr "mode"     "none")
8028    (set_attr "length"   "8")])
8030 (define_insn ""
8031   [(set (pc)
8032         (if_then_else (match_operator:DI 0 "equality_op"
8033                                          [(match_operand:DI 1 "se_register_operand" "d,t")
8034                                           (const_int 0)])
8035         (match_operand 2 "pc_or_label_operand" "")
8036         (match_operand 3 "pc_or_label_operand" "")))]
8037   "TARGET_MIPS16"
8038   "*
8040   if (operands[2] != pc_rtx)
8041     {
8042       if (which_alternative == 0)
8043         return \"%*b%C0z\\t%1,%2\";
8044       else
8045         return \"%*bt%C0z\\t%2\";
8046     }
8047   else
8048     {
8049       if (which_alternative == 0)
8050         return \"%*b%N0z\\t%1,%3\";
8051       else
8052         return \"%*bt%N0z\\t%3\";
8053     }
8055   [(set_attr "type"     "branch")
8056    (set_attr "mode"     "none")
8057    (set_attr "length"   "8")])
8059 (define_expand "beq"
8060   [(set (pc)
8061         (if_then_else (eq:CC (cc0)
8062                              (const_int 0))
8063                       (label_ref (match_operand 0 "" ""))
8064                       (pc)))]
8065   ""
8066   "
8068   if (operands[0])              /* avoid unused code warning */
8069     {
8070       gen_conditional_branch (operands, EQ);
8071       DONE;
8072     }
8075 (define_expand "bne"
8076   [(set (pc)
8077         (if_then_else (ne:CC (cc0)
8078                              (const_int 0))
8079                       (label_ref (match_operand 0 "" ""))
8080                       (pc)))]
8081   ""
8082   "
8084   if (operands[0])              /* avoid unused code warning */
8085     {
8086       gen_conditional_branch (operands, NE);
8087       DONE;
8088     }
8091 (define_expand "bgt"
8092   [(set (pc)
8093         (if_then_else (gt:CC (cc0)
8094                              (const_int 0))
8095                       (label_ref (match_operand 0 "" ""))
8096                       (pc)))]
8097   ""
8098   "
8100   if (operands[0])              /* avoid unused code warning */
8101     {
8102       gen_conditional_branch (operands, GT);
8103       DONE;
8104     }
8107 (define_expand "bge"
8108   [(set (pc)
8109         (if_then_else (ge:CC (cc0)
8110                              (const_int 0))
8111                       (label_ref (match_operand 0 "" ""))
8112                       (pc)))]
8113   ""
8114   "
8116   if (operands[0])              /* avoid unused code warning */
8117     {
8118       gen_conditional_branch (operands, GE);
8119       DONE;
8120     }
8123 (define_expand "blt"
8124   [(set (pc)
8125         (if_then_else (lt:CC (cc0)
8126                              (const_int 0))
8127                       (label_ref (match_operand 0 "" ""))
8128                       (pc)))]
8129   ""
8130   "
8132   if (operands[0])              /* avoid unused code warning */
8133     {
8134       gen_conditional_branch (operands, LT);
8135       DONE;
8136     }
8139 (define_expand "ble"
8140   [(set (pc)
8141         (if_then_else (le:CC (cc0)
8142                              (const_int 0))
8143                       (label_ref (match_operand 0 "" ""))
8144                       (pc)))]
8145   ""
8146   "
8148   if (operands[0])              /* avoid unused code warning */
8149     {
8150       gen_conditional_branch (operands, LE);
8151       DONE;
8152     }
8155 (define_expand "bgtu"
8156   [(set (pc)
8157         (if_then_else (gtu:CC (cc0)
8158                               (const_int 0))
8159                       (label_ref (match_operand 0 "" ""))
8160                       (pc)))]
8161   ""
8162   "
8164   if (operands[0])              /* avoid unused code warning */
8165     {
8166       gen_conditional_branch (operands, GTU);
8167       DONE;
8168     }
8171 (define_expand "bgeu"
8172   [(set (pc)
8173         (if_then_else (geu:CC (cc0)
8174                               (const_int 0))
8175                       (label_ref (match_operand 0 "" ""))
8176                       (pc)))]
8177   ""
8178   "
8180   if (operands[0])              /* avoid unused code warning */
8181     {
8182       gen_conditional_branch (operands, GEU);
8183       DONE;
8184     }
8188 (define_expand "bltu"
8189   [(set (pc)
8190         (if_then_else (ltu:CC (cc0)
8191                               (const_int 0))
8192                       (label_ref (match_operand 0 "" ""))
8193                       (pc)))]
8194   ""
8195   "
8197   if (operands[0])              /* avoid unused code warning */
8198     {
8199       gen_conditional_branch (operands, LTU);
8200       DONE;
8201     }
8204 (define_expand "bleu"
8205   [(set (pc)
8206         (if_then_else (leu:CC (cc0)
8207                               (const_int 0))
8208                       (label_ref (match_operand 0 "" ""))
8209                       (pc)))]
8210   ""
8211   "
8213   if (operands[0])              /* avoid unused code warning */
8214     {
8215       gen_conditional_branch (operands, LEU);
8216       DONE;
8217     }
8222 ;;  ....................
8224 ;;      SETTING A REGISTER FROM A COMPARISON
8226 ;;  ....................
8228 (define_expand "seq"
8229   [(set (match_operand:SI 0 "register_operand" "=d")
8230         (eq:SI (match_dup 1)
8231                (match_dup 2)))]
8232   ""
8233   "
8235   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8236     FAIL;
8238   /* set up operands from compare.  */
8239   operands[1] = branch_cmp[0];
8240   operands[2] = branch_cmp[1];
8242   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8243     {
8244       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8245       DONE;
8246     }
8248   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8249     operands[2] = force_reg (SImode, operands[2]);
8251   /* fall through and generate default code */
8255 (define_insn "seq_si_zero"
8256   [(set (match_operand:SI 0 "register_operand" "=d")
8257         (eq:SI (match_operand:SI 1 "register_operand" "d")
8258                (const_int 0)))]
8259   "!TARGET_MIPS16"
8260   "sltu\\t%0,%1,1"
8261   [(set_attr "type"     "arith")
8262    (set_attr "mode"     "SI")])
8264 (define_insn ""
8265   [(set (match_operand:SI 0 "register_operand" "=t")
8266         (eq:SI (match_operand:SI 1 "register_operand" "d")
8267                (const_int 0)))]
8268   "TARGET_MIPS16"
8269   "sltu\\t%1,1"
8270   [(set_attr "type"     "arith")
8271    (set_attr "mode"     "SI")])
8273 (define_insn "seq_di_zero"
8274   [(set (match_operand:DI 0 "register_operand" "=d")
8275         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8276                (const_int 0)))]
8277   "TARGET_64BIT && !TARGET_MIPS16"
8278   "sltu\\t%0,%1,1"
8279   [(set_attr "type"     "arith")
8280    (set_attr "mode"     "DI")])
8282 (define_insn ""
8283   [(set (match_operand:DI 0 "register_operand" "=t")
8284         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8285                (const_int 0)))]
8286   "TARGET_64BIT && TARGET_MIPS16"
8287   "sltu\\t%1,1"
8288   [(set_attr "type"     "arith")
8289    (set_attr "mode"     "DI")])
8291 (define_insn "seq_si"
8292   [(set (match_operand:SI 0 "register_operand" "=d,d")
8293         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8294                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8295   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8296   "@
8297    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8298    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8299   [(set_attr "type"     "arith")
8300    (set_attr "mode"     "SI")
8301    (set_attr "length"   "8")])
8303 (define_split
8304   [(set (match_operand:SI 0 "register_operand" "")
8305         (eq:SI (match_operand:SI 1 "register_operand" "")
8306                (match_operand:SI 2 "uns_arith_operand" "")))]
8307   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8308     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8309   [(set (match_dup 0)
8310         (xor:SI (match_dup 1)
8311                 (match_dup 2)))
8312    (set (match_dup 0)
8313         (ltu:SI (match_dup 0)
8314                 (const_int 1)))]
8315   "")
8317 (define_insn "seq_di"
8318   [(set (match_operand:DI 0 "register_operand" "=d,d")
8319         (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8320                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8321   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8322   "@
8323    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8324    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8325   [(set_attr "type"     "arith")
8326    (set_attr "mode"     "DI")
8327    (set_attr "length"   "8")])
8329 (define_split
8330   [(set (match_operand:DI 0 "register_operand" "")
8331         (eq:DI (match_operand:DI 1 "se_register_operand" "")
8332                (match_operand:DI 2 "se_uns_arith_operand" "")))]
8333   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8334     && !TARGET_MIPS16
8335     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8336   [(set (match_dup 0)
8337         (xor:DI (match_dup 1)
8338                 (match_dup 2)))
8339    (set (match_dup 0)
8340         (ltu:DI (match_dup 0)
8341                 (const_int 1)))]
8342   "")
8344 ;; On the mips16 the default code is better than using sltu.
8346 (define_expand "sne"
8347   [(set (match_operand:SI 0 "register_operand" "=d")
8348         (ne:SI (match_dup 1)
8349                (match_dup 2)))]
8350   "!TARGET_MIPS16"
8351   "
8353   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8354     FAIL;
8356   /* set up operands from compare.  */
8357   operands[1] = branch_cmp[0];
8358   operands[2] = branch_cmp[1];
8360   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
8361     {
8362       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8363       DONE;
8364     }
8366   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8367     operands[2] = force_reg (SImode, operands[2]);
8369   /* fall through and generate default code */
8372 (define_insn "sne_si_zero"
8373   [(set (match_operand:SI 0 "register_operand" "=d")
8374         (ne:SI (match_operand:SI 1 "register_operand" "d")
8375                (const_int 0)))]
8376   "!TARGET_MIPS16"
8377   "sltu\\t%0,%.,%1"
8378   [(set_attr "type"     "arith")
8379    (set_attr "mode"     "SI")])
8381 (define_insn "sne_di_zero"
8382   [(set (match_operand:DI 0 "register_operand" "=d")
8383         (ne:DI (match_operand:DI 1 "se_register_operand" "d")
8384                (const_int 0)))]
8385   "TARGET_64BIT && !TARGET_MIPS16"
8386   "sltu\\t%0,%.,%1"
8387   [(set_attr "type"     "arith")
8388    (set_attr "mode"     "DI")])
8390 (define_insn "sne_si"
8391   [(set (match_operand:SI 0 "register_operand" "=d,d")
8392         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8393                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8394   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8395   "@
8396     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8397     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8398   [(set_attr "type"     "arith")
8399    (set_attr "mode"     "SI")
8400    (set_attr "length"   "8")])
8402 (define_split
8403   [(set (match_operand:SI 0 "register_operand" "")
8404         (ne:SI (match_operand:SI 1 "register_operand" "")
8405                (match_operand:SI 2 "uns_arith_operand" "")))]
8406   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8407     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8408   [(set (match_dup 0)
8409         (xor:SI (match_dup 1)
8410                 (match_dup 2)))
8411    (set (match_dup 0)
8412         (gtu:SI (match_dup 0)
8413                 (const_int 0)))]
8414   "")
8416 (define_insn "sne_di"
8417   [(set (match_operand:DI 0 "register_operand" "=d,d")
8418         (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8419                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8420   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8421   "@
8422     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8423     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8424   [(set_attr "type"     "arith")
8425    (set_attr "mode"     "DI")
8426    (set_attr "length"   "8")])
8428 (define_split
8429   [(set (match_operand:DI 0 "register_operand" "")
8430         (ne:DI (match_operand:DI 1 "se_register_operand" "")
8431                (match_operand:DI 2 "se_uns_arith_operand" "")))]
8432   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8433     && !TARGET_MIPS16
8434     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8435   [(set (match_dup 0)
8436         (xor:DI (match_dup 1)
8437                 (match_dup 2)))
8438    (set (match_dup 0)
8439         (gtu:DI (match_dup 0)
8440                 (const_int 0)))]
8441   "")
8443 (define_expand "sgt"
8444   [(set (match_operand:SI 0 "register_operand" "=d")
8445         (gt:SI (match_dup 1)
8446                (match_dup 2)))]
8447   ""
8448   "
8450   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8451     FAIL;
8453   /* set up operands from compare.  */
8454   operands[1] = branch_cmp[0];
8455   operands[2] = branch_cmp[1];
8457   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8458     {
8459       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8460       DONE;
8461     }
8463   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8464     operands[2] = force_reg (SImode, operands[2]);
8466   /* fall through and generate default code */
8469 (define_insn "sgt_si"
8470   [(set (match_operand:SI 0 "register_operand" "=d")
8471         (gt:SI (match_operand:SI 1 "register_operand" "d")
8472                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8473   "!TARGET_MIPS16"
8474   "slt\\t%0,%z2,%1"
8475   [(set_attr "type"     "arith")
8476    (set_attr "mode"     "SI")])
8478 (define_insn ""
8479   [(set (match_operand:SI 0 "register_operand" "=t")
8480         (gt:SI (match_operand:SI 1 "register_operand" "d")
8481                (match_operand:SI 2 "register_operand" "d")))]
8482   "TARGET_MIPS16"
8483   "slt\\t%2,%1"
8484   [(set_attr "type"     "arith")
8485    (set_attr "mode"     "SI")])
8487 (define_insn "sgt_di"
8488   [(set (match_operand:DI 0 "register_operand" "=d")
8489         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8490                (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8491   "TARGET_64BIT && !TARGET_MIPS16"
8492   "slt\\t%0,%z2,%1"
8493   [(set_attr "type"     "arith")
8494    (set_attr "mode"     "DI")])
8496 (define_insn ""
8497   [(set (match_operand:DI 0 "register_operand" "=d")
8498         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8499                (match_operand:DI 2 "se_register_operand" "d")))]
8500   "TARGET_64BIT && TARGET_MIPS16"
8501   "slt\\t%2,%1"
8502   [(set_attr "type"     "arith")
8503    (set_attr "mode"     "DI")])
8505 (define_expand "sge"
8506   [(set (match_operand:SI 0 "register_operand" "=d")
8507         (ge:SI (match_dup 1)
8508                (match_dup 2)))]
8509   ""
8510   "
8512   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8513     FAIL;
8515   /* set up operands from compare.  */
8516   operands[1] = branch_cmp[0];
8517   operands[2] = branch_cmp[1];
8519   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8520     {
8521       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8522       DONE;
8523     }
8525   /* fall through and generate default code */
8528 (define_insn "sge_si"
8529   [(set (match_operand:SI 0 "register_operand" "=d")
8530         (ge:SI (match_operand:SI 1 "register_operand" "d")
8531                (match_operand:SI 2 "arith_operand" "dI")))]
8532   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8533   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8534   [(set_attr "type"     "arith")
8535    (set_attr "mode"     "SI")
8536    (set_attr "length"   "8")])
8538 (define_split
8539   [(set (match_operand:SI 0 "register_operand" "")
8540         (ge:SI (match_operand:SI 1 "register_operand" "")
8541                (match_operand:SI 2 "arith_operand" "")))]
8542   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8543   [(set (match_dup 0)
8544         (lt:SI (match_dup 1)
8545                (match_dup 2)))
8546    (set (match_dup 0)
8547         (xor:SI (match_dup 0)
8548                 (const_int 1)))]
8549   "")
8551 (define_insn "sge_di"
8552   [(set (match_operand:DI 0 "register_operand" "=d")
8553         (ge:DI (match_operand:DI 1 "se_register_operand" "d")
8554                (match_operand:DI 2 "se_arith_operand" "dI")))]
8555   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8556   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8557   [(set_attr "type"     "arith")
8558    (set_attr "mode"     "DI")
8559    (set_attr "length"   "8")])
8561 (define_split
8562   [(set (match_operand:DI 0 "register_operand" "")
8563         (ge:DI (match_operand:DI 1 "se_register_operand" "")
8564                (match_operand:DI 2 "se_arith_operand" "")))]
8565   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8566    && !TARGET_MIPS16"
8567   [(set (match_dup 0)
8568         (lt:DI (match_dup 1)
8569                (match_dup 2)))
8570    (set (match_dup 0)
8571         (xor:DI (match_dup 0)
8572                 (const_int 1)))]
8573   "")
8575 (define_expand "slt"
8576   [(set (match_operand:SI 0 "register_operand" "=d")
8577         (lt:SI (match_dup 1)
8578                (match_dup 2)))]
8579   ""
8580   "
8582   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8583     FAIL;
8585   /* set up operands from compare.  */
8586   operands[1] = branch_cmp[0];
8587   operands[2] = branch_cmp[1];
8589   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8590     {
8591       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8592       DONE;
8593     }
8595   /* fall through and generate default code */
8598 (define_insn "slt_si"
8599   [(set (match_operand:SI 0 "register_operand" "=d")
8600         (lt:SI (match_operand:SI 1 "register_operand" "d")
8601                (match_operand:SI 2 "arith_operand" "dI")))]
8602   "!TARGET_MIPS16"
8603   "slt\\t%0,%1,%2"
8604   [(set_attr "type"     "arith")
8605    (set_attr "mode"     "SI")])
8607 (define_insn ""
8608   [(set (match_operand:SI 0 "register_operand" "=t,t")
8609         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8610                (match_operand:SI 2 "arith_operand" "d,I")))]
8611   "TARGET_MIPS16"
8612   "slt\\t%1,%2"
8613   [(set_attr "type"     "arith")
8614    (set_attr "mode"     "SI")
8615    (set_attr_alternative "length"
8616                 [(const_int 4)
8617                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8618                                (const_int 4)
8619                                (const_int 8))])])
8621 (define_insn "slt_di"
8622   [(set (match_operand:DI 0 "register_operand" "=d")
8623         (lt:DI (match_operand:DI 1 "se_register_operand" "d")
8624                (match_operand:DI 2 "se_arith_operand" "dI")))]
8625   "TARGET_64BIT && !TARGET_MIPS16"
8626   "slt\\t%0,%1,%2"
8627   [(set_attr "type"     "arith")
8628    (set_attr "mode"     "DI")])
8630 (define_insn ""
8631   [(set (match_operand:DI 0 "register_operand" "=t,t")
8632         (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
8633                (match_operand:DI 2 "se_arith_operand" "d,I")))]
8634   "TARGET_64BIT && TARGET_MIPS16"
8635   "slt\\t%1,%2"
8636   [(set_attr "type"     "arith")
8637    (set_attr "mode"     "DI")
8638    (set_attr_alternative "length"
8639                 [(const_int 4)
8640                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8641                                (const_int 4)
8642                                (const_int 8))])])
8644 (define_expand "sle"
8645   [(set (match_operand:SI 0 "register_operand" "=d")
8646         (le:SI (match_dup 1)
8647                (match_dup 2)))]
8648   ""
8649   "
8651   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8652     FAIL;
8654   /* set up operands from compare.  */
8655   operands[1] = branch_cmp[0];
8656   operands[2] = branch_cmp[1];
8658   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8659     {
8660       gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8661       DONE;
8662     }
8664   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8665     operands[2] = force_reg (SImode, operands[2]);
8667   /* fall through and generate default code */
8670 (define_insn "sle_si_const"
8671   [(set (match_operand:SI 0 "register_operand" "=d")
8672         (le:SI (match_operand:SI 1 "register_operand" "d")
8673                (match_operand:SI 2 "small_int" "I")))]
8674   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8675   "*
8677   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8678   return \"slt\\t%0,%1,%2\";
8680   [(set_attr "type"     "arith")
8681    (set_attr "mode"     "SI")])
8683 (define_insn ""
8684   [(set (match_operand:SI 0 "register_operand" "=t")
8685         (le:SI (match_operand:SI 1 "register_operand" "d")
8686                (match_operand:SI 2 "small_int" "I")))]
8687   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8688   "*
8690   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8691   return \"slt\\t%1,%2\";
8693   [(set_attr "type"     "arith")
8694    (set_attr "mode"     "SI")
8695    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8696                                       (const_int 4)
8697                                       (const_int 8)))])
8699 (define_insn "sle_di_const"
8700   [(set (match_operand:DI 0 "register_operand" "=d")
8701         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8702                (match_operand:DI 2 "small_int" "I")))]
8703   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8704   "*
8706   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8707   return \"slt\\t%0,%1,%2\";
8709   [(set_attr "type"     "arith")
8710    (set_attr "mode"     "DI")])
8712 (define_insn ""
8713   [(set (match_operand:DI 0 "register_operand" "=t")
8714         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8715                (match_operand:DI 2 "small_int" "I")))]
8716   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8717   "*
8719   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8720   return \"slt\\t%1,%2\";
8722   [(set_attr "type"     "arith")
8723    (set_attr "mode"     "DI")
8724    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8725                                       (const_int 4)
8726                                       (const_int 8)))])
8728 (define_insn "sle_si_reg"
8729   [(set (match_operand:SI 0 "register_operand" "=d")
8730         (le:SI (match_operand:SI 1 "register_operand" "d")
8731                (match_operand:SI 2 "register_operand" "d")))]
8732   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8733   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8734   [(set_attr "type"     "arith")
8735    (set_attr "mode"     "SI")
8736    (set_attr "length"   "8")])
8738 (define_split
8739   [(set (match_operand:SI 0 "register_operand" "")
8740         (le:SI (match_operand:SI 1 "register_operand" "")
8741                (match_operand:SI 2 "register_operand" "")))]
8742   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8743   [(set (match_dup 0)
8744         (lt:SI (match_dup 2)
8745                (match_dup 1)))
8746    (set (match_dup 0)
8747         (xor:SI (match_dup 0)
8748                 (const_int 1)))]
8749   "")
8751 (define_insn "sle_di_reg"
8752   [(set (match_operand:DI 0 "register_operand" "=d")
8753         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8754                (match_operand:DI 2 "se_register_operand" "d")))]
8755   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8756   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8757   [(set_attr "type"     "arith")
8758    (set_attr "mode"     "DI")
8759    (set_attr "length"   "8")])
8761 (define_split
8762   [(set (match_operand:DI 0 "register_operand" "")
8763         (le:DI (match_operand:DI 1 "se_register_operand" "")
8764                (match_operand:DI 2 "se_register_operand" "")))]
8765   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8766    && !TARGET_MIPS16"
8767   [(set (match_dup 0)
8768         (lt:DI (match_dup 2)
8769                (match_dup 1)))
8770    (set (match_dup 0)
8771         (xor:DI (match_dup 0)
8772                 (const_int 1)))]
8773   "")
8775 (define_expand "sgtu"
8776   [(set (match_operand:SI 0 "register_operand" "=d")
8777         (gtu:SI (match_dup 1)
8778                 (match_dup 2)))]
8779   ""
8780   "
8782   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8783     FAIL;
8785   /* set up operands from compare.  */
8786   operands[1] = branch_cmp[0];
8787   operands[2] = branch_cmp[1];
8789   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8790     {
8791       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8792       DONE;
8793     }
8795   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8796     operands[2] = force_reg (SImode, operands[2]);
8798   /* fall through and generate default code */
8801 (define_insn "sgtu_si"
8802   [(set (match_operand:SI 0 "register_operand" "=d")
8803         (gtu:SI (match_operand:SI 1 "register_operand" "d")
8804                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8805   ""
8806   "sltu\\t%0,%z2,%1"
8807   [(set_attr "type"     "arith")
8808    (set_attr "mode"     "SI")])
8810 (define_insn ""
8811   [(set (match_operand:SI 0 "register_operand" "=t")
8812         (gtu:SI (match_operand:SI 1 "register_operand" "d")
8813                 (match_operand:SI 2 "register_operand" "d")))]
8814   ""
8815   "sltu\\t%2,%1"
8816   [(set_attr "type"     "arith")
8817    (set_attr "mode"     "SI")])
8819 (define_insn "sgtu_di"
8820   [(set (match_operand:DI 0 "register_operand" "=d")
8821         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8822                 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8823   "TARGET_64BIT"
8824   "sltu\\t%0,%z2,%1"
8825   [(set_attr "type"     "arith")
8826    (set_attr "mode"     "DI")])
8828 (define_insn ""
8829   [(set (match_operand:DI 0 "register_operand" "=t")
8830         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8831                 (match_operand:DI 2 "se_register_operand" "d")))]
8832   "TARGET_64BIT"
8833   "sltu\\t%2,%1"
8834   [(set_attr "type"     "arith")
8835    (set_attr "mode"     "DI")])
8837 (define_expand "sgeu"
8838   [(set (match_operand:SI 0 "register_operand" "=d")
8839         (geu:SI (match_dup 1)
8840                 (match_dup 2)))]
8841   ""
8842   "
8844   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8845     FAIL;
8847   /* set up operands from compare.  */
8848   operands[1] = branch_cmp[0];
8849   operands[2] = branch_cmp[1];
8851   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8852     {
8853       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8854       DONE;
8855     }
8857   /* fall through and generate default code */
8860 (define_insn "sgeu_si"
8861   [(set (match_operand:SI 0 "register_operand" "=d")
8862         (geu:SI (match_operand:SI 1 "register_operand" "d")
8863                 (match_operand:SI 2 "arith_operand" "dI")))]
8864   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8865   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8866   [(set_attr "type"     "arith")
8867    (set_attr "mode"     "SI")
8868    (set_attr "length"   "8")])
8870 (define_split
8871   [(set (match_operand:SI 0 "register_operand" "")
8872         (geu:SI (match_operand:SI 1 "register_operand" "")
8873                 (match_operand:SI 2 "arith_operand" "")))]
8874   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8875   [(set (match_dup 0)
8876         (ltu:SI (match_dup 1)
8877                 (match_dup 2)))
8878    (set (match_dup 0)
8879         (xor:SI (match_dup 0)
8880                 (const_int 1)))]
8881   "")
8883 (define_insn "sgeu_di"
8884   [(set (match_operand:DI 0 "register_operand" "=d")
8885         (geu:DI (match_operand:DI 1 "se_register_operand" "d")
8886                 (match_operand:DI 2 "se_arith_operand" "dI")))]
8887   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8888   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8889   [(set_attr "type"     "arith")
8890    (set_attr "mode"     "DI")
8891    (set_attr "length"   "8")])
8893 (define_split
8894   [(set (match_operand:DI 0 "register_operand" "")
8895         (geu:DI (match_operand:DI 1 "se_register_operand" "")
8896                 (match_operand:DI 2 "se_arith_operand" "")))]
8897   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8898    && !TARGET_MIPS16"
8899   [(set (match_dup 0)
8900         (ltu:DI (match_dup 1)
8901                 (match_dup 2)))
8902    (set (match_dup 0)
8903         (xor:DI (match_dup 0)
8904                 (const_int 1)))]
8905   "")
8907 (define_expand "sltu"
8908   [(set (match_operand:SI 0 "register_operand" "=d")
8909         (ltu:SI (match_dup 1)
8910                 (match_dup 2)))]
8911   ""
8912   "
8914   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8915     FAIL;
8917   /* set up operands from compare.  */
8918   operands[1] = branch_cmp[0];
8919   operands[2] = branch_cmp[1];
8921   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8922     {
8923       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8924       DONE;
8925     }
8927   /* fall through and generate default code */
8930 (define_insn "sltu_si"
8931   [(set (match_operand:SI 0 "register_operand" "=d")
8932         (ltu:SI (match_operand:SI 1 "register_operand" "d")
8933                 (match_operand:SI 2 "arith_operand" "dI")))]
8934   "!TARGET_MIPS16"
8935   "sltu\\t%0,%1,%2"
8936   [(set_attr "type"     "arith")
8937    (set_attr "mode"     "SI")])
8939 (define_insn ""
8940   [(set (match_operand:SI 0 "register_operand" "=t,t")
8941         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8942                 (match_operand:SI 2 "arith_operand" "d,I")))]
8943   "TARGET_MIPS16"
8944   "sltu\\t%1,%2"
8945   [(set_attr "type"     "arith")
8946    (set_attr "mode"     "SI")
8947    (set_attr_alternative "length"
8948                 [(const_int 4)
8949                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8950                                (const_int 4)
8951                                (const_int 8))])])
8953 (define_insn "sltu_di"
8954   [(set (match_operand:DI 0 "register_operand" "=d")
8955         (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
8956                 (match_operand:DI 2 "se_arith_operand" "dI")))]
8957   "TARGET_64BIT && !TARGET_MIPS16"
8958   "sltu\\t%0,%1,%2"
8959   [(set_attr "type"     "arith")
8960    (set_attr "mode"     "DI")])
8962 (define_insn ""
8963   [(set (match_operand:DI 0 "register_operand" "=t,t")
8964         (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
8965                 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8966   "TARGET_64BIT && TARGET_MIPS16"
8967   "sltu\\t%1,%2"
8968   [(set_attr "type"     "arith")
8969    (set_attr "mode"     "DI")
8970    (set_attr_alternative "length"
8971                 [(const_int 4)
8972                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8973                                (const_int 4)
8974                                (const_int 8))])])
8976 (define_expand "sleu"
8977   [(set (match_operand:SI 0 "register_operand" "=d")
8978         (leu:SI (match_dup 1)
8979                 (match_dup 2)))]
8980   ""
8981   "
8983   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8984     FAIL;
8986   /* set up operands from compare.  */
8987   operands[1] = branch_cmp[0];
8988   operands[2] = branch_cmp[1];
8990   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8991     {
8992       gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
8993       DONE;
8994     }
8996   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8997     operands[2] = force_reg (SImode, operands[2]);
8999   /* fall through and generate default code */
9002 (define_insn "sleu_si_const"
9003   [(set (match_operand:SI 0 "register_operand" "=d")
9004         (leu:SI (match_operand:SI 1 "register_operand" "d")
9005                 (match_operand:SI 2 "small_int" "I")))]
9006   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9007   "*
9009   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9010   return \"sltu\\t%0,%1,%2\";
9012   [(set_attr "type"     "arith")
9013    (set_attr "mode"     "SI")])
9015 (define_insn ""
9016   [(set (match_operand:SI 0 "register_operand" "=t")
9017         (leu:SI (match_operand:SI 1 "register_operand" "d")
9018                 (match_operand:SI 2 "small_int" "I")))]
9019   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9020   "*
9022   operands[2] = GEN_INT (INTVAL (operands[2])+1);
9023   return \"sltu\\t%1,%2\";
9025   [(set_attr "type"     "arith")
9026    (set_attr "mode"     "SI")
9027    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9028                                       (const_int 4)
9029                                       (const_int 8)))])
9031 (define_insn "sleu_di_const"
9032   [(set (match_operand:DI 0 "register_operand" "=d")
9033         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9034                 (match_operand:DI 2 "small_int" "I")))]
9035   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9036   "*
9038   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9039   return \"sltu\\t%0,%1,%2\";
9041   [(set_attr "type"     "arith")
9042    (set_attr "mode"     "DI")])
9044 (define_insn ""
9045   [(set (match_operand:DI 0 "register_operand" "=t")
9046         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9047                 (match_operand:DI 2 "small_int" "I")))]
9048   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9049   "*
9051   operands[2] = GEN_INT (INTVAL (operands[2])+1);
9052   return \"sltu\\t%1,%2\";
9054   [(set_attr "type"     "arith")
9055    (set_attr "mode"     "DI")
9056    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9057                                       (const_int 4)
9058                                       (const_int 8)))])
9060 (define_insn "sleu_si_reg"
9061   [(set (match_operand:SI 0 "register_operand" "=d")
9062         (leu:SI (match_operand:SI 1 "register_operand" "d")
9063                 (match_operand:SI 2 "register_operand" "d")))]
9064   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9065   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9066   [(set_attr "type"     "arith")
9067    (set_attr "mode"     "SI")
9068    (set_attr "length"   "8")])
9070 (define_split
9071   [(set (match_operand:SI 0 "register_operand" "")
9072         (leu:SI (match_operand:SI 1 "register_operand" "")
9073                 (match_operand:SI 2 "register_operand" "")))]
9074   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
9075   [(set (match_dup 0)
9076         (ltu:SI (match_dup 2)
9077                 (match_dup 1)))
9078    (set (match_dup 0)
9079         (xor:SI (match_dup 0)
9080                 (const_int 1)))]
9081   "")
9083 (define_insn "sleu_di_reg"
9084   [(set (match_operand:DI 0 "register_operand" "=d")
9085         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9086                 (match_operand:DI 2 "se_register_operand" "d")))]
9087   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9088   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9089   [(set_attr "type"     "arith")
9090    (set_attr "mode"     "DI")
9091    (set_attr "length"   "8")])
9093 (define_split
9094   [(set (match_operand:DI 0 "register_operand" "")
9095         (leu:DI (match_operand:DI 1 "se_register_operand" "")
9096                 (match_operand:DI 2 "se_register_operand" "")))]
9097   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9098    && !TARGET_MIPS16"
9099   [(set (match_dup 0)
9100         (ltu:DI (match_dup 2)
9101                 (match_dup 1)))
9102    (set (match_dup 0)
9103         (xor:DI (match_dup 0)
9104                 (const_int 1)))]
9105   "")
9109 ;;  ....................
9111 ;;      FLOATING POINT COMPARISONS
9113 ;;  ....................
9115 (define_insn "seq_df"
9116   [(set (match_operand:CC 0 "register_operand" "=z")
9117         (eq:CC (match_operand:DF 1 "register_operand" "f")
9118                (match_operand:DF 2 "register_operand" "f")))]
9119   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9120   "*
9122   return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9124  [(set_attr "type"      "fcmp")
9125   (set_attr "mode"      "FPSW")])
9127 (define_insn "slt_df"
9128   [(set (match_operand:CC 0 "register_operand" "=z")
9129         (lt:CC (match_operand:DF 1 "register_operand" "f")
9130                (match_operand:DF 2 "register_operand" "f")))]
9131   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9132   "*
9134   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9136  [(set_attr "type"      "fcmp")
9137   (set_attr "mode"      "FPSW")])
9139 (define_insn "sle_df"
9140   [(set (match_operand:CC 0 "register_operand" "=z")
9141         (le:CC (match_operand:DF 1 "register_operand" "f")
9142                (match_operand:DF 2 "register_operand" "f")))]
9143   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9144   "*
9146   return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9148  [(set_attr "type"      "fcmp")
9149   (set_attr "mode"      "FPSW")])
9151 (define_insn "sgt_df"
9152   [(set (match_operand:CC 0 "register_operand" "=z")
9153         (gt:CC (match_operand:DF 1 "register_operand" "f")
9154                (match_operand:DF 2 "register_operand" "f")))]
9155   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9156   "*
9158   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9160  [(set_attr "type"      "fcmp")
9161   (set_attr "mode"      "FPSW")])
9163 (define_insn "sge_df"
9164   [(set (match_operand:CC 0 "register_operand" "=z")
9165         (ge:CC (match_operand:DF 1 "register_operand" "f")
9166                (match_operand:DF 2 "register_operand" "f")))]
9167   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9168   "*
9170   return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9172  [(set_attr "type"      "fcmp")
9173   (set_attr "mode"      "FPSW")])
9175 (define_insn "seq_sf"
9176   [(set (match_operand:CC 0 "register_operand" "=z")
9177         (eq:CC (match_operand:SF 1 "register_operand" "f")
9178                (match_operand:SF 2 "register_operand" "f")))]
9179   "TARGET_HARD_FLOAT"
9180   "*
9182   return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9184  [(set_attr "type"      "fcmp")
9185   (set_attr "mode"      "FPSW")])
9187 (define_insn "slt_sf"
9188   [(set (match_operand:CC 0 "register_operand" "=z")
9189         (lt:CC (match_operand:SF 1 "register_operand" "f")
9190                (match_operand:SF 2 "register_operand" "f")))]
9191   "TARGET_HARD_FLOAT"
9192   "*
9194   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9196  [(set_attr "type"      "fcmp")
9197   (set_attr "mode"      "FPSW")])
9199 (define_insn "sle_sf"
9200   [(set (match_operand:CC 0 "register_operand" "=z")
9201         (le:CC (match_operand:SF 1 "register_operand" "f")
9202                (match_operand:SF 2 "register_operand" "f")))]
9203   "TARGET_HARD_FLOAT"
9204   "*
9206   return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9208  [(set_attr "type"      "fcmp")
9209   (set_attr "mode"      "FPSW")])
9211 (define_insn "sgt_sf"
9212   [(set (match_operand:CC 0 "register_operand" "=z")
9213         (gt:CC (match_operand:SF 1 "register_operand" "f")
9214                (match_operand:SF 2 "register_operand" "f")))]
9215   "TARGET_HARD_FLOAT"
9216   "*
9218   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9220  [(set_attr "type"      "fcmp")
9221   (set_attr "mode"      "FPSW")])
9223 (define_insn "sge_sf"
9224   [(set (match_operand:CC 0 "register_operand" "=z")
9225         (ge:CC (match_operand:SF 1 "register_operand" "f")
9226                (match_operand:SF 2 "register_operand" "f")))]
9227   "TARGET_HARD_FLOAT"
9228   "*
9230   return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9232  [(set_attr "type"      "fcmp")
9233   (set_attr "mode"      "FPSW")])
9237 ;;  ....................
9239 ;;      UNCONDITIONAL BRANCHES
9241 ;;  ....................
9243 ;; Unconditional branches.
9245 (define_insn "jump"
9246   [(set (pc)
9247         (label_ref (match_operand 0 "" "")))]
9248   "!TARGET_MIPS16"
9249   "*
9251   if (GET_CODE (operands[0]) == REG)
9252     return \"%*j\\t%0\";
9253   /* ??? I don't know why this is necessary.  This works around an
9254      assembler problem that appears when a label is defined, then referenced
9255      in a switch table, then used in a `j' instruction.  */
9256   else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
9257     return \"%*b\\t%l0\";
9258   else
9259     return \"%*j\\t%l0\";
9261   [(set_attr "type"     "jump")
9262    (set_attr "mode"     "none")])
9264 ;; We need a different insn for the mips16, because a mips16 branch
9265 ;; does not have a delay slot.
9267 (define_insn ""
9268   [(set (pc)
9269         (label_ref (match_operand 0 "" "")))]
9270   "TARGET_MIPS16 && GET_CODE (operands[0]) != REG"
9271   "b\\t%l0"
9272   [(set_attr "type"     "branch")
9273    (set_attr "mode"     "none")
9274    (set_attr "length"   "8")])
9276 (define_expand "indirect_jump"
9277   [(set (pc) (match_operand 0 "register_operand" "d"))]
9278   ""
9279   "
9281   rtx dest;
9283   if (operands[0])              /* eliminate unused code warnings */
9284     {
9285       dest = operands[0];
9286       if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9287         operands[0] = copy_to_mode_reg (Pmode, dest);
9289       if (!(Pmode == DImode))
9290         emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9291       else
9292         emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9294       DONE;
9295     }
9298 (define_insn "indirect_jump_internal1"
9299   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
9300   "!(Pmode == DImode)"
9301   "%*j\\t%0"
9302   [(set_attr "type"     "jump")
9303    (set_attr "mode"     "none")])
9305 (define_insn "indirect_jump_internal2"
9306   [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
9307   "Pmode == DImode"
9308   "%*j\\t%0"
9309   [(set_attr "type"     "jump")
9310    (set_attr "mode"     "none")])
9312 (define_expand "tablejump"
9313   [(set (pc)
9314         (match_operand 0 "register_operand" "d"))
9315    (use (label_ref (match_operand 1 "" "")))]
9316   ""
9317   "
9319   if (operands[0])              /* eliminate unused code warnings */
9320     {
9321       if (TARGET_MIPS16)
9322         {
9323           if (GET_MODE (operands[0]) != HImode)
9324             abort ();
9325           if (!(Pmode == DImode))
9326             emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
9327           else
9328             emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
9329           DONE;
9330         }
9332       if (GET_MODE (operands[0]) != Pmode)
9333         abort ();
9335       if (! flag_pic)
9336         {
9337           if (!(Pmode == DImode))
9338             emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9339           else
9340             emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
9341         }
9342       else
9343         {
9344           if (!(Pmode == DImode))
9345             emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
9346           else
9347             emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
9348         }
9350       DONE;
9351     }
9354 (define_insn "tablejump_internal1"
9355   [(set (pc)
9356         (match_operand:SI 0 "register_operand" "d"))
9357    (use (label_ref (match_operand 1 "" "")))]
9358   "!(Pmode == DImode)"
9359   "%*j\\t%0"
9360   [(set_attr "type"     "jump")
9361    (set_attr "mode"     "none")])
9363 (define_insn "tablejump_internal2"
9364   [(set (pc)
9365         (match_operand:DI 0 "se_register_operand" "d"))
9366    (use (label_ref (match_operand 1 "" "")))]
9367   "Pmode == DImode"
9368   "%*j\\t%0"
9369   [(set_attr "type"     "jump")
9370    (set_attr "mode"     "none")])
9372 (define_expand "tablejump_internal3"
9373   [(parallel [(set (pc)
9374                    (plus:SI (match_operand:SI 0 "register_operand" "d")
9375                             (label_ref:SI (match_operand 1 "" ""))))
9376               (use (label_ref:SI (match_dup 1)))])]
9377   ""
9378   "")
9380 (define_expand "tablejump_mips161"
9381   [(set (pc) (plus:SI (sign_extend:SI
9382                        (match_operand:HI 0 "register_operand" "d"))
9383                       (label_ref:SI (match_operand 1 "" ""))))]
9384   "TARGET_MIPS16 && !(Pmode == DImode)"
9385   "
9387   if (operands[0])      /* eliminate unused code warnings.  */
9388     {
9389       rtx t1, t2, t3;
9391       t1 = gen_reg_rtx (SImode);
9392       t2 = gen_reg_rtx (SImode);
9393       t3 = gen_reg_rtx (SImode);
9394       emit_insn (gen_extendhisi2 (t1, operands[0]));
9395       emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
9396       emit_insn (gen_addsi3 (t3, t1, t2));
9397       emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
9398       DONE;
9399     }
9402 (define_expand "tablejump_mips162"
9403   [(set (pc) (plus:DI (sign_extend:DI
9404                        (match_operand:HI 0 "register_operand" "d"))
9405                       (label_ref:DI (match_operand 1 "" ""))))]
9406   "TARGET_MIPS16 && Pmode == DImode"
9407   "
9409   if (operands[0])      /* eliminate unused code warnings.  */
9410     {
9411       rtx t1, t2, t3;
9413       t1 = gen_reg_rtx (DImode);
9414       t2 = gen_reg_rtx (DImode);
9415       t3 = gen_reg_rtx (DImode);
9416       emit_insn (gen_extendhidi2 (t1, operands[0]));
9417       emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
9418       emit_insn (gen_adddi3 (t3, t1, t2));
9419       emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
9420       DONE;
9421     }
9424 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
9425 ;;; it is not valid.  ??? With the USE, the condition tests may not be required
9426 ;;; any longer.
9428 ;;; ??? The length depends on the ABI.  It is two for o32, and one for n32.
9429 ;;; We just use the conservative number here.
9431 (define_insn ""
9432   [(set (pc)
9433         (plus:SI (match_operand:SI 0 "register_operand" "d")
9434                  (label_ref:SI (match_operand 1 "" ""))))
9435    (use (label_ref:SI (match_dup 1)))]
9436   "!(Pmode == DImode) && next_active_insn (insn) != 0
9437    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9438    && PREV_INSN (next_active_insn (insn)) == operands[1]"
9439   "*
9441   /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic.  */
9442   if (mips_abi == ABI_32 || mips_abi == ABI_O64)
9443     output_asm_insn (\".cpadd\\t%0\", operands);
9444   return \"%*j\\t%0\";
9446   [(set_attr "type"     "jump")
9447    (set_attr "mode"     "none")
9448    (set_attr "length"   "8")])
9450 (define_expand "tablejump_internal4"
9451   [(parallel [(set (pc)
9452                    (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9453                             (label_ref:DI (match_operand 1 "" ""))))
9454               (use (label_ref:DI (match_dup 1)))])]
9455   ""
9456   "")
9458 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
9459 ;;; it is not valid.  ??? With the USE, the condition tests may not be required
9460 ;;; any longer.
9462 (define_insn ""
9463   [(set (pc)
9464         (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9465                  (label_ref:DI (match_operand 1 "" ""))))
9466    (use (label_ref:DI (match_dup 1)))]
9467   "Pmode == DImode && next_active_insn (insn) != 0
9468    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9469    && PREV_INSN (next_active_insn (insn)) == operands[1]"
9470   "%*j\\t%0"
9471   [(set_attr "type"     "jump")
9472    (set_attr "mode"     "none")])
9474 ;; Implement a switch statement when generating embedded PIC code.
9475 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
9477 (define_expand "casesi"
9478   [(set (match_dup 5)
9479         (minus:SI (match_operand:SI 0 "register_operand" "d")
9480                   (match_operand:SI 1 "arith_operand" "dI")))
9481    (set (cc0)
9482         (compare:CC (match_dup 5)
9483                     (match_operand:SI 2 "arith_operand" "")))
9484    (set (pc)
9485         (if_then_else (gtu (cc0)
9486                            (const_int 0))
9487                       (label_ref (match_operand 4 "" ""))
9488                       (pc)))
9489    (parallel
9490     [(set (pc)
9491           (mem:SI (plus:SI (mult:SI (match_dup 5)
9492                                     (const_int 4))
9493                            (label_ref (match_operand 3 "" "")))))
9494      (clobber (match_scratch:SI 6 ""))
9495      (clobber (reg:SI 31))])]
9496   "TARGET_EMBEDDED_PIC"
9497   "
9499   if (operands[0])
9500     {
9501       rtx reg = gen_reg_rtx (SImode);
9503       /* If the index is too large, go to the default label.  */
9504       emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9505       emit_insn (gen_cmpsi (reg, operands[2]));
9506       emit_insn (gen_bgtu (operands[4]));
9508       /* Do the PIC jump.  */
9509       if (Pmode != DImode)
9510         emit_jump_insn (gen_casesi_internal (reg, operands[3],
9511                                              gen_reg_rtx (SImode)));
9512       else
9513         emit_jump_insn (gen_casesi_internal_di (reg, operands[3],
9514                                                 gen_reg_rtx (DImode)));
9516       DONE;
9517     }
9520 ;; An embedded PIC switch statement looks like this:
9521 ;;      bal     $LS1
9522 ;;      sll     $reg,$index,2
9523 ;; $LS1:
9524 ;;      addu    $reg,$reg,$31
9525 ;;      lw      $reg,$L1-$LS1($reg)
9526 ;;      addu    $reg,$reg,$31
9527 ;;      j       $reg
9528 ;; $L1:
9529 ;;      .word   case1-$LS1
9530 ;;      .word   case2-$LS1
9531 ;;      ...
9533 (define_insn "casesi_internal"
9534   [(set (pc)
9535         (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9536                                   (const_int 4))
9537                          (label_ref (match_operand 1 "" "")))))
9538    (clobber (match_operand:SI 2 "register_operand" "=d"))
9539    (clobber (reg:SI 31))]
9540   "TARGET_EMBEDDED_PIC"
9541   "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9542 lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2"
9543   [(set_attr "type"     "jump")
9544    (set_attr "mode"     "none")
9545    (set_attr "length"   "24")])
9547 ;; This code assumes that the table index will never be >= 29 bits wide,
9548 ;; which allows the 'sign extend' from SI to DI be a no-op.
9549 (define_insn "casesi_internal_di"
9550   [(set (pc)
9551         (mem:DI (plus:DI (sign_extend:DI
9552                           (mult:SI (match_operand:SI 0 "register_operand" "d")
9553                                   (const_int 8)))
9554                          (label_ref (match_operand 1 "" "")))))
9555    (clobber (match_operand:DI 2 "register_operand" "=d"))
9556    (clobber (reg:DI 31))]
9557   "TARGET_EMBEDDED_PIC"
9558   "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
9559 ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
9560   [(set_attr "type"     "jump")
9561    (set_attr "mode"     "none")
9562    (set_attr "length"   "24")])
9564 ;; For o32/n32/n64, we save the gp in the jmp_buf as well.  While it is
9565 ;; possible to either pull it off the stack (in the o32 case) or recalculate
9566 ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9567 ;; this is easy.
9569 (define_expand "builtin_setjmp_setup"
9570   [(unspec [(match_operand 0 "register_operand" "r")] UNSPEC_SETJMP)]
9571   "TARGET_ABICALLS"
9572   "
9574   if (Pmode == DImode)
9575     emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9576   else
9577     emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9578   DONE;
9581 (define_expand "builtin_setjmp_setup_32"
9582   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9583                    (const_int 12)))
9584       (reg:SI 28))]
9585   "TARGET_ABICALLS && ! (Pmode == DImode)"
9586   "")
9588 (define_expand "builtin_setjmp_setup_64"
9589   [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9590                    (const_int 24)))
9591       (reg:DI 28))]
9592   "TARGET_ABICALLS && Pmode == DImode"
9593   "")
9595 ;; For o32/n32/n64, we need to arrange for longjmp to put the
9596 ;; target address in t9 so that we can use it for loading $gp.
9598 (define_expand "builtin_longjmp"
9599   [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPEC_LONGJMP)]
9600   "TARGET_ABICALLS"
9601   "
9603   /* The elements of the buffer are, in order:  */
9604   int W = (Pmode == DImode ? 8 : 4);
9605   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9606   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9607   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9608   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9609   rtx pv = gen_rtx_REG (Pmode, 25);
9610   rtx gp = gen_rtx_REG (Pmode, 28);
9612   /* This bit is the same as expand_builtin_longjmp.  */
9613   emit_move_insn (hard_frame_pointer_rtx, fp);
9614   emit_move_insn (pv, lab);
9615   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9616   emit_move_insn (gp, gpv);
9617   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9618   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9619   emit_insn (gen_rtx_USE (VOIDmode, gp));
9620   emit_indirect_jump (pv);
9621   DONE;
9625 ;;  ....................
9627 ;;      Function prologue/epilogue
9629 ;;  ....................
9632 (define_expand "prologue"
9633   [(const_int 1)]
9634   ""
9635   "
9637   if (mips_isa >= 0)            /* avoid unused code warnings */
9638     {
9639       mips_expand_prologue ();
9640       DONE;
9641     }
9644 ;; Block any insns from being moved before this point, since the
9645 ;; profiling call to mcount can use various registers that aren't
9646 ;; saved or used to pass arguments.
9648 (define_insn "blockage"
9649   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
9650   ""
9651   ""
9652   [(set_attr "type"     "unknown")
9653    (set_attr "mode"     "none")
9654    (set_attr "length"   "0")])
9656 (define_expand "epilogue"
9657   [(const_int 2)]
9658   ""
9659   "
9661   if (mips_isa >= 0)            /* avoid unused code warnings */
9662     {
9663       mips_expand_epilogue ();
9664       DONE;
9665     }
9668 ;; Trivial return.  Make it look like a normal return insn as that
9669 ;; allows jump optimizations to work better .
9670 (define_insn "return"
9671   [(return)]
9672   "mips_can_use_return_insn ()"
9673   "%*j\\t$31"
9674   [(set_attr "type"     "jump")
9675    (set_attr "mode"     "none")])
9677 ;; Normal return.
9679 (define_insn "return_internal"
9680   [(use (match_operand 0 "pmode_register_operand" ""))
9681    (return)]
9682   ""
9683   "*
9685   return \"%*j\\t%0\";
9687   [(set_attr "type"     "jump")
9688    (set_attr "mode"     "none")])
9690 ;; When generating embedded PIC code we need to get the address of the
9691 ;; current function.  This specialized instruction does just that.
9693 (define_insn "get_fnaddr"
9694   [(set (match_operand 0 "register_operand" "=d")
9695         (unspec [(match_operand 1 "" "")] UNSPEC_GET_FNADDR))
9696    (clobber (reg:SI 31))]
9697   "TARGET_EMBEDDED_PIC
9698    && GET_CODE (operands[1]) == SYMBOL_REF"
9699   "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
9700   [(set_attr "type"     "call")
9701    (set_attr "mode"     "none")
9702    (set_attr "length"   "16")])
9704 ;; This is used in compiling the unwind routines.
9705 (define_expand "eh_return"
9706   [(use (match_operand 0 "general_operand" ""))
9707    (use (match_operand 1 "general_operand" ""))]
9708   ""
9709   "
9711   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
9713   if (GET_MODE (operands[1]) != gpr_mode)
9714     operands[1] = convert_to_mode (gpr_mode, operands[1], 0);
9715   if (TARGET_64BIT)
9716     emit_insn (gen_eh_set_lr_di (operands[1]));
9717   else
9718     emit_insn (gen_eh_set_lr_si (operands[1]));
9720   emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]);
9721   DONE;
9724 ;; Clobber the return address on the stack.  We can't expand this
9725 ;; until we know where it will be put in the stack frame.
9727 (define_insn "eh_set_lr_si"
9728   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9729    (clobber (match_scratch:SI 1 "=&r"))]
9730   "! TARGET_64BIT"
9731   "#")
9733 (define_insn "eh_set_lr_di"
9734   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9735    (clobber (match_scratch:DI 1 "=&r"))]
9736   "TARGET_64BIT"
9737   "#")
9739 (define_split
9740   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9741    (clobber (match_scratch 1 ""))]
9742   "reload_completed && !TARGET_DEBUG_D_MODE"
9743   [(const_int 0)]
9744   "
9746   HOST_WIDE_INT gp_offset;
9747   rtx base;
9749   compute_frame_size (get_frame_size ());
9750   if (((current_frame_info.mask >> 31) & 1) == 0)
9751     abort ();
9752   gp_offset = current_frame_info.gp_sp_offset;
9754   if (gp_offset < 32768)
9755     base = stack_pointer_rtx;
9756   else
9757     {
9758       base = operands[1];
9759       emit_move_insn (base, GEN_INT (gp_offset));
9760       if (Pmode == DImode)
9761         emit_insn (gen_adddi3 (base, base, stack_pointer_rtx));
9762       else
9763         emit_insn (gen_addsi3 (base, base, stack_pointer_rtx));
9764       gp_offset = 0;
9765     }
9766   emit_move_insn (gen_rtx_MEM (GET_MODE (operands[0]),
9767                                plus_constant (base, gp_offset)),
9768                   operands[0]);
9769   DONE;
9772 (define_insn "exception_receiver"
9773   [(unspec_volatile [(const_int 0)] UNSPEC_EH_RECEIVER)]
9774   "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
9775   "*
9777   rtx loc;
9779   operands[0] = pic_offset_table_rtx;
9780   if (frame_pointer_needed)
9781     loc = hard_frame_pointer_rtx;
9782   else
9783     loc = stack_pointer_rtx;
9784   loc = plus_constant (loc, current_frame_info.args_size);
9785   operands[1] = gen_rtx_MEM (Pmode, loc);
9787   return mips_move_1word (operands, insn, 0);
9789   [(set_attr "type"   "load")
9790    (set_attr "length" "8")])
9793 ;;  ....................
9795 ;;      FUNCTION CALLS
9797 ;;  ....................
9799 ;; calls.c now passes a third argument, make saber happy
9801 (define_expand "call"
9802   [(parallel [(call (match_operand 0 "memory_operand" "m")
9803                     (match_operand 1 "" "i"))
9804               (clobber (reg:SI 31))
9805               (use (match_operand 2 "" ""))             ;; next_arg_reg
9806               (use (match_operand 3 "" ""))])]          ;; struct_value_size_rtx
9807   ""
9808   "
9810   rtx addr;
9812   if (operands[0])              /* eliminate unused code warnings */
9813     {
9814       addr = XEXP (operands[0], 0);
9815       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9816           || ! call_insn_operand (addr, VOIDmode))
9817         XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
9819       /* In order to pass small structures by value in registers
9820          compatibly with the MIPS compiler, we need to shift the value
9821          into the high part of the register.  Function_arg has encoded
9822          a PARALLEL rtx, holding a vector of adjustments to be made
9823          as the next_arg_reg variable, so we split up the insns,
9824          and emit them separately.  */
9826       if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
9827         {
9828           rtvec adjust = XVEC (operands[2], 0);
9829           int num = GET_NUM_ELEM (adjust);
9830           int i;
9832           for (i = 0; i < num; i++)
9833             emit_insn (RTVEC_ELT (adjust, i));
9834         }
9836       if (TARGET_MIPS16
9837           && mips16_hard_float
9838           && operands[2] != 0
9839           && (int) GET_MODE (operands[2]) != 0)
9840         {
9841           if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
9842                                       (int) GET_MODE (operands[2])))
9843             DONE;
9844         }
9846       emit_call_insn (gen_call_internal0 (operands[0], operands[1],
9847                                           gen_rtx_REG (SImode,
9848                                                        GP_REG_FIRST + 31)));
9849       DONE;
9850     }
9853 (define_expand "call_internal0"
9854   [(parallel [(call (match_operand 0 "" "")
9855                     (match_operand 1 "" ""))
9856               (clobber (match_operand:SI 2 "" ""))])]
9857   ""
9858   "")
9860 ;; We need to recognize reg:SI 31 specially for the mips16, because we
9861 ;; don't have a constraint letter for it.
9863 (define_insn ""
9864   [(call (mem (match_operand 0 "call_insn_operand" "ei"))
9865          (match_operand 1 "" "i"))
9866    (clobber (match_operand:SI 2 "register_operand" "=y"))]
9867   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9868    && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9869   "%*jal\\t%0"
9870   [(set_attr "type"     "call")
9871    (set_attr "mode"     "none")
9872    (set_attr "length"   "8")])
9874 (define_insn "call_internal1"
9875   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9876          (match_operand 1 "" "i"))
9877    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9878   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9879   "*
9881   register rtx target = operands[0];
9883   if (GET_CODE (target) == CONST_INT)
9884     return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
9885   else if (CONSTANT_ADDRESS_P (target))
9886     return \"%*jal\\t%0\";
9887   else
9888     return \"%*jal\\t%2,%0\";
9890   [(set_attr "type"     "call")
9891    (set_attr "mode"     "none")])
9893 (define_insn "call_internal2"
9894   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9895          (match_operand 1 "" "i"))
9896    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9897   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9898   "*
9900   register rtx target = operands[0];
9902   if (GET_CODE (target) == CONST_INT)
9903     return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
9904   else if (CONSTANT_ADDRESS_P (target))
9905     {
9906       if (GET_MODE (target) == SImode)
9907         return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
9908       else
9909         return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
9910     }
9911   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9912     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9913   else
9914     return \"jal\\t%2,%0\";
9916   [(set_attr "type"     "call")
9917    (set_attr "mode"     "none")
9918    (set_attr "length"   "8")])
9920 (define_insn "call_internal3a"
9921   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9922          (match_operand 1 "" "i"))
9923    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9924   "!TARGET_MIPS16
9925    && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9926   "%*jal\\t%2,%0"
9927   [(set_attr "type"     "call")
9928    (set_attr "mode"     "none")])
9930 (define_insn "call_internal3b"
9931   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9932          (match_operand 1 "" "i"))
9933    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9934   "!TARGET_MIPS16
9935    && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9936   "%*jal\\t%2,%0"
9937   [(set_attr "type"     "call")
9938    (set_attr "mode"     "none")
9939    (set_attr "length"   "1")])
9941 (define_insn "call_internal3c"
9942   [(call (mem:SI (match_operand:SI 0 "register_operand" "e"))
9943          (match_operand 1 "" "i"))
9944    (clobber (match_operand:SI 2 "register_operand" "=y"))]
9945   "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
9946    && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9947   "%*jal\\t%2,%0"
9948   [(set_attr "type"     "call")
9949    (set_attr "mode"     "none")])
9951 (define_insn "call_internal4a"
9952   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9953          (match_operand 1 "" "i"))
9954    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9955   "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
9956   "*
9958   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9959     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9960   else
9961     return \"jal\\t%2,%0\";
9963   [(set_attr "type"     "call")
9964    (set_attr "mode"     "none")
9965    (set_attr "length"   "8")])
9967 (define_insn "call_internal4b"
9968   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9969          (match_operand 1 "" "i"))
9970    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9971   "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
9972   "*
9974   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9975     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9976   else
9977     return \"jal\\t%2,%0\";
9979   [(set_attr "type"     "call")
9980    (set_attr "mode"     "none")
9981    (set_attr "length"   "8")])
9983 ;; calls.c now passes a fourth argument, make saber happy
9985 (define_expand "call_value"
9986   [(parallel [(set (match_operand 0 "register_operand" "=df")
9987                    (call (match_operand 1 "memory_operand" "m")
9988                          (match_operand 2 "" "i")))
9989               (clobber (reg:SI 31))
9990               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
9991   ""
9992   "
9994   rtx addr;
9996   if (operands[0])              /* eliminate unused code warning */
9997     {
9998       addr = XEXP (operands[1], 0);
9999       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
10000           || ! call_insn_operand (addr, VOIDmode))
10001         XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
10003       /* In order to pass small structures by value in registers
10004          compatibly with the MIPS compiler, we need to shift the value
10005          into the high part of the register.  Function_arg has encoded
10006          a PARALLEL rtx, holding a vector of adjustments to be made
10007          as the next_arg_reg variable, so we split up the insns,
10008          and emit them separately.  */
10010       if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
10011         {
10012           rtvec adjust = XVEC (operands[3], 0);
10013           int num = GET_NUM_ELEM (adjust);
10014           int i;
10016           for (i = 0; i < num; i++)
10017             emit_insn (RTVEC_ELT (adjust, i));
10018         }
10020       if (TARGET_MIPS16
10021           && mips16_hard_float
10022           && ((operands[3] != 0
10023                && (int) GET_MODE (operands[3]) != 0)
10024               || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
10025         {
10026           if (build_mips16_call_stub (operands[0], operands[1], operands[2],
10027                                       (operands[3] == 0 ? 0
10028                                        : (int) GET_MODE (operands[3]))))
10029             DONE;
10030         }
10032       /* Handle Irix6 function calls that have multiple non-contiguous
10033          results.  */
10034       if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
10035         {
10036           emit_call_insn (gen_call_value_multiple_internal0
10037                           (XEXP (XVECEXP (operands[0], 0, 0), 0),
10038                            operands[1], operands[2],
10039                            XEXP (XVECEXP (operands[0], 0, 1), 0),
10040                            gen_rtx_REG (SImode, GP_REG_FIRST + 31)));
10041           DONE;
10042         }
10044       /* We have a call returning a DImode structure in an FP reg.
10045          Strip off the now unnecessary PARALLEL.  */
10046       if (GET_CODE (operands[0]) == PARALLEL)
10047         operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
10049       emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
10050                                                 gen_rtx_REG (SImode,
10051                                                              GP_REG_FIRST + 31)));
10053       DONE;
10054     }
10057 (define_expand "call_value_internal0"
10058   [(parallel [(set (match_operand 0 "" "")
10059                    (call (match_operand 1 "" "")
10060                          (match_operand 2 "" "")))
10061               (clobber (match_operand:SI 3 "" ""))])]
10062   ""
10063   "")
10065 ;; Recognize $31 specially on the mips16, because we don't have a
10066 ;; constraint letter for it.
10068 (define_insn ""
10069   [(set (match_operand 0 "register_operand" "=d")
10070         (call (mem (match_operand 1 "call_insn_operand" "ei"))
10071               (match_operand 2 "" "i")))
10072    (clobber (match_operand:SI 3 "register_operand" "=y"))]
10073   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
10074    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10075   "%*jal\\t%1"
10076   [(set_attr "type"     "call")
10077    (set_attr "mode"     "none")
10078    (set_attr "length"   "8")])
10080 (define_insn "call_value_internal1"
10081   [(set (match_operand 0 "register_operand" "=df")
10082         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10083               (match_operand 2 "" "i")))
10084    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10085   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10086   "*
10088   register rtx target = operands[1];
10090   if (GET_CODE (target) == CONST_INT)
10091     return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
10092   else if (CONSTANT_ADDRESS_P (target))
10093     return \"%*jal\\t%1\";
10094   else
10095     return \"%*jal\\t%3,%1\";
10097   [(set_attr "type"     "call")
10098    (set_attr "mode"     "none")])
10100 (define_insn "call_value_internal2"
10101   [(set (match_operand 0 "register_operand" "=df")
10102         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10103               (match_operand 2 "" "i")))
10104    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10105   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10106   "*
10108   register rtx target = operands[1];
10110   if (GET_CODE (target) == CONST_INT)
10111     return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
10112   else if (CONSTANT_ADDRESS_P (target))
10113     {
10114       if (GET_MODE (target) == SImode)
10115         return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
10116       else
10117         return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
10118     }
10119   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10120     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10121   else
10122     return \"jal\\t%3,%1\";
10124   [(set_attr "type"     "call")
10125    (set_attr "mode"     "none")
10126    (set_attr "length"   "8")])
10128 (define_insn "call_value_internal3a"
10129   [(set (match_operand 0 "register_operand" "=df")
10130         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10131               (match_operand 2 "" "i")))
10132    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10133   "!TARGET_MIPS16
10134    && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10135   "%*jal\\t%3,%1"
10136   [(set_attr "type"     "call")
10137    (set_attr "mode"     "none")])
10139 (define_insn "call_value_internal3b"
10140   [(set (match_operand 0 "register_operand" "=df")
10141         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10142               (match_operand 2 "" "i")))
10143    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10144   "!TARGET_MIPS16
10145    && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10146   "%*jal\\t%3,%1"
10147   [(set_attr "type"     "call")
10148    (set_attr "mode"     "none")])
10150 (define_insn "call_value_internal3c"
10151   [(set (match_operand 0 "register_operand" "=df")
10152         (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
10153               (match_operand 2 "" "i")))
10154    (clobber (match_operand:SI 3 "register_operand" "=y"))]
10155   "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
10156    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10157   "%*jal\\t%3,%1"
10158   [(set_attr "type"     "call")
10159    (set_attr "mode"     "none")])
10161 (define_insn "call_value_internal4a"
10162   [(set (match_operand 0 "register_operand" "=df")
10163         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10164               (match_operand 2 "" "i")))
10165    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10166   "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
10167   "*
10169   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10170     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10171   else
10172     return \"jal\\t%3,%1\";
10174   [(set_attr "type"     "call")
10175    (set_attr "mode"     "none")
10176    (set_attr "length"   "8")])
10178 (define_insn "call_value_internal4b"
10179   [(set (match_operand 0 "register_operand" "=df")
10180         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10181               (match_operand 2 "" "i")))
10182    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10183   "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
10184   "*
10186   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10187     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10188   else
10189     return \"jal\\t%3,%1\";
10191   [(set_attr "type"     "call")
10192    (set_attr "mode"     "none")
10193    (set_attr "length"   "8")])
10195 (define_expand "call_value_multiple_internal0"
10196   [(parallel [(set (match_operand 0 "" "")
10197                    (call (match_operand 1 "" "")
10198                          (match_operand 2 "" "")))
10199               (set (match_operand 3 "" "")
10200                    (call (match_dup 1)
10201                          (match_dup 2)))
10202               (clobber (match_operand:SI 4 "" ""))])]
10203   ""
10204   "")
10206 ;; ??? May eventually need all 6 versions of the call patterns with multiple
10207 ;; return values.
10209 (define_insn "call_value_multiple_internal1"
10210   [(set (match_operand 0 "register_operand" "=df")
10211         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10212               (match_operand 2 "" "i")))
10213    (set (match_operand 3 "register_operand" "=df")
10214         (call (mem (match_dup 1))
10215               (match_dup 2)))
10216   (clobber (match_operand:SI 4 "register_operand" "=d"))]
10217   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10218   "*
10220   register rtx target = operands[1];
10222   if (GET_CODE (target) == CONST_INT)
10223     return \"%[li\\t%@,%1\\n\\t%*jal\\t%4,%@%]\";
10224   else if (CONSTANT_ADDRESS_P (target))
10225     return \"%*jal\\t%1\";
10226   else
10227     return \"%*jal\\t%4,%1\";
10229   [(set_attr "type"     "call")
10230    (set_attr "mode"     "none")])
10232 (define_insn "call_value_multiple_internal2"
10233   [(set (match_operand 0 "register_operand" "=df")
10234         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10235               (match_operand 2 "" "i")))
10236    (set (match_operand 3 "register_operand" "=df")
10237         (call (mem (match_dup 1))
10238               (match_dup 2)))
10239    (clobber (match_operand:SI 4 "register_operand" "=d"))]
10240   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10241   "*
10243   register rtx target = operands[1];
10245   if (GET_CODE (target) == CONST_INT)
10246     return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
10247   else if (CONSTANT_ADDRESS_P (target))
10248     {
10249       if (GET_MODE (target) == SImode)
10250         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10251       else
10252         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10253     }
10254   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10255     return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
10256   else
10257     return \"jal\\t%4,%1\";
10259   [(set_attr "type"     "call")
10260    (set_attr "mode"     "none")
10261    (set_attr "length"   "8")])
10264 ;; Call subroutine returning any type.
10266 (define_expand "untyped_call"
10267   [(parallel [(call (match_operand 0 "" "")
10268                     (const_int 0))
10269               (match_operand 1 "" "")
10270               (match_operand 2 "" "")])]
10271   ""
10272   "
10274   if (operands[0])              /* silence statement not reached warnings */
10275     {
10276       int i;
10278       emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
10280       for (i = 0; i < XVECLEN (operands[2], 0); i++)
10281         {
10282           rtx set = XVECEXP (operands[2], 0, i);
10283           emit_move_insn (SET_DEST (set), SET_SRC (set));
10284         }
10286       emit_insn (gen_blockage ());
10287       DONE;
10288     }
10292 ;;  ....................
10294 ;;      MISC.
10296 ;;  ....................
10299 (define_insn "nop"
10300   [(const_int 0)]
10301   ""
10302   "%(nop%)"
10303   [(set_attr "type"     "nop")
10304    (set_attr "mode"     "none")])
10306 ;; The MIPS chip does not seem to require stack probes.
10308 ;; (define_expand "probe"
10309 ;;   [(set (match_dup 0)
10310 ;;      (match_dup 1))]
10311 ;;   ""
10312 ;;   "
10313 ;; {
10314 ;;   operands[0] = gen_reg_rtx (SImode);
10315 ;;   operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
10316 ;;   MEM_VOLATILE_P (operands[1]) = TRUE;
10318 ;;   /* fall through and generate default code */
10319 ;; }")
10323 ;; MIPS4 Conditional move instructions.
10325 (define_insn ""
10326   [(set (match_operand:SI 0 "register_operand" "=d,d")
10327         (if_then_else:SI
10328          (match_operator 4 "equality_op"
10329                          [(match_operand:SI 1 "register_operand" "d,d")
10330                           (const_int 0)])
10331          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10332          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10333   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10334   "@
10335     mov%B4\\t%0,%z2,%1
10336     mov%b4\\t%0,%z3,%1"
10337   [(set_attr "type" "move")
10338    (set_attr "mode" "SI")])
10340 (define_insn ""
10341   [(set (match_operand:SI 0 "register_operand" "=d,d")
10342         (if_then_else:SI
10343          (match_operator 4 "equality_op"
10344                          [(match_operand:DI 1 "se_register_operand" "d,d")
10345                           (const_int 0)])
10346          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10347          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10348   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10349   "@
10350     mov%B4\\t%0,%z2,%1
10351     mov%b4\\t%0,%z3,%1"
10352   [(set_attr "type" "move")
10353    (set_attr "mode" "SI")])
10355 (define_insn ""
10356   [(set (match_operand:SI 0 "register_operand" "=d,d")
10357         (if_then_else:SI
10358          (match_operator 3 "equality_op" [(match_operand:CC 4
10359                                                             "register_operand"
10360                                                             "z,z")
10361                                           (const_int 0)])
10362          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
10363          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
10364   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10365   "@
10366     mov%T3\\t%0,%z1,%4
10367     mov%t3\\t%0,%z2,%4"
10368   [(set_attr "type" "move")
10369    (set_attr "mode" "SI")])
10371 (define_insn ""
10372   [(set (match_operand:DI 0 "register_operand" "=d,d")
10373         (if_then_else:DI
10374          (match_operator 4 "equality_op"
10375                          [(match_operand:SI 1 "register_operand" "d,d")
10376                           (const_int 0)])
10377          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10378          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10379   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10380   "@
10381     mov%B4\\t%0,%z2,%1
10382     mov%b4\\t%0,%z3,%1"
10383   [(set_attr "type" "move")
10384    (set_attr "mode" "DI")])
10386 (define_insn ""
10387   [(set (match_operand:DI 0 "register_operand" "=d,d")
10388         (if_then_else:DI
10389          (match_operator 4 "equality_op"
10390                          [(match_operand:DI 1 "se_register_operand" "d,d")
10391                           (const_int 0)])
10392          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10393          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10394   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10395   "@
10396     mov%B4\\t%0,%z2,%1
10397     mov%b4\\t%0,%z3,%1"
10398   [(set_attr "type" "move")
10399    (set_attr "mode" "DI")])
10401 (define_insn ""
10402   [(set (match_operand:DI 0 "register_operand" "=d,d")
10403         (if_then_else:DI
10404          (match_operator 3 "equality_op" [(match_operand:CC 4
10405                                                             "register_operand"
10406                                                             "z,z")
10407                                           (const_int 0)])
10408          (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
10409          (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
10410   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
10411   "@
10412     mov%T3\\t%0,%z1,%4
10413     mov%t3\\t%0,%z2,%4"
10414   [(set_attr "type" "move")
10415    (set_attr "mode" "DI")])
10417 (define_insn ""
10418   [(set (match_operand:SF 0 "register_operand" "=f,f")
10419         (if_then_else:SF
10420          (match_operator 4 "equality_op"
10421                          [(match_operand:SI 1 "register_operand" "d,d")
10422                           (const_int 0)])
10423          (match_operand:SF 2 "register_operand" "f,0")
10424          (match_operand:SF 3 "register_operand" "0,f")))]
10425   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10426   "@
10427     mov%B4.s\\t%0,%2,%1
10428     mov%b4.s\\t%0,%3,%1"
10429   [(set_attr "type" "move")
10430    (set_attr "mode" "SF")])
10432 (define_insn ""
10433   [(set (match_operand:SF 0 "register_operand" "=f,f")
10434         (if_then_else:SF
10435          (match_operator 4 "equality_op"
10436                          [(match_operand:DI 1 "se_register_operand" "d,d")
10437                           (const_int 0)])
10438          (match_operand:SF 2 "register_operand" "f,0")
10439          (match_operand:SF 3 "register_operand" "0,f")))]
10440   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10441   "@
10442     mov%B4.s\\t%0,%2,%1
10443     mov%b4.s\\t%0,%3,%1"
10444   [(set_attr "type" "move")
10445    (set_attr "mode" "SF")])
10447 (define_insn ""
10448   [(set (match_operand:SF 0 "register_operand" "=f,f")
10449         (if_then_else:SF
10450          (match_operator 3 "equality_op" [(match_operand:CC 4
10451                                                             "register_operand"
10452                                                             "z,z")
10453                                           (const_int 0)])
10454          (match_operand:SF 1 "register_operand" "f,0")
10455          (match_operand:SF 2 "register_operand" "0,f")))]
10456   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10457   "@
10458     mov%T3.s\\t%0,%1,%4
10459     mov%t3.s\\t%0,%2,%4"
10460   [(set_attr "type" "move")
10461    (set_attr "mode" "SF")])
10463 (define_insn ""
10464   [(set (match_operand:DF 0 "register_operand" "=f,f")
10465         (if_then_else:DF
10466          (match_operator 4 "equality_op"
10467                          [(match_operand:SI 1 "register_operand" "d,d")
10468                           (const_int 0)])
10469          (match_operand:DF 2 "register_operand" "f,0")
10470          (match_operand:DF 3 "register_operand" "0,f")))]
10471   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10472   "@
10473     mov%B4.d\\t%0,%2,%1
10474     mov%b4.d\\t%0,%3,%1"
10475   [(set_attr "type" "move")
10476    (set_attr "mode" "DF")])
10478 (define_insn ""
10479   [(set (match_operand:DF 0 "register_operand" "=f,f")
10480         (if_then_else:DF
10481          (match_operator 4 "equality_op"
10482                          [(match_operand:DI 1 "se_register_operand" "d,d")
10483                           (const_int 0)])
10484          (match_operand:DF 2 "register_operand" "f,0")
10485          (match_operand:DF 3 "register_operand" "0,f")))]
10486   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10487   "@
10488     mov%B4.d\\t%0,%2,%1
10489     mov%b4.d\\t%0,%3,%1"
10490   [(set_attr "type" "move")
10491    (set_attr "mode" "DF")])
10493 (define_insn ""
10494   [(set (match_operand:DF 0 "register_operand" "=f,f")
10495         (if_then_else:DF
10496          (match_operator 3 "equality_op" [(match_operand:CC 4
10497                                                             "register_operand"
10498                                                             "z,z")
10499                                           (const_int 0)])
10500          (match_operand:DF 1 "register_operand" "f,0")
10501          (match_operand:DF 2 "register_operand" "0,f")))]
10502   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10503   "@
10504     mov%T3.d\\t%0,%1,%4
10505     mov%t3.d\\t%0,%2,%4"
10506   [(set_attr "type" "move")
10507    (set_attr "mode" "DF")])
10509 ;; These are the main define_expand's used to make conditional moves.
10511 (define_expand "movsicc"
10512   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10513    (set (match_operand:SI 0 "register_operand" "")
10514         (if_then_else:SI (match_dup 5)
10515                          (match_operand:SI 2 "reg_or_0_operand" "")
10516                          (match_operand:SI 3 "reg_or_0_operand" "")))]
10517   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10518   "
10520   gen_conditional_move (operands);
10521   DONE;
10524 (define_expand "movdicc"
10525   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10526    (set (match_operand:DI 0 "register_operand" "")
10527         (if_then_else:DI (match_dup 5)
10528                          (match_operand:DI 2 "se_reg_or_0_operand" "")
10529                          (match_operand:DI 3 "se_reg_or_0_operand" "")))]
10530   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10531   "
10533   if (mips_isa == 32)
10534     FAIL;
10535   gen_conditional_move (operands);
10536   DONE;
10539 (define_expand "movsfcc"
10540   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10541    (set (match_operand:SF 0 "register_operand" "")
10542         (if_then_else:SF (match_dup 5)
10543                          (match_operand:SF 2 "register_operand" "")
10544                          (match_operand:SF 3 "register_operand" "")))]
10545   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10546   "
10548   gen_conditional_move (operands);
10549   DONE;
10552 (define_expand "movdfcc"
10553   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10554    (set (match_operand:DF 0 "register_operand" "")
10555         (if_then_else:DF (match_dup 5)
10556                          (match_operand:DF 2 "register_operand" "")
10557                          (match_operand:DF 3 "register_operand" "")))]
10558   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10559   "
10561   gen_conditional_move (operands);
10562   DONE;
10566 ;;  ....................
10568 ;;      mips16 inline constant tables
10570 ;;  ....................
10573 (define_insn "consttable_qi"
10574   [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")]
10575                     UNSPEC_CONSTTABLE_QI)]
10576   "TARGET_MIPS16"
10577   "*
10579   assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
10580   return \"\";
10582   [(set_attr "type"     "unknown")
10583    (set_attr "mode"     "QI")
10584    (set_attr "length"   "8")])
10586 (define_insn "consttable_hi"
10587   [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")]
10588                     UNSPEC_CONSTTABLE_HI)]
10589   "TARGET_MIPS16"
10590   "*
10592   assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10593   return \"\";
10595   [(set_attr "type"     "unknown")
10596    (set_attr "mode"     "HI")
10597    (set_attr "length"   "8")])
10599 (define_insn "consttable_si"
10600   [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")]
10601                     UNSPEC_CONSTTABLE_SI)]
10602   "TARGET_MIPS16"
10603   "*
10605   assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10606   return \"\";
10608   [(set_attr "type"     "unknown")
10609    (set_attr "mode"     "SI")
10610    (set_attr "length"   "8")])
10612 (define_insn "consttable_di"
10613   [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")]
10614                     UNSPEC_CONSTTABLE_DI)]
10615   "TARGET_MIPS16"
10616   "*
10618   assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10619   return \"\";
10621   [(set_attr "type"     "unknown")
10622    (set_attr "mode"     "DI")
10623    (set_attr "length"   "16")])
10625 (define_insn "consttable_sf"
10626   [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")]
10627                     UNSPEC_CONSTTABLE_SF)]
10628   "TARGET_MIPS16"
10629   "*
10631   REAL_VALUE_TYPE d;
10633   if (GET_CODE (operands[0]) != CONST_DOUBLE)
10634     abort ();
10635   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10636   assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10637   return \"\";
10639   [(set_attr "type"     "unknown")
10640    (set_attr "mode"     "SF")
10641    (set_attr "length"   "8")])
10643 (define_insn "consttable_df"
10644   [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")]
10645                     UNSPEC_CONSTTABLE_DF)]
10646   "TARGET_MIPS16"
10647   "*
10649   REAL_VALUE_TYPE d;
10651   if (GET_CODE (operands[0]) != CONST_DOUBLE)
10652     abort ();
10653   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10654   assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10655   return \"\";
10657   [(set_attr "type"     "unknown")
10658    (set_attr "mode"     "DF")
10659    (set_attr "length"   "16")])
10661 (define_insn "align_2"
10662   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_2)]
10663   "TARGET_MIPS16"
10664   ".align 1"
10665   [(set_attr "type"     "unknown")
10666    (set_attr "mode"     "HI")
10667    (set_attr "length"   "8")])
10669 (define_insn "align_4"
10670   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_4)]
10671   "TARGET_MIPS16"
10672   ".align 2"
10673   [(set_attr "type"     "unknown")
10674    (set_attr "mode"     "SI")
10675    (set_attr "length"   "8")])
10677 (define_insn "align_8"
10678   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_8)]
10679   "TARGET_MIPS16"
10680   ".align 3"
10681   [(set_attr "type"     "unknown")
10682    (set_attr "mode"     "DI")
10683    (set_attr "length"   "12")])
10686 ;;  ....................
10688 ;;      mips16 peepholes
10690 ;;  ....................
10693 ;; On the mips16, reload will sometimes decide that a pseudo register
10694 ;; should go into $24, and then later on have to reload that register.
10695 ;; When that happens, we get a load of a general register followed by
10696 ;; a move from the general register to $24 followed by a branch.
10697 ;; These peepholes catch the common case, and fix it to just use the
10698 ;; general register for the branch.
10700 (define_peephole
10701   [(set (match_operand:SI 0 "register_operand" "=t")
10702         (match_operand:SI 1 "register_operand" "d"))
10703    (set (pc)
10704         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10705                                                           (const_int 0)])
10706                       (match_operand 3 "pc_or_label_operand" "")
10707                       (match_operand 4 "pc_or_label_operand" "")))]
10708   "TARGET_MIPS16
10709    && GET_CODE (operands[0]) == REG
10710    && REGNO (operands[0]) == 24
10711    && dead_or_set_p (insn, operands[0])
10712    && GET_CODE (operands[1]) == REG
10713    && M16_REG_P (REGNO (operands[1]))"
10714   "*
10716   if (operands[3] != pc_rtx)
10717     return \"%*b%C2z\\t%1,%3\";
10718   else
10719     return \"%*b%N2z\\t%1,%4\";
10721   [(set_attr "type"     "branch")
10722    (set_attr "mode"     "none")
10723    (set_attr "length"   "8")])
10725 (define_peephole
10726   [(set (match_operand:DI 0 "register_operand" "=t")
10727         (match_operand:DI 1 "register_operand" "d"))
10728    (set (pc)
10729         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10730                                                           (const_int 0)])
10731                       (match_operand 3 "pc_or_label_operand" "")
10732                       (match_operand 4 "pc_or_label_operand" "")))]
10733   "TARGET_MIPS16 && TARGET_64BIT
10734    && GET_CODE (operands[0]) == REG
10735    && REGNO (operands[0]) == 24
10736    && dead_or_set_p (insn, operands[0])
10737    && GET_CODE (operands[1]) == REG
10738    && M16_REG_P (REGNO (operands[1]))"
10739   "*
10741   if (operands[3] != pc_rtx)
10742     return \"%*b%C2z\\t%1,%3\";
10743   else
10744     return \"%*b%N2z\\t%1,%4\";
10746   [(set_attr "type"     "branch")
10747    (set_attr "mode"     "none")
10748    (set_attr "length"   "8")])
10750 ;; We can also have the reverse reload: reload will spill $24 into
10751 ;; another register, and then do a branch on that register when it
10752 ;; could have just stuck with $24.
10754 (define_peephole
10755   [(set (match_operand:SI 0 "register_operand" "=d")
10756         (match_operand:SI 1 "register_operand" "t"))
10757    (set (pc)
10758         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10759                                                           (const_int 0)])
10760                       (match_operand 3 "pc_or_label_operand" "")
10761                       (match_operand 4 "pc_or_label_operand" "")))]
10762   "TARGET_MIPS16
10763    && GET_CODE (operands[1]) == REG
10764    && REGNO (operands[1]) == 24
10765    && GET_CODE (operands[0]) == REG
10766    && M16_REG_P (REGNO (operands[0]))
10767    && dead_or_set_p (insn, operands[0])"
10768   "*
10770   if (operands[3] != pc_rtx)
10771     return \"%*bt%C2z\\t%3\";
10772   else
10773     return \"%*bt%N2z\\t%4\";
10775   [(set_attr "type"     "branch")
10776    (set_attr "mode"     "none")
10777    (set_attr "length"   "8")])
10779 (define_peephole
10780   [(set (match_operand:DI 0 "register_operand" "=d")
10781         (match_operand:DI 1 "register_operand" "t"))
10782    (set (pc)
10783         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10784                                                           (const_int 0)])
10785                       (match_operand 3 "pc_or_label_operand" "")
10786                       (match_operand 4 "pc_or_label_operand" "")))]
10787   "TARGET_MIPS16 && TARGET_64BIT
10788    && GET_CODE (operands[1]) == REG
10789    && REGNO (operands[1]) == 24
10790    && GET_CODE (operands[0]) == REG
10791    && M16_REG_P (REGNO (operands[0]))
10792    && dead_or_set_p (insn, operands[0])"
10793   "*
10795   if (operands[3] != pc_rtx)
10796     return \"%*bt%C2z\\t%3\";
10797   else
10798     return \"%*bt%N2z\\t%4\";
10800   [(set_attr "type"     "branch")
10801    (set_attr "mode"     "none")
10802    (set_attr "length"   "8")])
10804 ;; For the rare case where we need to load an address into a register
10805 ;; that can not be recognized by the normal movsi/addsi instructions.
10806 ;; I have no idea how many insns this can actually generate.  It should
10807 ;; be rare, so over-estimating as 10 instructions should not have any
10808 ;; real performance impact.
10809 (define_insn "leasi"
10810   [(set (match_operand:SI 0 "register_operand" "=d")
10811         (match_operand:SI 1 "address_operand" "p"))]
10812   "Pmode == SImode"
10813   "la %0,%a1"
10814   [(set_attr "type"     "arith")
10815    (set_attr "mode"     "SI")
10816    (set_attr "length"   "40")])
10818 ;; Similarly for targets where we have 64bit pointers.
10819 (define_insn "leadi"
10820   [(set (match_operand:DI 0 "register_operand" "=d")
10821         (match_operand:DI 1 "address_operand" "p"))]
10822   "Pmode == DImode"
10823   "la %0,%a1"
10824   [(set_attr "type"     "arith")
10825    (set_attr "mode"     "DI")
10826    (set_attr "length"   "40")])