2001-12-03 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / config / mips / mips.md
blob0a0fae45cd9cf9533c24ad7579434d624a2cbcdb
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 ;; UNSPEC values used in mips.md
30 ;; Number       USE
31 ;; 0            movsi_ul
32 ;; 1            movsi_us, get_fnaddr
33 ;; 2            reload_in*, reload_out* : sets delay on HILO register
34 ;; 3            eh_set_return
35 ;; 20           builtin_setjmp_setup
37 ;; UNSPEC_VOLATILE values
38 ;; 0            blockage
39 ;; 2            loadgp
40 ;; 3            builtin_longjmp
41 ;; 4            exception_receiver
42 ;; 10           consttable_qi
43 ;; 11           consttable_hi
44 ;; 12           consttable_si
45 ;; 13           consttable_di
46 ;; 14           consttable_sf
47 ;; 15           consttable_df
48 ;; 16           align_2
49 ;; 17           align_4
50 ;; 18           align_8
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 ;; Attribute defining whether or not we can use the branch-likely instructions
140 (define_attr "branch_likely" "no,yes"
141   (const
142    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
143                  (const_string "yes")
144                  (const_string "no"))))
147 ;; Describe a user's asm statement.
148 (define_asm_attributes
149   [(set_attr "type" "multi")])
151 ;; whether or not generating calls to position independent functions
152 (define_attr "abicalls" "no,yes"
153   (const (symbol_ref "mips_abicalls_attr")))
157 ;; .........................
159 ;;      Delay slots, can't describe load/fcmp/xfer delay slots here
161 ;; .........................
163 (define_delay (and (eq_attr "type" "branch")
164                    (eq (symbol_ref "mips16") (const_int 0)))
165   [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
166    (nil)
167    (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "4")))])
169 (define_delay (eq_attr "type" "jump")
170   [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
171    (nil)
172    (nil)])
174 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
175   [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
176    (nil)
177    (nil)])
181 ;; .........................
183 ;;      Functional units
185 ;; .........................
187 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
188 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
190 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
192 (define_function_unit "memory" 1 0
193   (and (eq_attr "type" "load")
194        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
195   3 0)
197 (define_function_unit "memory" 1 0
198   (and (eq_attr "type" "load")
199        (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
200   2 0)
202 (define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
204 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
206 (define_function_unit "imuldiv"  1 0
207   (eq_attr "type" "hilo")
208   1 3)
210 (define_function_unit "imuldiv"  1 0
211   (and (eq_attr "type" "imul")
212        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
213   17 17)
215 ;; On them mips16, we want to stronly discourage a mult from appearing
216 ;; after an mflo, since that requires explicit nop instructions.  We
217 ;; do this by pretending that mflo ties up the function unit for long
218 ;; enough that the scheduler will ignore load stalls and the like when
219 ;; selecting instructions to between the two instructions.
221 (define_function_unit "imuldiv" 1 0
222   (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
223   1 5)
225 (define_function_unit "imuldiv"  1 0
226   (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
227   12 12)
229 (define_function_unit "imuldiv"  1 0
230   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
231   10 10)
233 (define_function_unit "imuldiv"  1 0
234   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
235   4 4)
237 (define_function_unit "imuldiv"  1 0
238   (and (eq_attr "type" "imul")
239        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
240   1 1)
242 (define_function_unit "imuldiv"  1 0
243   (and (eq_attr "type" "imul")
244        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
245   4 4)
247 (define_function_unit "imuldiv"  1 0
248   (and (eq_attr "type" "imul")
249        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
250   5 5)
252 (define_function_unit "imuldiv"  1 0
253   (and (eq_attr "type" "imul")
254        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
255   8 8)
257 (define_function_unit "imuldiv"  1 0
258   (and (eq_attr "type" "imul")
259        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
260   9 9)
262 (define_function_unit "imuldiv"  1 0
263   (and (eq_attr "type" "idiv")
264        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
265   38 38)
267 (define_function_unit "imuldiv"  1 0
268   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
269   35 35)
271 (define_function_unit "imuldiv"  1 0
272   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
273   42 42)
275 (define_function_unit "imuldiv"  1 0
276   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
277   36 36)
279 (define_function_unit "imuldiv"  1 0
280   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
281   69 69)
283 (define_function_unit "imuldiv" 1 0
284   (and (eq_attr "type" "idiv")
285        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
286   35 35)
288 (define_function_unit "imuldiv" 1 0
289   (and (eq_attr "type" "idiv")
290        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
291   67 67)
293 (define_function_unit "imuldiv" 1 0
294   (and (eq_attr "type" "idiv")
295        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
296   37 37)
298 (define_function_unit "imuldiv" 1 0
299   (and (eq_attr "type" "idiv")
300        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
301   69 69)
303 (define_function_unit "imuldiv" 1 0
304   (and (eq_attr "type" "idiv")
305        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
306   36 36)
308 (define_function_unit "imuldiv" 1 0
309   (and (eq_attr "type" "idiv")
310        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
311   68 68)
313 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
314 ;; the FP hardware is part of the normal ALU circuitry.  This means FP
315 ;; instructions affect the pipe-line, and no functional unit
316 ;; parallelism can occur on R4300 processors.  To force GCC into coding
317 ;; for only a single functional unit, we force the R4300 FP
318 ;; instructions to be processed in the "imuldiv" unit.
320 (define_function_unit "adder" 1 1
321   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
322   3 0)
324 (define_function_unit "adder" 1 1
325   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
326   2 0)
328 (define_function_unit "adder" 1 1
329   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
330   1 0)
332 (define_function_unit "adder" 1 1
333   (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
334   4 0)
336 (define_function_unit "adder" 1 1
337   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
338   2 0)
340 (define_function_unit "adder" 1 1
341   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
342   3 0)
344 (define_function_unit "adder" 1 1
345   (and (eq_attr "type" "fabs,fneg")
346        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
347   2 0)
349 (define_function_unit "adder" 1 1
350   (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
351   1 0)
353 (define_function_unit "mult" 1 1
354   (and (eq_attr "type" "fmul")
355        (and (eq_attr "mode" "SF")
356             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
357   7 0)
359 (define_function_unit "mult" 1 1
360   (and (eq_attr "type" "fmul")
361        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
362   4 0)
364 (define_function_unit "mult" 1 1
365   (and (eq_attr "type" "fmul")
366        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
367   5 0)
369 (define_function_unit "mult" 1 1
370   (and (eq_attr "type" "fmul")
371        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
372   8 0)
374 (define_function_unit "mult" 1 1
375   (and (eq_attr "type" "fmul")
376        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
377   8 0)
379 (define_function_unit "mult" 1 1
380   (and (eq_attr "type" "fmul")
381        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
382   5 0)
384 (define_function_unit "mult" 1 1
385   (and (eq_attr "type" "fmul")
386        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
387   6 0)
389 (define_function_unit "divide" 1 1
390   (and (eq_attr "type" "fdiv")
391        (and (eq_attr "mode" "SF")
392             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
393   23 0)
395 (define_function_unit "divide" 1 1
396   (and (eq_attr "type" "fdiv")
397        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
398   12 0)
400 (define_function_unit "divide" 1 1
401   (and (eq_attr "type" "fdiv")
402        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
403   15 0)
405 (define_function_unit "divide" 1 1
406   (and (eq_attr "type" "fdiv")
407        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
408   32 0)
410 (define_function_unit "divide" 1 1
411   (and (eq_attr "type" "fdiv")
412        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
413   21 0)
415 (define_function_unit "divide" 1 1
416   (and (eq_attr "type" "fdiv")
417        (and (eq_attr "mode" "DF")
418             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
419   36 0)
421 (define_function_unit "divide" 1 1
422   (and (eq_attr "type" "fdiv")
423        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
424   19 0)
426 (define_function_unit "divide" 1 1
427   (and (eq_attr "type" "fdiv")
428        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
429   16 0)
431 (define_function_unit "divide" 1 1
432   (and (eq_attr "type" "fdiv")
433        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
434   61 0)
436 ;;; ??? Is this number right?
437 (define_function_unit "divide" 1 1
438   (and (eq_attr "type" "fsqrt")
439        (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
440   54 0)
442 (define_function_unit "divide" 1 1
443   (and (eq_attr "type" "fsqrt")
444        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
445   31 0)
447 (define_function_unit "divide" 1 1
448   (and (eq_attr "type" "fsqrt")
449        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
450   21 0)
452 ;;; ??? Is this number right?
453 (define_function_unit "divide" 1 1
454   (and (eq_attr "type" "fsqrt")
455        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
456   112 0)
458 (define_function_unit "divide" 1 1
459   (and (eq_attr "type" "fsqrt")
460        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
461   60 0)
463 (define_function_unit "divide" 1 1
464   (and (eq_attr "type" "fsqrt")
465        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
466   36 0)
468 ;; R4300 FP instruction classes treated as part of the "imuldiv"
469 ;; functional unit:
471 (define_function_unit "imuldiv" 1 0
472   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
473   3 3)
475 (define_function_unit "imuldiv" 1 0
476   (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
477   1 1)
479 (define_function_unit "imuldiv" 1 0
480   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
481   5 5)
482 (define_function_unit "imuldiv" 1 0
483   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
484   8 8)
486 (define_function_unit "imuldiv" 1 0
487   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
488        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
489   29 29)
490 (define_function_unit "imuldiv" 1 0
491   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
492        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
493   58 58)
495 ;; The following functional units do not use the cpu type, and use
496 ;; much less memory in genattrtab.c.
498 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "load")                                3 0)
499 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "store")                               1 0)
501 ;; (define_function_unit "fp_comp"  1 0 (eq_attr "type" "fcmp")                                2 0)
503 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer")                                2 0)
504 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo")                                3 0)
506 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "imul")                               17 0)
507 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "idiv")                               38 0)
509 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fadd")                                4 0)
510 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fabs,fneg")                           2 0)
512 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF"))    7 0)
513 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF"))    8 0)
515 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF"))   23 0)
516 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF"))   36 0)
518 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF"))  54 0)
519 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
522 ;;  ....................
524 ;;      CONDITIONAL TRAPS
526 ;;  ....................
529 (define_insn "trap"
530   [(trap_if (const_int 1) (const_int 0))]
531   ""
532   "*
534   if (ISA_HAS_COND_TRAP)
535     return \"teq\\t$0,$0\";
536   else
537     return \"break\";
540 (define_expand "conditional_trap"
541   [(trap_if (match_operator 0 "cmp_op"
542                             [(match_dup 2) (match_dup 3)])
543             (match_operand 1 "const_int_operand" ""))]
544   "ISA_HAS_COND_TRAP"
545   "
547   mips_gen_conditional_trap (operands);
548   DONE;
551 ;; Match a TRAP_IF with 2nd arg of 0.  The div_trap_* insns match a
552 ;; 2nd arg of any CONST_INT, so this insn must appear first.
553 ;; gen_div_trap always generates TRAP_IF with 2nd arg of 6 or 7.
555 (define_insn ""
556   [(trap_if (match_operator 0 "trap_cmp_op"
557                             [(match_operand:SI 1 "reg_or_0_operand" "d")
558                              (match_operand:SI 2 "nonmemory_operand" "dI")])
559             (const_int 0))]
560   "ISA_HAS_COND_TRAP"
561   "t%C0\\t%z1,%z2")
564 ;;  ....................
566 ;;      ADDITION
568 ;;  ....................
571 (define_insn "adddf3"
572   [(set (match_operand:DF 0 "register_operand" "=f")
573         (plus:DF (match_operand:DF 1 "register_operand" "f")
574                  (match_operand:DF 2 "register_operand" "f")))]
575   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
576   "add.d\\t%0,%1,%2"
577   [(set_attr "type"     "fadd")
578    (set_attr "mode"     "DF")])
580 (define_insn "addsf3"
581   [(set (match_operand:SF 0 "register_operand" "=f")
582         (plus:SF (match_operand:SF 1 "register_operand" "f")
583                  (match_operand:SF 2 "register_operand" "f")))]
584   "TARGET_HARD_FLOAT"
585   "add.s\\t%0,%1,%2"
586   [(set_attr "type"     "fadd")
587    (set_attr "mode"     "SF")])
589 (define_expand "addsi3"
590   [(set (match_operand:SI 0 "register_operand" "=d")
591         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
592                  (match_operand:SI 2 "arith_operand" "dI")))]
593   ""
594   "
596   /* The mips16 assembler handles -32768 correctly, and so does gas,
597      but some other MIPS assemblers think that -32768 needs to be
598      loaded into a register before it can be added in.  */
599   if (! TARGET_MIPS16
600       && ! TARGET_GAS
601       && GET_CODE (operands[2]) == CONST_INT
602       && INTVAL (operands[2]) == -32768)
603     operands[2] = force_reg (SImode, operands[2]);
606 (define_insn "addsi3_internal"
607   [(set (match_operand:SI 0 "register_operand" "=d")
608         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
609                  (match_operand:SI 2 "arith_operand" "dI")))]
610   "! TARGET_MIPS16
611    && (TARGET_GAS
612        || GET_CODE (operands[2]) != CONST_INT
613        || INTVAL (operands[2]) != -32768)"
614   "addu\\t%0,%z1,%2"
615   [(set_attr "type"     "arith")
616    (set_attr "mode"     "SI")])
618 ;; For the mips16, we need to recognize stack pointer additions
619 ;; explicitly, since we don't have a constraint for $sp.  These insns
620 ;; will be generated by the save_restore_insns functions.
622 (define_insn ""
623   [(set (reg:SI 29)
624         (plus:SI (reg:SI 29)
625                  (match_operand:SI 0 "small_int" "I")))]
626   "TARGET_MIPS16"
627   "addu\\t%$,%$,%0"
628   [(set_attr "type"     "arith")
629    (set_attr "mode"     "SI")
630    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
631                                       (const_int 4)
632                                       (const_int 8)))])
634 (define_insn ""
635   [(set (match_operand:SI 0 "register_operand" "=d")
636         (plus:SI (reg:SI 29)
637                  (match_operand:SI 1 "small_int" "I")))]
638   "TARGET_MIPS16"
639   "addu\\t%0,%$,%1"
640   [(set_attr "type"     "arith")
641    (set_attr "mode"     "SI")
642    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
643                                       (const_int 4)
644                                       (const_int 8)))])
646 (define_insn ""
647   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
648         (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
649                  (match_operand:SI 2 "arith_operand" "IQ,O,d")))]
650   "TARGET_MIPS16
651    && (GET_CODE (operands[1]) != REG
652        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
653        || M16_REG_P (REGNO (operands[1]))
654        || REGNO (operands[1]) == ARG_POINTER_REGNUM
655        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
656        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
657    && (GET_CODE (operands[2]) != REG
658        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
659        || M16_REG_P (REGNO (operands[2]))
660        || REGNO (operands[2]) == ARG_POINTER_REGNUM
661        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
662        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
663   "*
665   if (REGNO (operands[0]) == REGNO (operands[1]))
666     return \"addu\\t%0,%2\";
667   return \"addu\\t%0,%1,%2\";
669   [(set_attr "type"     "arith")
670    (set_attr "mode"     "SI")
671    (set_attr_alternative "length"
672                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
673                                (const_int 4)
674                                (const_int 8))
675                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
676                                (const_int 4)
677                                (const_int 8))
678                  (const_int 4)])])
681 ;; On the mips16, we can sometimes split an add of a constant which is
682 ;; a 4 byte instruction into two adds which are both 2 byte
683 ;; instructions.  There are two cases: one where we are adding a
684 ;; constant plus a register to another register, and one where we are
685 ;; simply adding a constant to a register.
687 (define_split
688   [(set (match_operand:SI 0 "register_operand" "")
689         (plus:SI (match_dup 0)
690                  (match_operand:SI 1 "const_int_operand" "")))]
691   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
692    && GET_CODE (operands[0]) == REG
693    && M16_REG_P (REGNO (operands[0]))
694    && GET_CODE (operands[1]) == CONST_INT
695    && ((INTVAL (operands[1]) > 0x7f
696         && INTVAL (operands[1]) <= 0x7f + 0x7f)
697        || (INTVAL (operands[1]) < - 0x80
698            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
699   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
700    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
701   "
703   HOST_WIDE_INT val = INTVAL (operands[1]);
705   if (val >= 0)
706     {
707       operands[1] = GEN_INT (0x7f);
708       operands[2] = GEN_INT (val - 0x7f);
709     }
710   else
711     {
712       operands[1] = GEN_INT (- 0x80);
713       operands[2] = GEN_INT (val + 0x80);
714     }
717 (define_split
718   [(set (match_operand:SI 0 "register_operand" "")
719         (plus:SI (match_operand:SI 1 "register_operand" "")
720                  (match_operand:SI 2 "const_int_operand" "")))]
721   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
722    && GET_CODE (operands[0]) == REG
723    && M16_REG_P (REGNO (operands[0]))
724    && GET_CODE (operands[1]) == REG
725    && M16_REG_P (REGNO (operands[1]))
726    && REGNO (operands[0]) != REGNO (operands[1])
727    && GET_CODE (operands[2]) == CONST_INT
728    && ((INTVAL (operands[2]) > 0x7
729         && INTVAL (operands[2]) <= 0x7 + 0x7f)
730        || (INTVAL (operands[2]) < - 0x8
731            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
732   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
733    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
734   "
736   HOST_WIDE_INT val = INTVAL (operands[2]);
738   if (val >= 0)
739     {
740       operands[2] = GEN_INT (0x7);
741       operands[3] = GEN_INT (val - 0x7);
742     }
743   else
744     {
745       operands[2] = GEN_INT (- 0x8);
746       operands[3] = GEN_INT (val + 0x8);
747     }
750 (define_expand "adddi3"
751   [(parallel [(set (match_operand:DI 0 "register_operand" "")
752                    (plus:DI (match_operand:DI 1 "se_register_operand" "")
753                             (match_operand:DI 2 "se_arith_operand" "")))
754               (clobber (match_dup 3))])]
755   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
756   "
758   /* The mips16 assembler handles -32768 correctly, and so does gas,
759      but some other MIPS assemblers think that -32768 needs to be
760      loaded into a register before it can be added in.  */
761   if (! TARGET_MIPS16
762       && ! TARGET_GAS
763       && GET_CODE (operands[2]) == CONST_INT
764       && INTVAL (operands[2]) == -32768)
765     operands[2] = force_reg (DImode, operands[2]);
767   if (TARGET_64BIT)
768     {
769       emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
770                                         operands[2]));
771       DONE;
772     }
774   operands[3] = gen_reg_rtx (SImode);
777 (define_insn "adddi3_internal_1"
778   [(set (match_operand:DI 0 "register_operand" "=d,&d")
779         (plus:DI (match_operand:DI 1 "register_operand" "0,d")
780                  (match_operand:DI 2 "register_operand" "d,d")))
781    (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
782   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
783   "*
785   return (REGNO (operands[0]) == REGNO (operands[1])
786           && REGNO (operands[0]) == REGNO (operands[2]))
787     ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
788     : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
790   [(set_attr "type"     "darith")
791    (set_attr "mode"     "DI")
792    (set_attr "length"   "16")])
794 (define_split
795   [(set (match_operand:DI 0 "register_operand" "")
796         (plus:DI (match_operand:DI 1 "register_operand" "")
797                  (match_operand:DI 2 "register_operand" "")))
798    (clobber (match_operand:SI 3 "register_operand" ""))]
799   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
800    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
801    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
802    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
803    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
804    && (REGNO (operands[0]) != REGNO (operands[1])
805        || REGNO (operands[0]) != REGNO (operands[2]))"
807   [(set (subreg:SI (match_dup 0) 0)
808         (plus:SI (subreg:SI (match_dup 1) 0)
809                  (subreg:SI (match_dup 2) 0)))
811    (set (match_dup 3)
812         (ltu:SI (subreg:SI (match_dup 0) 0)
813                 (subreg:SI (match_dup 2) 0)))
815    (set (subreg:SI (match_dup 0) 4)
816         (plus:SI (subreg:SI (match_dup 1) 4)
817                  (subreg:SI (match_dup 2) 4)))
819    (set (subreg:SI (match_dup 0) 4)
820         (plus:SI (subreg:SI (match_dup 0) 4)
821                  (match_dup 3)))]
822   "")
824 (define_split
825   [(set (match_operand:DI 0 "register_operand" "")
826         (plus:DI (match_operand:DI 1 "register_operand" "")
827                  (match_operand:DI 2 "register_operand" "")))
828    (clobber (match_operand:SI 3 "register_operand" ""))]
829   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
830    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
831    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
832    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
833    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
834    && (REGNO (operands[0]) != REGNO (operands[1])
835        || REGNO (operands[0]) != REGNO (operands[2]))"
837   [(set (subreg:SI (match_dup 0) 4)
838         (plus:SI (subreg:SI (match_dup 1) 4)
839                  (subreg:SI (match_dup 2) 4)))
841    (set (match_dup 3)
842         (ltu:SI (subreg:SI (match_dup 0) 4)
843                 (subreg:SI (match_dup 2) 4)))
845    (set (subreg:SI (match_dup 0) 0)
846         (plus:SI (subreg:SI (match_dup 1) 0)
847                  (subreg:SI (match_dup 2) 0)))
849    (set (subreg:SI (match_dup 0) 0)
850         (plus:SI (subreg:SI (match_dup 0) 0)
851                  (match_dup 3)))]
852   "")
854 (define_insn "adddi3_internal_2"
855   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
856         (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
857                  (match_operand:DI 2 "small_int" "P,J,N")))
858    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
859   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
860    && (TARGET_GAS
861        || GET_CODE (operands[2]) != CONST_INT
862        || INTVAL (operands[2]) != -32768)"
863   "@
864    addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
865    move\\t%L0,%L1\;move\\t%M0,%M1
866    subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
867   [(set_attr "type"     "darith")
868    (set_attr "mode"     "DI")
869    (set_attr "length"   "12,8,16")])
871 (define_split
872   [(set (match_operand:DI 0 "register_operand" "")
873         (plus:DI (match_operand:DI 1 "register_operand" "")
874                  (match_operand:DI 2 "small_int" "")))
875    (clobber (match_operand:SI 3 "register_operand" ""))]
876   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
877    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
878    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
879    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
880    && INTVAL (operands[2]) > 0"
882   [(set (subreg:SI (match_dup 0) 0)
883         (plus:SI (subreg:SI (match_dup 1) 0)
884                  (match_dup 2)))
886    (set (match_dup 3)
887         (ltu:SI (subreg:SI (match_dup 0) 0)
888                 (match_dup 2)))
890    (set (subreg:SI (match_dup 0) 4)
891         (plus:SI (subreg:SI (match_dup 1) 4)
892                  (match_dup 3)))]
893   "")
895 (define_split
896   [(set (match_operand:DI 0 "register_operand" "")
897         (plus:DI (match_operand:DI 1 "register_operand" "")
898                  (match_operand:DI 2 "small_int" "")))
899    (clobber (match_operand:SI 3 "register_operand" ""))]
900   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
901    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
902    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
903    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
904    && INTVAL (operands[2]) > 0"
906   [(set (subreg:SI (match_dup 0) 4)
907         (plus:SI (subreg:SI (match_dup 1) 4)
908                  (match_dup 2)))
910    (set (match_dup 3)
911         (ltu:SI (subreg:SI (match_dup 0) 4)
912                 (match_dup 2)))
914    (set (subreg:SI (match_dup 0) 0)
915         (plus:SI (subreg:SI (match_dup 1) 0)
916                  (match_dup 3)))]
917   "")
919 (define_insn "adddi3_internal_3"
920   [(set (match_operand:DI 0 "register_operand" "=d")
921         (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
922                  (match_operand:DI 2 "se_arith_operand" "dI")))]
923   "TARGET_64BIT
924    && !TARGET_MIPS16
925    && (TARGET_GAS
926        || GET_CODE (operands[2]) != CONST_INT
927        || INTVAL (operands[2]) != -32768)"
928   "*
930   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
931     ? \"dsubu\\t%0,%z1,%n2\"
932     : \"daddu\\t%0,%z1,%2\";
934   [(set_attr "type"     "darith")
935    (set_attr "mode"     "DI")])
937 ;; For the mips16, we need to recognize stack pointer additions
938 ;; explicitly, since we don't have a constraint for $sp.  These insns
939 ;; will be generated by the save_restore_insns functions.
941 (define_insn ""
942   [(set (reg:DI 29)
943         (plus:DI (reg:DI 29)
944                  (match_operand:DI 0 "small_int" "I")))]
945   "TARGET_MIPS16 && TARGET_64BIT"
946   "daddu\\t%$,%$,%0"
947   [(set_attr "type"     "arith")
948    (set_attr "mode"     "DI")
949    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
950                                       (const_int 4)
951                                       (const_int 8)))])
953 (define_insn ""
954   [(set (match_operand:DI 0 "register_operand" "=d")
955         (plus:DI (reg:DI 29)
956                  (match_operand:DI 1 "small_int" "I")))]
957   "TARGET_MIPS16 && TARGET_64BIT"
958   "daddu\\t%0,%$,%1"
959   [(set_attr "type"     "arith")
960    (set_attr "mode"     "DI")
961    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
962                                       (const_int 4)
963                                       (const_int 8)))])
965 (define_insn ""
966   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
967         (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
968                  (match_operand:DI 2 "arith_operand" "IQ,O,d")))]
969   "TARGET_MIPS16 && TARGET_64BIT
970    && (GET_CODE (operands[1]) != REG
971        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
972        || M16_REG_P (REGNO (operands[1]))
973        || REGNO (operands[1]) == ARG_POINTER_REGNUM
974        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
975        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
976    && (GET_CODE (operands[2]) != REG
977        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
978        || M16_REG_P (REGNO (operands[2]))
979        || REGNO (operands[2]) == ARG_POINTER_REGNUM
980        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
981        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
982   "*
984   if (REGNO (operands[0]) == REGNO (operands[1]))
985     return \"daddu\\t%0,%2\";
986   return \"daddu\\t%0,%1,%2\";
988   [(set_attr "type"     "arith")
989    (set_attr "mode"     "DI")
990    (set_attr_alternative "length"
991                 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
992                                (const_int 4)
993                                (const_int 8))
994                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
995                                (const_int 4)
996                                (const_int 8))
997                  (const_int 4)])])
1000 ;; On the mips16, we can sometimes split an add of a constant which is
1001 ;; a 4 byte instruction into two adds which are both 2 byte
1002 ;; instructions.  There are two cases: one where we are adding a
1003 ;; constant plus a register to another register, and one where we are
1004 ;; simply adding a constant to a register.
1006 (define_split
1007   [(set (match_operand:DI 0 "register_operand" "")
1008         (plus:DI (match_dup 0)
1009                  (match_operand:DI 1 "const_int_operand" "")))]
1010   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1011    && GET_CODE (operands[0]) == REG
1012    && M16_REG_P (REGNO (operands[0]))
1013    && GET_CODE (operands[1]) == CONST_INT
1014    && ((INTVAL (operands[1]) > 0xf
1015         && INTVAL (operands[1]) <= 0xf + 0xf)
1016        || (INTVAL (operands[1]) < - 0x10
1017            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1018   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1019    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1020   "
1022   HOST_WIDE_INT val = INTVAL (operands[1]);
1024   if (val >= 0)
1025     {
1026       operands[1] = GEN_INT (0xf);
1027       operands[2] = GEN_INT (val - 0xf);
1028     }
1029   else
1030     {
1031       operands[1] = GEN_INT (- 0x10);
1032       operands[2] = GEN_INT (val + 0x10);
1033     }
1036 (define_split
1037   [(set (match_operand:DI 0 "register_operand" "")
1038         (plus:DI (match_operand:DI 1 "register_operand" "")
1039                  (match_operand:DI 2 "const_int_operand" "")))]
1040   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1041    && GET_CODE (operands[0]) == REG
1042    && M16_REG_P (REGNO (operands[0]))
1043    && GET_CODE (operands[1]) == REG
1044    && M16_REG_P (REGNO (operands[1]))
1045    && REGNO (operands[0]) != REGNO (operands[1])
1046    && GET_CODE (operands[2]) == CONST_INT
1047    && ((INTVAL (operands[2]) > 0x7
1048         && INTVAL (operands[2]) <= 0x7 + 0xf)
1049        || (INTVAL (operands[2]) < - 0x8
1050            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1051   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1052    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1053   "
1055   HOST_WIDE_INT val = INTVAL (operands[2]);
1057   if (val >= 0)
1058     {
1059       operands[2] = GEN_INT (0x7);
1060       operands[3] = GEN_INT (val - 0x7);
1061     }
1062   else
1063     {
1064       operands[2] = GEN_INT (- 0x8);
1065       operands[3] = GEN_INT (val + 0x8);
1066     }
1069 (define_insn "addsi3_internal_2"
1070   [(set (match_operand:DI 0 "register_operand" "=d")
1071         (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1072                                  (match_operand:SI 2 "arith_operand" "dI"))))]
1073   "TARGET_64BIT
1074    && !TARGET_MIPS16
1075    && (TARGET_GAS
1076        || GET_CODE (operands[2]) != CONST_INT
1077        || INTVAL (operands[2]) != -32768)"
1078   "*
1080   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1081     ? \"subu\\t%0,%z1,%n2\"
1082     : \"addu\\t%0,%z1,%2\";
1084   [(set_attr "type"     "arith")
1085    (set_attr "mode"     "SI")])
1087 (define_insn ""
1088   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1089         (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1090                                  (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1091   "TARGET_MIPS16 && TARGET_64BIT"
1092   "*
1094   if (REGNO (operands[0]) == REGNO (operands[1]))
1095     return \"addu\\t%0,%2\";
1096   return \"addu\\t%0,%1,%2\";
1098   [(set_attr "type"     "arith")
1099    (set_attr "mode"     "SI")
1100    (set_attr_alternative "length"
1101                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1102                                (const_int 4)
1103                                (const_int 8))
1104                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1105                                (const_int 4)
1106                                (const_int 8))
1107                  (const_int 4)])])
1111 ;;  ....................
1113 ;;      SUBTRACTION
1115 ;;  ....................
1118 (define_insn "subdf3"
1119   [(set (match_operand:DF 0 "register_operand" "=f")
1120         (minus:DF (match_operand:DF 1 "register_operand" "f")
1121                   (match_operand:DF 2 "register_operand" "f")))]
1122   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1123   "sub.d\\t%0,%1,%2"
1124   [(set_attr "type"     "fadd")
1125    (set_attr "mode"     "DF")])
1127 (define_insn "subsf3"
1128   [(set (match_operand:SF 0 "register_operand" "=f")
1129         (minus:SF (match_operand:SF 1 "register_operand" "f")
1130                   (match_operand:SF 2 "register_operand" "f")))]
1131   "TARGET_HARD_FLOAT"
1132   "sub.s\\t%0,%1,%2"
1133   [(set_attr "type"     "fadd")
1134    (set_attr "mode"     "SF")])
1136 (define_expand "subsi3"
1137   [(set (match_operand:SI 0 "register_operand" "=d")
1138         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1139                   (match_operand:SI 2 "arith_operand" "dI")))]
1140   ""
1141   "
1143   if (GET_CODE (operands[2]) == CONST_INT
1144       && (INTVAL (operands[2]) == -32768
1145           || (TARGET_MIPS16
1146               && INTVAL (operands[2]) == -0x4000)))
1147     operands[2] = force_reg (SImode, operands[2]);
1150 (define_insn "subsi3_internal"
1151   [(set (match_operand:SI 0 "register_operand" "=d")
1152         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1153                   (match_operand:SI 2 "arith_operand" "dI")))]
1154   "!TARGET_MIPS16
1155    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1156   "subu\\t%0,%z1,%2"
1157   [(set_attr "type"     "arith")
1158    (set_attr "mode"     "SI")])
1160 ;; For the mips16, we need to recognize stack pointer subtractions
1161 ;; explicitly, since we don't have a constraint for $sp.  These insns
1162 ;; will be generated by the save_restore_insns functions.
1164 (define_insn ""
1165   [(set (reg:SI 29)
1166         (minus:SI (reg:SI 29)
1167                   (match_operand:SI 0 "small_int" "I")))]
1168   "TARGET_MIPS16
1169    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1170   "addu\\t%$,%$,%n0"
1171   [(set_attr "type"     "arith")
1172    (set_attr "mode"     "SI")
1173    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1174                                       (const_int 4)
1175                                       (const_int 8)))])
1177 (define_insn ""
1178   [(set (match_operand:SI 0 "register_operand" "=d")
1179         (minus:SI (reg:SI 29)
1180                   (match_operand:SI 1 "small_int" "I")))]
1181   "TARGET_MIPS16
1182    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1183   "addu\\t%0,%$,%n1"
1184   [(set_attr "type"     "arith")
1185    (set_attr "mode"     "SI")
1186    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
1187                                       (const_int 4)
1188                                       (const_int 8)))])
1191 (define_insn ""
1192   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1193         (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1194                   (match_operand:SI 2 "arith_operand" "I,O,d")))]
1195   "TARGET_MIPS16
1196    && (GET_CODE (operands[2]) != CONST_INT
1197        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1198   "*
1200   if (REGNO (operands[0]) == REGNO (operands[1]))
1201     return \"subu\\t%0,%2\";
1202   return \"subu\\t%0,%1,%2\";
1204   [(set_attr "type"     "arith")
1205    (set_attr "mode"     "SI")
1206    (set_attr_alternative "length"
1207                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1208                                (const_int 4)
1209                                (const_int 8))
1210                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1211                                (const_int 4)
1212                                (const_int 8))
1213                  (const_int 4)])])
1215 ;; On the mips16, we can sometimes split an subtract of a constant
1216 ;; which is a 4 byte instruction into two adds which are both 2 byte
1217 ;; instructions.  There are two cases: one where we are setting a
1218 ;; register to a register minus a constant, and one where we are
1219 ;; simply subtracting a constant from a register.
1221 (define_split
1222   [(set (match_operand:SI 0 "register_operand" "")
1223         (minus:SI (match_dup 0)
1224                   (match_operand:SI 1 "const_int_operand" "")))]
1225   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1226    && GET_CODE (operands[0]) == REG
1227    && M16_REG_P (REGNO (operands[0]))
1228    && GET_CODE (operands[1]) == CONST_INT
1229    && ((INTVAL (operands[1]) > 0x80
1230         && INTVAL (operands[1]) <= 0x80 + 0x80)
1231        || (INTVAL (operands[1]) < - 0x7f
1232            && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1233   [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1234    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1235   "
1237   HOST_WIDE_INT val = INTVAL (operands[1]);
1239   if (val >= 0)
1240     {
1241       operands[1] = GEN_INT (0x80);
1242       operands[2] = GEN_INT (val - 0x80);
1243     }
1244   else
1245     {
1246       operands[1] = GEN_INT (- 0x7f);
1247       operands[2] = GEN_INT (val + 0x7f);
1248     }
1251 (define_split
1252   [(set (match_operand:SI 0 "register_operand" "")
1253         (minus:SI (match_operand:SI 1 "register_operand" "")
1254                   (match_operand:SI 2 "const_int_operand" "")))]
1255   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1256    && GET_CODE (operands[0]) == REG
1257    && M16_REG_P (REGNO (operands[0]))
1258    && GET_CODE (operands[1]) == REG
1259    && M16_REG_P (REGNO (operands[1]))
1260    && REGNO (operands[0]) != REGNO (operands[1])
1261    && GET_CODE (operands[2]) == CONST_INT
1262    && ((INTVAL (operands[2]) > 0x8
1263         && INTVAL (operands[2]) <= 0x8 + 0x80)
1264        || (INTVAL (operands[2]) < - 0x7
1265            && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1266   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1267    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1268   "
1270   HOST_WIDE_INT val = INTVAL (operands[2]);
1272   if (val >= 0)
1273     {
1274       operands[2] = GEN_INT (0x8);
1275       operands[3] = GEN_INT (val - 0x8);
1276     }
1277   else
1278     {
1279       operands[2] = GEN_INT (- 0x7);
1280       operands[3] = GEN_INT (val + 0x7);
1281     }
1284 (define_expand "subdi3"
1285   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1286                    (minus:DI (match_operand:DI 1 "se_register_operand" "d")
1287                              (match_operand:DI 2 "se_register_operand" "d")))
1288               (clobber (match_dup 3))])]
1289   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1290   "
1292   if (TARGET_64BIT)
1293     {
1294       emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1295                                         operands[2]));
1296       DONE;
1297     }
1299   operands[3] = gen_reg_rtx (SImode);
1302 (define_insn "subdi3_internal"
1303   [(set (match_operand:DI 0 "register_operand" "=d")
1304         (minus:DI (match_operand:DI 1 "register_operand" "d")
1305                   (match_operand:DI 2 "register_operand" "d")))
1306    (clobber (match_operand:SI 3 "register_operand" "=d"))]
1307   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1308   "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1309   [(set_attr "type"     "darith")
1310    (set_attr "mode"     "DI")
1311    (set_attr "length"   "16")])
1313 (define_split
1314   [(set (match_operand:DI 0 "register_operand" "")
1315         (minus:DI (match_operand:DI 1 "register_operand" "")
1316                   (match_operand:DI 2 "register_operand" "")))
1317    (clobber (match_operand:SI 3 "register_operand" ""))]
1318   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1319    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1320    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1321    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1322    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1324   [(set (match_dup 3)
1325         (ltu:SI (subreg:SI (match_dup 1) 0)
1326                 (subreg:SI (match_dup 2) 0)))
1328    (set (subreg:SI (match_dup 0) 0)
1329         (minus:SI (subreg:SI (match_dup 1) 0)
1330                   (subreg:SI (match_dup 2) 0)))
1332    (set (subreg:SI (match_dup 0) 4)
1333         (minus:SI (subreg:SI (match_dup 1) 4)
1334                   (subreg:SI (match_dup 2) 4)))
1336    (set (subreg:SI (match_dup 0) 4)
1337         (minus:SI (subreg:SI (match_dup 0) 4)
1338                   (match_dup 3)))]
1339   "")
1341 (define_split
1342   [(set (match_operand:DI 0 "register_operand" "")
1343         (minus:DI (match_operand:DI 1 "register_operand" "")
1344                   (match_operand:DI 2 "register_operand" "")))
1345    (clobber (match_operand:SI 3 "register_operand" ""))]
1346   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1347    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1348    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1349    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1350    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1352   [(set (match_dup 3)
1353         (ltu:SI (subreg:SI (match_dup 1) 4)
1354                 (subreg:SI (match_dup 2) 4)))
1356    (set (subreg:SI (match_dup 0) 4)
1357         (minus:SI (subreg:SI (match_dup 1) 4)
1358                   (subreg:SI (match_dup 2) 4)))
1360    (set (subreg:SI (match_dup 0) 0)
1361         (minus:SI (subreg:SI (match_dup 1) 0)
1362                   (subreg:SI (match_dup 2) 0)))
1364    (set (subreg:SI (match_dup 0) 0)
1365         (minus:SI (subreg:SI (match_dup 0) 0)
1366                   (match_dup 3)))]
1367   "")
1369 (define_insn "subdi3_internal_2"
1370   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1371         (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1372                   (match_operand:DI 2 "small_int" "P,J,N")))
1373    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1374   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1375    && INTVAL (operands[2]) != -32768"
1376   "@
1377    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1378    move\\t%L0,%L1\;move\\t%M0,%M1
1379    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1380   [(set_attr "type"     "darith")
1381    (set_attr "mode"     "DI")
1382    (set_attr "length"   "12,8,16")])
1384 (define_split
1385   [(set (match_operand:DI 0 "register_operand" "")
1386         (minus:DI (match_operand:DI 1 "register_operand" "")
1387                   (match_operand:DI 2 "small_int" "")))
1388    (clobber (match_operand:SI 3 "register_operand" ""))]
1389   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1390    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1391    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1392    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1393    && INTVAL (operands[2]) > 0"
1395   [(set (match_dup 3)
1396         (ltu:SI (subreg:SI (match_dup 1) 0)
1397                 (match_dup 2)))
1399    (set (subreg:SI (match_dup 0) 0)
1400         (minus:SI (subreg:SI (match_dup 1) 0)
1401                   (match_dup 2)))
1403    (set (subreg:SI (match_dup 0) 4)
1404         (minus:SI (subreg:SI (match_dup 1) 4)
1405                   (match_dup 3)))]
1406   "")
1408 (define_split
1409   [(set (match_operand:DI 0 "register_operand" "")
1410         (minus:DI (match_operand:DI 1 "register_operand" "")
1411                   (match_operand:DI 2 "small_int" "")))
1412    (clobber (match_operand:SI 3 "register_operand" ""))]
1413   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1414    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1415    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1416    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1417    && INTVAL (operands[2]) > 0"
1419   [(set (match_dup 3)
1420         (ltu:SI (subreg:SI (match_dup 1) 4)
1421                 (match_dup 2)))
1423    (set (subreg:SI (match_dup 0) 4)
1424         (minus:SI (subreg:SI (match_dup 1) 4)
1425                   (match_dup 2)))
1427    (set (subreg:SI (match_dup 0) 0)
1428         (minus:SI (subreg:SI (match_dup 1) 0)
1429                   (match_dup 3)))]
1430   "")
1432 (define_insn "subdi3_internal_3"
1433   [(set (match_operand:DI 0 "register_operand" "=d")
1434         (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
1435                   (match_operand:DI 2 "se_arith_operand" "dI")))]
1436   "TARGET_64BIT && !TARGET_MIPS16
1437    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1438   "*
1440   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1441     ? \"daddu\\t%0,%z1,%n2\"
1442     : \"dsubu\\t%0,%z1,%2\";
1444   [(set_attr "type"     "darith")
1445    (set_attr "mode"     "DI")])
1447 ;; For the mips16, we need to recognize stack pointer subtractions
1448 ;; explicitly, since we don't have a constraint for $sp.  These insns
1449 ;; will be generated by the save_restore_insns functions.
1451 (define_insn ""
1452   [(set (reg:DI 29)
1453         (minus:DI (reg:DI 29)
1454                   (match_operand:DI 0 "small_int" "I")))]
1455   "TARGET_MIPS16
1456    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1457   "daddu\\t%$,%$,%n0"
1458   [(set_attr "type"     "arith")
1459    (set_attr "mode"     "DI")
1460    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1461                                       (const_int 4)
1462                                       (const_int 8)))])
1464 (define_insn ""
1465   [(set (match_operand:DI 0 "register_operand" "=d")
1466         (minus:DI (reg:DI 29)
1467                   (match_operand:DI 1 "small_int" "I")))]
1468   "TARGET_MIPS16
1469    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1470   "daddu\\t%0,%$,%n1"
1471   [(set_attr "type"     "arith")
1472    (set_attr "mode"     "DI")
1473    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
1474                                       (const_int 4)
1475                                       (const_int 8)))])
1477 (define_insn ""
1478   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1479         (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1480                   (match_operand:DI 2 "arith_operand" "I,O,d")))]
1481   "TARGET_MIPS16
1482    && (GET_CODE (operands[2]) != CONST_INT
1483        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1484   "*
1486   if (REGNO (operands[0]) == REGNO (operands[1]))
1487     return \"dsubu\\t%0,%2\";
1488   return \"dsubu\\t%0,%1,%2\";
1490   [(set_attr "type"     "arith")
1491    (set_attr "mode"     "DI")
1492    (set_attr_alternative "length"
1493                 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
1494                                (const_int 4)
1495                                (const_int 8))
1496                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1497                                (const_int 4)
1498                                (const_int 8))
1499                  (const_int 4)])])
1501 ;; On the mips16, we can sometimes split an add of a constant which is
1502 ;; a 4 byte instruction into two adds which are both 2 byte
1503 ;; instructions.  There are two cases: one where we are adding a
1504 ;; constant plus a register to another register, and one where we are
1505 ;; simply adding a constant to a register.
1507 (define_split
1508   [(set (match_operand:DI 0 "register_operand" "")
1509         (minus:DI (match_dup 0)
1510                   (match_operand:DI 1 "const_int_operand" "")))]
1511   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1512    && GET_CODE (operands[0]) == REG
1513    && M16_REG_P (REGNO (operands[0]))
1514    && GET_CODE (operands[1]) == CONST_INT
1515    && ((INTVAL (operands[1]) > 0x10
1516         && INTVAL (operands[1]) <= 0x10 + 0x10)
1517        || (INTVAL (operands[1]) < - 0xf
1518            && INTVAL (operands[1]) >= - 0xf - 0xf))"
1519   [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1520    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1521   "
1523   HOST_WIDE_INT val = INTVAL (operands[1]);
1525   if (val >= 0)
1526     {
1527       operands[1] = GEN_INT (0xf);
1528       operands[2] = GEN_INT (val - 0xf);
1529     }
1530   else
1531     {
1532       operands[1] = GEN_INT (- 0x10);
1533       operands[2] = GEN_INT (val + 0x10);
1534     }
1537 (define_split
1538   [(set (match_operand:DI 0 "register_operand" "")
1539         (minus:DI (match_operand:DI 1 "register_operand" "")
1540                   (match_operand:DI 2 "const_int_operand" "")))]
1541   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1542    && GET_CODE (operands[0]) == REG
1543    && M16_REG_P (REGNO (operands[0]))
1544    && GET_CODE (operands[1]) == REG
1545    && M16_REG_P (REGNO (operands[1]))
1546    && REGNO (operands[0]) != REGNO (operands[1])
1547    && GET_CODE (operands[2]) == CONST_INT
1548    && ((INTVAL (operands[2]) > 0x8
1549         && INTVAL (operands[2]) <= 0x8 + 0x10)
1550        || (INTVAL (operands[2]) < - 0x7
1551            && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1552   [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1553    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1554   "
1556   HOST_WIDE_INT val = INTVAL (operands[2]);
1558   if (val >= 0)
1559     {
1560       operands[2] = GEN_INT (0x8);
1561       operands[3] = GEN_INT (val - 0x8);
1562     }
1563   else
1564     {
1565       operands[2] = GEN_INT (- 0x7);
1566       operands[3] = GEN_INT (val + 0x7);
1567     }
1570 (define_insn "subsi3_internal_2"
1571   [(set (match_operand:DI 0 "register_operand" "=d")
1572         (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1573                                   (match_operand:SI 2 "arith_operand" "dI"))))]
1574   "TARGET_64BIT && !TARGET_MIPS16
1575    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1576   "*
1578   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1579     ? \"addu\\t%0,%z1,%n2\"
1580     : \"subu\\t%0,%z1,%2\";
1582   [(set_attr "type"     "arith")
1583    (set_attr "mode"     "DI")])
1585 (define_insn ""
1586   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1587         (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1588                                   (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1589   "TARGET_64BIT && TARGET_MIPS16
1590    && (GET_CODE (operands[2]) != CONST_INT
1591        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1592   "*
1594   if (REGNO (operands[0]) == REGNO (operands[1]))
1595     return \"subu\\t%0,%2\";
1596   return \"subu\\t%0,%1,%2\";
1598   [(set_attr "type"     "arith")
1599    (set_attr "mode"     "SI")
1600    (set_attr_alternative "length"
1601                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1602                                (const_int 4)
1603                                (const_int 8))
1604                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1605                                (const_int 4)
1606                                (const_int 8))
1607                  (const_int 4)])])
1612 ;;  ....................
1614 ;;      MULTIPLICATION
1616 ;;  ....................
1619 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1620 ;; operands may corrupt immediately following multiplies. This is a
1621 ;; simple fix to insert NOPs.
1623 (define_expand "muldf3"
1624   [(set (match_operand:DF 0 "register_operand" "=f")
1625         (mult:DF (match_operand:DF 1 "register_operand" "f")
1626                  (match_operand:DF 2 "register_operand" "f")))]
1627   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1628   "
1630   if (!TARGET_MIPS4300)
1631     emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1632   else
1633     emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1634   DONE;
1637 (define_insn "muldf3_internal"
1638   [(set (match_operand:DF 0 "register_operand" "=f")
1639         (mult:DF (match_operand:DF 1 "register_operand" "f")
1640                  (match_operand:DF 2 "register_operand" "f")))]
1641   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_MIPS4300"
1642   "mul.d\\t%0,%1,%2"
1643   [(set_attr "type"     "fmul")
1644    (set_attr "mode"     "DF")])
1646 (define_insn "muldf3_r4300"
1647   [(set (match_operand:DF 0 "register_operand" "=f")
1648         (mult:DF (match_operand:DF 1 "register_operand" "f")
1649                  (match_operand:DF 2 "register_operand" "f")))]
1650   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_MIPS4300"
1651   "*
1653   output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1654   if (TARGET_4300_MUL_FIX)
1655     output_asm_insn (\"nop\", operands);
1656   return \"\";
1658   [(set_attr "type"     "fmul")
1659    (set_attr "mode"     "DF")
1660    (set_attr "length"   "8")])  ;; mul.d + nop
1662 (define_expand "mulsf3"
1663   [(set (match_operand:SF 0 "register_operand" "=f")
1664         (mult:SF (match_operand:SF 1 "register_operand" "f")
1665                  (match_operand:SF 2 "register_operand" "f")))]
1666   "TARGET_HARD_FLOAT"
1667   "
1669   if (!TARGET_MIPS4300)
1670     emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1671   else
1672     emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1673   DONE;
1676 (define_insn "mulsf3_internal"
1677   [(set (match_operand:SF 0 "register_operand" "=f")
1678         (mult:SF (match_operand:SF 1 "register_operand" "f")
1679                  (match_operand:SF 2 "register_operand" "f")))]
1680   "TARGET_HARD_FLOAT && !TARGET_MIPS4300"
1681   "mul.s\\t%0,%1,%2"
1682   [(set_attr "type"     "fmul")
1683    (set_attr "mode"     "SF")])
1685 (define_insn "mulsf3_r4300"
1686   [(set (match_operand:SF 0 "register_operand" "=f")
1687         (mult:SF (match_operand:SF 1 "register_operand" "f")
1688                  (match_operand:SF 2 "register_operand" "f")))]
1689   "TARGET_HARD_FLOAT && TARGET_MIPS4300"
1690   "*
1692   output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1693   if (TARGET_4300_MUL_FIX)
1694     output_asm_insn (\"nop\", operands);
1695   return \"\";
1697   [(set_attr "type"     "fmul")
1698    (set_attr "mode"     "SF")
1699    (set_attr "length"   "8")])  ;; mul.s + nop
1702 ;; ??? The R4000 (only) has a cpu bug.  If a double-word shift executes while
1703 ;; a multiply is in progress, it may give an incorrect result.  Avoid
1704 ;; this by keeping the mflo with the mult on the R4000.
1706 (define_expand "mulsi3"
1707   [(set (match_operand:SI 0 "register_operand" "=l")
1708         (mult:SI (match_operand:SI 1 "register_operand" "d")
1709                  (match_operand:SI 2 "register_operand" "d")))
1710    (clobber (match_scratch:SI 3 "=h"))
1711    (clobber (match_scratch:SI 4 "=a"))]
1712   ""
1713   "
1715   if (GENERATE_MULT3_SI || TARGET_MAD)
1716     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1717   else if (!TARGET_MIPS4000 || TARGET_MIPS16)
1718     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1719   else
1720     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1721   DONE;
1724 (define_insn "mulsi3_mult3"
1725   [(set (match_operand:SI 0 "register_operand" "=d,l")
1726         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1727                  (match_operand:SI 2 "register_operand" "d,d")))
1728    (clobber (match_scratch:SI 3 "=h,h"))
1729    (clobber (match_scratch:SI 4 "=l,X"))
1730    (clobber (match_scratch:SI 5 "=a,a"))]
1731   "GENERATE_MULT3_SI
1732    || TARGET_MAD"
1733   "*
1735   if (which_alternative == 1)
1736     return \"mult\\t%1,%2\";
1737   if (TARGET_MAD
1738       || mips_isa == 32
1739       || mips_isa == 64)
1740     return \"mul\\t%0,%1,%2\";
1741   return \"mult\\t%0,%1,%2\";
1743   [(set_attr "type"     "imul")
1744    (set_attr "mode"     "SI")])
1746 (define_insn "mulsi3_internal"
1747   [(set (match_operand:SI 0 "register_operand" "=l")
1748         (mult:SI (match_operand:SI 1 "register_operand" "d")
1749                  (match_operand:SI 2 "register_operand" "d")))
1750    (clobber (match_scratch:SI 3 "=h"))
1751    (clobber (match_scratch:SI 4 "=a"))]
1752   "!TARGET_MIPS4000 || TARGET_MIPS16"
1753   "mult\\t%1,%2"
1754   [(set_attr "type"     "imul")
1755    (set_attr "mode"     "SI")])
1757 (define_insn "mulsi3_r4000"
1758   [(set (match_operand:SI 0 "register_operand" "=d")
1759         (mult:SI (match_operand:SI 1 "register_operand" "d")
1760                  (match_operand:SI 2 "register_operand" "d")))
1761    (clobber (match_scratch:SI 3 "=h"))
1762    (clobber (match_scratch:SI 4 "=l"))
1763    (clobber (match_scratch:SI 5 "=a"))]
1764   "TARGET_MIPS4000 && !TARGET_MIPS16"
1765   "*
1767   rtx xoperands[10];
1769   xoperands[0] = operands[0];
1770   xoperands[1] = gen_rtx_REG (SImode, LO_REGNUM);
1772   output_asm_insn (\"mult\\t%1,%2\", operands);
1773   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1774   return \"\";
1776   [(set_attr "type"     "imul")
1777    (set_attr "mode"     "SI")
1778    (set_attr "length"   "12")])         ;; mult + mflo + delay
1780 ;; Multiply-accumulate patterns
1782 ;; For processors that can copy the output to a general register:
1784 ;; The all-d alternative is needed because the combiner will find this
1785 ;; pattern and then register alloc/reload will move registers around to
1786 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1788 ;; The last alternative should be made slightly less desirable, but adding
1789 ;; "?" to the constraint is too strong, and causes values to be loaded into
1790 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1791 ;; trick.
1792 (define_insn "*mul_acc_si"
1793   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1794         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1795                           (match_operand:SI 2 "register_operand" "d,d,d"))
1796                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1797    (clobber (match_scratch:SI 4 "=h,h,h"))
1798    (clobber (match_scratch:SI 5 "=X,3,l"))
1799    (clobber (match_scratch:SI 6 "=a,a,a"))
1800    (clobber (match_scratch:SI 7 "=X,X,d"))]
1801   "(TARGET_MIPS3900
1802    || ISA_HAS_MADD_MSUB)
1803    && !TARGET_MIPS16"
1804   "*
1806   static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
1807   if (which_alternative == 2)
1808     return \"#\";
1809   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1810     return \"#\";
1811   return madd[which_alternative];
1813   [(set_attr "type"     "imul,imul,multi")
1814    (set_attr "mode"     "SI")
1815    (set_attr "length"   "4,4,8")])
1817 ;; Split the above insn if we failed to get LO allocated.
1818 (define_split
1819   [(set (match_operand:SI 0 "register_operand" "")
1820         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1821                           (match_operand:SI 2 "register_operand" ""))
1822                  (match_operand:SI 3 "register_operand" "")))
1823    (clobber (match_scratch:SI 4 ""))
1824    (clobber (match_scratch:SI 5 ""))
1825    (clobber (match_scratch:SI 6 ""))
1826    (clobber (match_scratch:SI 7 ""))]
1827   "reload_completed && !TARGET_DEBUG_D_MODE
1828    && GP_REG_P (true_regnum (operands[0]))
1829    && GP_REG_P (true_regnum (operands[3]))"
1830   [(parallel [(set (match_dup 7)
1831                    (mult:SI (match_dup 1) (match_dup 2)))
1832               (clobber (match_dup 4))
1833               (clobber (match_dup 5))
1834               (clobber (match_dup 6))])
1835    (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
1836   "")
1838 ;; Splitter to copy result of MADD to a general register
1839 (define_split
1840   [(set (match_operand:SI                   0 "register_operand" "")
1841         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1842                           (match_operand:SI 2 "register_operand" ""))
1843                  (match_operand:SI          3 "register_operand" "")))
1844    (clobber (match_scratch:SI               4 ""))
1845    (clobber (match_scratch:SI               5 ""))
1846    (clobber (match_scratch:SI               6 ""))
1847    (clobber (match_scratch:SI               7 ""))]
1848   "reload_completed && !TARGET_DEBUG_D_MODE
1849    && GP_REG_P (true_regnum (operands[0]))
1850    && true_regnum (operands[3]) == LO_REGNUM"
1851   [(parallel [(set (match_dup 3)
1852                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1853                             (match_dup 3)))
1854               (clobber (match_dup 4))
1855               (clobber (match_dup 5))
1856               (clobber (match_dup 6))
1857               (clobber (match_dup 7))])
1858    (set (match_dup 0) (match_dup 3))]
1859   "")
1861 (define_insn "*mul_sub_si"
1862   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1863         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1864                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1865                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1866    (clobber (match_scratch:SI 4 "=h,h,h"))
1867    (clobber (match_scratch:SI 5 "=X,3,l"))
1868    (clobber (match_scratch:SI 6 "=a,a,a"))
1869    (clobber (match_scratch:SI 7 "=X,X,d"))]
1870   "ISA_HAS_MADD_MSUB"
1871   "*
1873   if (which_alternative != 0)
1874     return \"#\";
1875   return \"msub\\t%2,%3\";
1877   [(set_attr "type"     "imul,imul,multi")
1878    (set_attr "mode"     "SI")
1879    (set_attr "length"   "4,8,8")])
1881 ;; Split the above insn if we failed to get LO allocated.
1882 (define_split
1883   [(set (match_operand:SI 0 "register_operand" "")
1884         (minus:SI (match_operand:SI 1 "register_operand" "")
1885                   (mult:SI (match_operand:SI 2 "register_operand" "")
1886                            (match_operand:SI 3 "register_operand" ""))))
1887    (clobber (match_scratch:SI 4 ""))
1888    (clobber (match_scratch:SI 5 ""))
1889    (clobber (match_scratch:SI 6 ""))
1890    (clobber (match_scratch:SI 7 ""))]
1891   "reload_completed && !TARGET_DEBUG_D_MODE
1892    && GP_REG_P (true_regnum (operands[0]))
1893    && GP_REG_P (true_regnum (operands[1]))"
1894   [(parallel [(set (match_dup 7)
1895                    (mult:SI (match_dup 2) (match_dup 3)))
1896               (clobber (match_dup 4))
1897               (clobber (match_dup 5))
1898               (clobber (match_dup 6))])
1899    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
1900   "")
1902 ;; Splitter to copy result of MSUB to a general register
1903 (define_split
1904   [(set (match_operand:SI 0 "register_operand" "")
1905         (minus:SI (match_operand:SI 1 "register_operand" "")
1906                   (mult:SI (match_operand:SI 2 "register_operand" "")
1907                            (match_operand:SI 3 "register_operand" ""))))
1908    (clobber (match_scratch:SI 4 ""))
1909    (clobber (match_scratch:SI 5 ""))
1910    (clobber (match_scratch:SI 6 ""))
1911    (clobber (match_scratch:SI 7 ""))]
1912   "reload_completed && !TARGET_DEBUG_D_MODE
1913    && GP_REG_P (true_regnum (operands[0]))
1914    && true_regnum (operands[1]) == LO_REGNUM"
1915   [(parallel [(set (match_dup 1)
1916                    (minus:SI (match_dup 1)
1917                              (mult:SI (match_dup 2) (match_dup 3))))
1918               (clobber (match_dup 4))
1919               (clobber (match_dup 5))
1920               (clobber (match_dup 6))
1921               (clobber (match_dup 7))])
1922    (set (match_dup 0) (match_dup 1))]
1923   "")
1926 (define_split
1927   [(set (match_operand:SI 0 "register_operand" "")
1928         (minus:SI (match_operand:SI 1 "register_operand" "")
1929                   (mult:SI (match_operand:SI 2 "register_operand" "")
1930                            (match_operand:SI 3 "register_operand" ""))))
1931    (clobber (match_scratch:SI 4 ""))
1932    (clobber (match_scratch:SI 5 ""))
1933    (clobber (match_scratch:SI 6 ""))
1934    (clobber (match_scratch:SI 7 ""))]
1935   "reload_completed && !TARGET_DEBUG_D_MODE
1936    && GP_REG_P (true_regnum (operands[0]))
1937    && GP_REG_P (true_regnum (operands[1]))"
1938   [(parallel [(set (match_dup 7)
1939                    (mult:SI (match_dup 2) (match_dup 3)))
1940               (clobber (match_dup 4))
1941               (clobber (match_dup 5))
1942               (clobber (match_dup 6))])
1943    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
1944   "")
1946 (define_expand "muldi3"
1947   [(set (match_operand:DI 0 "register_operand" "=l")
1948         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1949                  (match_operand:DI 2 "register_operand" "d")))
1950    (clobber (match_scratch:DI 3 "=h"))
1951    (clobber (match_scratch:DI 4 "=a"))]
1952   "TARGET_64BIT"
1954   "
1956   if (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)
1957     emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
1958   else
1959     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1960   DONE;
1963 ;; Don't accept both operands using se_register_operand, because if
1964 ;; both operands are sign extended we would prefer to use mult in the
1965 ;; mulsidi3 pattern.  Commutativity should permit either operand to be
1966 ;; sign extended.
1968 (define_insn "muldi3_internal"
1969   [(set (match_operand:DI 0 "register_operand" "=l")
1970         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1971                  (match_operand:DI 2 "register_operand" "d")))
1972    (clobber (match_scratch:DI 3 "=h"))
1973    (clobber (match_scratch:DI 4 "=a"))]
1974   "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16"
1975   "dmult\\t%1,%2"
1976   [(set_attr "type"     "imul")
1977    (set_attr "mode"     "DI")])
1979 (define_insn "muldi3_internal2"
1980   [(set (match_operand:DI 0 "register_operand" "=d")
1981         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1982                  (match_operand:DI 2 "register_operand" "d")))
1983    (clobber (match_scratch:DI 3 "=h"))
1984    (clobber (match_scratch:DI 4 "=l"))
1985    (clobber (match_scratch:DI 5 "=a"))]
1986   "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)"
1987   "*
1989   if (GENERATE_MULT3_DI)
1990     output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
1991   else
1992     {
1993       rtx xoperands[10];
1995       xoperands[0] = operands[0];
1996       xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM);
1998       output_asm_insn (\"dmult\\t%1,%2\", operands);
1999       output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2000     }
2001   return \"\";
2003   [(set_attr "type"     "imul")
2004    (set_attr "mode"     "DI")
2005    (set (attr "length")
2006         (if_then_else (ne (symbol_ref "GENERATE_MULT3_DI") (const_int 0))
2007                        (const_int 4)
2008                        (const_int 12)))])       ;; mult + mflo + delay
2010 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
2012 (define_expand "mulsidi3"
2013   [(set (match_operand:DI 0 "register_operand" "=x")
2014         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2015                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2016   ""
2017   "
2019   rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
2020   if (TARGET_64BIT)
2021     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
2022                                    dummy, dummy));
2023   else
2024     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
2025                                       dummy, dummy));
2026   DONE;
2029 (define_expand "umulsidi3"
2030   [(set (match_operand:DI 0 "register_operand" "=x")
2031         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2032                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2033   ""
2034   "
2036   rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
2037   if (TARGET_64BIT)
2038     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
2039                                    dummy, dummy));
2040   else
2041     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
2042                                       dummy, dummy));
2043   DONE;
2046 (define_insn "mulsidi3_internal"
2047   [(set (match_operand:DI 0 "register_operand" "=x")
2048         (mult:DI (match_operator:DI 3 "extend_operator"
2049                                     [(match_operand:SI 1 "register_operand" "d")])
2050                  (match_operator:DI 4 "extend_operator"
2051                                     [(match_operand:SI 2 "register_operand" "d")])))
2052    (clobber (match_scratch:SI 5 "=a"))]
2053   "!TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2054   "*
2056   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2057     return \"mult\\t%1,%2\";
2058   return \"multu\\t%1,%2\";
2060   [(set_attr "type"     "imul")
2061    (set_attr "mode"     "SI")])
2063 (define_insn "mulsidi3_64bit"
2064   [(set (match_operand:DI 0 "register_operand" "=a")
2065         (mult:DI (match_operator:DI 3 "extend_operator"
2066                                     [(match_operand:SI 1 "register_operand" "d")])
2067                  (match_operator:DI 4 "extend_operator"
2068                                     [(match_operand:SI 2 "register_operand" "d")])))
2069    (clobber (match_scratch:DI 5 "=l"))
2070    (clobber (match_scratch:DI 6 "=h"))]
2071   "TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2072   "*
2074   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2075     return \"mult\\t%1,%2\";
2076   return \"multu\\t%1,%2\";
2078   [(set_attr "type"     "imul")
2079    (set_attr "mode"     "SI")])
2081 ;; _highpart patterns
2082 (define_expand "smulsi3_highpart"
2083   [(set (match_operand:SI 0 "register_operand" "=h")
2084         (truncate:SI
2085          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2086                                (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2087                       (const_int 32))))]
2088   ""
2089   "
2091   rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
2092   rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
2093 #ifndef NO_MD_PROTOTYPES
2094   rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
2095 #else
2096   rtx (*genfn) ();
2097 #endif
2098   genfn = gen_xmulsi3_highpart_internal;
2099   emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2100                        dummy, dummy2));
2101   DONE;
2104 (define_expand "umulsi3_highpart"
2105   [(set (match_operand:SI 0 "register_operand" "=h")
2106         (truncate:SI
2107          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2108                                (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2109                       (const_int 32))))]
2110   ""
2111   "
2113   rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
2114   rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
2115 #ifndef NO_MD_PROTOTYPES
2116   rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
2117 #else
2118   rtx (*genfn) ();
2119 #endif
2120   genfn = gen_xmulsi3_highpart_internal;
2121   emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2122                        dummy, dummy2));
2123   DONE;
2126 (define_insn "xmulsi3_highpart_internal"
2127   [(set (match_operand:SI 0 "register_operand" "=h")
2128         (truncate:SI
2129          (match_operator:DI 5 "highpart_shift_operator"
2130                             [(mult:DI (match_operator:DI 3 "extend_operator"
2131                                                          [(match_operand:SI 1 "register_operand" "d")])
2132                                       (match_operator:DI 4 "extend_operator"
2133                                                          [(match_operand:SI 2 "register_operand" "d")]))
2134                              (const_int 32)])))
2135    (clobber (match_scratch:SI 6 "=l"))
2136    (clobber (match_scratch:SI 7 "=a"))]
2137   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
2138   "*
2140   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2141     return \"mult\\t%1,%2\";
2142   else
2143     return \"multu\\t%1,%2\";
2145   [(set_attr "type"     "imul")
2146    (set_attr "mode"     "SI")])
2148 (define_insn "smuldi3_highpart"
2149   [(set (match_operand:DI 0 "register_operand" "=h")
2150         (truncate:DI
2151          (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2152                                (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2153                       (const_int 64))))
2154    (clobber (match_scratch:DI 3 "=l"))
2155    (clobber (match_scratch:DI 4 "=a"))]
2156   "TARGET_64BIT"
2157   "dmult\\t%1,%2"
2158   [(set_attr "type"     "imul")
2159    (set_attr "mode"     "DI")])
2161 (define_insn "umuldi3_highpart"
2162   [(set (match_operand:DI 0 "register_operand" "=h")
2163         (truncate:DI
2164          (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2165                                (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2166                       (const_int 64))))
2167    (clobber (match_scratch:DI 3 "=l"))
2168    (clobber (match_scratch:DI 4 "=a"))]
2169   "TARGET_64BIT"
2170   "dmultu\\t%1,%2"
2171   [(set_attr "type"     "imul")
2172    (set_attr "mode"     "DI")])
2174 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2175 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
2177 (define_insn "madsi"
2178   [(set (match_operand:SI 0 "register_operand" "+l")
2179         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2180                           (match_operand:SI 2 "register_operand" "d"))
2181                  (match_dup 0)))
2182    (clobber (match_scratch:SI 3 "=h"))
2183    (clobber (match_scratch:SI 4 "=a"))]
2184   "TARGET_MAD"
2185   "mad\\t%1,%2"
2186   [(set_attr "type"     "imul")
2187    (set_attr "mode"     "SI")])
2189 (define_insn "*mul_acc_di"
2190   [(set (match_operand:DI 0 "register_operand" "+x")
2191         (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2192                            [(match_operand:SI 1 "register_operand" "d")])
2193                           (match_operator:DI 4 "extend_operator"
2194                            [(match_operand:SI 2 "register_operand" "d")]))
2195                  (match_dup 0)))
2196    (clobber (match_scratch:SI 5 "=a"))]
2197   "TARGET_MAD
2198    && ! TARGET_64BIT
2199    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2200   "*
2202   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2203     return \"mad\\t%1,%2\";
2204   else
2205     return \"madu\\t%1,%2\";
2207   [(set_attr "type"     "imul")
2208    (set_attr "mode"     "SI")])
2210 (define_insn "*mul_acc_64bit_di"
2211   [(set (match_operand:DI 0 "register_operand" "+a")
2212         (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2213                            [(match_operand:SI 1 "register_operand" "d")])
2214                           (match_operator:DI 4 "extend_operator"
2215                            [(match_operand:SI 2 "register_operand" "d")]))
2216                  (match_dup 0)))
2217    (clobber (match_scratch:SI 5 "=h"))
2218    (clobber (match_scratch:SI 6 "=l"))]
2219   "TARGET_MAD
2220    && TARGET_64BIT
2221    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2222   "*
2224   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2225     return \"mad\\t%1,%2\";
2226   else
2227     return \"madu\\t%1,%2\";
2229   [(set_attr "type"     "imul")
2230    (set_attr "mode"     "SI")])
2232 ;; Floating point multiply accumulate instructions.
2234 (define_insn ""
2235   [(set (match_operand:DF 0 "register_operand" "=f")
2236         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2237                           (match_operand:DF 2 "register_operand" "f"))
2238                  (match_operand:DF 3 "register_operand" "f")))]
2239   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2240   "madd.d\\t%0,%3,%1,%2"
2241   [(set_attr "type"     "fmadd")
2242    (set_attr "mode"     "DF")])
2244 (define_insn ""
2245   [(set (match_operand:SF 0 "register_operand" "=f")
2246         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2247                           (match_operand:SF 2 "register_operand" "f"))
2248                  (match_operand:SF 3 "register_operand" "f")))]
2249   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2250   "madd.s\\t%0,%3,%1,%2"
2251   [(set_attr "type"     "fmadd")
2252    (set_attr "mode"     "SF")])
2254 (define_insn ""
2255   [(set (match_operand:DF 0 "register_operand" "=f")
2256         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2257                            (match_operand:DF 2 "register_operand" "f"))
2258                   (match_operand:DF 3 "register_operand" "f")))]
2259   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2260   "msub.d\\t%0,%3,%1,%2"
2261   [(set_attr "type"     "fmadd")
2262    (set_attr "mode"     "DF")])
2264 (define_insn ""
2265   [(set (match_operand:SF 0 "register_operand" "=f")
2266         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2267                            (match_operand:SF 2 "register_operand" "f"))
2268                   (match_operand:SF 3 "register_operand" "f")))]
2270   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2271   "msub.s\\t%0,%3,%1,%2"
2272   [(set_attr "type"     "fmadd")
2273    (set_attr "mode"     "SF")])
2275 (define_insn ""
2276   [(set (match_operand:DF 0 "register_operand" "=f")
2277         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2278                                   (match_operand:DF 2 "register_operand" "f"))
2279                          (match_operand:DF 3 "register_operand" "f"))))]
2280   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2281   "nmadd.d\\t%0,%3,%1,%2"
2282   [(set_attr "type"     "fmadd")
2283    (set_attr "mode"     "DF")])
2285 (define_insn ""
2286   [(set (match_operand:SF 0 "register_operand" "=f")
2287         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2288                                   (match_operand:SF 2 "register_operand" "f"))
2289                          (match_operand:SF 3 "register_operand" "f"))))]
2290   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2291   "nmadd.s\\t%0,%3,%1,%2"
2292   [(set_attr "type"     "fmadd")
2293    (set_attr "mode"     "SF")])
2295 (define_insn ""
2296   [(set (match_operand:DF 0 "register_operand" "=f")
2297         (minus:DF (match_operand:DF 1 "register_operand" "f")
2298                   (mult:DF (match_operand:DF 2 "register_operand" "f")
2299                            (match_operand:DF 3 "register_operand" "f"))))]
2300   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2301   "nmsub.d\\t%0,%1,%2,%3"
2302   [(set_attr "type"     "fmadd")
2303    (set_attr "mode"     "DF")])
2305 (define_insn ""
2306   [(set (match_operand:SF 0 "register_operand" "=f")
2307         (minus:SF (match_operand:SF 1 "register_operand" "f")
2308                   (mult:SF (match_operand:SF 2 "register_operand" "f")
2309                            (match_operand:SF 3 "register_operand" "f"))))]
2310   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2311   "nmsub.s\\t%0,%1,%2,%3"
2312   [(set_attr "type"     "fmadd")
2313    (set_attr "mode"     "SF")])
2316 ;;  ....................
2318 ;;      DIVISION and REMAINDER
2320 ;;  ....................
2323 (define_insn "divdf3"
2324   [(set (match_operand:DF 0 "register_operand" "=f")
2325         (div:DF (match_operand:DF 1 "register_operand" "f")
2326                 (match_operand:DF 2 "register_operand" "f")))]
2327   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2328   "div.d\\t%0,%1,%2"
2329   [(set_attr "type"     "fdiv")
2330    (set_attr "mode"     "DF")])
2332 (define_insn "divsf3"
2333   [(set (match_operand:SF 0 "register_operand" "=f")
2334         (div:SF (match_operand:SF 1 "register_operand" "f")
2335                 (match_operand:SF 2 "register_operand" "f")))]
2336   "TARGET_HARD_FLOAT"
2337   "div.s\\t%0,%1,%2"
2338   [(set_attr "type"     "fdiv")
2339    (set_attr "mode"     "SF")])
2341 (define_insn ""
2342   [(set (match_operand:DF 0 "register_operand" "=f")
2343         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2344                 (match_operand:DF 2 "register_operand" "f")))]
2345   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2346   "recip.d\\t%0,%2"
2347   [(set_attr "type"     "fdiv")
2348    (set_attr "mode"     "DF")])
2350 (define_insn ""
2351   [(set (match_operand:SF 0 "register_operand" "=f")
2352         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2353                 (match_operand:SF 2 "register_operand" "f")))]
2354   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2355   "recip.s\\t%0,%2"
2356   [(set_attr "type"     "fdiv")
2357    (set_attr "mode"     "SF")])
2359 ;; If optimizing, prefer the divmod functions over separate div and
2360 ;; mod functions, since this will allow using one instruction for both
2361 ;; the quotient and remainder.  At present, the divmod is not moved out
2362 ;; of loops if it is constant within the loop, so allow -mdebugc to
2363 ;; use the old method of doing things.
2365 ;; 64 is the multiply/divide hi register
2366 ;; 65 is the multiply/divide lo register
2368 ;; ??? We can't accept constants here, because the MIPS assembler will replace
2369 ;; a divide by power of 2 with a shift, and then the remainder is no longer
2370 ;; available.
2372 (define_expand "divmodsi4"
2373   [(set (match_operand:SI 0 "register_operand" "=d")
2374         (div:SI (match_operand:SI 1 "register_operand" "d")
2375                 (match_operand:SI 2 "register_operand" "d")))
2376    (set (match_operand:SI 3 "register_operand" "=d")
2377         (mod:SI (match_dup 1)
2378                 (match_dup 2)))
2379    (clobber (match_scratch:SI 4 "=l"))
2380    (clobber (match_scratch:SI 5 "=h"))
2381    (clobber (match_scratch:SI 6 "=a"))]
2382   "optimize"
2383   "
2385   emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
2386              operands[3]));
2387   if (!TARGET_NO_CHECK_ZERO_DIV)
2388     {
2389       emit_insn (gen_div_trap (operands[2],
2390                                GEN_INT (0),
2391                                GEN_INT (0x7)));
2392     }
2393   if (TARGET_CHECK_RANGE_DIV)
2394     {
2395       emit_insn (gen_div_trap (operands[2],
2396                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2397                                GEN_INT (0x6)));
2398       emit_insn (gen_div_trap (operands[2],
2399                                copy_to_mode_reg (SImode,
2400                                                  GEN_INT
2401                                                  (trunc_int_for_mode
2402                                                   (BITMASK_HIGH, SImode))),
2403                                GEN_INT (0x6)));
2404     }
2406   DONE;
2409 (define_insn "divmodsi4_internal"
2410   [(set (match_operand:SI 0 "register_operand" "=l")
2411         (div:SI (match_operand:SI 1 "register_operand" "d")
2412                 (match_operand:SI 2 "register_operand" "d")))
2413    (set (match_operand:SI 3 "register_operand" "=h")
2414         (mod:SI (match_dup 1)
2415                 (match_dup 2)))
2416    (clobber (match_scratch:SI 4 "=a"))]
2417   "optimize"
2418   "div\\t$0,%1,%2"
2419   [(set_attr "type"     "idiv")
2420    (set_attr "mode"     "SI")])
2422 (define_expand "divmoddi4"
2423   [(set (match_operand:DI 0 "register_operand" "=d")
2424         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2425                 (match_operand:DI 2 "se_register_operand" "d")))
2426    (set (match_operand:DI 3 "register_operand" "=d")
2427         (mod:DI (match_dup 1)
2428                 (match_dup 2)))
2429    (clobber (match_scratch:DI 4 "=l"))
2430    (clobber (match_scratch:DI 5 "=h"))
2431    (clobber (match_scratch:DI 6 "=a"))]
2432   "TARGET_64BIT && optimize"
2433   "
2435   emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
2436              operands[3]));
2437   if (!TARGET_NO_CHECK_ZERO_DIV)
2438     {
2439       emit_insn (gen_div_trap (operands[2],
2440                                GEN_INT (0),
2441                                GEN_INT (0x7)));
2442     }
2443   if (TARGET_CHECK_RANGE_DIV)
2444     {
2445       emit_insn (gen_div_trap (operands[2],
2446                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2447                                GEN_INT (0x6)));
2448       emit_insn (gen_div_trap (operands[2],
2449                                copy_to_mode_reg (DImode,
2450                                                  GEN_INT (BITMASK_HIGH)),
2451                                GEN_INT (0x6)));
2452     }
2454   DONE;
2457 (define_insn "divmoddi4_internal"
2458   [(set (match_operand:DI 0 "register_operand" "=l")
2459         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2460                 (match_operand:DI 2 "se_register_operand" "d")))
2461    (set (match_operand:DI 3 "register_operand" "=h")
2462         (mod:DI (match_dup 1)
2463                 (match_dup 2)))
2464    (clobber (match_scratch:DI 4 "=a"))]
2465   "TARGET_64BIT && optimize"
2466   "ddiv\\t$0,%1,%2"
2467   [(set_attr "type"     "idiv")
2468    (set_attr "mode"     "SI")])
2470 (define_expand "udivmodsi4"
2471   [(set (match_operand:SI 0 "register_operand" "=d")
2472         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2473                  (match_operand:SI 2 "register_operand" "d")))
2474    (set (match_operand:SI 3 "register_operand" "=d")
2475         (umod:SI (match_dup 1)
2476                  (match_dup 2)))
2477    (clobber (match_scratch:SI 4 "=l"))
2478    (clobber (match_scratch:SI 5 "=h"))
2479    (clobber (match_scratch:SI 6 "=a"))]
2480   "optimize"
2481   "
2483   emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
2484                                       operands[3]));
2485   if (!TARGET_NO_CHECK_ZERO_DIV)
2486     {
2487       emit_insn (gen_div_trap (operands[2],
2488                                GEN_INT (0),
2489                                GEN_INT (0x7)));
2490     }
2492   DONE;
2495 (define_insn "udivmodsi4_internal"
2496   [(set (match_operand:SI 0 "register_operand" "=l")
2497         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2498                  (match_operand:SI 2 "register_operand" "d")))
2499    (set (match_operand:SI 3 "register_operand" "=h")
2500         (umod:SI (match_dup 1)
2501                  (match_dup 2)))
2502    (clobber (match_scratch:SI 4 "=a"))]
2503   "optimize"
2504   "divu\\t$0,%1,%2"
2505   [(set_attr "type"     "idiv")
2506    (set_attr "mode"     "SI")])
2508 (define_expand "udivmoddi4"
2509   [(set (match_operand:DI 0 "register_operand" "=d")
2510         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2511                  (match_operand:DI 2 "se_register_operand" "d")))
2512    (set (match_operand:DI 3 "register_operand" "=d")
2513         (umod:DI (match_dup 1)
2514                  (match_dup 2)))
2515    (clobber (match_scratch:DI 4 "=l"))
2516    (clobber (match_scratch:DI 5 "=h"))
2517    (clobber (match_scratch:DI 6 "=a"))]
2518   "TARGET_64BIT && optimize"
2519   "
2521   emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
2522                                       operands[3]));
2523   if (!TARGET_NO_CHECK_ZERO_DIV)
2524     {
2525       emit_insn (gen_div_trap (operands[2],
2526                                GEN_INT (0),
2527                                GEN_INT (0x7)));
2528     }
2530   DONE;
2533 (define_insn "udivmoddi4_internal"
2534   [(set (match_operand:DI 0 "register_operand" "=l")
2535         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2536                  (match_operand:DI 2 "se_register_operand" "d")))
2537    (set (match_operand:DI 3 "register_operand" "=h")
2538         (umod:DI (match_dup 1)
2539                  (match_dup 2)))
2540    (clobber (match_scratch:DI 4 "=a"))]
2541   "TARGET_64BIT && optimize"
2542   "ddivu\\t$0,%1,%2"
2543   [(set_attr "type"     "idiv")
2544    (set_attr "mode"     "SI")])
2546 ;; Division trap
2548 (define_expand "div_trap"
2549   [(trap_if (eq (match_operand 0 "register_operand" "d")
2550                 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2551             (match_operand 2 "immediate_operand" ""))]
2552   ""
2553   "
2555   if (TARGET_MIPS16)
2556     emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
2557   else
2558     emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
2559   DONE;
2562 (define_insn "div_trap_normal"
2563   [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2564                 (match_operand 1 "true_reg_or_0_operand" "d,J"))
2565             (match_operand 2 "immediate_operand" ""))]
2566   "!TARGET_MIPS16"
2567   "*
2569   rtx link;
2570   int have_dep_anti = 0;
2572   /* For divmod if one division is not needed then we don't need an extra
2573      divide by zero trap, which is anti dependent on previous trap */
2574   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2576     if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2577         && GET_CODE (XEXP (link, 0)) == INSN
2578         && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2579         && which_alternative == 1)
2580       have_dep_anti = 1;
2581   if (! have_dep_anti)
2582     {
2583       if (GENERATE_BRANCHLIKELY)
2584         {
2585           if (which_alternative == 1)
2586             return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2587           else
2588             return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2589         }
2590       else
2591         {
2592           if (which_alternative == 1)
2593             return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2594           else
2595             return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2596         }
2597     }
2598   return \"\";
2600   [(set_attr "type" "unknown")
2601    (set_attr "length" "12")])
2604 ;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
2606 (define_insn "div_trap_mips16"
2607   [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2608                 (match_operand 1 "true_reg_or_0_operand" "d,J"))
2609             (match_operand 2 "immediate_operand" ""))
2610    (clobber (reg:SI 24))]
2611   "TARGET_MIPS16"
2612   "*
2614   rtx link;
2615   int have_dep_anti = 0;
2617   /* For divmod if one division is not needed then we don't need an extra
2618      divide by zero trap, which is anti dependent on previous trap */
2619   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2621     if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2622         && GET_CODE (XEXP (link, 0)) == INSN
2623         && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2624         && which_alternative == 1)
2625       have_dep_anti = 1;
2626   if (! have_dep_anti)
2627     {
2628       /* No branch delay slots on mips16.  */
2629       if (which_alternative == 1)
2630         return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2631       else
2632         return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2633     }
2634   return \"\";
2636   [(set_attr "type" "unknown")
2637    (set_attr "length" "12")])
2639 (define_expand "divsi3"
2640   [(set (match_operand:SI 0 "register_operand" "=l")
2641         (div:SI (match_operand:SI 1 "register_operand" "d")
2642                 (match_operand:SI 2 "register_operand" "d")))
2643    (clobber (match_scratch:SI 3 "=h"))
2644    (clobber (match_scratch:SI 4 "=a"))]
2645   "!optimize"
2646   "
2648   emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
2649   if (!TARGET_NO_CHECK_ZERO_DIV)
2650     {
2651       emit_insn (gen_div_trap (operands[2],
2652                                GEN_INT (0),
2653                                GEN_INT (0x7)));
2654     }
2655   if (TARGET_CHECK_RANGE_DIV)
2656     {
2657       emit_insn (gen_div_trap (operands[2],
2658                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2659                                GEN_INT (0x6)));
2660       emit_insn (gen_div_trap (operands[2],
2661                                copy_to_mode_reg (SImode,
2662                                                  GEN_INT
2663                                                  (trunc_int_for_mode
2664                                                   (BITMASK_HIGH, SImode))),
2665                                GEN_INT (0x6)));
2666     }
2668   DONE;
2671 (define_insn "divsi3_internal"
2672   [(set (match_operand:SI 0 "register_operand" "=l")
2673         (div:SI (match_operand:SI 1 "register_operand" "d")
2674                 (match_operand:SI 2 "nonmemory_operand" "di")))
2675    (clobber (match_scratch:SI 3 "=h"))
2676    (clobber (match_scratch:SI 4 "=a"))]
2677   "!optimize"
2678   "div\\t$0,%1,%2"
2679   [(set_attr "type"     "idiv")
2680    (set_attr "mode"     "SI")])
2682 (define_expand "divdi3"
2683   [(set (match_operand:DI 0 "register_operand" "=l")
2684         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2685                 (match_operand:DI 2 "se_register_operand" "d")))
2686    (clobber (match_scratch:DI 3 "=h"))
2687    (clobber (match_scratch:DI 4 "=a"))]
2688   "TARGET_64BIT && !optimize"
2689   "
2691   emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
2692   if (!TARGET_NO_CHECK_ZERO_DIV)
2693     {
2694       emit_insn (gen_div_trap (operands[2],
2695                                GEN_INT (0),
2696                                GEN_INT (0x7)));
2697     }
2698   if (TARGET_CHECK_RANGE_DIV)
2699     {
2700       emit_insn (gen_div_trap (operands[2],
2701                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2702                                GEN_INT (0x6)));
2703       emit_insn (gen_div_trap (operands[2],
2704                                copy_to_mode_reg (DImode,
2705                                                  GEN_INT (BITMASK_HIGH)),
2706                                GEN_INT (0x6)));
2707     }
2709   DONE;
2712 (define_insn "divdi3_internal"
2713   [(set (match_operand:DI 0 "register_operand" "=l")
2714         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2715                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2716    (clobber (match_scratch:SI 3 "=h"))
2717    (clobber (match_scratch:SI 4 "=a"))]
2718   "TARGET_64BIT && !optimize"
2719   "ddiv\\t$0,%1,%2"
2720   [(set_attr "type"     "idiv")
2721    (set_attr "mode"     "DI")])
2723 (define_expand "modsi3"
2724   [(set (match_operand:SI 0 "register_operand" "=h")
2725         (mod:SI (match_operand:SI 1 "register_operand" "d")
2726                 (match_operand:SI 2 "register_operand" "d")))
2727    (clobber (match_scratch:SI 3 "=l"))
2728    (clobber (match_scratch:SI 4 "=a"))]
2729   "!optimize"
2730   "
2732   emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
2733   if (!TARGET_NO_CHECK_ZERO_DIV)
2734     {
2735       emit_insn (gen_div_trap (operands[2],
2736                                GEN_INT (0),
2737                                GEN_INT (0x7)));
2738     }
2739   if (TARGET_CHECK_RANGE_DIV)
2740     {
2741       emit_insn (gen_div_trap (operands[2],
2742                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2743                                GEN_INT (0x6)));
2744       emit_insn (gen_div_trap (operands[2],
2745                                copy_to_mode_reg (SImode,
2746                                                  GEN_INT
2747                                                  (trunc_int_for_mode
2748                                                   (BITMASK_HIGH, SImode))),
2749                                GEN_INT (0x6)));
2750     }
2752   DONE;
2755 (define_insn "modsi3_internal"
2756   [(set (match_operand:SI 0 "register_operand" "=h")
2757         (mod:SI (match_operand:SI 1 "register_operand" "d")
2758                 (match_operand:SI 2 "nonmemory_operand" "di")))
2759    (clobber (match_scratch:SI 3 "=l"))
2760    (clobber (match_scratch:SI 4 "=a"))]
2761   "!optimize"
2762   "div\\t$0,%1,%2"
2763   [(set_attr "type"     "idiv")
2764    (set_attr "mode"     "SI")])
2766 (define_expand "moddi3"
2767   [(set (match_operand:DI 0 "register_operand" "=h")
2768         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2769                 (match_operand:DI 2 "se_register_operand" "d")))
2770    (clobber (match_scratch:DI 3 "=l"))
2771    (clobber (match_scratch:DI 4 "=a"))]
2772   "TARGET_64BIT && !optimize"
2773   "
2775   emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
2776   if (!TARGET_NO_CHECK_ZERO_DIV)
2777     {
2778       emit_insn (gen_div_trap (operands[2],
2779                                GEN_INT (0),
2780                                GEN_INT (0x7)));
2781     }
2782   if (TARGET_CHECK_RANGE_DIV)
2783     {
2784       emit_insn (gen_div_trap (operands[2],
2785                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2786                                GEN_INT (0x6)));
2787       emit_insn (gen_div_trap (operands[2],
2788                                copy_to_mode_reg (DImode,
2789                                                  GEN_INT (BITMASK_HIGH)),
2790                                GEN_INT (0x6)));
2791     }
2793   DONE;
2796 (define_insn "moddi3_internal"
2797   [(set (match_operand:DI 0 "register_operand" "=h")
2798         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2799                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2800    (clobber (match_scratch:SI 3 "=l"))
2801    (clobber (match_scratch:SI 4 "=a"))]
2802   "TARGET_64BIT && !optimize"
2803   "ddiv\\t$0,%1,%2"
2804   [(set_attr "type"     "idiv")
2805    (set_attr "mode"     "DI")])
2807 (define_expand "udivsi3"
2808   [(set (match_operand:SI 0 "register_operand" "=l")
2809         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2810                  (match_operand:SI 2 "register_operand" "d")))
2811    (clobber (match_scratch:SI 3 "=h"))
2812    (clobber (match_scratch:SI 4 "=a"))]
2813   "!optimize"
2814   "
2816   emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
2817   if (!TARGET_NO_CHECK_ZERO_DIV)
2818     {
2819       emit_insn (gen_div_trap (operands[2],
2820                                GEN_INT (0),
2821                                GEN_INT (0x7)));
2822     }
2824   DONE;
2827 (define_insn "udivsi3_internal"
2828   [(set (match_operand:SI 0 "register_operand" "=l")
2829         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2830                  (match_operand:SI 2 "nonmemory_operand" "di")))
2831    (clobber (match_scratch:SI 3 "=h"))
2832    (clobber (match_scratch:SI 4 "=a"))]
2833   "!optimize"
2834   "divu\\t$0,%1,%2"
2835   [(set_attr "type"     "idiv")
2836    (set_attr "mode"     "SI")])
2838 (define_expand "udivdi3"
2839   [(set (match_operand:DI 0 "register_operand" "=l")
2840         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2841                  (match_operand:DI 2 "se_register_operand" "di")))
2842    (clobber (match_scratch:DI 3 "=h"))
2843    (clobber (match_scratch:DI 4 "=a"))]
2844   "TARGET_64BIT && !optimize"
2845   "
2847   emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
2848   if (!TARGET_NO_CHECK_ZERO_DIV)
2849     {
2850       emit_insn (gen_div_trap (operands[2],
2851                                GEN_INT (0),
2852                                GEN_INT (0x7)));
2853     }
2855   DONE;
2858 (define_insn "udivdi3_internal"
2859   [(set (match_operand:DI 0 "register_operand" "=l")
2860         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2861                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
2862    (clobber (match_scratch:SI 3 "=h"))
2863    (clobber (match_scratch:SI 4 "=a"))]
2864   "TARGET_64BIT && !optimize"
2865   "ddivu\\t$0,%1,%2"
2866   [(set_attr "type"     "idiv")
2867    (set_attr "mode"     "DI")])
2869 (define_expand "umodsi3"
2870   [(set (match_operand:SI 0 "register_operand" "=h")
2871         (umod:SI (match_operand:SI 1 "register_operand" "d")
2872                  (match_operand:SI 2 "register_operand" "d")))
2873    (clobber (match_scratch:SI 3 "=l"))
2874    (clobber (match_scratch:SI 4 "=a"))]
2875   "!optimize"
2876   "
2878   emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
2879   if (!TARGET_NO_CHECK_ZERO_DIV)
2880     {
2881       emit_insn (gen_div_trap (operands[2],
2882                                GEN_INT (0),
2883                                GEN_INT (0x7)));
2884     }
2886   DONE;
2889 (define_insn "umodsi3_internal"
2890   [(set (match_operand:SI 0 "register_operand" "=h")
2891         (umod:SI (match_operand:SI 1 "register_operand" "d")
2892                  (match_operand:SI 2 "nonmemory_operand" "di")))
2893    (clobber (match_scratch:SI 3 "=l"))
2894    (clobber (match_scratch:SI 4 "=a"))]
2895   "!optimize"
2896   "divu\\t$0,%1,%2"
2897   [(set_attr "type"     "idiv")
2898    (set_attr "mode"     "SI")])
2900 (define_expand "umoddi3"
2901   [(set (match_operand:DI 0 "register_operand" "=h")
2902         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2903                  (match_operand:DI 2 "se_register_operand" "di")))
2904    (clobber (match_scratch:DI 3 "=l"))
2905    (clobber (match_scratch:DI 4 "=a"))]
2906   "TARGET_64BIT && !optimize"
2907   "
2909   emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
2910   if (!TARGET_NO_CHECK_ZERO_DIV)
2911     {
2912       emit_insn (gen_div_trap (operands[2],
2913                                GEN_INT (0),
2914                                GEN_INT (0x7)));
2915     }
2917   DONE;
2920 (define_insn "umoddi3_internal"
2921   [(set (match_operand:DI 0 "register_operand" "=h")
2922         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2923                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
2924    (clobber (match_scratch:SI 3 "=l"))
2925    (clobber (match_scratch:SI 4 "=a"))]
2926   "TARGET_64BIT && !optimize"
2927   "ddivu\\t$0,%1,%2"
2928   [(set_attr "type"     "idiv")
2929    (set_attr "mode"     "DI")])
2932 ;;  ....................
2934 ;;      SQUARE ROOT
2936 ;;  ....................
2938 (define_insn "sqrtdf2"
2939   [(set (match_operand:DF 0 "register_operand" "=f")
2940         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2941   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2942   "sqrt.d\\t%0,%1"
2943   [(set_attr "type"     "fsqrt")
2944    (set_attr "mode"     "DF")])
2946 (define_insn "sqrtsf2"
2947   [(set (match_operand:SF 0 "register_operand" "=f")
2948         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2949   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2950   "sqrt.s\\t%0,%1"
2951   [(set_attr "type"     "fsqrt")
2952    (set_attr "mode"     "SF")])
2954 (define_insn ""
2955   [(set (match_operand:DF 0 "register_operand" "=f")
2956         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2957                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2958   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2959   "rsqrt.d\\t%0,%2"
2960   [(set_attr "type"     "fsqrt")
2961    (set_attr "mode"     "DF")])
2963 (define_insn ""
2964   [(set (match_operand:SF 0 "register_operand" "=f")
2965         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2966                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2967   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2968   "rsqrt.s\\t%0,%2"
2969   [(set_attr "type"     "fsqrt")
2970    (set_attr "mode"     "SF")])
2974 ;;  ....................
2976 ;;      ABSOLUTE VALUE
2978 ;;  ....................
2980 ;; Do not use the integer abs macro instruction, since that signals an
2981 ;; exception on -2147483648 (sigh).
2983 (define_insn "abssi2"
2984   [(set (match_operand:SI 0 "register_operand" "=d")
2985         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2986   "!TARGET_MIPS16"
2987   "*
2989   dslots_jump_total++;
2990   dslots_jump_filled++;
2991   operands[2] = const0_rtx;
2993   if (REGNO (operands[0]) == REGNO (operands[1]))
2994     {
2995       if (GENERATE_BRANCHLIKELY)
2996         return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
2997       else
2998         return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
2999     }
3000   else
3001     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
3003   [(set_attr "type"     "multi")
3004    (set_attr "mode"     "SI")
3005    (set_attr "length"   "12")])
3007 (define_insn "absdi2"
3008   [(set (match_operand:DI 0 "register_operand" "=d")
3009         (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
3010   "TARGET_64BIT && !TARGET_MIPS16"
3011   "*
3013   unsigned int regno1;
3014   dslots_jump_total++;
3015   dslots_jump_filled++;
3016   operands[2] = const0_rtx;
3018   if (GET_CODE (operands[1]) == REG)
3019     regno1 = REGNO (operands[1]);
3020   else
3021     regno1 = REGNO (XEXP (operands[1], 0));
3023   if (REGNO (operands[0]) == regno1)
3024     return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3025   else
3026     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3028   [(set_attr "type"     "multi")
3029    (set_attr "mode"     "DI")
3030    (set_attr "length"   "12")])
3032 (define_insn "absdf2"
3033   [(set (match_operand:DF 0 "register_operand" "=f")
3034         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
3035   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3036   "abs.d\\t%0,%1"
3037   [(set_attr "type"     "fabs")
3038    (set_attr "mode"     "DF")])
3040 (define_insn "abssf2"
3041   [(set (match_operand:SF 0 "register_operand" "=f")
3042         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
3043   "TARGET_HARD_FLOAT"
3044   "abs.s\\t%0,%1"
3045   [(set_attr "type"     "fabs")
3046    (set_attr "mode"     "SF")])
3050 ;;  ....................
3052 ;;      FIND FIRST BIT INSTRUCTION
3054 ;;  ....................
3057 (define_insn "ffssi2"
3058   [(set (match_operand:SI 0 "register_operand" "=&d")
3059         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
3060    (clobber (match_scratch:SI 2 "=&d"))
3061    (clobber (match_scratch:SI 3 "=&d"))]
3062   "!TARGET_MIPS16"
3063   "*
3065   dslots_jump_total += 2;
3066   dslots_jump_filled += 2;
3067   operands[4] = const0_rtx;
3069   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3070     return \"%(\\
3071 move\\t%0,%z4\\n\\
3072 \\tbeq\\t%1,%z4,2f\\n\\
3073 %~1:\\tand\\t%2,%1,0x0001\\n\\
3074 \\taddu\\t%0,%0,1\\n\\
3075 \\tbeq\\t%2,%z4,1b\\n\\
3076 \\tsrl\\t%1,%1,1\\n\\
3077 %~2:%)\";
3079   return \"%(\\
3080 move\\t%0,%z4\\n\\
3081 \\tmove\\t%3,%1\\n\\
3082 \\tbeq\\t%3,%z4,2f\\n\\
3083 %~1:\\tand\\t%2,%3,0x0001\\n\\
3084 \\taddu\\t%0,%0,1\\n\\
3085 \\tbeq\\t%2,%z4,1b\\n\\
3086 \\tsrl\\t%3,%3,1\\n\\
3087 %~2:%)\";
3089   [(set_attr "type"     "multi")
3090    (set_attr "mode"     "SI")
3091    (set_attr "length"   "12")])
3093 (define_insn "ffsdi2"
3094   [(set (match_operand:DI 0 "register_operand" "=&d")
3095         (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
3096    (clobber (match_scratch:DI 2 "=&d"))
3097    (clobber (match_scratch:DI 3 "=&d"))]
3098   "TARGET_64BIT && !TARGET_MIPS16"
3099   "*
3101   dslots_jump_total += 2;
3102   dslots_jump_filled += 2;
3103   operands[4] = const0_rtx;
3105   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3106     return \"%(\\
3107 move\\t%0,%z4\\n\\
3108 \\tbeq\\t%1,%z4,2f\\n\\
3109 %~1:\\tand\\t%2,%1,0x0001\\n\\
3110 \\tdaddu\\t%0,%0,1\\n\\
3111 \\tbeq\\t%2,%z4,1b\\n\\
3112 \\tdsrl\\t%1,%1,1\\n\\
3113 %~2:%)\";
3115   return \"%(\\
3116 move\\t%0,%z4\\n\\
3117 \\tmove\\t%3,%1\\n\\
3118 \\tbeq\\t%3,%z4,2f\\n\\
3119 %~1:\\tand\\t%2,%3,0x0001\\n\\
3120 \\tdaddu\\t%0,%0,1\\n\\
3121 \\tbeq\\t%2,%z4,1b\\n\\
3122 \\tdsrl\\t%3,%3,1\\n\\
3123 %~2:%)\";
3125   [(set_attr "type"     "multi")
3126    (set_attr "mode"     "DI")
3127    (set_attr "length"   "24")])
3131 ;;  ....................
3133 ;;      NEGATION and ONE'S COMPLEMENT
3135 ;;  ....................
3137 (define_insn "negsi2"
3138   [(set (match_operand:SI 0 "register_operand" "=d")
3139         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
3140   ""
3141   "*
3143   if (TARGET_MIPS16)
3144     return \"neg\\t%0,%1\";
3145   operands[2] = const0_rtx;
3146   return \"subu\\t%0,%z2,%1\";
3148   [(set_attr "type"     "arith")
3149    (set_attr "mode"     "SI")])
3151 (define_expand "negdi2"
3152   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
3153                    (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
3154               (clobber (match_dup 2))])]
3155   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3156   "
3158   if (TARGET_64BIT)
3159     {
3160       emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
3161       DONE;
3162     }
3164   operands[2] = gen_reg_rtx (SImode);
3167 (define_insn "negdi2_internal"
3168   [(set (match_operand:DI 0 "register_operand" "=d")
3169         (neg:DI (match_operand:DI 1 "register_operand" "d")))
3170    (clobber (match_operand:SI 2 "register_operand" "=d"))]
3171   "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
3172   "*
3174   operands[3] = const0_rtx;
3175   return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
3177   [(set_attr "type"     "darith")
3178    (set_attr "mode"     "DI")
3179    (set_attr "length"   "16")])
3181 (define_insn "negdi2_internal_2"
3182   [(set (match_operand:DI 0 "register_operand" "=d")
3183         (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
3184   "TARGET_64BIT && !TARGET_MIPS16"
3185   "*
3187   operands[2] = const0_rtx;
3188   return \"dsubu\\t%0,%z2,%1\";
3190   [(set_attr "type"     "arith")
3191    (set_attr "mode"     "DI")])
3193 (define_insn "negdf2"
3194   [(set (match_operand:DF 0 "register_operand" "=f")
3195         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3196   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3197   "neg.d\\t%0,%1"
3198   [(set_attr "type"     "fneg")
3199    (set_attr "mode"     "DF")])
3201 (define_insn "negsf2"
3202   [(set (match_operand:SF 0 "register_operand" "=f")
3203         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3204   "TARGET_HARD_FLOAT"
3205   "neg.s\\t%0,%1"
3206   [(set_attr "type"     "fneg")
3207    (set_attr "mode"     "SF")])
3209 (define_insn "one_cmplsi2"
3210   [(set (match_operand:SI 0 "register_operand" "=d")
3211         (not:SI (match_operand:SI 1 "register_operand" "d")))]
3212   ""
3213   "*
3215   if (TARGET_MIPS16)
3216     return \"not\\t%0,%1\";
3217   operands[2] = const0_rtx;
3218   return \"nor\\t%0,%z2,%1\";
3220   [(set_attr "type"     "arith")
3221    (set_attr "mode"     "SI")])
3223 (define_insn "one_cmpldi2"
3224   [(set (match_operand:DI 0 "register_operand" "=d")
3225         (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
3226   ""
3227   "*
3229   if (TARGET_MIPS16)
3230     {
3231       if (TARGET_64BIT)
3232         return \"not\\t%0,%1\";
3233       return \"not\\t%M0,%M1\;not\\t%L0,%L1\";
3234     }
3235   operands[2] = const0_rtx;
3236   if (TARGET_64BIT)
3237     return \"nor\\t%0,%z2,%1\";
3238   return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
3240   [(set_attr "type"     "darith")
3241    (set_attr "mode"     "DI")
3242    (set (attr "length")
3243         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3244                        (const_int 4)
3245                        (const_int 8)))])
3247 (define_split
3248   [(set (match_operand:DI 0 "register_operand" "")
3249         (not:DI (match_operand:DI 1 "register_operand" "")))]
3250   "reload_completed && !TARGET_64BIT
3251    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3252    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3253    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3255   [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
3256    (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))]
3257   "")
3261 ;;  ....................
3263 ;;      LOGICAL
3265 ;;  ....................
3268 ;; Many of these instructions uses trivial define_expands, because we
3269 ;; want to use a different set of constraints when TARGET_MIPS16.
3271 (define_expand "andsi3"
3272   [(set (match_operand:SI 0 "register_operand" "=d,d")
3273         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3274                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3275   ""
3276   "
3278   if (TARGET_MIPS16)
3279     operands[2] = force_reg (SImode, operands[2]);
3282 (define_insn ""
3283   [(set (match_operand:SI 0 "register_operand" "=d,d")
3284         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3285                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3286   "!TARGET_MIPS16"
3287   "@
3288    and\\t%0,%1,%2
3289    andi\\t%0,%1,%x2"
3290   [(set_attr "type"     "arith")
3291    (set_attr "mode"     "SI")])
3293 (define_insn ""
3294   [(set (match_operand:SI 0 "register_operand" "=d")
3295         (and:SI (match_operand:SI 1 "register_operand" "%0")
3296                 (match_operand:SI 2 "register_operand" "d")))]
3297   "TARGET_MIPS16"
3298   "and\\t%0,%2"
3299   [(set_attr "type"     "arith")
3300    (set_attr "mode"     "SI")])
3302 (define_expand "anddi3"
3303   [(set (match_operand:DI 0 "register_operand" "=d")
3304         (and:DI (match_operand:DI 1 "se_register_operand" "d")
3305                 (match_operand:DI 2 "se_register_operand" "d")))]
3306   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3307   "
3309   if (TARGET_MIPS16)
3310     operands[2] = force_reg (DImode, operands[2]);
3313 (define_insn ""
3314   [(set (match_operand:DI 0 "register_operand" "=d")
3315         (and:DI (match_operand:DI 1 "se_register_operand" "d")
3316                 (match_operand:DI 2 "se_register_operand" "d")))]
3317   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3318   "*
3320   if (TARGET_64BIT)
3321     return \"and\\t%0,%1,%2\";
3322   return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
3324   [(set_attr "type"     "darith")
3325    (set_attr "mode"     "DI")
3326    (set (attr "length")
3327         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3328                        (const_int 4)
3329                        (const_int 8)))])
3331 (define_insn ""
3332   [(set (match_operand:DI 0 "register_operand" "=d")
3333         (and:DI (match_operand:DI 1 "se_register_operand" "0")
3334                 (match_operand:DI 2 "se_register_operand" "d")))]
3335   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3336   "*
3338   if (TARGET_64BIT)
3339     return \"and\\t%0,%2\";
3340   return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
3342   [(set_attr "type"     "darith")
3343    (set_attr "mode"     "DI")
3344    (set (attr "length")
3345         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3346                        (const_int 4)
3347                        (const_int 8)))])
3349 (define_split
3350   [(set (match_operand:DI 0 "register_operand" "")
3351         (and:DI (match_operand:DI 1 "register_operand" "")
3352                 (match_operand:DI 2 "register_operand" "")))]
3353   "reload_completed && !TARGET_64BIT
3354    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3355    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3356    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3357    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3359   [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3360    (set (subreg:SI (match_dup 0) 4) (and:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3361   "")
3363 (define_insn "anddi3_internal1"
3364   [(set (match_operand:DI 0 "register_operand" "=d,d")
3365         (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
3366                 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
3367   "TARGET_64BIT && !TARGET_MIPS16"
3368   "@
3369    and\\t%0,%1,%2
3370    andi\\t%0,%1,%x2"
3371   [(set_attr "type"     "arith")
3372    (set_attr "mode"     "DI")])
3374 (define_expand "iorsi3"
3375   [(set (match_operand:SI 0 "register_operand" "=d,d")
3376         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3377                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3378   ""
3379   "
3381   if (TARGET_MIPS16)
3382     operands[2] = force_reg (SImode, operands[2]);
3385 (define_insn ""
3386   [(set (match_operand:SI 0 "register_operand" "=d,d")
3387         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3388                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3389   "!TARGET_MIPS16"
3390   "@
3391    or\\t%0,%1,%2
3392    ori\\t%0,%1,%x2"
3393   [(set_attr "type"     "arith")
3394    (set_attr "mode"     "SI")])
3396 (define_insn ""
3397   [(set (match_operand:SI 0 "register_operand" "=d")
3398         (ior:SI (match_operand:SI 1 "register_operand" "%0")
3399                 (match_operand:SI 2 "register_operand" "d")))]
3400   "TARGET_MIPS16"
3401   "or\\t%0,%2"
3402   [(set_attr "type"     "arith")
3403    (set_attr "mode"     "SI")])
3405 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
3406 ;;; TARGET_64BIT
3408 (define_expand "iordi3"
3409   [(set (match_operand:DI 0 "register_operand" "=d")
3410         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3411                 (match_operand:DI 2 "se_register_operand" "d")))]
3412   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3413   "")
3415 (define_insn ""
3416   [(set (match_operand:DI 0 "register_operand" "=d")
3417         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3418                 (match_operand:DI 2 "se_register_operand" "d")))]
3419   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3420   "*
3422   if (TARGET_64BIT)
3423     return \"or\\t%0,%1,%2\";
3424   return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
3426   [(set_attr "type"     "darith")
3427    (set_attr "mode"     "DI")
3428    (set (attr "length")
3429         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3430                        (const_int 4)
3431                        (const_int 8)))])
3433 (define_insn ""
3434   [(set (match_operand:DI 0 "register_operand" "=d")
3435         (ior:DI (match_operand:DI 1 "se_register_operand" "0")
3436                 (match_operand:DI 2 "se_register_operand" "d")))]
3437   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3438   "*
3440   if (TARGET_64BIT)
3441     return \"or\\t%0,%2\";
3442   return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
3444   [(set_attr "type"     "darith")
3445    (set_attr "mode"     "DI")
3446    (set (attr "length")
3447         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3448                        (const_int 4)
3449                        (const_int 8)))])
3451 (define_split
3452   [(set (match_operand:DI 0 "register_operand" "")
3453         (ior:DI (match_operand:DI 1 "register_operand" "")
3454                 (match_operand:DI 2 "register_operand" "")))]
3455   "reload_completed && !TARGET_64BIT
3456    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3457    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3458    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3459    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3461   [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3462    (set (subreg:SI (match_dup 0) 4) (ior:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3463   "")
3465 (define_expand "xorsi3"
3466   [(set (match_operand:SI 0 "register_operand" "=d,d")
3467         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3468                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3469   ""
3470   "")
3472 (define_insn ""
3473   [(set (match_operand:SI 0 "register_operand" "=d,d")
3474         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3475                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3476   "!TARGET_MIPS16"
3477   "@
3478    xor\\t%0,%1,%2
3479    xori\\t%0,%1,%x2"
3480   [(set_attr "type"     "arith")
3481    (set_attr "mode"     "SI")])
3483 (define_insn ""
3484   [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3485         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3486                 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3487   "TARGET_MIPS16"
3488   "@
3489    xor\\t%0,%2
3490    cmpi\\t%1,%2
3491    cmp\\t%1,%2"
3492   [(set_attr "type"     "arith")
3493    (set_attr "mode"     "SI")
3494    (set_attr_alternative "length"
3495                 [(const_int 4)
3496                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3497                                (const_int 4)
3498                                (const_int 8))
3499                  (const_int 4)])])
3501 ;; ??? If delete the 32-bit long long patterns, then could merge this with
3502 ;; the following xordi3_internal pattern.
3503 (define_expand "xordi3"
3504   [(set (match_operand:DI 0 "register_operand" "=d")
3505         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3506                 (match_operand:DI 2 "se_register_operand" "d")))]
3507   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3508   "")
3510 (define_insn ""
3511   [(set (match_operand:DI 0 "register_operand" "=d")
3512         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3513                 (match_operand:DI 2 "se_register_operand" "d")))]
3514   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3515   "*
3517   if (TARGET_64BIT)
3518     return \"xor\\t%0,%1,%2\";
3519   return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
3521   [(set_attr "type"     "darith")
3522    (set_attr "mode"     "DI")
3523    (set (attr "length")
3524         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3525                        (const_int 4)
3526                        (const_int 8)))])
3528 (define_insn ""
3529   [(set (match_operand:DI 0 "register_operand" "=d")
3530         (xor:DI (match_operand:DI 1 "se_register_operand" "0")
3531                 (match_operand:DI 2 "se_register_operand" "d")))]
3532   "!TARGET_64BIT && TARGET_MIPS16"
3533   "xor\\t%M0,%M2\;xor\\t%L0,%L2"
3534   [(set_attr "type"     "darith")
3535    (set_attr "mode"     "DI")
3536    (set_attr "length"   "8")])
3538 (define_insn ""
3539   [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3540         (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
3541                 (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
3542   "TARGET_64BIT && TARGET_MIPS16"
3543   "@
3544    xor\\t%0,%2
3545    cmpi\\t%1,%2
3546    cmp\\t%1,%2"
3547   [(set_attr "type"     "arith")
3548    (set_attr "mode"     "DI")
3549    (set_attr_alternative "length"
3550                 [(const_int 4)
3551                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3552                                (const_int 4)
3553                                (const_int 8))
3554                  (const_int 4)])])
3556 (define_split
3557   [(set (match_operand:DI 0 "register_operand" "")
3558         (xor:DI (match_operand:DI 1 "register_operand" "")
3559                 (match_operand:DI 2 "register_operand" "")))]
3560   "reload_completed && !TARGET_64BIT
3561    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3562    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3563    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3564    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3566   [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3567    (set (subreg:SI (match_dup 0) 4) (xor:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3568   "")
3570 (define_insn "xordi3_immed"
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_uns_arith_operand" "K")))]
3574   "TARGET_64BIT && !TARGET_MIPS16"
3575   "xori\\t%0,%1,%x2"
3576   [(set_attr "type"     "arith")
3577    (set_attr "mode"     "DI")])
3579 (define_insn "*norsi3"
3580   [(set (match_operand:SI 0 "register_operand" "=d")
3581         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3582                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3583   "!TARGET_MIPS16"
3584   "nor\\t%0,%z1,%z2"
3585   [(set_attr "type"     "arith")
3586    (set_attr "mode"     "SI")])
3588 (define_insn "*nordi3"
3589   [(set (match_operand:DI 0 "register_operand" "=d")
3590         (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
3591                 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
3592   "!TARGET_MIPS16"
3593   "*
3595   if (TARGET_64BIT)
3596     return \"nor\\t%0,%z1,%z2\";
3597   return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
3599   [(set_attr "type"     "darith")
3600    (set_attr "mode"     "DI")
3601    (set (attr "length")
3602         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3603                        (const_int 4)
3604                        (const_int 8)))])
3606 (define_split
3607   [(set (match_operand:DI 0 "register_operand" "")
3608         (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
3609                 (not:DI (match_operand:DI 2 "register_operand" ""))))]
3610   "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT
3611    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3612    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3613    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3614    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3616   [(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))))
3617    (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))))]
3618   "")
3621 ;;  ....................
3623 ;;      TRUNCATION
3625 ;;  ....................
3627 (define_insn "truncdfsf2"
3628   [(set (match_operand:SF 0 "register_operand" "=f")
3629         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3630   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3631   "cvt.s.d\\t%0,%1"
3632   [(set_attr "type"     "fcvt")
3633    (set_attr "mode"     "SF")])
3635 (define_insn "truncdisi2"
3636   [(set (match_operand:SI 0 "register_operand" "=d")
3637         (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
3638   "TARGET_64BIT"
3639   "*
3641   if (TARGET_MIPS16)
3642     return \"dsll\\t%0,%1,32\;dsra\\t%0,32\";
3643   return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
3645   [(set_attr "type"     "darith")
3646    (set_attr "mode"     "SI")
3647    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3648                                       (const_int 8)
3649                                       (const_int 16)))])
3651 (define_insn "truncdihi2"
3652   [(set (match_operand:HI 0 "register_operand" "=d")
3653         (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
3654   "TARGET_64BIT"
3655   "*
3657   if (TARGET_MIPS16)
3658     return \"dsll\\t%0,%1,48\;dsra\\t%0,48\";
3659   return \"andi\\t%0,%1,0xffff\";
3661   [(set_attr "type"     "darith")
3662    (set_attr "mode"     "HI")
3663    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3664                                       (const_int 4)
3665                                       (const_int 16)))])
3666 (define_insn "truncdiqi2"
3667   [(set (match_operand:QI 0 "register_operand" "=d")
3668         (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
3669   "TARGET_64BIT"
3670   "*
3672   if (TARGET_MIPS16)
3673     return \"dsll\\t%0,%1,56\;dsra\\t%0,56\";
3674   return \"andi\\t%0,%1,0x00ff\";
3676   [(set_attr "type"     "darith")
3677    (set_attr "mode"     "QI")
3678    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3679                                       (const_int 4)
3680                                       (const_int 16)))])
3682 ;; Combiner patterns to optimize shift/truncate combinations.
3683 (define_insn ""
3684   [(set (match_operand:SI 0 "register_operand" "=d")
3685         (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3686                                   (match_operand:DI 2 "small_int" "I"))))]
3687   "TARGET_64BIT && !TARGET_MIPS16"
3688   "*
3690   int shift_amt = INTVAL (operands[2]) & 0x3f;
3692   if (shift_amt < 32)
3693     {
3694       operands[2] = GEN_INT (32 - shift_amt);
3695       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3696     }
3697   else
3698     {
3699       operands[2] = GEN_INT (shift_amt);
3700       return \"dsra\\t%0,%1,%2\";
3701     }
3703   [(set_attr "type"     "darith")
3704    (set_attr "mode"     "SI")
3705    (set_attr "length"   "8")])
3707 (define_insn ""
3708   [(set (match_operand:SI 0 "register_operand" "=d")
3709         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3710                                   (match_operand:DI 2 "small_int" "I"))))]
3711   "TARGET_64BIT && !TARGET_MIPS16"
3712   "*
3714   int shift_amt = INTVAL (operands[2]) & 0x3f;
3716   if (shift_amt < 32)
3717     {
3718       operands[2] = GEN_INT (32 - shift_amt);
3719       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3720     }
3721   else if (shift_amt == 32)
3722     return \"dsra\\t%0,%1,32\";
3723   else
3724     {
3725       operands[2] = GEN_INT (shift_amt);
3726       return \"dsrl\\t%0,%1,%2\";
3727     }
3729   [(set_attr "type"     "darith")
3730    (set_attr "mode"     "SI")
3731    (set_attr "length"   "8")])
3733 (define_insn ""
3734   [(set (match_operand:SI 0 "register_operand" "=d")
3735         (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
3736                                 (match_operand:DI 2 "small_int" "I"))))]
3737   "TARGET_64BIT"
3738   "*
3740   int shift_amt = INTVAL (operands[2]) & 0x3f;
3742   if (shift_amt < 32)
3743     {
3744       operands[2] = GEN_INT (32 + shift_amt);
3745       if (TARGET_MIPS16)
3746         return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\";
3747       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3748     }
3749   else
3750     return \"move\\t%0,%.\";
3752   [(set_attr "type"     "darith")
3753    (set_attr "mode"     "SI")
3754    (set_attr "length"   "8")])
3756 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3758 (define_insn ""
3759   [(set (match_operand:SI 0 "register_operand" "=d")
3760         (zero_extend:SI (truncate:HI
3761                          (match_operand:DI 1 "se_register_operand" "d"))))]
3762   "TARGET_64BIT && !TARGET_MIPS16"
3763   "andi\\t%0,%1,0xffff"
3764   [(set_attr "type"     "darith")
3765    (set_attr "mode"     "SI")])
3767 (define_insn ""
3768   [(set (match_operand:SI 0 "register_operand" "=d")
3769         (zero_extend:SI (truncate:QI
3770                          (match_operand:DI 1 "se_register_operand" "d"))))]
3771   "TARGET_64BIT && !TARGET_MIPS16"
3772   "andi\\t%0,%1,0xff"
3773   [(set_attr "type"     "darith")
3774    (set_attr "mode"     "SI")])
3776 (define_insn ""
3777   [(set (match_operand:HI 0 "register_operand" "=d")
3778         (zero_extend:HI (truncate:QI
3779                          (match_operand:DI 1 "se_register_operand" "d"))))]
3780   "TARGET_64BIT && !TARGET_MIPS16"
3781   "andi\\t%0,%1,0xff"
3782   [(set_attr "type"     "darith")
3783    (set_attr "mode"     "HI")])
3786 ;;  ....................
3788 ;;      ZERO EXTENSION
3790 ;;  ....................
3792 ;; Extension insns.
3793 ;; Those for integer source operand are ordered widest source type first.
3795 (define_expand "zero_extendsidi2"
3796   [(set (match_operand:DI 0 "register_operand" "")
3797         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3798   "TARGET_64BIT"
3799   "
3801   if ((optimize || TARGET_MIPS16) && GET_CODE (operands[1]) == MEM)
3802     operands[1] = force_not_mem (operands[1]);
3804   if (GET_CODE (operands[1]) != MEM)
3805     {
3806       rtx op1   = gen_lowpart (DImode, operands[1]);
3807       rtx temp  = gen_reg_rtx (DImode);
3808       rtx shift = GEN_INT (32);
3810       emit_insn (gen_ashldi3 (temp, op1, shift));
3811       emit_insn (gen_lshrdi3 (operands[0], temp, shift));
3812       DONE;
3813     }
3816 (define_insn "zero_extendsidi2_internal"
3817   [(set (match_operand:DI 0 "register_operand" "=d,d")
3818         (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
3819   "TARGET_64BIT && !TARGET_MIPS16"
3820   "* return mips_move_1word (operands, insn, TRUE);"
3821   [(set_attr "type"     "load")
3822    (set_attr "mode"     "DI")
3823    (set_attr "length"   "4,8")])
3825 (define_expand "zero_extendhisi2"
3826   [(set (match_operand:SI 0 "register_operand" "")
3827         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3828   ""
3829   "
3831   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3832     {
3833       rtx op = gen_lowpart (SImode, operands[1]);
3834       rtx temp = force_reg (SImode, GEN_INT (0xffff));
3836       emit_insn (gen_andsi3 (operands[0], op, temp));
3837       DONE;
3838     }
3841 (define_insn ""
3842   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3843         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3844   "!TARGET_MIPS16"
3845   "*
3847   if (which_alternative == 0)
3848     return \"andi\\t%0,%1,0xffff\";
3849   else
3850     return mips_move_1word (operands, insn, TRUE);
3852   [(set_attr "type"     "arith,load,load")
3853    (set_attr "mode"     "SI")
3854    (set_attr "length"   "4,4,8")])
3856 (define_insn ""
3857   [(set (match_operand:SI 0 "register_operand" "=d,d")
3858         (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3859   "TARGET_MIPS16"
3860   "* return mips_move_1word (operands, insn, TRUE);"
3861   [(set_attr "type"     "load,load")
3862    (set_attr "mode"     "SI")
3863    (set_attr "length"   "4,8")])
3865 (define_expand "zero_extendhidi2"
3866   [(set (match_operand:DI 0 "register_operand" "")
3867         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3868   "TARGET_64BIT"
3869   "
3871   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3872     {
3873       rtx op = gen_lowpart (DImode, operands[1]);
3874       rtx temp = force_reg (DImode, GEN_INT (0xffff));
3876       emit_insn (gen_anddi3 (operands[0], op, temp));
3877       DONE;
3878     }
3881 (define_insn ""
3882   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3883         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3884   "TARGET_64BIT && !TARGET_MIPS16"
3885   "*
3887   if (which_alternative == 0)
3888     return \"andi\\t%0,%1,0xffff\";
3889   else
3890     return mips_move_1word (operands, insn, TRUE);
3892   [(set_attr "type"     "arith,load,load")
3893    (set_attr "mode"     "DI")
3894    (set_attr "length"   "4,4,8")])
3896 (define_insn ""
3897   [(set (match_operand:DI 0 "register_operand" "=d,d")
3898         (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3899   "TARGET_64BIT && TARGET_MIPS16"
3900   "* return mips_move_1word (operands, insn, TRUE);"
3901   [(set_attr "type"     "load,load")
3902    (set_attr "mode"     "DI")
3903    (set_attr "length"   "4,8")])
3905 (define_expand "zero_extendqihi2"
3906   [(set (match_operand:HI 0 "register_operand" "")
3907         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3908   ""
3909   "
3911   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3912     {
3913       rtx op0 = gen_lowpart (SImode, operands[0]);
3914       rtx op1 = gen_lowpart (SImode, operands[1]);
3915       rtx temp = force_reg (SImode, GEN_INT (0xff));
3917       emit_insn (gen_andsi3 (op0, op1, temp));
3918       DONE;
3919     }
3922 (define_insn ""
3923   [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3924         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3925   "!TARGET_MIPS16"
3926   "*
3928   if (which_alternative == 0)
3929     return \"andi\\t%0,%1,0x00ff\";
3930   else
3931     return mips_move_1word (operands, insn, TRUE);
3933   [(set_attr "type"     "arith,load,load")
3934    (set_attr "mode"     "HI")
3935    (set_attr "length"   "4,4,8")])
3937 (define_insn ""
3938   [(set (match_operand:HI 0 "register_operand" "=d,d")
3939         (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3940   "TARGET_MIPS16"
3941   "* return mips_move_1word (operands, insn, TRUE);"
3942   [(set_attr "type"     "load,load")
3943    (set_attr "mode"     "HI")
3944    (set_attr "length"   "4,8")])
3946 (define_expand "zero_extendqisi2"
3947   [(set (match_operand:SI 0 "register_operand" "")
3948         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3949   ""
3950   "
3952   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3953     {
3954       rtx op = gen_lowpart (SImode, operands[1]);
3955       rtx temp = force_reg (SImode, GEN_INT (0xff));
3957       emit_insn (gen_andsi3 (operands[0], op, temp));
3958       DONE;
3959     }
3962 (define_insn ""
3963   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3964         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3965   "!TARGET_MIPS16"
3966   "*
3968   if (which_alternative == 0)
3969     return \"andi\\t%0,%1,0x00ff\";
3970   else
3971     return mips_move_1word (operands, insn, TRUE);
3973   [(set_attr "type"     "arith,load,load")
3974    (set_attr "mode"     "SI")
3975    (set_attr "length"   "4,4,8")])
3977 (define_insn ""
3978   [(set (match_operand:SI 0 "register_operand" "=d,d")
3979         (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
3980   "TARGET_MIPS16"
3981   "* return mips_move_1word (operands, insn, TRUE);"
3982   [(set_attr "type"     "load,load")
3983    (set_attr "mode"     "SI")
3984    (set_attr "length"   "4,8")])
3986 (define_expand "zero_extendqidi2"
3987   [(set (match_operand:DI 0 "register_operand" "")
3988         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3989   "TARGET_64BIT"
3990   "
3992   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3993     {
3994       rtx op = gen_lowpart (DImode, operands[1]);
3995       rtx temp = force_reg (DImode, GEN_INT (0xff));
3997       emit_insn (gen_anddi3 (operands[0], op, temp));
3998       DONE;
3999     }
4002 (define_insn ""
4003   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4004         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
4005   "TARGET_64BIT && !TARGET_MIPS16"
4006   "*
4008   if (which_alternative == 0)
4009     return \"andi\\t%0,%1,0x00ff\";
4010   else
4011     return mips_move_1word (operands, insn, TRUE);
4013   [(set_attr "type"     "arith,load,load")
4014    (set_attr "mode"     "DI")
4015    (set_attr "length"   "4,4,8")])
4017 ;; These can be created when a paradoxical subreg operand with an implicit
4018 ;; sign_extend operator is reloaded.  Because of the subreg, this is really
4019 ;; a zero extend.
4020 ;; ??? It might be possible to eliminate the need for these patterns by adding
4021 ;; more support to reload for implicit sign_extend operators.
4022 (define_insn "*paradoxical_extendhidi2"
4023   [(set (match_operand:DI 0 "register_operand" "=d,d")
4024         (sign_extend:DI
4025          (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
4026   "TARGET_64BIT"
4027   "*
4029   return mips_move_1word (operands, insn, TRUE);
4031   [(set_attr "type"     "load,load")
4032    (set_attr "mode"     "DI")
4033    (set_attr "length"   "4,8")])
4035 (define_insn ""
4036   [(set (match_operand:DI 0 "register_operand" "=d,d")
4037         (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4038   "TARGET_64BIT && TARGET_MIPS16"
4039   "* return mips_move_1word (operands, insn, TRUE);"
4040   [(set_attr "type"     "load,load")
4041    (set_attr "mode"     "DI")
4042    (set_attr "length"   "4,8")])
4045 ;;  ....................
4047 ;;      SIGN EXTENSION
4049 ;;  ....................
4051 ;; Extension insns.
4052 ;; Those for integer source operand are ordered widest source type first.
4054 ;; In 64 bit mode, 32 bit values in general registers are always
4055 ;; correctly sign extended.  That means that if the target is a
4056 ;; general register, we can sign extend from SImode to DImode just by
4057 ;; doing a move.
4059 (define_insn "extendsidi2"
4060   [(set (match_operand:DI 0 "register_operand" "=d,y,d,*d,d,d")
4061         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,d,y,*x,R,m")))]
4062   "TARGET_64BIT"
4063   "* return mips_move_1word (operands, insn, FALSE);"
4064   [(set_attr "type"     "move,move,move,hilo,load,load")
4065    (set_attr "mode"     "DI")
4066    (set_attr "length"   "4,4,4,4,4,8")])
4068 ;; These patterns originally accepted general_operands, however, slightly
4069 ;; better code is generated by only accepting register_operands, and then
4070 ;; letting combine generate the lh and lb insns.
4072 (define_expand "extendhidi2"
4073   [(set (match_operand:DI 0 "register_operand" "")
4074         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
4075   "TARGET_64BIT"
4076   "
4078   if (optimize && GET_CODE (operands[1]) == MEM)
4079     operands[1] = force_not_mem (operands[1]);
4081   if (GET_CODE (operands[1]) != MEM)
4082     {
4083       rtx op1   = gen_lowpart (DImode, operands[1]);
4084       rtx temp  = gen_reg_rtx (DImode);
4085       rtx shift = GEN_INT (48);
4087       emit_insn (gen_ashldi3 (temp, op1, shift));
4088       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4089       DONE;
4090     }
4093 (define_insn "extendhidi2_internal"
4094   [(set (match_operand:DI 0 "register_operand" "=d,d")
4095         (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
4096   "TARGET_64BIT"
4097   "* return mips_move_1word (operands, insn, FALSE);"
4098   [(set_attr "type"     "load")
4099    (set_attr "mode"     "DI")
4100    (set_attr "length"   "4,8")])
4102 (define_expand "extendhisi2"
4103   [(set (match_operand:SI 0 "register_operand" "")
4104         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4105   ""
4106   "
4108   if (optimize && GET_CODE (operands[1]) == MEM)
4109     operands[1] = force_not_mem (operands[1]);
4111   if (GET_CODE (operands[1]) != MEM)
4112     {
4113       rtx op1   = gen_lowpart (SImode, operands[1]);
4114       rtx temp  = gen_reg_rtx (SImode);
4115       rtx shift = GEN_INT (16);
4117       emit_insn (gen_ashlsi3 (temp, op1, shift));
4118       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4119       DONE;
4120     }
4123 (define_insn "extendhisi2_internal"
4124   [(set (match_operand:SI 0 "register_operand" "=d,d")
4125         (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
4126   ""
4127   "* return mips_move_1word (operands, insn, FALSE);"
4128   [(set_attr "type"     "load")
4129    (set_attr "mode"     "SI")
4130    (set_attr "length"   "4,8")])
4132 (define_expand "extendqihi2"
4133   [(set (match_operand:HI 0 "register_operand" "")
4134         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
4135   ""
4136   "
4138   if (optimize && GET_CODE (operands[1]) == MEM)
4139     operands[1] = force_not_mem (operands[1]);
4141   if (GET_CODE (operands[1]) != MEM)
4142     {
4143       rtx op0   = gen_lowpart (SImode, operands[0]);
4144       rtx op1   = gen_lowpart (SImode, operands[1]);
4145       rtx temp  = gen_reg_rtx (SImode);
4146       rtx shift = GEN_INT (24);
4148       emit_insn (gen_ashlsi3 (temp, op1, shift));
4149       emit_insn (gen_ashrsi3 (op0, temp, shift));
4150       DONE;
4151     }
4154 (define_insn "extendqihi2_internal"
4155   [(set (match_operand:HI 0 "register_operand" "=d,d")
4156         (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
4157   ""
4158   "* return mips_move_1word (operands, insn, FALSE);"
4159   [(set_attr "type"     "load")
4160    (set_attr "mode"     "SI")
4161    (set_attr "length"   "4,8")])
4164 (define_expand "extendqisi2"
4165   [(set (match_operand:SI 0 "register_operand" "")
4166         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4167   ""
4168   "
4170   if (optimize && GET_CODE (operands[1]) == MEM)
4171     operands[1] = force_not_mem (operands[1]);
4173   if (GET_CODE (operands[1]) != MEM)
4174     {
4175       rtx op1   = gen_lowpart (SImode, operands[1]);
4176       rtx temp  = gen_reg_rtx (SImode);
4177       rtx shift = GEN_INT (24);
4179       emit_insn (gen_ashlsi3 (temp, op1, shift));
4180       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4181       DONE;
4182     }
4185 (define_insn "extendqisi2_insn"
4186   [(set (match_operand:SI 0 "register_operand" "=d,d")
4187         (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4188   ""
4189   "* return mips_move_1word (operands, insn, FALSE);"
4190   [(set_attr "type"     "load")
4191    (set_attr "mode"     "SI")
4192    (set_attr "length"   "4,8")])
4194 (define_expand "extendqidi2"
4195   [(set (match_operand:DI 0 "register_operand" "")
4196         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4197   "TARGET_64BIT"
4198   "
4200   if (optimize && GET_CODE (operands[1]) == MEM)
4201     operands[1] = force_not_mem (operands[1]);
4203   if (GET_CODE (operands[1]) != MEM)
4204     {
4205       rtx op1   = gen_lowpart (DImode, operands[1]);
4206       rtx temp  = gen_reg_rtx (DImode);
4207       rtx shift = GEN_INT (56);
4209       emit_insn (gen_ashldi3 (temp, op1, shift));
4210       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4211       DONE;
4212     }
4215 (define_insn "extendqidi2_insn"
4216   [(set (match_operand:DI 0 "register_operand" "=d,d")
4217         (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4218   "TARGET_64BIT"
4219   "* return mips_move_1word (operands, insn, FALSE);"
4220   [(set_attr "type"     "load")
4221    (set_attr "mode"     "DI")
4222    (set_attr "length"   "4,8")])
4225 (define_insn "extendsfdf2"
4226   [(set (match_operand:DF 0 "register_operand" "=f")
4227         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
4228   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4229   "cvt.d.s\\t%0,%1"
4230   [(set_attr "type"     "fcvt")
4231    (set_attr "mode"     "DF")])
4236 ;;  ....................
4238 ;;      CONVERSIONS
4240 ;;  ....................
4242 ;; The SImode scratch register can not be shared with address regs used for
4243 ;; operand zero, because then the address in the move instruction will be
4244 ;; clobbered.  We mark the scratch register as early clobbered to prevent this.
4246 ;; We need the ?X in alternative 1 so that it will be chosen only if the
4247 ;; destination is a floating point register.  Otherwise, alternative 1 can
4248 ;; have lower cost than alternative 0 (because there is one less loser), and
4249 ;; can be chosen when it won't work (because integral reloads into FP
4250 ;; registers are not supported).
4252 (define_insn "fix_truncdfsi2"
4253   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,*f,R,To")
4254         (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4255    (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4256    (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
4257   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4258   "*
4260   rtx xoperands[10];
4262   if (which_alternative == 1)
4263     return \"trunc.w.d %0,%1,%2\";
4265   output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
4267   xoperands[0] = operands[0];
4268   xoperands[1] = operands[3];
4269   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4270   return \"\";
4272   [(set_attr "type"     "fcvt")
4273    (set_attr "mode"     "DF")
4274    (set_attr "length"   "44,36,40,44")])
4277 (define_insn "fix_truncsfsi2"
4278   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,*f,R,To")
4279         (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4280    (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4281    (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
4282   "TARGET_HARD_FLOAT"
4283   "*
4285   rtx xoperands[10];
4287   if (which_alternative == 1)
4288     return \"trunc.w.s %0,%1,%2\";
4290   output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
4292   xoperands[0] = operands[0];
4293   xoperands[1] = operands[3];
4294   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4295   return \"\";
4297   [(set_attr "type"     "fcvt")
4298    (set_attr "mode"     "SF")
4299    (set_attr "length"   "44,36,40,44")])
4302 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
4303 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
4304 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
4306 ;;; Deleting this means that we now need two libgcc2.a libraries.  One for
4307 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
4309 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
4311 (define_insn "fix_truncdfdi2"
4312   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,*f,R,To")
4313         (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4314    (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4315   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4316   "*
4318   rtx xoperands[10];
4320   if (which_alternative == 1)
4321     return \"trunc.l.d %0,%1\";
4323   output_asm_insn (\"trunc.l.d %2,%1\", operands);
4325   xoperands[0] = operands[0];
4326   xoperands[1] = operands[2];
4327   output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
4328   return \"\";
4330   [(set_attr "type"     "fcvt")
4331    (set_attr "mode"     "DF")
4332    (set_attr "length"   "8,4,8,12")])
4335 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
4336 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
4337 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
4338 (define_insn "fix_truncsfdi2"
4339   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,*f,R,To")
4340         (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4341    (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4342   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4343   "*
4345   rtx xoperands[10];
4347   if (which_alternative == 1)
4348     return \"trunc.l.s %0,%1\";
4350   output_asm_insn (\"trunc.l.s %2,%1\", operands);
4352   xoperands[0] = operands[0];
4353   xoperands[1] = operands[2];
4354   output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
4355   return \"\";
4357   [(set_attr "type"     "fcvt")
4358    (set_attr "mode"     "SF")
4359    (set_attr "length"   "8,4,8,12")])
4362 (define_insn "floatsidf2"
4363   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4364         (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4365   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4366   "*
4368   dslots_load_total++;
4369   if (GET_CODE (operands[1]) == MEM)
4370     return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
4372   return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
4374   [(set_attr "type"     "fcvt")
4375    (set_attr "mode"     "DF")
4376    (set_attr "length"   "12,16,12")])
4379 (define_insn "floatdidf2"
4380   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4381         (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4382   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4383   "*
4385   dslots_load_total++;
4386   if (GET_CODE (operands[1]) == MEM)
4387     return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
4389   return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
4391   [(set_attr "type"     "fcvt")
4392    (set_attr "mode"     "DF")
4393    (set_attr "length"   "12,16,12")])
4396 (define_insn "floatsisf2"
4397   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4398         (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4399   "TARGET_HARD_FLOAT"
4400   "*
4402   dslots_load_total++;
4403   if (GET_CODE (operands[1]) == MEM)
4404     return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
4406   return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
4408   [(set_attr "type"     "fcvt")
4409    (set_attr "mode"     "SF")
4410    (set_attr "length"   "12,16,12")])
4413 (define_insn "floatdisf2"
4414   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4415         (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4416   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4417   "*
4419   dslots_load_total++;
4420   if (GET_CODE (operands[1]) == MEM)
4421     return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
4423   return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
4425   [(set_attr "type"     "fcvt")
4426    (set_attr "mode"     "SF")
4427    (set_attr "length"   "12,16,12")])
4430 (define_expand "fixuns_truncdfsi2"
4431   [(set (match_operand:SI 0 "register_operand" "")
4432         (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
4433   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4434   "
4436   rtx reg1 = gen_reg_rtx (DFmode);
4437   rtx reg2 = gen_reg_rtx (DFmode);
4438   rtx reg3 = gen_reg_rtx (SImode);
4439   rtx label1 = gen_label_rtx ();
4440   rtx label2 = gen_label_rtx ();
4441   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4443   if (reg1)                     /* turn off complaints about unreached code */
4444     {
4445       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4446       do_pending_stack_adjust ();
4448       emit_insn (gen_cmpdf (operands[1], reg1));
4449       emit_jump_insn (gen_bge (label1));
4451       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
4452       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4453                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4454       emit_barrier ();
4456       emit_label (label1);
4457       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4458       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4459                                      (BITMASK_HIGH, SImode)));
4461       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4462       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4464       emit_label (label2);
4466       /* allow REG_NOTES to be set on last insn (labels don't have enough
4467          fields, and can't be used for REG_NOTES anyway).  */
4468       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4469       DONE;
4470     }
4474 (define_expand "fixuns_truncdfdi2"
4475   [(set (match_operand:DI 0 "register_operand" "")
4476         (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
4477   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4478   "
4480   rtx reg1 = gen_reg_rtx (DFmode);
4481   rtx reg2 = gen_reg_rtx (DFmode);
4482   rtx reg3 = gen_reg_rtx (DImode);
4483   rtx label1 = gen_label_rtx ();
4484   rtx label2 = gen_label_rtx ();
4485   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4487   if (reg1)                     /* turn off complaints about unreached code */
4488     {
4489       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4490       do_pending_stack_adjust ();
4492       emit_insn (gen_cmpdf (operands[1], reg1));
4493       emit_jump_insn (gen_bge (label1));
4495       emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
4496       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4497                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4498       emit_barrier ();
4500       emit_label (label1);
4501       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4502       emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4503       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4505       emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4506       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4508       emit_label (label2);
4510       /* allow REG_NOTES to be set on last insn (labels don't have enough
4511          fields, and can't be used for REG_NOTES anyway).  */
4512       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4513       DONE;
4514     }
4518 (define_expand "fixuns_truncsfsi2"
4519   [(set (match_operand:SI 0 "register_operand" "")
4520         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4521   "TARGET_HARD_FLOAT"
4522   "
4524   rtx reg1 = gen_reg_rtx (SFmode);
4525   rtx reg2 = gen_reg_rtx (SFmode);
4526   rtx reg3 = gen_reg_rtx (SImode);
4527   rtx label1 = gen_label_rtx ();
4528   rtx label2 = gen_label_rtx ();
4529   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4531   if (reg1)                     /* turn off complaints about unreached code */
4532     {
4533       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4534       do_pending_stack_adjust ();
4536       emit_insn (gen_cmpsf (operands[1], reg1));
4537       emit_jump_insn (gen_bge (label1));
4539       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4540       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4541                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4542       emit_barrier ();
4544       emit_label (label1);
4545       emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4546       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4547                                      (BITMASK_HIGH, SImode)));
4549       emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4550       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4552       emit_label (label2);
4554       /* allow REG_NOTES to be set on last insn (labels don't have enough
4555          fields, and can't be used for REG_NOTES anyway).  */
4556       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4557       DONE;
4558     }
4562 (define_expand "fixuns_truncsfdi2"
4563   [(set (match_operand:DI 0 "register_operand" "")
4564         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4565   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4566   "
4568   rtx reg1 = gen_reg_rtx (SFmode);
4569   rtx reg2 = gen_reg_rtx (SFmode);
4570   rtx reg3 = gen_reg_rtx (DImode);
4571   rtx label1 = gen_label_rtx ();
4572   rtx label2 = gen_label_rtx ();
4573   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4575   if (reg1)                     /* turn off complaints about unreached code */
4576     {
4577       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4578       do_pending_stack_adjust ();
4580       emit_insn (gen_cmpsf (operands[1], reg1));
4581       emit_jump_insn (gen_bge (label1));
4583       emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4584       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4585                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4586       emit_barrier ();
4588       emit_label (label1);
4589       emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4590       emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4591       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4593       emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4594       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4596       emit_label (label2);
4598       /* allow REG_NOTES to be set on last insn (labels don't have enough
4599          fields, and can't be used for REG_NOTES anyway).  */
4600       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4601       DONE;
4602     }
4607 ;;  ....................
4609 ;;      DATA MOVEMENT
4611 ;;  ....................
4613 ;; Bit field extract patterns which use lwl/lwr.
4615 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4616 ;; It isn't clear whether this will give better code.
4618 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4619 (define_expand "extv"
4620   [(set (match_operand 0 "register_operand" "")
4621         (sign_extract (match_operand:QI 1 "memory_operand" "")
4622                       (match_operand 2 "immediate_operand" "")
4623                       (match_operand 3 "immediate_operand" "")))]
4624   "!TARGET_MIPS16"
4625   "
4627   /* If the field does not start on a byte boundary, then fail.  */
4628   if (INTVAL (operands[3]) % 8 != 0)
4629     FAIL;
4631   /* MIPS I and MIPS II can only handle a 32bit field.  */
4632   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4633     FAIL;
4635   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4636   if (TARGET_64BIT
4637       && INTVAL (operands[2]) != 64
4638       && INTVAL (operands[2]) != 32)
4639     FAIL;
4641   /* This can happen for a 64 bit target, when extracting a value from
4642      a 64 bit union member.  extract_bit_field doesn't verify that our
4643      source matches the predicate, so we force it to be a MEM here.  */
4644   if (GET_CODE (operands[1]) != MEM)
4645     FAIL;
4647   /* Change the mode to BLKmode for aliasing purposes.  */
4648   operands[1] = adjust_address (operands[1], BLKmode, 0);
4650   /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value.  */
4651   if (INTVAL (operands[2]) == 64)
4652     emit_insn (gen_movdi_uld (operands[0], operands[1]));
4653   else
4654     {
4655       if (TARGET_64BIT)
4656         {
4657           operands[0] = gen_lowpart (SImode, operands[0]);
4658           if (operands[0] == NULL_RTX)
4659             FAIL;
4660         }
4661       emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4662     }
4663   DONE;
4666 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4667 (define_expand "extzv"
4668   [(set (match_operand 0 "register_operand" "")
4669         (zero_extract (match_operand:QI 1 "memory_operand" "")
4670                       (match_operand 2 "immediate_operand" "")
4671                       (match_operand 3 "immediate_operand" "")))]
4672   "!TARGET_MIPS16"
4673   "
4675   /* If the field does not start on a byte boundary, then fail.  */
4676   if (INTVAL (operands[3]) % 8 != 0)
4677     FAIL;
4679   /* MIPS I and MIPS II can only handle a 32bit field.  */
4680   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4681     FAIL;
4683   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4684   if (TARGET_64BIT
4685       && INTVAL (operands[2]) != 64
4686       && INTVAL (operands[2]) != 32)
4687     FAIL;
4689   /* This can happen for a 64 bit target, when extracting a value from
4690      a 64 bit union member.  extract_bit_field doesn't verify that our
4691      source matches the predicate, so we force it to be a MEM here.  */
4692   if (GET_CODE (operands[1]) != MEM)
4693     FAIL;
4695   /* Change the mode to BLKmode for aliasing purposes.  */
4696   operands[1] = adjust_address (operands[1], BLKmode, 0);
4698   /* Otherwise, emit a lwl/lwr pair to load the value.  */
4699   if (INTVAL (operands[2]) == 64)
4700     emit_insn (gen_movdi_uld (operands[0], operands[1]));
4701   else
4702     {
4703       if (TARGET_64BIT)
4704         {
4705           operands[0] = gen_lowpart (SImode, operands[0]);
4706           if (operands[0] == NULL_RTX)
4707             FAIL;
4708         }
4709       emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4710     }
4711   DONE;
4714 ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
4715 (define_expand "insv"
4716   [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4717                       (match_operand 1 "immediate_operand" "")
4718                       (match_operand 2 "immediate_operand" ""))
4719         (match_operand 3 "register_operand" ""))]
4720   "!TARGET_MIPS16"
4721   "
4723   /* If the field does not start on a byte boundary, then fail.  */
4724   if (INTVAL (operands[2]) % 8 != 0)
4725     FAIL;
4727   /* MIPS I and MIPS II can only handle a 32bit field.  */
4728   if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
4729     FAIL;
4731   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4732   if (TARGET_64BIT
4733       && INTVAL (operands[1]) != 64
4734       && INTVAL (operands[1]) != 32)
4735     FAIL;
4737   /* This can happen for a 64 bit target, when storing into a 32 bit union
4738      member.  store_bit_field doesn't verify that our target matches the
4739      predicate, so we force it to be a MEM here.  */
4740   if (GET_CODE (operands[0]) != MEM)
4741     FAIL;
4743   /* Change the mode to BLKmode for aliasing purposes.  */
4744   operands[0] = adjust_address (operands[0], BLKmode, 0);
4746   /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value.  */
4747   if (INTVAL (operands[1]) == 64)
4748     emit_insn (gen_movdi_usd (operands[0], operands[3]));
4749   else
4750     {
4751       if (TARGET_64BIT)
4752         {
4753           operands[3] = gen_lowpart (SImode, operands[3]);
4754           if (operands[3] == NULL_RTX)
4755             FAIL;
4756         }
4757       emit_insn (gen_movsi_usw (operands[0], operands[3]));
4758     }
4759   DONE;
4762 ;; unaligned word moves generated by the bit field patterns
4764 (define_insn "movsi_ulw"
4765   [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4766         (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4767   "!TARGET_MIPS16"
4768   "*
4770   rtx offset = const0_rtx;
4771   rtx addr = XEXP (operands[1], 0);
4772   rtx mem_addr = eliminate_constant_term (addr, &offset);
4773   const char *ret;
4775   if (TARGET_STATS)
4776     mips_count_memory_refs (operands[1], 2);
4778   /* The stack/frame pointers are always aligned, so we can convert
4779      to the faster lw if we are referencing an aligned stack location.  */
4781   if ((INTVAL (offset) & 3) == 0
4782       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4783     ret = \"lw\\t%0,%1\";
4784   else
4785     ret = \"ulw\\t%0,%1\";
4787   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4789   [(set_attr "type"     "load,load")
4790    (set_attr "mode"     "SI")
4791    (set_attr "length"   "8,16")])
4793 (define_insn "movsi_usw"
4794   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4795         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4796   "!TARGET_MIPS16"
4797   "*
4799   rtx offset = const0_rtx;
4800   rtx addr = XEXP (operands[0], 0);
4801   rtx mem_addr = eliminate_constant_term (addr, &offset);
4803   if (TARGET_STATS)
4804     mips_count_memory_refs (operands[0], 2);
4806   /* The stack/frame pointers are always aligned, so we can convert
4807      to the faster sw if we are referencing an aligned stack location.  */
4809   if ((INTVAL (offset) & 3) == 0
4810       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4811     return \"sw\\t%z1,%0\";
4813   return \"usw\\t%z1,%0\";
4815   [(set_attr "type"     "store")
4816    (set_attr "mode"     "SI")
4817    (set_attr "length"   "8,16")])
4819 ;; Bit field extract patterns which use ldl/ldr.
4821 ;; unaligned double word moves generated by the bit field patterns
4823 (define_insn "movdi_uld"
4824   [(set (match_operand:DI 0 "register_operand" "=&d,&d")
4825         (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4826   ""
4827   "*
4829   rtx offset = const0_rtx;
4830   rtx addr = XEXP (operands[1], 0);
4831   rtx mem_addr = eliminate_constant_term (addr, &offset);
4832   const char *ret;
4834   if (TARGET_STATS)
4835     mips_count_memory_refs (operands[1], 2);
4837   /* The stack/frame pointers are always aligned, so we can convert
4838      to the faster lw if we are referencing an aligned stack location.  */
4840   if ((INTVAL (offset) & 7) == 0
4841       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4842     ret = \"ld\\t%0,%1\";
4843   else
4844     ret = \"uld\\t%0,%1\";
4846   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4848   [(set_attr "type"     "load,load")
4849    (set_attr "mode"     "SI")
4850    (set_attr "length"   "8,16")])
4852 (define_insn "movdi_usd"
4853   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4854         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4855   ""
4856   "*
4858   rtx offset = const0_rtx;
4859   rtx addr = XEXP (operands[0], 0);
4860   rtx mem_addr = eliminate_constant_term (addr, &offset);
4862   if (TARGET_STATS)
4863     mips_count_memory_refs (operands[0], 2);
4865   /* The stack/frame pointers are always aligned, so we can convert
4866      to the faster sw if we are referencing an aligned stack location.  */
4868   if ((INTVAL (offset) & 7) == 0
4869       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4870     return \"sd\\t%1,%0\";
4872   return \"usd\\t%z1,%0\";
4874   [(set_attr "type"     "store")
4875    (set_attr "mode"     "SI")
4876    (set_attr "length"   "8,16")])
4878 ;; These two patterns support loading addresses with two instructions instead
4879 ;; of using the macro instruction la.
4881 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
4882 ;; unnecessary.
4884 (define_insn "high"
4885   [(set (match_operand:SI 0 "register_operand" "=r")
4886         (high:SI (match_operand:SI 1 "immediate_operand" "")))]
4887   "mips_split_addresses && !TARGET_MIPS16"
4888   "lui\\t%0,%%hi(%1) # high"
4889   [(set_attr "type"     "move")])
4891 (define_insn "low"
4892   [(set (match_operand:SI 0 "register_operand" "=r")
4893         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
4894                    (match_operand:SI 2 "immediate_operand" "")))]
4895   "mips_split_addresses && !TARGET_MIPS16"
4896   "addiu\\t%0,%1,%%lo(%2) # low"
4897   [(set_attr "type"     "arith")
4898    (set_attr "mode"     "SI")])
4900 ;; 64-bit integer moves
4902 ;; Unlike most other insns, the move insns can't be split with
4903 ;; different predicates, because register spilling and other parts of
4904 ;; the compiler, have memoized the insn number already.
4906 (define_expand "movdi"
4907   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4908         (match_operand:DI 1 "general_operand" ""))]
4909   ""
4910   "
4912   if (mips_split_addresses && mips_check_split (operands[1], DImode))
4913     {
4914       enum machine_mode mode = GET_MODE (operands[0]);
4915       rtx tem = ((reload_in_progress | reload_completed)
4916                  ? operands[0] : gen_reg_rtx (mode));
4918       emit_insn (gen_rtx_SET (VOIDmode, tem,
4919                               gen_rtx_HIGH (mode, operands[1])));
4921       operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
4922     }
4924   /* If we are generating embedded PIC code, and we are referring to a
4925      symbol in the .text section, we must use an offset from the start
4926      of the function.  */
4927   if (TARGET_EMBEDDED_PIC
4928       && (GET_CODE (operands[1]) == LABEL_REF
4929           || (GET_CODE (operands[1]) == SYMBOL_REF
4930               && ! SYMBOL_REF_FLAG (operands[1]))))
4931     {
4932       rtx temp;
4934       temp = embedded_pic_offset (operands[1]);
4935       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_rtx,
4936                            force_reg (DImode, temp));
4937       emit_move_insn (operands[0], force_reg (DImode, temp));
4938       DONE;
4939     }
4941   /* If operands[1] is a constant address illegal for pic, then we need to
4942      handle it just like LEGITIMIZE_ADDRESS does.  */
4943   if (flag_pic && pic_address_needs_scratch (operands[1]))
4944     {
4945       rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
4946       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
4948       if (! SMALL_INT (temp2))
4949         temp2 = force_reg (DImode, temp2);
4951       emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
4952       DONE;
4953     }
4955   /* On the mips16, we can handle a GP relative reference by adding in
4956      $gp.  We need to check the name to see whether this is a string
4957      constant.  */
4958   if (TARGET_MIPS16
4959       && register_operand (operands[0], DImode)
4960       && GET_CODE (operands[1]) == SYMBOL_REF
4961       && SYMBOL_REF_FLAG (operands[1]))
4962     {
4963       const char *name = XSTR (operands[1], 0);
4965       if (name[0] != '*'
4966           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
4967                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
4968         {
4969           rtx base_reg;
4971           if (reload_in_progress || reload_completed)
4972             {
4973               /* In movsi we use the constant table here.  However, in
4974                  this case, we're better off copying $28 into a
4975                  register and adding, because the constant table entry
4976                  would be 8 bytes.  */
4977               base_reg = operands[0];
4978               emit_move_insn (base_reg,
4979                               gen_rtx (CONST, DImode,
4980                                        gen_rtx (REG, DImode,
4981                                                 GP_REG_FIRST + 28)));
4982             }
4983           else
4984             {
4985               base_reg = gen_reg_rtx (Pmode);
4986               emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
4987             }
4989           emit_move_insn (operands[0],
4990                           gen_rtx (PLUS, Pmode, base_reg,
4991                                    mips16_gp_offset (operands[1])));
4992           DONE;
4993         }
4994     }
4996   if ((reload_in_progress | reload_completed) == 0
4997       && !register_operand (operands[0], DImode)
4998       && !register_operand (operands[1], DImode)
4999       && (TARGET_MIPS16
5000           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5001                && operands[1] != CONST0_RTX (DImode))))
5002     {
5003       rtx temp = force_reg (DImode, operands[1]);
5004       emit_move_insn (operands[0], temp);
5005       DONE;
5006     }
5009 ;; For mips16, we need a special case to handle storing $31 into
5010 ;; memory, since we don't have a constraint to match $31.  This
5011 ;; instruction can be generated by save_restore_insns.
5013 (define_insn ""
5014   [(set (match_operand:DI 0 "memory_operand" "=R,m")
5015         (reg:DI 31))]
5016   "TARGET_MIPS16 && TARGET_64BIT"
5017   "*
5019   operands[1] = gen_rtx (REG, DImode, 31);
5020   return mips_move_2words (operands, insn);
5022   [(set_attr "type"     "store")
5023    (set_attr "mode"     "DI")
5024    (set_attr "length"   "4,8")])
5026 (define_insn "movdi_internal"
5027   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
5028         (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
5029   "!TARGET_64BIT && !TARGET_MIPS16
5030    && (register_operand (operands[0], DImode)
5031        || register_operand (operands[1], DImode)
5032        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5033        || operands[1] == CONST0_RTX (DImode))"
5034   "* return mips_move_2words (operands, insn); "
5035   [(set_attr "type"     "move,arith,load,load,store,store,hilo,hilo,hilo")
5036    (set_attr "mode"     "DI")
5037    (set_attr "length"   "8,16,8,16,8,16,8,8,8")])
5039 (define_insn ""
5040   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
5041         (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
5042   "!TARGET_64BIT && TARGET_MIPS16
5043    && (register_operand (operands[0], DImode)
5044        || register_operand (operands[1], DImode))"
5045   "* return mips_move_2words (operands, insn);"
5046   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
5047    (set_attr "mode"     "DI")
5048    (set_attr "length"   "8,8,8,8,12,8,16,8,16,8")])
5050 (define_split
5051   [(set (match_operand:DI 0 "register_operand" "")
5052         (match_operand:DI 1 "register_operand" ""))]
5053   "reload_completed && !TARGET_64BIT
5054    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5055    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
5056    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
5058   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
5059    (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
5060   "")
5062 (define_insn "movdi_internal2"
5063   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
5064         (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
5065   "TARGET_64BIT && !TARGET_MIPS16
5066    && (register_operand (operands[0], DImode)
5067        || se_register_operand (operands[1], DImode)
5068        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5069        || operands[1] == CONST0_RTX (DImode))"
5070   "* return mips_move_2words (operands, insn); "
5071   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo")
5072    (set_attr "mode"     "DI")
5073    (set_attr "length"   "4,8,4,8,4,8,4,8,4,4,4,8")])
5075 (define_insn ""
5076   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
5077         (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
5078   "TARGET_64BIT && TARGET_MIPS16
5079    && (register_operand (operands[0], DImode)
5080        || se_register_operand (operands[1], DImode))"
5081   "* return mips_move_2words (operands, insn);"
5082   [(set_attr "type"     "move,move,move,arith,arith,arith,load,load,store,store,hilo")
5083    (set_attr "mode"     "DI")
5084    (set_attr_alternative "length"
5085                 [(const_int 4)
5086                  (const_int 4)
5087                  (const_int 4)
5088                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5089                                (const_int 4)
5090                                (const_int 8))
5091                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5092                                (const_int 8)
5093                                (const_int 12))
5094                  (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
5095                                (const_int 4)
5096                                (const_int 8))
5097                  (const_int 4)
5098                  (const_int 8)
5099                  (const_int 4)
5100                  (const_int 8)
5101                  (const_int 4)])])
5103 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
5104 ;; when the original load is a 4 byte instruction but the add and the
5105 ;; load are 2 2 byte instructions.
5107 (define_split
5108   [(set (match_operand:DI 0 "register_operand" "")
5109         (mem:DI (plus:DI (match_dup 0)
5110                          (match_operand:DI 1 "const_int_operand" ""))))]
5111   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
5112    && !TARGET_DEBUG_D_MODE
5113    && GET_CODE (operands[0]) == REG
5114    && M16_REG_P (REGNO (operands[0]))
5115    && GET_CODE (operands[1]) == CONST_INT
5116    && ((INTVAL (operands[1]) < 0
5117         && INTVAL (operands[1]) >= -0x10)
5118        || (INTVAL (operands[1]) >= 32 * 8
5119            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
5120        || (INTVAL (operands[1]) >= 0
5121            && INTVAL (operands[1]) < 32 * 8
5122            && (INTVAL (operands[1]) & 7) != 0))"
5123   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
5124    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
5125   "
5127   HOST_WIDE_INT val = INTVAL (operands[1]);
5129   if (val < 0)
5130     operands[2] = GEN_INT (0);
5131   else if (val >= 32 * 8)
5132     {
5133       int off = val & 7;
5135       operands[1] = GEN_INT (0x8 + off);
5136       operands[2] = GEN_INT (val - off - 0x8);
5137     }
5138   else
5139     {
5140       int off = val & 7;
5142       operands[1] = GEN_INT (off);
5143       operands[2] = GEN_INT (val - off);
5144     }
5147 ;; Handle input reloads in DImode.
5148 ;; This is mainly to handle reloading HILO_REGNUM.  Note that we may
5149 ;; see it as the source or the destination, depending upon which way
5150 ;; reload handles the instruction.
5151 ;; Making the second operand TImode is a trick.  The compiler may
5152 ;; reuse the same register for operand 0 and operand 2.  Using TImode
5153 ;; gives us two registers, so we can always use the one which is not
5154 ;; used.
5156 (define_expand "reload_indi"
5157   [(set (match_operand:DI 0 "register_operand" "=b")
5158         (match_operand:DI 1 "" "b"))
5159    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5160   "TARGET_64BIT"
5161   "
5163   rtx scratch = gen_rtx_REG (DImode,
5164                              (REGNO (operands[0]) == REGNO (operands[2])
5165                               ? REGNO (operands[2]) + 1
5166                               : REGNO (operands[2])));
5168   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5169     {
5170       if (GET_CODE (operands[1]) == MEM)
5171         {
5172           rtx memword, offword, hi_word, lo_word;
5173           rtx addr = find_replacement (&XEXP (operands[1], 0));
5174           rtx op1 = replace_equiv_address (operands[1], addr);
5176           scratch = gen_rtx_REG (SImode, REGNO (scratch));
5177           memword = adjust_address (op1, SImode, 0);
5178           offword = adjust_address (op1, SImode, 4);
5180           if (BYTES_BIG_ENDIAN)
5181             {
5182               hi_word = memword;
5183               lo_word = offword;
5184             }
5185           else
5186             {
5187               hi_word = offword;
5188               lo_word = memword;
5189             }
5190           emit_move_insn (scratch, hi_word);
5191           emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
5192           emit_move_insn (scratch, lo_word);
5193           emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
5194           emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
5195         }
5196       else
5197         {
5198           emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5199           emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
5200           emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5201           emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5202           emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5203           emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
5204         }
5205       DONE;
5206     }
5207   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5208     {
5209       emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
5210       emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5211       emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5212       emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
5213       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5214       emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5215       emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
5216       DONE;
5217     }
5218   /* This handles moves between a float register and HI/LO.  */
5219   emit_move_insn (scratch, operands[1]);
5220   emit_move_insn (operands[0], scratch);
5221   DONE;
5224 ;; Handle output reloads in DImode.
5226 ;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5227 ;; use a TImode scratch reg.
5229 (define_expand "reload_outdi"
5230   [(set (match_operand:DI 0 "general_operand" "=b")
5231         (match_operand:DI 1 "se_register_operand" "b"))
5232    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5233   "TARGET_64BIT"
5234   "
5236   rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5238   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5239     {
5240       emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5241       emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5242       emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5243       emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5244       emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5245       emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
5246       DONE;
5247     }
5248   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5249     {
5250       if (GET_CODE (operands[0]) == MEM)
5251         {
5252           rtx scratch, memword, offword, hi_word, lo_word;
5253           rtx addr = find_replacement (&XEXP (operands[0], 0));
5254           rtx op0 = replace_equiv_address (operands[0], addr);
5256           scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
5257           memword = adjust_address (op0, SImode, 0);
5258           offword = adjust_address (op0, SImode, 4);
5260           if (BYTES_BIG_ENDIAN)
5261             {
5262               hi_word = memword;
5263               lo_word = offword;
5264             }
5265           else
5266             {
5267               hi_word = offword;
5268               lo_word = memword;
5269             }
5270           emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
5271           emit_move_insn (hi_word, scratch);
5272           emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
5273           emit_move_insn (lo_word, scratch);
5274           emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
5275         }
5276       else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
5277         {
5278           /* Handle the case where operand[0] is not a 'd' register,
5279              and hence we can not directly move from the HILO register
5280              into it.  */
5281           rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5282           emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5283           emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5284           emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5285           emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
5286           emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
5287           emit_insn (gen_iordi3 (scratch, scratch, scratch2));
5288           emit_insn (gen_movdi (operands[0], scratch));
5289           emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
5290         }
5291       else
5292         {
5293           emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5294           emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5295           emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5296           emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5297           emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5298           emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5299           emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
5300         }
5301       DONE;
5302     }
5303   /* This handles moves between a float register and HI/LO.  */
5304   emit_move_insn (scratch, operands[1]);
5305   emit_move_insn (operands[0], scratch);
5306   DONE;
5309 ;; 32-bit Integer moves
5311 (define_split
5312   [(set (match_operand:SI 0 "register_operand" "")
5313         (match_operand:SI 1 "large_int" ""))]
5314   "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
5315   [(set (match_dup 0)
5316         (match_dup 2))
5317    (set (match_dup 0)
5318         (ior:SI (match_dup 0)
5319                 (match_dup 3)))]
5320   "
5322   operands[2] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
5323                                              & BITMASK_UPPER16,
5324                                              SImode));
5325   operands[3] = GEN_INT (INTVAL (operands[1]) & BITMASK_LOWER16);
5328 ;; Unlike most other insns, the move insns can't be split with
5329 ;; different predicates, because register spilling and other parts of
5330 ;; the compiler, have memoized the insn number already.
5332 (define_expand "movsi"
5333   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5334         (match_operand:SI 1 "general_operand" ""))]
5335   ""
5336   "
5338   if (mips_split_addresses && mips_check_split (operands[1], SImode))
5339     {
5340       enum machine_mode mode = GET_MODE (operands[0]);
5341       rtx tem = ((reload_in_progress | reload_completed)
5342                  ? operands[0] : gen_reg_rtx (mode));
5344       emit_insn (gen_rtx_SET (VOIDmode, tem,
5345                               gen_rtx_HIGH (mode, operands[1])));
5347       operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
5348     }
5350   /* If we are generating embedded PIC code, and we are referring to a
5351      symbol in the .text section, we must use an offset from the start
5352      of the function.  */
5353   if (TARGET_EMBEDDED_PIC
5354       && (GET_CODE (operands[1]) == LABEL_REF
5355           || (GET_CODE (operands[1]) == SYMBOL_REF
5356               && ! SYMBOL_REF_FLAG (operands[1]))))
5357     {
5358       rtx temp;
5360       temp = embedded_pic_offset (operands[1]);
5361       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_rtx,
5362                            force_reg (SImode, temp));
5363       emit_move_insn (operands[0], force_reg (SImode, temp));
5364       DONE;
5365     }
5367   /* If operands[1] is a constant address invalid for pic, then we need to
5368      handle it just like LEGITIMIZE_ADDRESS does.  */
5369   if (flag_pic && pic_address_needs_scratch (operands[1]))
5370     {
5371       rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
5372       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5374       if (! SMALL_INT (temp2))
5375         temp2 = force_reg (SImode, temp2);
5377       emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, temp2));
5378       DONE;
5379     }
5381   /* On the mips16, we can handle a GP relative reference by adding in
5382      $gp.  We need to check the name to see whether this is a string
5383      constant.  */
5384   if (TARGET_MIPS16
5385       && register_operand (operands[0], SImode)
5386       && GET_CODE (operands[1]) == SYMBOL_REF
5387       && SYMBOL_REF_FLAG (operands[1]))
5388     {
5389       const char *name = XSTR (operands[1], 0);
5391       if (name[0] != '*'
5392           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5393                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5394         {
5395           rtx base_reg;
5397           if (reload_in_progress || reload_completed)
5398             {
5399               /* We need to reload this address.  In this case we
5400                  aren't going to have a chance to combine loading the
5401                  address with the load or store.  That means that we
5402                  can either generate a 2 byte move followed by a 4
5403                  byte addition, or a 2 byte load with a 4 byte entry
5404                  in the constant table.  Since the entry in the
5405                  constant table might be shared, we're better off, on
5406                  average, loading the address from the constant table.  */
5407               emit_move_insn (operands[0],
5408                               force_const_mem (SImode, operands[1]));
5409               DONE;
5410             }
5412           base_reg = gen_reg_rtx (Pmode);
5413           emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5415           emit_move_insn (operands[0],
5416                           gen_rtx (PLUS, Pmode, base_reg,
5417                                    mips16_gp_offset (operands[1])));
5418           DONE;
5419         }
5420     }
5422   if ((reload_in_progress | reload_completed) == 0
5423       && !register_operand (operands[0], SImode)
5424       && !register_operand (operands[1], SImode)
5425       && (TARGET_MIPS16
5426           || GET_CODE (operands[1]) != CONST_INT
5427           || INTVAL (operands[1]) != 0))
5428     {
5429       rtx temp = force_reg (SImode, operands[1]);
5430       emit_move_insn (operands[0], temp);
5431       DONE;
5432     }
5435 ;; For mips16, we need a special case to handle storing $31 into
5436 ;; memory, since we don't have a constraint to match $31.  This
5437 ;; instruction can be generated by save_restore_insns.
5439 (define_insn ""
5440   [(set (match_operand:SI 0 "memory_operand" "=R,m")
5441         (reg:SI 31))]
5442   "TARGET_MIPS16"
5443   "*
5445   operands[1] = gen_rtx (REG, SImode, 31);
5446   return mips_move_1word (operands, insn, FALSE);
5448   [(set_attr "type"     "store")
5449    (set_attr "mode"     "SI")
5450    (set_attr "length"   "4,8")])
5452 ;; The difference between these two is whether or not ints are allowed
5453 ;; in FP registers (off by default, use -mdebugh to enable).
5455 (define_insn "movsi_internal1"
5456   [(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")
5457         (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"))]
5458   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5459    && (register_operand (operands[0], SImode)
5460        || register_operand (operands[1], SImode)
5461        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5462   "* return mips_move_1word (operands, insn, FALSE);"
5463   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
5464    (set_attr "mode"     "SI")
5465    (set_attr "length"   "4,8,4,8,4,8,4,8,4,4,4,4,8,4,8,4,4,4,4")])
5467 (define_insn "movsi_internal2"
5468   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
5469         (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
5470   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5471    && (register_operand (operands[0], SImode)
5472        || register_operand (operands[1], SImode)
5473        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5474   "* return mips_move_1word (operands, insn, FALSE);"
5475   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
5476    (set_attr "mode"     "SI")
5477    (set_attr "length"   "4,8,4,8,4,8,4,8,4,4,4,4,4,4")])
5479 ;; This is the mips16 movsi instruction.  We accept a small integer as
5480 ;; the source if the destination is a GP memory reference.  This is
5481 ;; because we want the combine pass to turn adding a GP reference to a
5482 ;; register into a direct GP reference, but the combine pass will pass
5483 ;; in the source as a constant if it finds an equivalent one.  If the
5484 ;; instruction is recognized, reload will force the constant back out
5485 ;; into a register.
5487 (define_insn ""
5488   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,d,R,m,*d,*d")
5489         (match_operand:SI 1 "move_operand" "d,d,y,S,K,N,s,R,m,d,d,*x,*a"))]
5490   "TARGET_MIPS16
5491    && (register_operand (operands[0], SImode)
5492        || register_operand (operands[1], SImode)
5493        || (GET_CODE (operands[0]) == MEM
5494            && GET_CODE (XEXP (operands[0], 0)) == PLUS
5495            && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
5496            && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
5497            && GET_CODE (operands[1]) == CONST_INT
5498            && (SMALL_INT (operands[1])
5499                || SMALL_INT_UNSIGNED (operands[1]))))"
5500   "* return mips_move_1word (operands, insn, FALSE);"
5501   [(set_attr "type"     "move,move,move,load,arith,arith,arith,load,load,store,store,hilo,hilo")
5502    (set_attr "mode"     "SI")
5503    (set_attr_alternative "length"
5504                 [(const_int 4)
5505                  (const_int 4)
5506                  (const_int 4)
5507                  (const_int 8)
5508                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5509                                (const_int 4)
5510                                (const_int 8))
5511                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5512                                (const_int 8)
5513                                (const_int 12))
5514                  (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
5515                                (const_int 4)
5516                                (const_int 8))
5517                  (const_int 4)
5518                  (const_int 8)
5519                  (const_int 4)
5520                  (const_int 8)
5521                  (const_int 4)
5522                  (const_int 4)])])
5524 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
5525 ;; when the original load is a 4 byte instruction but the add and the
5526 ;; load are 2 2 byte instructions.
5528 (define_split
5529   [(set (match_operand:SI 0 "register_operand" "")
5530         (mem:SI (plus:SI (match_dup 0)
5531                          (match_operand:SI 1 "const_int_operand" ""))))]
5532   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5533    && GET_CODE (operands[0]) == REG
5534    && M16_REG_P (REGNO (operands[0]))
5535    && GET_CODE (operands[1]) == CONST_INT
5536    && ((INTVAL (operands[1]) < 0
5537         && INTVAL (operands[1]) >= -0x80)
5538        || (INTVAL (operands[1]) >= 32 * 4
5539            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5540        || (INTVAL (operands[1]) >= 0
5541            && INTVAL (operands[1]) < 32 * 4
5542            && (INTVAL (operands[1]) & 3) != 0))"
5543   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5544    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
5545   "
5547   HOST_WIDE_INT val = INTVAL (operands[1]);
5549   if (val < 0)
5550     operands[2] = GEN_INT (0);
5551   else if (val >= 32 * 4)
5552     {
5553       int off = val & 3;
5555       operands[1] = GEN_INT (0x7c + off);
5556       operands[2] = GEN_INT (val - off - 0x7c);
5557     }
5558   else
5559     {
5560       int off = val & 3;
5562       operands[1] = GEN_INT (off);
5563       operands[2] = GEN_INT (val - off);
5564     }
5567 ;; On the mips16, we can split a load of certain constants into a load
5568 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
5569 ;; instructions.
5571 (define_split
5572   [(set (match_operand:SI 0 "register_operand" "")
5573         (match_operand:SI 1 "const_int_operand" ""))]
5574   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5575    && GET_CODE (operands[0]) == REG
5576    && M16_REG_P (REGNO (operands[0]))
5577    && GET_CODE (operands[1]) == CONST_INT
5578    && INTVAL (operands[1]) >= 0x100
5579    && INTVAL (operands[1]) <= 0xff + 0x7f"
5580   [(set (match_dup 0) (match_dup 1))
5581    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5582   "
5584   int val = INTVAL (operands[1]);
5586   operands[1] = GEN_INT (0xff);
5587   operands[2] = GEN_INT (val - 0xff);
5590 ;; On the mips16, we can split a load of a negative constant into a
5591 ;; load and a neg.  That's what mips_move_1word will generate anyhow.
5593 (define_split
5594   [(set (match_operand:SI 0 "register_operand" "")
5595         (match_operand:SI 1 "const_int_operand" ""))]
5596   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5597    && GET_CODE (operands[0]) == REG
5598    && M16_REG_P (REGNO (operands[0]))
5599    && GET_CODE (operands[1]) == CONST_INT
5600    && INTVAL (operands[1]) < 0
5601    && INTVAL (operands[1]) > - 0x8000"
5602   [(set (match_dup 0) (match_dup 1))
5603    (set (match_dup 0) (neg:SI (match_dup 0)))]
5604   "
5606   operands[1] = GEN_INT (- INTVAL (operands[1]));
5609 ;; Reload HILO_REGNUM in SI mode.  This needs a scratch register in
5610 ;; order to set the sign bit correctly in the HI register.
5612 (define_expand "reload_outsi"
5613   [(set (match_operand:SI 0 "general_operand" "=b")
5614         (match_operand:SI 1 "register_operand" "b"))
5615    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5616   "TARGET_64BIT || TARGET_MIPS16"
5617   "
5619   if (TARGET_64BIT
5620       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5621     {
5622       emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
5623       emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5624       emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
5625       emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
5626       DONE;
5627     }
5628   /* Use a mult to reload LO on mips16.  ??? This is hideous.  */
5629   if (TARGET_MIPS16
5630       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5631     {
5632       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5633       /* This is gen_mulsi3_internal, but we need to fill in the
5634          scratch registers.  */
5635       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5636                           gen_rtvec (3,
5637                                      gen_rtx (SET, VOIDmode,
5638                                               operands[0],
5639                                               gen_rtx (MULT, SImode,
5640                                                        operands[1],
5641                                                        operands[2])),
5642                                      gen_rtx (CLOBBER, VOIDmode,
5643                                               gen_rtx (REG, SImode, 64)),
5644                                      gen_rtx (CLOBBER, VOIDmode,
5645                                               gen_rtx (REG, SImode, 66)))));
5646       DONE;
5647     }
5648   /* FIXME: I don't know how to get a value into the HI register.  */
5649   if (GET_CODE (operands[0]) == REG
5650       && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5651           : GP_REG_P (REGNO (operands[0]))))
5652     {
5653       emit_move_insn (operands[0], operands[1]);
5654       DONE;
5655     }
5656   /* This handles moves between a float register and HI/LO.  */
5657   emit_move_insn (operands[2], operands[1]);
5658   emit_move_insn (operands[0], operands[2]);
5659   DONE;
5662 ;; Reload a value into HI or LO.  There is no mthi or mtlo on mips16,
5663 ;; so we use a mult.  ??? This is hideous, and we ought to figure out
5664 ;; something better.
5666 ;; We use no predicate for operand1, because it may be a PLUS, and there
5667 ;; is no convenient predicate for that.
5669 (define_expand "reload_insi"
5670   [(set (match_operand:SI 0 "register_operand" "=b")
5671         (match_operand:SI 1 "" "b"))
5672    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5673   "TARGET_MIPS16"
5674   "
5676   if (TARGET_MIPS16
5677       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5678     {
5679       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5680       /* This is gen_mulsi3_internal, but we need to fill in the
5681          scratch registers.  */
5682       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5683                           gen_rtvec (3,
5684                                      gen_rtx (SET, VOIDmode,
5685                                               operands[0],
5686                                               gen_rtx (MULT, SImode,
5687                                                        operands[1],
5688                                                        operands[2])),
5689                                      gen_rtx (CLOBBER, VOIDmode,
5690                                               gen_rtx (REG, SImode, 64)),
5691                                      gen_rtx (CLOBBER, VOIDmode,
5692                                               gen_rtx (REG, SImode, 66)))));
5693       DONE;
5694     }
5696   /* If this is a plus, then this must be an add of the stack pointer against
5697      either a hard register or a pseudo.  */
5698   if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5699     {
5700       rtx plus_op;
5702       if (XEXP (operands[1], 0) == stack_pointer_rtx)
5703         plus_op = XEXP (operands[1], 1);
5704       else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5705         plus_op = XEXP (operands[1], 0);
5706       else
5707         abort ();
5709       /* We should have a register now.  */
5710       if (GET_CODE (plus_op) != REG)
5711         abort ();
5713       if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5714         {
5715           /* We have to have at least one temporary register which is not
5716              overlapping plus_op.  */
5717           if (! rtx_equal_p (plus_op, operands[0]))
5718             {
5719               emit_move_insn (operands[0], stack_pointer_rtx);
5720               emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5721             }
5722           else if (! rtx_equal_p (plus_op, operands[2]))
5723             {
5724               emit_move_insn (operands[2], stack_pointer_rtx);
5725               emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5726             }
5727           else
5728             abort ();
5729         }
5730       else
5731         {
5732           /* We need two registers in this case.  */
5733           if (! rtx_equal_p (operands[0], operands[2]))
5734             {
5735               emit_move_insn (operands[0], stack_pointer_rtx);
5736               emit_move_insn (operands[2], plus_op);
5737               emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5738             }
5739           else
5740             abort ();
5741         }
5742       DONE;
5743     }
5745   /* FIXME: I don't know how to get a value into the HI register.  */
5746   emit_move_insn (operands[0], operands[1]);
5747   DONE;
5750 ;; This insn is for the unspec delay for HILO.
5752 (define_insn "*HILO_delay"
5753   [(unspec [(match_operand 0 "register_operand" "=b")] 2 )]
5754   ""
5755   ""
5756   [(set_attr "type" "nop")
5757    (set_attr "mode" "none")])
5759 ;; This insn handles moving CCmode values.  It's really just a
5760 ;; slightly simplified copy of movsi_internal2, with additional cases
5761 ;; to move a condition register to a general register and to move
5762 ;; between the general registers and the floating point registers.
5764 (define_insn "movcc"
5765   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
5766         (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
5767   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5768   "* return mips_move_1word (operands, insn, FALSE);"
5769   [(set_attr "type"     "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
5770    (set_attr "mode"     "SI")
5771    (set_attr "length"   "8,4,4,8,4,8,4,4,4,4,8,4,8")])
5773 ;; Reload condition code registers.  These need scratch registers.
5775 (define_expand "reload_incc"
5776   [(set (match_operand:CC 0 "register_operand" "=z")
5777         (match_operand:CC 1 "general_operand" "z"))
5778    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5779   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5780   "
5782   rtx source;
5783   rtx fp1, fp2;
5784   int regno;
5786   /* This is called when are copying some value into a condition code
5787      register.  Operand 0 is the condition code register.  Operand 1
5788      is the source.  Operand 2 is a scratch register; we use TFmode
5789      because we actually need two floating point registers.  */
5790   if (! ST_REG_P (true_regnum (operands[0]))
5791       || ! FP_REG_P (true_regnum (operands[2])))
5792     abort ();
5794   /* We need to get the source in SFmode so that the insn is
5795      recognized.  */
5796   if (GET_CODE (operands[1]) == MEM)
5797     source = adjust_address (operands[1], SFmode, 0);
5798   else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
5799     source = gen_rtx_REG (SFmode, true_regnum (operands[1]));
5800   else
5801     source = operands[1];
5803   /* FP1 and FP2 are the two halves of the TFmode scratch operand.  They
5804      will be single registers in 64-bit mode and register pairs in 32-bit
5805      mode.  SOURCE is loaded into FP1 and zero is loaded into FP2.  */
5806   regno = REGNO (operands[2]);
5807   fp1 = gen_rtx_REG (SFmode, regno);
5808   fp2 = gen_rtx_REG (SFmode, regno + HARD_REGNO_NREGS (regno, DFmode));
5810   emit_insn (gen_move_insn (fp1, source));
5811   emit_insn (gen_move_insn (fp2, gen_rtx_REG (SFmode, 0)));
5812   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5813                           gen_rtx_LT (CCmode, fp2, fp1)));
5815   DONE;
5818 (define_expand "reload_outcc"
5819   [(set (match_operand:CC 0 "general_operand" "=z")
5820         (match_operand:CC 1 "register_operand" "z"))
5821    (clobber (match_operand:CC 2 "register_operand" "=&d"))]
5822   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5823   "
5825   /* This is called when we are copying a condition code register out
5826      to save it somewhere.  Operand 0 should be the location we are
5827      going to save it to.  Operand 1 should be the condition code
5828      register.  Operand 2 should be a scratch general purpose register
5829      created for us by reload.  The mips_secondary_reload_class
5830      function should have told reload that we don't need a scratch
5831      register if the destination is a general purpose register anyhow.  */
5832   if (ST_REG_P (true_regnum (operands[0]))
5833       || GP_REG_P (true_regnum (operands[0]))
5834       || ! ST_REG_P (true_regnum (operands[1]))
5835       || ! GP_REG_P (true_regnum (operands[2])))
5836     abort ();
5838   /* All we have to do is copy the value from the condition code to
5839      the data register, which movcc can handle, and then store the
5840      value into the real final destination.  */
5841   emit_insn (gen_move_insn (operands[2], operands[1]));
5842   emit_insn (gen_move_insn (operands[0], operands[2]));
5844   DONE;
5847 ;; MIPS4 supports loading and storing a floating point register from
5848 ;; the sum of two general registers.  We use two versions for each of
5849 ;; these four instructions: one where the two general registers are
5850 ;; SImode, and one where they are DImode.  This is because general
5851 ;; registers will be in SImode when they hold 32 bit values, but,
5852 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5853 ;; instructions will still work correctly.
5855 ;; ??? Perhaps it would be better to support these instructions by
5856 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
5857 ;; these instructions can only be used to load and store floating
5858 ;; point registers, that would probably cause trouble in reload.
5860 (define_insn ""
5861   [(set (match_operand:SF 0 "register_operand" "=f")
5862         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5863                          (match_operand:SI 2 "register_operand" "d"))))]
5864   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5865   "lwxc1\\t%0,%1(%2)"
5866   [(set_attr "type"     "load")
5867    (set_attr "mode"     "SF")])
5869 (define_insn ""
5870   [(set (match_operand:SF 0 "register_operand" "=f")
5871         (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5872                          (match_operand:DI 2 "se_register_operand" "d"))))]
5873   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5874   "lwxc1\\t%0,%1(%2)"
5875   [(set_attr "type"     "load")
5876    (set_attr "mode"     "SF")])
5878 (define_insn ""
5879   [(set (match_operand:DF 0 "register_operand" "=f")
5880         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5881                          (match_operand:SI 2 "register_operand" "d"))))]
5882   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5883   "ldxc1\\t%0,%1(%2)"
5884   [(set_attr "type"     "load")
5885    (set_attr "mode"     "DF")])
5887 (define_insn ""
5888   [(set (match_operand:DF 0 "register_operand" "=f")
5889         (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5890                          (match_operand:DI 2 "se_register_operand" "d"))))]
5891   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5892   "ldxc1\\t%0,%1(%2)"
5893   [(set_attr "type"     "load")
5894    (set_attr "mode"     "DF")])
5896 (define_insn ""
5897   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5898                          (match_operand:SI 2 "register_operand" "d")))
5899         (match_operand:SF 0 "register_operand" "f"))]
5900   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5901   "swxc1\\t%0,%1(%2)"
5902   [(set_attr "type"     "store")
5903    (set_attr "mode"     "SF")])
5905 (define_insn ""
5906   [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5907                          (match_operand:DI 2 "se_register_operand" "d")))
5908         (match_operand:SF 0 "register_operand" "f"))]
5909   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5910   "swxc1\\t%0,%1(%2)"
5911   [(set_attr "type"     "store")
5912    (set_attr "mode"     "SF")])
5914 (define_insn ""
5915   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5916                          (match_operand:SI 2 "register_operand" "d")))
5917         (match_operand:DF 0 "register_operand" "f"))]
5918   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5919   "sdxc1\\t%0,%1(%2)"
5920   [(set_attr "type"     "store")
5921    (set_attr "mode"     "DF")])
5923 (define_insn ""
5924   [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5925                          (match_operand:DI 2 "se_register_operand" "d")))
5926         (match_operand:DF 0 "register_operand" "f"))]
5927   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5928   "sdxc1\\t%0,%1(%2)"
5929   [(set_attr "type"     "store")
5930    (set_attr "mode"     "DF")])
5932 ;; 16-bit Integer moves
5934 ;; Unlike most other insns, the move insns can't be split with
5935 ;; different predicates, because register spilling and other parts of
5936 ;; the compiler, have memoized the insn number already.
5937 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5939 (define_expand "movhi"
5940   [(set (match_operand:HI 0 "nonimmediate_operand" "")
5941         (match_operand:HI 1 "general_operand" ""))]
5942   ""
5943   "
5945   if ((reload_in_progress | reload_completed) == 0
5946       && !register_operand (operands[0], HImode)
5947       && !register_operand (operands[1], HImode)
5948       && (TARGET_MIPS16
5949           || (GET_CODE (operands[1]) != CONST_INT
5950           || INTVAL (operands[1]) != 0)))
5951     {
5952       rtx temp = force_reg (HImode, operands[1]);
5953       emit_move_insn (operands[0], temp);
5954       DONE;
5955     }
5958 ;; The difference between these two is whether or not ints are allowed
5959 ;; in FP registers (off by default, use -mdebugh to enable).
5961 (define_insn "movhi_internal1"
5962   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
5963         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
5964   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5965    && (register_operand (operands[0], HImode)
5966        || register_operand (operands[1], HImode)
5967        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5968   "* return mips_move_1word (operands, insn, TRUE);"
5969   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
5970    (set_attr "mode"     "HI")
5971    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,4")])
5973 (define_insn "movhi_internal2"
5974   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5975         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
5976   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5977    && (register_operand (operands[0], HImode)
5978        || register_operand (operands[1], HImode)
5979        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5980   "* return mips_move_1word (operands, insn, TRUE);"
5981   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5982    (set_attr "mode"     "HI")
5983    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4")])
5985 (define_insn ""
5986   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5987         (match_operand:HI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
5988   "TARGET_MIPS16
5989    && (register_operand (operands[0], HImode)
5990        || register_operand (operands[1], HImode))"
5991   "* return mips_move_1word (operands, insn, TRUE);"
5992   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
5993    (set_attr "mode"     "HI")
5994    (set_attr_alternative "length"
5995                 [(const_int 4)
5996                  (const_int 4)
5997                  (const_int 4)
5998                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5999                                (const_int 4)
6000                                (const_int 8))
6001                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6002                                (const_int 8)
6003                                (const_int 12))
6004                  (const_int 4)
6005                  (const_int 8)
6006                  (const_int 4)
6007                  (const_int 8)
6008                  (const_int 4)])])
6011 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
6012 ;; when the original load is a 4 byte instruction but the add and the
6013 ;; load are 2 2 byte instructions.
6015 (define_split
6016   [(set (match_operand:HI 0 "register_operand" "")
6017         (mem:HI (plus:SI (match_dup 0)
6018                          (match_operand:SI 1 "const_int_operand" ""))))]
6019   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6020    && GET_CODE (operands[0]) == REG
6021    && M16_REG_P (REGNO (operands[0]))
6022    && GET_CODE (operands[1]) == CONST_INT
6023    && ((INTVAL (operands[1]) < 0
6024         && INTVAL (operands[1]) >= -0x80)
6025        || (INTVAL (operands[1]) >= 32 * 2
6026            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
6027        || (INTVAL (operands[1]) >= 0
6028            && INTVAL (operands[1]) < 32 * 2
6029            && (INTVAL (operands[1]) & 1) != 0))"
6030   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6031    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
6032   "
6034   HOST_WIDE_INT val = INTVAL (operands[1]);
6036   if (val < 0)
6037     operands[2] = GEN_INT (0);
6038   else if (val >= 32 * 2)
6039     {
6040       int off = val & 1;
6042       operands[1] = GEN_INT (0x7e + off);
6043       operands[2] = GEN_INT (val - off - 0x7e);
6044     }
6045   else
6046     {
6047       int off = val & 1;
6049       operands[1] = GEN_INT (off);
6050       operands[2] = GEN_INT (val - off);
6051     }
6054 ;; 8-bit Integer moves
6056 ;; Unlike most other insns, the move insns can't be split with
6057 ;; different predicates, because register spilling and other parts of
6058 ;; the compiler, have memoized the insn number already.
6059 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6061 (define_expand "movqi"
6062   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6063         (match_operand:QI 1 "general_operand" ""))]
6064   ""
6065   "
6067   if ((reload_in_progress | reload_completed) == 0
6068       && !register_operand (operands[0], QImode)
6069       && !register_operand (operands[1], QImode)
6070       && (TARGET_MIPS16
6071           || (GET_CODE (operands[1]) != CONST_INT
6072           || INTVAL (operands[1]) != 0)))
6073     {
6074       rtx temp = force_reg (QImode, operands[1]);
6075       emit_move_insn (operands[0], temp);
6076       DONE;
6077     }
6080 ;; The difference between these two is whether or not ints are allowed
6081 ;; in FP registers (off by default, use -mdebugh to enable).
6083 (define_insn "movqi_internal1"
6084   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
6085         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6086   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6087    && (register_operand (operands[0], QImode)
6088        || register_operand (operands[1], QImode)
6089        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6090   "* return mips_move_1word (operands, insn, TRUE);"
6091   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6092    (set_attr "mode"     "QI")
6093    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,4")])
6095 (define_insn "movqi_internal2"
6096   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
6097         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
6098   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6099    && (register_operand (operands[0], QImode)
6100        || register_operand (operands[1], QImode)
6101        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6102   "* return mips_move_1word (operands, insn, TRUE);"
6103   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
6104    (set_attr "mode"     "QI")
6105    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4")])
6107 (define_insn ""
6108   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6109         (match_operand:QI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
6110   "TARGET_MIPS16
6111    && (register_operand (operands[0], QImode)
6112        || register_operand (operands[1], QImode))"
6113   "* return mips_move_1word (operands, insn, TRUE);"
6114   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
6115    (set_attr "mode"     "QI")
6116    (set_attr_alternative "length"
6117                 [(const_int 4)
6118                  (const_int 4)
6119                  (const_int 4)
6120                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6121                                (const_int 4)
6122                                (const_int 8))
6123                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6124                                (const_int 8)
6125                                (const_int 12))
6126                  (const_int 4)
6127                  (const_int 8)
6128                  (const_int 4)
6129                  (const_int 8)
6130                  (const_int 4)])])
6133 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
6134 ;; when the original load is a 4 byte instruction but the add and the
6135 ;; load are 2 2 byte instructions.
6137 (define_split
6138   [(set (match_operand:QI 0 "register_operand" "")
6139         (mem:QI (plus:SI (match_dup 0)
6140                          (match_operand:SI 1 "const_int_operand" ""))))]
6141   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6142    && GET_CODE (operands[0]) == REG
6143    && M16_REG_P (REGNO (operands[0]))
6144    && GET_CODE (operands[1]) == CONST_INT
6145    && ((INTVAL (operands[1]) < 0
6146         && INTVAL (operands[1]) >= -0x80)
6147        || (INTVAL (operands[1]) >= 32
6148            && INTVAL (operands[1]) <= 31 + 0x7f))"
6149   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6150    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
6151   "
6153   HOST_WIDE_INT val = INTVAL (operands[1]);
6155   if (val < 0)
6156     operands[2] = GEN_INT (0);
6157   else
6158     {
6159       operands[1] = GEN_INT (0x7f);
6160       operands[2] = GEN_INT (val - 0x7f);
6161     }
6164 ;; 32-bit floating point moves
6166 (define_expand "movsf"
6167   [(set (match_operand:SF 0 "nonimmediate_operand" "")
6168         (match_operand:SF 1 "general_operand" ""))]
6169   ""
6170   "
6172   if ((reload_in_progress | reload_completed) == 0
6173       && !register_operand (operands[0], SFmode)
6174       && !register_operand (operands[1], SFmode)
6175       && (TARGET_MIPS16
6176           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6177                && operands[1] != CONST0_RTX (SFmode))))
6178     {
6179       rtx temp = force_reg (SFmode, operands[1]);
6180       emit_move_insn (operands[0], temp);
6181       DONE;
6182     }
6185 (define_insn "movsf_internal1"
6186   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
6187         (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
6188   "TARGET_HARD_FLOAT
6189    && (register_operand (operands[0], SFmode)
6190        || register_operand (operands[1], SFmode)
6191        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6192        || operands[1] == CONST0_RTX (SFmode))"
6193   "* return mips_move_1word (operands, insn, FALSE);"
6194   [(set_attr "type"     "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
6195    (set_attr "mode"     "SF")
6196    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,8,4,8")])
6199 (define_insn "movsf_internal2"
6200   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
6201         (match_operand:SF 1 "general_operand" "      Gd,R,Fm,d,d"))]
6202   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
6203    && (register_operand (operands[0], SFmode)
6204        || register_operand (operands[1], SFmode)
6205        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6206        || operands[1] == CONST0_RTX (SFmode))"
6207   "* return mips_move_1word (operands, insn, FALSE);"
6208   [(set_attr "type"     "move,load,load,store,store")
6209    (set_attr "mode"     "SF")
6210    (set_attr "length"   "4,4,8,4,8")])
6212 (define_insn ""
6213   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
6214         (match_operand:SF 1 "general_operand"      "d,d,y,R,Fm,d,d"))]
6215   "TARGET_MIPS16
6216    && (register_operand (operands[0], SFmode)
6217        || register_operand (operands[1], SFmode))"
6218   "* return mips_move_1word (operands, insn, FALSE);"
6219   [(set_attr "type"     "move,move,move,load,load,store,store")
6220    (set_attr "mode"     "SF")
6221    (set_attr "length"   "4,4,4,4,8,4,8")])
6224 ;; 64-bit floating point moves
6226 (define_expand "movdf"
6227   [(set (match_operand:DF 0 "nonimmediate_operand" "")
6228         (match_operand:DF 1 "general_operand" ""))]
6229   ""
6230   "
6232   if ((reload_in_progress | reload_completed) == 0
6233       && !register_operand (operands[0], DFmode)
6234       && !register_operand (operands[1], DFmode)
6235       && (TARGET_MIPS16
6236           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6237                && operands[1] != CONST0_RTX (DFmode))))
6238     {
6239       rtx temp = force_reg (DFmode, operands[1]);
6240       emit_move_insn (operands[0], temp);
6241       DONE;
6242     }
6245 (define_insn "movdf_internal1"
6246   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,To,f,*f,*d,*d,*d,*d,*R,*T")
6247         (match_operand:DF 1 "general_operand" "f,R,To,fG,fG,F,*d,*f,*d*G,*R,*T*F,*d,*d"))]
6248   "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
6249    && TARGET_DOUBLE_FLOAT
6250    && (register_operand (operands[0], DFmode)
6251        || register_operand (operands[1], DFmode)
6252        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6253        || operands[1] == CONST0_RTX (DFmode))"
6254   "* return mips_move_2words (operands, insn); "
6255   [(set_attr "type"     "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
6256    (set_attr "mode"     "DF")
6257    (set_attr "length"   "4,8,16,8,16,16,8,8,8,8,16,8,16")])
6259 (define_insn "movdf_internal1a"
6260   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,*d,*d,*d,*To,*R,*d")
6261         (match_operand:DF 1 "general_operand"      " f,To,f,G,f,G,*F,*To,*R,*d,*d,*d"))]
6262   "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
6263    && TARGET_DOUBLE_FLOAT
6264    && (register_operand (operands[0], DFmode)
6265        || register_operand (operands[1], DFmode)
6266        || (GET_CODE (operands [0]) == MEM
6267            && ((GET_CODE (operands[1]) == CONST_INT
6268                 && INTVAL (operands[1]) == 0)
6269                || operands[1] == CONST0_RTX (DFmode))))"
6270   "* return mips_move_2words (operands, insn); "
6271   [(set_attr "type"     "move,load,store,store,store,store,load,load,load,store,store,move")
6272    (set_attr "mode"     "DF")
6273    (set_attr "length"   "4,8,4,4,8,8,8,8,4,8,4,4")])
6275 (define_insn "movdf_internal2"
6276   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To,*d")
6277         (match_operand:DF 1 "general_operand" "dG,R,ToF,d,d,*f"))]
6278   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
6279    && (register_operand (operands[0], DFmode)
6280        || register_operand (operands[1], DFmode)
6281        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6282        || operands[1] == CONST0_RTX (DFmode))"
6283   "* return mips_move_2words (operands, insn); "
6284   [(set_attr "type"     "move,load,load,store,store,xfer")
6285    (set_attr "mode"     "DF")
6286    (set_attr "length"   "8,8,16,8,16,8")])
6288 (define_insn ""
6289   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
6290         (match_operand:DF 1 "general_operand" "d,d,y,R,ToF,d,d"))]
6291   "TARGET_MIPS16
6292    && (register_operand (operands[0], DFmode)
6293        || register_operand (operands[1], DFmode))"
6294   "* return mips_move_2words (operands, insn);"
6295   [(set_attr "type"     "move,move,move,load,load,store,store")
6296    (set_attr "mode"     "DF")
6297    (set_attr "length"   "8,8,8,8,16,8,16")])
6299 (define_split
6300   [(set (match_operand:DF 0 "register_operand" "")
6301         (match_operand:DF 1 "register_operand" ""))]
6302   "reload_completed && !TARGET_64BIT
6303    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6304    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6305    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
6306   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
6307    (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
6308   "")
6310 ;; Instructions to load the global pointer register.
6311 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
6312 ;; uses in front of it.  All symbol_refs implicitly use the gp reg.
6314 (define_insn "loadgp"
6315   [(set (reg:DI 28)
6316         (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
6317                              (match_operand:DI 1 "register_operand" "")] 2))
6318    (clobber (reg:DI 1))]
6319   ""
6320   "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
6321   [(set_attr "type"     "move")
6322    (set_attr "mode"     "DI")
6323    (set_attr "length"   "12")])
6325 ;; Block moves, see mips.c for more details.
6326 ;; Argument 0 is the destination
6327 ;; Argument 1 is the source
6328 ;; Argument 2 is the length
6329 ;; Argument 3 is the alignment
6331 (define_expand "movstrsi"
6332   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6333                    (match_operand:BLK 1 "general_operand" ""))
6334               (use (match_operand:SI 2 "arith32_operand" ""))
6335               (use (match_operand:SI 3 "immediate_operand" ""))])]
6336   "!TARGET_MIPS16"
6337   "
6339   if (operands[0])              /* avoid unused code messages */
6340     {
6341       expand_block_move (operands);
6342       DONE;
6343     }
6346 ;; Insn generated by block moves
6348 (define_insn "movstrsi_internal"
6349   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6350         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6351    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6352    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6353    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6354    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6355    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6356    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6357    (use (const_int 0))]                                 ;; normal block move
6358   ""
6359   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6360   [(set_attr "type"     "store")
6361    (set_attr "mode"     "none")
6362    (set_attr "length"   "80")])
6364 ;; We need mips16 versions, because an offset from the stack pointer
6365 ;; is not offsettable, since the stack pointer can only handle 4 and 8
6366 ;; byte loads.
6368 (define_insn ""
6369   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6370         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6371    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6372    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6373    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6374    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6375    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6376    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6377    (use (const_int 0))]                                 ;; normal block move
6378   "TARGET_MIPS16"
6379   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6380   [(set_attr "type"     "multi")
6381    (set_attr "mode"     "none")
6382    (set_attr "length"   "80")])
6384 ;; Split a block move into 2 parts, the first part is everything
6385 ;; except for the last move, and the second part is just the last
6386 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
6387 ;; fill a delay slot.  This also prevents a bug in delayed branches
6388 ;; from showing up, which reuses one of the registers in our clobbers.
6390 (define_split
6391   [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6392         (mem:BLK (match_operand:SI 1 "register_operand" "")))
6393    (clobber (match_operand:SI 4 "register_operand" ""))
6394    (clobber (match_operand:SI 5 "register_operand" ""))
6395    (clobber (match_operand:SI 6 "register_operand" ""))
6396    (clobber (match_operand:SI 7 "register_operand" ""))
6397    (use (match_operand:SI 2 "small_int" ""))
6398    (use (match_operand:SI 3 "small_int" ""))
6399    (use (const_int 0))]
6401   "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
6403   ;; All but the last move
6404   [(parallel [(set (mem:BLK (match_dup 0))
6405                    (mem:BLK (match_dup 1)))
6406               (clobber (match_dup 4))
6407               (clobber (match_dup 5))
6408               (clobber (match_dup 6))
6409               (clobber (match_dup 7))
6410               (use (match_dup 2))
6411               (use (match_dup 3))
6412               (use (const_int 1))])
6414    ;; The last store, so it can fill a delay slot
6415    (parallel [(set (mem:BLK (match_dup 0))
6416                    (mem:BLK (match_dup 1)))
6417               (clobber (match_dup 4))
6418               (clobber (match_dup 5))
6419               (clobber (match_dup 6))
6420               (clobber (match_dup 7))
6421               (use (match_dup 2))
6422               (use (match_dup 3))
6423               (use (const_int 2))])]
6425   "")
6427 (define_insn "movstrsi_internal2"
6428   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6429         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6430    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6431    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6432    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6433    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6434    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6435    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6436    (use (const_int 1))]                                 ;; all but last store
6437   ""
6438   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6439   [(set_attr "type"     "store")
6440    (set_attr "mode"     "none")
6441    (set_attr "length"   "80")])
6443 (define_insn ""
6444   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6445         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6446    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6447    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6448    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6449    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6450    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6451    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6452    (use (const_int 1))]                                 ;; all but last store
6453   "TARGET_MIPS16"
6454   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6455   [(set_attr "type"     "multi")
6456    (set_attr "mode"     "none")
6457    (set_attr "length"   "80")])
6459 (define_insn "movstrsi_internal3"
6460   [(set (match_operand:BLK 0 "memory_operand" "=Ro")    ;; destination
6461         (match_operand:BLK 1 "memory_operand" "Ro"))    ;; source
6462    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6463    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6464    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6465    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6466    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6467    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6468    (use (const_int 2))]                                 ;; just last store of block move
6469   ""
6470   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6471   [(set_attr "type"     "store")
6472    (set_attr "mode"     "none")])
6475 ;;  ....................
6477 ;;      SHIFTS
6479 ;;  ....................
6481 ;; Many of these instructions uses trivial define_expands, because we
6482 ;; want to use a different set of constraints when TARGET_MIPS16.
6484 (define_expand "ashlsi3"
6485   [(set (match_operand:SI 0 "register_operand" "=d")
6486         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6487                    (match_operand:SI 2 "arith_operand" "dI")))]
6488   ""
6489   "
6491   /* On the mips16, a shift of more than 8 is a four byte instruction,
6492      so, for a shift between 8 and 16, it is just as fast to do two
6493      shifts of 8 or less.  If there is a lot of shifting going on, we
6494      may win in CSE.  Otherwise combine will put the shifts back
6495      together again.  This can be called by function_arg, so we must
6496      be careful not to allocate a new register if we've reached the
6497      reload pass.  */
6498   if (TARGET_MIPS16
6499       && optimize
6500       && GET_CODE (operands[2]) == CONST_INT
6501       && INTVAL (operands[2]) > 8
6502       && INTVAL (operands[2]) <= 16
6503       && ! reload_in_progress
6504       && ! reload_completed)
6505     {
6506       rtx temp = gen_reg_rtx (SImode);
6508       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6509       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6510                                         GEN_INT (INTVAL (operands[2]) - 8)));
6511       DONE;
6512     }
6515 (define_insn "ashlsi3_internal1"
6516   [(set (match_operand:SI 0 "register_operand" "=d")
6517         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6518                    (match_operand:SI 2 "arith_operand" "dI")))]
6519   "!TARGET_MIPS16"
6520   "*
6522   if (GET_CODE (operands[2]) == CONST_INT)
6523     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6525   return \"sll\\t%0,%1,%2\";
6527   [(set_attr "type"     "arith")
6528    (set_attr "mode"     "SI")])
6530 (define_insn "ashlsi3_internal2"
6531   [(set (match_operand:SI 0 "register_operand" "=d,d")
6532         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6533                    (match_operand:SI 2 "arith_operand" "d,I")))]
6534   "TARGET_MIPS16"
6535   "*
6537   if (which_alternative == 0)
6538     return \"sll\\t%0,%2\";
6540   if (GET_CODE (operands[2]) == CONST_INT)
6541     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6543   return \"sll\\t%0,%1,%2\";
6545   [(set_attr "type"     "arith")
6546    (set_attr "mode"     "SI")
6547    (set_attr_alternative "length"
6548                 [(const_int 4)
6549                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6550                                (const_int 4)
6551                                (const_int 8))])])
6553 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6555 (define_split
6556   [(set (match_operand:SI 0 "register_operand" "")
6557         (ashift:SI (match_operand:SI 1 "register_operand" "")
6558                    (match_operand:SI 2 "const_int_operand" "")))]
6559   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6560    && GET_CODE (operands[2]) == CONST_INT
6561    && INTVAL (operands[2]) > 8
6562    && INTVAL (operands[2]) <= 16"
6563   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6564    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6567   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6570 (define_expand "ashldi3"
6571   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6572                    (ashift:DI (match_operand:DI 1 "se_register_operand" "")
6573                               (match_operand:SI 2 "arith_operand" "")))
6574               (clobber (match_dup  3))])]
6575   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6576   "
6578   if (TARGET_64BIT)
6579     {
6580       /* On the mips16, a shift of more than 8 is a four byte
6581          instruction, so, for a shift between 8 and 16, it is just as
6582          fast to do two shifts of 8 or less.  If there is a lot of
6583          shifting going on, we may win in CSE.  Otherwise combine will
6584          put the shifts back together again.  This can be called by
6585          function_arg, so we must be careful not to allocate a new
6586          register if we've reached the reload pass.  */
6587       if (TARGET_MIPS16
6588           && optimize
6589           && GET_CODE (operands[2]) == CONST_INT
6590           && INTVAL (operands[2]) > 8
6591           && INTVAL (operands[2]) <= 16
6592           && ! reload_in_progress
6593           && ! reload_completed)
6594         {
6595           rtx temp = gen_reg_rtx (DImode);
6597           emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6598           emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6599                                             GEN_INT (INTVAL (operands[2]) - 8)));
6600           DONE;
6601         }
6603       emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6604                                         operands[2]));
6605       DONE;
6606     }
6608   operands[3] = gen_reg_rtx (SImode);
6612 (define_insn "ashldi3_internal"
6613   [(set (match_operand:DI 0 "register_operand" "=&d")
6614         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6615                    (match_operand:SI 2 "register_operand" "d")))
6616    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6617   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6618   "*
6620   operands[4] = const0_rtx;
6621   dslots_jump_total += 3;
6622   dslots_jump_filled += 2;
6624   return \"sll\\t%3,%2,26\\n\\
6625 \\tbgez\\t%3,1f\\n\\
6626 \\tsll\\t%M0,%L1,%2\\n\\
6627 \\t%(b\\t3f\\n\\
6628 \\tmove\\t%L0,%z4%)\\n\\
6629 \\n\\
6630 %~1:\\n\\
6631 \\t%(beq\\t%3,%z4,2f\\n\\
6632 \\tsll\\t%M0,%M1,%2%)\\n\\
6633 \\n\\
6634 \\tsubu\\t%3,%z4,%2\\n\\
6635 \\tsrl\\t%3,%L1,%3\\n\\
6636 \\tor\\t%M0,%M0,%3\\n\\
6637 %~2:\\n\\
6638 \\tsll\\t%L0,%L1,%2\\n\\
6639 %~3:\";
6641   [(set_attr "type"     "darith")
6642    (set_attr "mode"     "SI")
6643    (set_attr "length"   "48")])
6646 (define_insn "ashldi3_internal2"
6647   [(set (match_operand:DI 0 "register_operand" "=d")
6648         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6649                    (match_operand:SI 2 "small_int" "IJK")))
6650    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6651   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6652    && (INTVAL (operands[2]) & 32) != 0"
6653   "*
6655   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6656   operands[4] = const0_rtx;
6657   return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6659   [(set_attr "type"     "darith")
6660    (set_attr "mode"     "DI")
6661    (set_attr "length"   "8")])
6664 (define_split
6665   [(set (match_operand:DI 0 "register_operand" "")
6666         (ashift:DI (match_operand:DI 1 "register_operand" "")
6667                    (match_operand:SI 2 "small_int" "")))
6668    (clobber (match_operand:SI 3 "register_operand" ""))]
6669   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6670    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6671    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6672    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6673    && (INTVAL (operands[2]) & 32) != 0"
6675   [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6676    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6678   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6681 (define_split
6682   [(set (match_operand:DI 0 "register_operand" "")
6683         (ashift:DI (match_operand:DI 1 "register_operand" "")
6684                    (match_operand:SI 2 "small_int" "")))
6685    (clobber (match_operand:SI 3 "register_operand" ""))]
6686   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6687    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6688    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6689    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6690    && (INTVAL (operands[2]) & 32) != 0"
6692   [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6693    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
6695   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6698 (define_insn "ashldi3_internal3"
6699   [(set (match_operand:DI 0 "register_operand" "=d")
6700         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6701                    (match_operand:SI 2 "small_int" "IJK")))
6702    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6703   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6704    && (INTVAL (operands[2]) & 63) < 32
6705    && (INTVAL (operands[2]) & 63) != 0"
6706   "*
6708   int amount = INTVAL (operands[2]);
6710   operands[2] = GEN_INT (amount & 31);
6711   operands[4] = const0_rtx;
6712   operands[5] = GEN_INT ((-amount) & 31);
6714   return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6716   [(set_attr "type"     "darith")
6717    (set_attr "mode"     "DI")
6718    (set_attr "length"   "16")])
6721 (define_split
6722   [(set (match_operand:DI 0 "register_operand" "")
6723         (ashift:DI (match_operand:DI 1 "register_operand" "")
6724                    (match_operand:SI 2 "small_int" "")))
6725    (clobber (match_operand:SI 3 "register_operand" ""))]
6726   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6727    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6728    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6729    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6730    && (INTVAL (operands[2]) & 63) < 32
6731    && (INTVAL (operands[2]) & 63) != 0"
6733   [(set (subreg:SI (match_dup 0) 4)
6734         (ashift:SI (subreg:SI (match_dup 1) 4)
6735                    (match_dup 2)))
6737    (set (match_dup 3)
6738         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6739                      (match_dup 4)))
6741    (set (subreg:SI (match_dup 0) 4)
6742         (ior:SI (subreg:SI (match_dup 0) 4)
6743                 (match_dup 3)))
6745    (set (subreg:SI (match_dup 0) 0)
6746         (ashift:SI (subreg:SI (match_dup 1) 0)
6747                    (match_dup 2)))]
6748   "
6750   int amount = INTVAL (operands[2]);
6751   operands[2] = GEN_INT (amount & 31);
6752   operands[4] = GEN_INT ((-amount) & 31);
6756 (define_split
6757   [(set (match_operand:DI 0 "register_operand" "")
6758         (ashift:DI (match_operand:DI 1 "register_operand" "")
6759                    (match_operand:SI 2 "small_int" "")))
6760    (clobber (match_operand:SI 3 "register_operand" ""))]
6761   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6762    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6763    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6764    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6765    && (INTVAL (operands[2]) & 63) < 32
6766    && (INTVAL (operands[2]) & 63) != 0"
6768   [(set (subreg:SI (match_dup 0) 0)
6769         (ashift:SI (subreg:SI (match_dup 1) 0)
6770                    (match_dup 2)))
6772    (set (match_dup 3)
6773         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6774                      (match_dup 4)))
6776    (set (subreg:SI (match_dup 0) 0)
6777         (ior:SI (subreg:SI (match_dup 0) 0)
6778                 (match_dup 3)))
6780    (set (subreg:SI (match_dup 0) 4)
6781         (ashift:SI (subreg:SI (match_dup 1) 4)
6782                    (match_dup 2)))]
6783   "
6785   int amount = INTVAL (operands[2]);
6786   operands[2] = GEN_INT (amount & 31);
6787   operands[4] = GEN_INT ((-amount) & 31);
6791 (define_insn "ashldi3_internal4"
6792   [(set (match_operand:DI 0 "register_operand" "=d")
6793         (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6794                    (match_operand:SI 2 "arith_operand" "dI")))]
6795   "TARGET_64BIT && !TARGET_MIPS16"
6796   "*
6798   if (GET_CODE (operands[2]) == CONST_INT)
6799     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6801   return \"dsll\\t%0,%1,%2\";
6803   [(set_attr "type"     "arith")
6804    (set_attr "mode"     "DI")])
6806 (define_insn ""
6807   [(set (match_operand:DI 0 "register_operand" "=d,d")
6808         (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
6809                    (match_operand:SI 2 "arith_operand" "d,I")))]
6810   "TARGET_64BIT && TARGET_MIPS16"
6811   "*
6813   if (which_alternative == 0)
6814     return \"dsll\\t%0,%2\";
6816   if (GET_CODE (operands[2]) == CONST_INT)
6817     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6819   return \"dsll\\t%0,%1,%2\";
6821   [(set_attr "type"     "arith")
6822    (set_attr "mode"     "DI")
6823    (set_attr_alternative "length"
6824                 [(const_int 4)
6825                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6826                                (const_int 4)
6827                                (const_int 8))])])
6830 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
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 "const_int_operand" "")))]
6836   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
6837    && reload_completed
6838    && GET_CODE (operands[2]) == CONST_INT
6839    && INTVAL (operands[2]) > 8
6840    && INTVAL (operands[2]) <= 16"
6841   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6842    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6845   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6848 (define_expand "ashrsi3"
6849   [(set (match_operand:SI 0 "register_operand" "=d")
6850         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6851                      (match_operand:SI 2 "arith_operand" "dI")))]
6852   ""
6853   "
6855   /* On the mips16, a shift of more than 8 is a four byte instruction,
6856      so, for a shift between 8 and 16, it is just as fast to do two
6857      shifts of 8 or less.  If there is a lot of shifting going on, we
6858      may win in CSE.  Otherwise combine will put the shifts back
6859      together again.  */
6860   if (TARGET_MIPS16
6861       && optimize
6862       && GET_CODE (operands[2]) == CONST_INT
6863       && INTVAL (operands[2]) > 8
6864       && INTVAL (operands[2]) <= 16)
6865     {
6866       rtx temp = gen_reg_rtx (SImode);
6868       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6869       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6870                                         GEN_INT (INTVAL (operands[2]) - 8)));
6871       DONE;
6872     }
6875 (define_insn "ashrsi3_internal1"
6876   [(set (match_operand:SI 0 "register_operand" "=d")
6877         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6878                      (match_operand:SI 2 "arith_operand" "dI")))]
6879   "!TARGET_MIPS16"
6880   "*
6882   if (GET_CODE (operands[2]) == CONST_INT)
6883     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6885   return \"sra\\t%0,%1,%2\";
6887   [(set_attr "type"     "arith")
6888    (set_attr "mode"     "SI")])
6890 (define_insn "ashrsi3_internal2"
6891   [(set (match_operand:SI 0 "register_operand" "=d,d")
6892         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6893                      (match_operand:SI 2 "arith_operand" "d,I")))]
6894   "TARGET_MIPS16"
6895   "*
6897   if (which_alternative == 0)
6898     return \"sra\\t%0,%2\";
6900   if (GET_CODE (operands[2]) == CONST_INT)
6901     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6903   return \"sra\\t%0,%1,%2\";
6905   [(set_attr "type"     "arith")
6906    (set_attr "mode"     "SI")
6907    (set_attr_alternative "length"
6908                 [(const_int 4)
6909                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6910                                (const_int 4)
6911                                (const_int 8))])])
6914 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6916 (define_split
6917   [(set (match_operand:SI 0 "register_operand" "")
6918         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6919                      (match_operand:SI 2 "const_int_operand" "")))]
6920   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6921    && GET_CODE (operands[2]) == CONST_INT
6922    && INTVAL (operands[2]) > 8
6923    && INTVAL (operands[2]) <= 16"
6924   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
6925    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
6928   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6931 (define_expand "ashrdi3"
6932   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6933                    (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
6934                                 (match_operand:SI 2 "arith_operand" "")))
6935               (clobber (match_dup  3))])]
6936   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6937   "
6939   if (TARGET_64BIT)
6940     {
6941       /* On the mips16, a shift of more than 8 is a four byte
6942          instruction, so, for a shift between 8 and 16, it is just as
6943          fast to do two shifts of 8 or less.  If there is a lot of
6944          shifting going on, we may win in CSE.  Otherwise combine will
6945          put the shifts back together again.  */
6946       if (TARGET_MIPS16
6947           && optimize
6948           && GET_CODE (operands[2]) == CONST_INT
6949           && INTVAL (operands[2]) > 8
6950           && INTVAL (operands[2]) <= 16)
6951         {
6952           rtx temp = gen_reg_rtx (DImode);
6954           emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
6955           emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
6956                                             GEN_INT (INTVAL (operands[2]) - 8)));
6957           DONE;
6958         }
6960       emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
6961                                         operands[2]));
6962       DONE;
6963     }
6965   operands[3] = gen_reg_rtx (SImode);
6969 (define_insn "ashrdi3_internal"
6970   [(set (match_operand:DI 0 "register_operand" "=&d")
6971         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6972                      (match_operand:SI 2 "register_operand" "d")))
6973    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6974   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6975   "*
6977   operands[4] = const0_rtx;
6978   dslots_jump_total += 3;
6979   dslots_jump_filled += 2;
6981   return \"sll\\t%3,%2,26\\n\\
6982 \\tbgez\\t%3,1f\\n\\
6983 \\tsra\\t%L0,%M1,%2\\n\\
6984 \\t%(b\\t3f\\n\\
6985 \\tsra\\t%M0,%M1,31%)\\n\\
6986 \\n\\
6987 %~1:\\n\\
6988 \\t%(beq\\t%3,%z4,2f\\n\\
6989 \\tsrl\\t%L0,%L1,%2%)\\n\\
6990 \\n\\
6991 \\tsubu\\t%3,%z4,%2\\n\\
6992 \\tsll\\t%3,%M1,%3\\n\\
6993 \\tor\\t%L0,%L0,%3\\n\\
6994 %~2:\\n\\
6995 \\tsra\\t%M0,%M1,%2\\n\\
6996 %~3:\";
6998   [(set_attr "type"     "darith")
6999    (set_attr "mode"     "DI")
7000    (set_attr "length"   "48")])
7003 (define_insn "ashrdi3_internal2"
7004   [(set (match_operand:DI 0 "register_operand" "=d")
7005         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7006                      (match_operand:SI 2 "small_int" "IJK")))
7007    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7008   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
7009   "*
7011   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7012   return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
7014   [(set_attr "type"     "darith")
7015    (set_attr "mode"     "DI")
7016    (set_attr "length"   "8")])
7019 (define_split
7020   [(set (match_operand:DI 0 "register_operand" "")
7021         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7022                      (match_operand:SI 2 "small_int" "")))
7023    (clobber (match_operand:SI 3 "register_operand" ""))]
7024   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7025    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7026    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7027    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7028    && (INTVAL (operands[2]) & 32) != 0"
7030   [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7031    (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
7033   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7036 (define_split
7037   [(set (match_operand:DI 0 "register_operand" "")
7038         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7039                      (match_operand:SI 2 "small_int" "")))
7040    (clobber (match_operand:SI 3 "register_operand" ""))]
7041   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7042    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7043    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7044    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7045    && (INTVAL (operands[2]) & 32) != 0"
7047   [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7048    (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
7050   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7053 (define_insn "ashrdi3_internal3"
7054   [(set (match_operand:DI 0 "register_operand" "=d")
7055         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7056                      (match_operand:SI 2 "small_int" "IJK")))
7057    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7058   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7059    && (INTVAL (operands[2]) & 63) < 32
7060    && (INTVAL (operands[2]) & 63) != 0"
7061   "*
7063   int amount = INTVAL (operands[2]);
7065   operands[2] = GEN_INT (amount & 31);
7066   operands[4] = GEN_INT ((-amount) & 31);
7068   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
7070   [(set_attr "type"     "darith")
7071    (set_attr "mode"     "DI")
7072    (set_attr "length"   "16")])
7075 (define_split
7076   [(set (match_operand:DI 0 "register_operand" "")
7077         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7078                      (match_operand:SI 2 "small_int" "")))
7079    (clobber (match_operand:SI 3 "register_operand" ""))]
7080   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7081    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7082    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7083    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7084    && (INTVAL (operands[2]) & 63) < 32
7085    && (INTVAL (operands[2]) & 63) != 0"
7087   [(set (subreg:SI (match_dup 0) 0)
7088         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7089                      (match_dup 2)))
7091    (set (match_dup 3)
7092         (ashift:SI (subreg:SI (match_dup 1) 4)
7093                    (match_dup 4)))
7095    (set (subreg:SI (match_dup 0) 0)
7096         (ior:SI (subreg:SI (match_dup 0) 0)
7097                 (match_dup 3)))
7099    (set (subreg:SI (match_dup 0) 4)
7100         (ashiftrt:SI (subreg:SI (match_dup 1) 4)
7101                      (match_dup 2)))]
7102   "
7104   int amount = INTVAL (operands[2]);
7105   operands[2] = GEN_INT (amount & 31);
7106   operands[4] = GEN_INT ((-amount) & 31);
7110 (define_split
7111   [(set (match_operand:DI 0 "register_operand" "")
7112         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7113                      (match_operand:SI 2 "small_int" "")))
7114    (clobber (match_operand:SI 3 "register_operand" ""))]
7115   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7116    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7117    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7118    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7119    && (INTVAL (operands[2]) & 63) < 32
7120    && (INTVAL (operands[2]) & 63) != 0"
7122   [(set (subreg:SI (match_dup 0) 4)
7123         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7124                      (match_dup 2)))
7126    (set (match_dup 3)
7127         (ashift:SI (subreg:SI (match_dup 1) 0)
7128                    (match_dup 4)))
7130    (set (subreg:SI (match_dup 0) 4)
7131         (ior:SI (subreg:SI (match_dup 0) 4)
7132                 (match_dup 3)))
7134    (set (subreg:SI (match_dup 0) 0)
7135         (ashiftrt:SI (subreg:SI (match_dup 1) 0)
7136                      (match_dup 2)))]
7137   "
7139   int amount = INTVAL (operands[2]);
7140   operands[2] = GEN_INT (amount & 31);
7141   operands[4] = GEN_INT ((-amount) & 31);
7145 (define_insn "ashrdi3_internal4"
7146   [(set (match_operand:DI 0 "register_operand" "=d")
7147         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7148                      (match_operand:SI 2 "arith_operand" "dI")))]
7149   "TARGET_64BIT && !TARGET_MIPS16"
7150   "*
7152   if (GET_CODE (operands[2]) == CONST_INT)
7153     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7155   return \"dsra\\t%0,%1,%2\";
7157   [(set_attr "type"     "arith")
7158    (set_attr "mode"     "DI")])
7160 (define_insn ""
7161   [(set (match_operand:DI 0 "register_operand" "=d,d")
7162         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7163                      (match_operand:SI 2 "arith_operand" "d,I")))]
7164   "TARGET_64BIT && TARGET_MIPS16"
7165   "*
7167   if (GET_CODE (operands[2]) == CONST_INT)
7168     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7170   return \"dsra\\t%0,%2\";
7172   [(set_attr "type"     "arith")
7173    (set_attr "mode"     "DI")
7174    (set_attr_alternative "length"
7175                 [(const_int 4)
7176                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7177                                (const_int 4)
7178                                (const_int 8))])])
7180 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7182 (define_split
7183   [(set (match_operand:DI 0 "register_operand" "")
7184         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7185                      (match_operand:SI 2 "const_int_operand" "")))]
7186   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
7187    && reload_completed
7188    && GET_CODE (operands[2]) == CONST_INT
7189    && INTVAL (operands[2]) > 8
7190    && INTVAL (operands[2]) <= 16"
7191   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7192    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7195   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7198 (define_expand "lshrsi3"
7199   [(set (match_operand:SI 0 "register_operand" "=d")
7200         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7201                      (match_operand:SI 2 "arith_operand" "dI")))]
7202   ""
7203   "
7205   /* On the mips16, a shift of more than 8 is a four byte instruction,
7206      so, for a shift between 8 and 16, it is just as fast to do two
7207      shifts of 8 or less.  If there is a lot of shifting going on, we
7208      may win in CSE.  Otherwise combine will put the shifts back
7209      together again.  */
7210   if (TARGET_MIPS16
7211       && optimize
7212       && GET_CODE (operands[2]) == CONST_INT
7213       && INTVAL (operands[2]) > 8
7214       && INTVAL (operands[2]) <= 16)
7215     {
7216       rtx temp = gen_reg_rtx (SImode);
7218       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7219       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7220                                         GEN_INT (INTVAL (operands[2]) - 8)));
7221       DONE;
7222     }
7225 (define_insn "lshrsi3_internal1"
7226   [(set (match_operand:SI 0 "register_operand" "=d")
7227         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7228                      (match_operand:SI 2 "arith_operand" "dI")))]
7229   "!TARGET_MIPS16"
7230   "*
7232   if (GET_CODE (operands[2]) == CONST_INT)
7233     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7235   return \"srl\\t%0,%1,%2\";
7237   [(set_attr "type"     "arith")
7238    (set_attr "mode"     "SI")])
7240 (define_insn "lshrsi3_internal2"
7241   [(set (match_operand:SI 0 "register_operand" "=d,d")
7242         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7243                      (match_operand:SI 2 "arith_operand" "d,I")))]
7244   "TARGET_MIPS16"
7245   "*
7247   if (which_alternative == 0)
7248     return \"srl\\t%0,%2\";
7250   if (GET_CODE (operands[2]) == CONST_INT)
7251     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7253   return \"srl\\t%0,%1,%2\";
7255   [(set_attr "type"     "arith")
7256    (set_attr "mode"     "SI")
7257    (set_attr_alternative "length"
7258                 [(const_int 4)
7259                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7260                                (const_int 4)
7261                                (const_int 8))])])
7264 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7266 (define_split
7267   [(set (match_operand:SI 0 "register_operand" "")
7268         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7269                      (match_operand:SI 2 "const_int_operand" "")))]
7270   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7271    && GET_CODE (operands[2]) == CONST_INT
7272    && INTVAL (operands[2]) > 8
7273    && INTVAL (operands[2]) <= 16"
7274   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7275    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7278   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7281 ;; If we load a byte on the mips16 as a bitfield, the resulting
7282 ;; sequence of instructions is too complicated for combine, because it
7283 ;; involves four instructions: a load, a shift, a constant load into a
7284 ;; register, and an and (the key problem here is that the mips16 does
7285 ;; not have and immediate).  We recognize a shift of a load in order
7286 ;; to make it simple enough for combine to understand.
7288 (define_insn ""
7289   [(set (match_operand:SI 0 "register_operand" "=d,d")
7290         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
7291                      (match_operand:SI 2 "immediate_operand" "I,I")))]
7292   "TARGET_MIPS16"
7293   "lw\\t%0,%1\;srl\\t%0,%2"
7294   [(set_attr "type"     "load")
7295    (set_attr "mode"     "SI")
7296    (set_attr_alternative "length"
7297                 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7298                                (const_int 8)
7299                                (const_int 12))
7300                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7301                                (const_int 12)
7302                                (const_int 16))])])
7304 (define_split
7305   [(set (match_operand:SI 0 "register_operand" "")
7306         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7307                      (match_operand:SI 2 "immediate_operand" "")))]
7308   "TARGET_MIPS16 && !TARGET_DEBUG_D_MODE"
7309   [(set (match_dup 0) (match_dup 1))
7310    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7311   "")
7313 (define_expand "lshrdi3"
7314   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7315                    (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7316                                 (match_operand:SI 2 "arith_operand" "")))
7317               (clobber (match_dup  3))])]
7318   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7319   "
7321   if (TARGET_64BIT)
7322     {
7323       /* On the mips16, a shift of more than 8 is a four byte
7324          instruction, so, for a shift between 8 and 16, it is just as
7325          fast to do two shifts of 8 or less.  If there is a lot of
7326          shifting going on, we may win in CSE.  Otherwise combine will
7327          put the shifts back together again.  */
7328       if (TARGET_MIPS16
7329           && optimize
7330           && GET_CODE (operands[2]) == CONST_INT
7331           && INTVAL (operands[2]) > 8
7332           && INTVAL (operands[2]) <= 16)
7333         {
7334           rtx temp = gen_reg_rtx (DImode);
7336           emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7337           emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7338                                             GEN_INT (INTVAL (operands[2]) - 8)));
7339           DONE;
7340         }
7342       emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7343                                         operands[2]));
7344       DONE;
7345     }
7347   operands[3] = gen_reg_rtx (SImode);
7351 (define_insn "lshrdi3_internal"
7352   [(set (match_operand:DI 0 "register_operand" "=&d")
7353         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7354                      (match_operand:SI 2 "register_operand" "d")))
7355    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7356   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7357   "*
7359   operands[4] = const0_rtx;
7360   dslots_jump_total += 3;
7361   dslots_jump_filled += 2;
7363   return \"sll\\t%3,%2,26\\n\\
7364 \\tbgez\\t%3,1f\\n\\
7365 \\tsrl\\t%L0,%M1,%2\\n\\
7366 \\t%(b\\t3f\\n\\
7367 \\tmove\\t%M0,%z4%)\\n\\
7368 \\n\\
7369 %~1:\\n\\
7370 \\t%(beq\\t%3,%z4,2f\\n\\
7371 \\tsrl\\t%L0,%L1,%2%)\\n\\
7372 \\n\\
7373 \\tsubu\\t%3,%z4,%2\\n\\
7374 \\tsll\\t%3,%M1,%3\\n\\
7375 \\tor\\t%L0,%L0,%3\\n\\
7376 %~2:\\n\\
7377 \\tsrl\\t%M0,%M1,%2\\n\\
7378 %~3:\";
7380   [(set_attr "type"     "darith")
7381    (set_attr "mode"     "DI")
7382    (set_attr "length"   "48")])
7385 (define_insn "lshrdi3_internal2"
7386   [(set (match_operand:DI 0 "register_operand" "=d")
7387         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7388                      (match_operand:SI 2 "small_int" "IJK")))
7389    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7390   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7391    && (INTVAL (operands[2]) & 32) != 0"
7392   "*
7394   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7395   operands[4] = const0_rtx;
7396   return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7398   [(set_attr "type"     "darith")
7399    (set_attr "mode"     "DI")
7400    (set_attr "length"   "8")])
7403 (define_split
7404   [(set (match_operand:DI 0 "register_operand" "")
7405         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7406                      (match_operand:SI 2 "small_int" "")))
7407    (clobber (match_operand:SI 3 "register_operand" ""))]
7408   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7409    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7410    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7411    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7412    && (INTVAL (operands[2]) & 32) != 0"
7414   [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7415    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
7417   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7420 (define_split
7421   [(set (match_operand:DI 0 "register_operand" "")
7422         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7423                      (match_operand:SI 2 "small_int" "")))
7424    (clobber (match_operand:SI 3 "register_operand" ""))]
7425   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7426    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7427    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7428    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7429    && (INTVAL (operands[2]) & 32) != 0"
7431   [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7432    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7434   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7437 (define_insn "lshrdi3_internal3"
7438   [(set (match_operand:DI 0 "register_operand" "=d")
7439         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7440                    (match_operand:SI 2 "small_int" "IJK")))
7441    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7442   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7443    && (INTVAL (operands[2]) & 63) < 32
7444    && (INTVAL (operands[2]) & 63) != 0"
7445   "*
7447   int amount = INTVAL (operands[2]);
7449   operands[2] = GEN_INT (amount & 31);
7450   operands[4] = GEN_INT ((-amount) & 31);
7452   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7454   [(set_attr "type"     "darith")
7455    (set_attr "mode"     "DI")
7456    (set_attr "length"   "16")])
7459 (define_split
7460   [(set (match_operand:DI 0 "register_operand" "")
7461         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7462                      (match_operand:SI 2 "small_int" "")))
7463    (clobber (match_operand:SI 3 "register_operand" ""))]
7464   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7465    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7466    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7467    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7468    && (INTVAL (operands[2]) & 63) < 32
7469    && (INTVAL (operands[2]) & 63) != 0"
7471   [(set (subreg:SI (match_dup 0) 0)
7472         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7473                      (match_dup 2)))
7475    (set (match_dup 3)
7476         (ashift:SI (subreg:SI (match_dup 1) 4)
7477                    (match_dup 4)))
7479    (set (subreg:SI (match_dup 0) 0)
7480         (ior:SI (subreg:SI (match_dup 0) 0)
7481                 (match_dup 3)))
7483    (set (subreg:SI (match_dup 0) 4)
7484         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7485                      (match_dup 2)))]
7486   "
7488   int amount = INTVAL (operands[2]);
7489   operands[2] = GEN_INT (amount & 31);
7490   operands[4] = GEN_INT ((-amount) & 31);
7494 (define_split
7495   [(set (match_operand:DI 0 "register_operand" "")
7496         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7497                      (match_operand:SI 2 "small_int" "")))
7498    (clobber (match_operand:SI 3 "register_operand" ""))]
7499   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7500    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7501    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7502    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7503    && (INTVAL (operands[2]) & 63) < 32
7504    && (INTVAL (operands[2]) & 63) != 0"
7506   [(set (subreg:SI (match_dup 0) 4)
7507         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7508                      (match_dup 2)))
7510    (set (match_dup 3)
7511         (ashift:SI (subreg:SI (match_dup 1) 0)
7512                    (match_dup 4)))
7514    (set (subreg:SI (match_dup 0) 4)
7515         (ior:SI (subreg:SI (match_dup 0) 4)
7516                 (match_dup 3)))
7518    (set (subreg:SI (match_dup 0) 0)
7519         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7520                      (match_dup 2)))]
7521   "
7523   int amount = INTVAL (operands[2]);
7524   operands[2] = GEN_INT (amount & 31);
7525   operands[4] = GEN_INT ((-amount) & 31);
7529 (define_insn "lshrdi3_internal4"
7530   [(set (match_operand:DI 0 "register_operand" "=d")
7531         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7532                      (match_operand:SI 2 "arith_operand" "dI")))]
7533   "TARGET_64BIT && !TARGET_MIPS16"
7534   "*
7536   if (GET_CODE (operands[2]) == CONST_INT)
7537     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7539   return \"dsrl\\t%0,%1,%2\";
7541   [(set_attr "type"     "arith")
7542    (set_attr "mode"     "DI")])
7544 (define_insn ""
7545   [(set (match_operand:DI 0 "register_operand" "=d,d")
7546         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7547                      (match_operand:SI 2 "arith_operand" "d,I")))]
7548   "TARGET_64BIT && TARGET_MIPS16"
7549   "*
7551   if (GET_CODE (operands[2]) == CONST_INT)
7552     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7554   return \"dsrl\\t%0,%2\";
7556   [(set_attr "type"     "arith")
7557    (set_attr "mode"     "DI")
7558    (set_attr_alternative "length"
7559                 [(const_int 4)
7560                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7561                                (const_int 4)
7562                                (const_int 8))])])
7564 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7566 (define_split
7567   [(set (match_operand:DI 0 "register_operand" "")
7568         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7569                      (match_operand:SI 2 "const_int_operand" "")))]
7570   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7571    && GET_CODE (operands[2]) == CONST_INT
7572    && INTVAL (operands[2]) > 8
7573    && INTVAL (operands[2]) <= 16"
7574   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7575    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7578   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7583 ;;  ....................
7585 ;;      COMPARISONS
7587 ;;  ....................
7589 ;; Flow here is rather complex:
7591 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the
7592 ;;      arguments into the branch_cmp array, and the type into
7593 ;;      branch_type.  No RTL is generated.
7595 ;;  2)  The appropriate branch define_expand is called, which then
7596 ;;      creates the appropriate RTL for the comparison and branch.
7597 ;;      Different CC modes are used, based on what type of branch is
7598 ;;      done, so that we can constrain things appropriately.  There
7599 ;;      are assumptions in the rest of GCC that break if we fold the
7600 ;;      operands into the branchs for integer operations, and use cc0
7601 ;;      for floating point, so we use the fp status register instead.
7602 ;;      If needed, an appropriate temporary is created to hold the
7603 ;;      of the integer compare.
7605 (define_expand "cmpsi"
7606   [(set (cc0)
7607         (compare:CC (match_operand:SI 0 "register_operand" "")
7608                     (match_operand:SI 1 "arith_operand" "")))]
7609   ""
7610   "
7612   if (operands[0])              /* avoid unused code message */
7613     {
7614       branch_cmp[0] = operands[0];
7615       branch_cmp[1] = operands[1];
7616       branch_type = CMP_SI;
7617       DONE;
7618     }
7621 (define_expand "tstsi"
7622   [(set (cc0)
7623         (match_operand:SI 0 "register_operand" ""))]
7624   ""
7625   "
7627   if (operands[0])              /* avoid unused code message */
7628     {
7629       branch_cmp[0] = operands[0];
7630       branch_cmp[1] = const0_rtx;
7631       branch_type = CMP_SI;
7632       DONE;
7633     }
7636 (define_expand "cmpdi"
7637   [(set (cc0)
7638         (compare:CC (match_operand:DI 0 "se_register_operand" "")
7639                     (match_operand:DI 1 "se_arith_operand" "")))]
7640   "TARGET_64BIT"
7641   "
7643   if (operands[0])              /* avoid unused code message */
7644     {
7645       branch_cmp[0] = operands[0];
7646       branch_cmp[1] = operands[1];
7647       branch_type = CMP_DI;
7648       DONE;
7649     }
7652 (define_expand "tstdi"
7653   [(set (cc0)
7654         (match_operand:DI 0 "se_register_operand" ""))]
7655   "TARGET_64BIT"
7656   "
7658   if (operands[0])              /* avoid unused code message */
7659     {
7660       branch_cmp[0] = operands[0];
7661       branch_cmp[1] = const0_rtx;
7662       branch_type = CMP_DI;
7663       DONE;
7664     }
7667 (define_expand "cmpdf"
7668   [(set (cc0)
7669         (compare:CC (match_operand:DF 0 "register_operand" "")
7670                     (match_operand:DF 1 "register_operand" "")))]
7671   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7672   "
7674   if (operands[0])              /* avoid unused code message */
7675     {
7676       branch_cmp[0] = operands[0];
7677       branch_cmp[1] = operands[1];
7678       branch_type = CMP_DF;
7679       DONE;
7680     }
7683 (define_expand "cmpsf"
7684   [(set (cc0)
7685         (compare:CC (match_operand:SF 0 "register_operand" "")
7686                     (match_operand:SF 1 "register_operand" "")))]
7687   "TARGET_HARD_FLOAT"
7688   "
7690   if (operands[0])              /* avoid unused code message */
7691     {
7692       branch_cmp[0] = operands[0];
7693       branch_cmp[1] = operands[1];
7694       branch_type = CMP_SF;
7695       DONE;
7696     }
7701 ;;  ....................
7703 ;;      CONDITIONAL BRANCHES
7705 ;;  ....................
7707 ;; Conditional branches on floating-point equality tests.
7709 (define_insn "branch_fp"
7710   [(set (pc)
7711         (if_then_else
7712          (match_operator:CC 0 "cmp_op"
7713                             [(match_operand:CC 2 "register_operand" "z")
7714                              (const_int 0)])
7715          (label_ref (match_operand 1 "" ""))
7716          (pc)))]
7717   "TARGET_HARD_FLOAT"
7718   "*
7720   return mips_output_conditional_branch (insn,
7721                                          operands,
7722                                          /*two_operands_p=*/0,
7723                                          /*float_p=*/1,
7724                                          /*inverted_p=*/0,
7725                                          get_attr_length (insn));
7727   [(set_attr "type"     "branch")
7728    (set_attr "mode"     "none")])
7730 (define_insn "branch_fp_inverted"
7731   [(set (pc)
7732         (if_then_else
7733          (match_operator:CC 0 "cmp_op"
7734                             [(match_operand:CC 2 "register_operand" "z")
7735                              (const_int 0)])
7736          (pc)
7737          (label_ref (match_operand 1 "" ""))))]
7738   "TARGET_HARD_FLOAT"
7739   "*
7741   return mips_output_conditional_branch (insn,
7742                                          operands,
7743                                          /*two_operands_p=*/0,
7744                                          /*float_p=*/1,
7745                                          /*inverted_p=*/1,
7746                                          get_attr_length (insn));
7748   [(set_attr "type"     "branch")
7749    (set_attr "mode"     "none")])
7751 ;; Conditional branches on comparisons with zero.
7753 (define_insn "branch_zero"
7754   [(set (pc)
7755         (if_then_else
7756          (match_operator:SI 0 "cmp_op"
7757                             [(match_operand:SI 2 "register_operand" "d")
7758                              (const_int 0)])
7759         (label_ref (match_operand 1 "" ""))
7760         (pc)))]
7761   "!TARGET_MIPS16"
7762   "*
7764   return mips_output_conditional_branch (insn,
7765                                          operands,
7766                                          /*two_operands_p=*/0,
7767                                          /*float_p=*/0,
7768                                          /*inverted_p=*/0,
7769                                          get_attr_length (insn));
7771   [(set_attr "type"     "branch")
7772    (set_attr "mode"     "none")])
7774 (define_insn "branch_zero_inverted"
7775   [(set (pc)
7776         (if_then_else
7777          (match_operator:SI 0 "cmp_op"
7778                             [(match_operand:SI 2 "register_operand" "d")
7779                              (const_int 0)])
7780         (pc)
7781         (label_ref (match_operand 1 "" ""))))]
7782   "!TARGET_MIPS16"
7783   "*
7785   return mips_output_conditional_branch (insn,
7786                                          operands,
7787                                          /*two_operands_p=*/0,
7788                                          /*float_p=*/0,
7789                                          /*inverted_p=*/1,
7790                                          get_attr_length (insn));
7792   [(set_attr "type"     "branch")
7793    (set_attr "mode"     "none")])
7795 (define_insn "branch_zero_di"
7796   [(set (pc)
7797         (if_then_else
7798          (match_operator:DI 0 "cmp_op"
7799                             [(match_operand:DI 2 "se_register_operand" "d")
7800                              (const_int 0)])
7801         (label_ref (match_operand 1 "" ""))
7802         (pc)))]
7803   "!TARGET_MIPS16"
7804   "*
7806   return mips_output_conditional_branch (insn,
7807                                          operands,
7808                                          /*two_operands_p=*/0,
7809                                          /*float_p=*/0,
7810                                          /*inverted_p=*/0,
7811                                          get_attr_length (insn));
7813   [(set_attr "type"     "branch")
7814    (set_attr "mode"     "none")])
7816 (define_insn "branch_zero_di_inverted"
7817   [(set (pc)
7818         (if_then_else
7819          (match_operator:DI 0 "cmp_op"
7820                             [(match_operand:DI 2 "se_register_operand" "d")
7821                              (const_int 0)])
7822         (pc)
7823         (label_ref (match_operand 1 "" ""))))]
7824   "!TARGET_MIPS16"
7825   "*
7827   return mips_output_conditional_branch (insn,
7828                                          operands,
7829                                          /*two_operands_p=*/0,
7830                                          /*float_p=*/0,
7831                                          /*inverted_p=*/1,
7832                                          get_attr_length (insn));
7834   [(set_attr "type"     "branch")
7835    (set_attr "mode"     "none")])
7837 ;; Conditional branch on equality comparision.
7839 (define_insn "branch_equality"
7840   [(set (pc)
7841         (if_then_else
7842          (match_operator:SI 0 "equality_op"
7843                             [(match_operand:SI 2 "register_operand" "d")
7844                              (match_operand:SI 3 "register_operand" "d")])
7845          (label_ref (match_operand 1 "" ""))
7846          (pc)))]
7847   "!TARGET_MIPS16"
7848   "*
7850   return mips_output_conditional_branch (insn,
7851                                          operands,
7852                                          /*two_operands_p=*/1,
7853                                          /*float_p=*/0,
7854                                          /*inverted_p=*/0,
7855                                          get_attr_length (insn));
7857   [(set_attr "type"     "branch")
7858    (set_attr "mode"     "none")])
7860 (define_insn "branch_equality_di"
7861   [(set (pc)
7862         (if_then_else
7863          (match_operator:DI 0 "equality_op"
7864                             [(match_operand:DI 2 "se_register_operand" "d")
7865                              (match_operand:DI 3 "se_register_operand" "d")])
7866         (label_ref (match_operand 1 "" ""))
7867         (pc)))]
7868   "!TARGET_MIPS16"
7869   "*
7871   return mips_output_conditional_branch (insn,
7872                                          operands,
7873                                          /*two_operands_p=*/1,
7874                                          /*float_p=*/0,
7875                                          /*inverted_p=*/0,
7876                                          get_attr_length (insn));
7878   [(set_attr "type"     "branch")
7879    (set_attr "mode"     "none")])
7881 (define_insn "branch_equality_inverted"
7882   [(set (pc)
7883         (if_then_else
7884          (match_operator:SI 0 "equality_op"
7885                             [(match_operand:SI 2 "register_operand" "d")
7886                              (match_operand:SI 3 "register_operand" "d")])
7887          (pc)
7888          (label_ref (match_operand 1 "" ""))))]
7889   "!TARGET_MIPS16"
7890   "*
7892   return mips_output_conditional_branch (insn,
7893                                          operands,
7894                                          /*two_operands_p=*/1,
7895                                          /*float_p=*/0,
7896                                          /*inverted_p=*/1,
7897                                          get_attr_length (insn));
7899   [(set_attr "type"     "branch")
7900    (set_attr "mode"     "none")])
7902 (define_insn "branch_equality_di_inverted"
7903   [(set (pc)
7904         (if_then_else
7905          (match_operator:DI 0 "equality_op"
7906                             [(match_operand:DI 2 "se_register_operand" "d")
7907                              (match_operand:DI 3 "se_register_operand" "d")])
7908         (pc)
7909         (label_ref (match_operand 1 "" ""))))]
7910   "!TARGET_MIPS16"
7911   "*
7913   return mips_output_conditional_branch (insn,
7914                                          operands,
7915                                          /*two_operands_p=*/1,
7916                                          /*float_p=*/0,
7917                                          /*inverted_p=*/1,
7918                                          get_attr_length (insn));
7920   [(set_attr "type"     "branch")
7921    (set_attr "mode"     "none")])
7923 ;; MIPS16 branches
7925 (define_insn ""
7926   [(set (pc)
7927         (if_then_else (match_operator:SI 0 "equality_op"
7928                                          [(match_operand:SI 1 "register_operand" "d,t")
7929                                           (const_int 0)])
7930         (match_operand 2 "pc_or_label_operand" "")
7931         (match_operand 3 "pc_or_label_operand" "")))]
7932   "TARGET_MIPS16"
7933   "*
7935   if (operands[2] != pc_rtx)
7936     {
7937       if (which_alternative == 0)
7938         return \"%*b%C0z\\t%1,%2\";
7939       else
7940         return \"%*bt%C0z\\t%2\";
7941     }
7942   else
7943     {
7944       if (which_alternative == 0)
7945         return \"%*b%N0z\\t%1,%3\";
7946       else
7947         return \"%*bt%N0z\\t%3\";
7948     }
7950   [(set_attr "type"     "branch")
7951    (set_attr "mode"     "none")
7952    (set_attr "length"   "8")])
7954 (define_insn ""
7955   [(set (pc)
7956         (if_then_else (match_operator:DI 0 "equality_op"
7957                                          [(match_operand:DI 1 "se_register_operand" "d,t")
7958                                           (const_int 0)])
7959         (match_operand 2 "pc_or_label_operand" "")
7960         (match_operand 3 "pc_or_label_operand" "")))]
7961   "TARGET_MIPS16"
7962   "*
7964   if (operands[2] != pc_rtx)
7965     {
7966       if (which_alternative == 0)
7967         return \"%*b%C0z\\t%1,%2\";
7968       else
7969         return \"%*bt%C0z\\t%2\";
7970     }
7971   else
7972     {
7973       if (which_alternative == 0)
7974         return \"%*b%N0z\\t%1,%3\";
7975       else
7976         return \"%*bt%N0z\\t%3\";
7977     }
7979   [(set_attr "type"     "branch")
7980    (set_attr "mode"     "none")
7981    (set_attr "length"   "8")])
7983 (define_expand "beq"
7984   [(set (pc)
7985         (if_then_else (eq:CC (cc0)
7986                              (const_int 0))
7987                       (label_ref (match_operand 0 "" ""))
7988                       (pc)))]
7989   ""
7990   "
7992   if (operands[0])              /* avoid unused code warning */
7993     {
7994       gen_conditional_branch (operands, EQ);
7995       DONE;
7996     }
7999 (define_expand "bne"
8000   [(set (pc)
8001         (if_then_else (ne:CC (cc0)
8002                              (const_int 0))
8003                       (label_ref (match_operand 0 "" ""))
8004                       (pc)))]
8005   ""
8006   "
8008   if (operands[0])              /* avoid unused code warning */
8009     {
8010       gen_conditional_branch (operands, NE);
8011       DONE;
8012     }
8015 (define_expand "bgt"
8016   [(set (pc)
8017         (if_then_else (gt:CC (cc0)
8018                              (const_int 0))
8019                       (label_ref (match_operand 0 "" ""))
8020                       (pc)))]
8021   ""
8022   "
8024   if (operands[0])              /* avoid unused code warning */
8025     {
8026       gen_conditional_branch (operands, GT);
8027       DONE;
8028     }
8031 (define_expand "bge"
8032   [(set (pc)
8033         (if_then_else (ge:CC (cc0)
8034                              (const_int 0))
8035                       (label_ref (match_operand 0 "" ""))
8036                       (pc)))]
8037   ""
8038   "
8040   if (operands[0])              /* avoid unused code warning */
8041     {
8042       gen_conditional_branch (operands, GE);
8043       DONE;
8044     }
8047 (define_expand "blt"
8048   [(set (pc)
8049         (if_then_else (lt:CC (cc0)
8050                              (const_int 0))
8051                       (label_ref (match_operand 0 "" ""))
8052                       (pc)))]
8053   ""
8054   "
8056   if (operands[0])              /* avoid unused code warning */
8057     {
8058       gen_conditional_branch (operands, LT);
8059       DONE;
8060     }
8063 (define_expand "ble"
8064   [(set (pc)
8065         (if_then_else (le:CC (cc0)
8066                              (const_int 0))
8067                       (label_ref (match_operand 0 "" ""))
8068                       (pc)))]
8069   ""
8070   "
8072   if (operands[0])              /* avoid unused code warning */
8073     {
8074       gen_conditional_branch (operands, LE);
8075       DONE;
8076     }
8079 (define_expand "bgtu"
8080   [(set (pc)
8081         (if_then_else (gtu:CC (cc0)
8082                               (const_int 0))
8083                       (label_ref (match_operand 0 "" ""))
8084                       (pc)))]
8085   ""
8086   "
8088   if (operands[0])              /* avoid unused code warning */
8089     {
8090       gen_conditional_branch (operands, GTU);
8091       DONE;
8092     }
8095 (define_expand "bgeu"
8096   [(set (pc)
8097         (if_then_else (geu:CC (cc0)
8098                               (const_int 0))
8099                       (label_ref (match_operand 0 "" ""))
8100                       (pc)))]
8101   ""
8102   "
8104   if (operands[0])              /* avoid unused code warning */
8105     {
8106       gen_conditional_branch (operands, GEU);
8107       DONE;
8108     }
8112 (define_expand "bltu"
8113   [(set (pc)
8114         (if_then_else (ltu:CC (cc0)
8115                               (const_int 0))
8116                       (label_ref (match_operand 0 "" ""))
8117                       (pc)))]
8118   ""
8119   "
8121   if (operands[0])              /* avoid unused code warning */
8122     {
8123       gen_conditional_branch (operands, LTU);
8124       DONE;
8125     }
8128 (define_expand "bleu"
8129   [(set (pc)
8130         (if_then_else (leu:CC (cc0)
8131                               (const_int 0))
8132                       (label_ref (match_operand 0 "" ""))
8133                       (pc)))]
8134   ""
8135   "
8137   if (operands[0])              /* avoid unused code warning */
8138     {
8139       gen_conditional_branch (operands, LEU);
8140       DONE;
8141     }
8146 ;;  ....................
8148 ;;      SETTING A REGISTER FROM A COMPARISON
8150 ;;  ....................
8152 (define_expand "seq"
8153   [(set (match_operand:SI 0 "register_operand" "=d")
8154         (eq:SI (match_dup 1)
8155                (match_dup 2)))]
8156   ""
8157   "
8159   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8160     FAIL;
8162   /* set up operands from compare.  */
8163   operands[1] = branch_cmp[0];
8164   operands[2] = branch_cmp[1];
8166   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8167     {
8168       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8169       DONE;
8170     }
8172   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8173     operands[2] = force_reg (SImode, operands[2]);
8175   /* fall through and generate default code */
8179 (define_insn "seq_si_zero"
8180   [(set (match_operand:SI 0 "register_operand" "=d")
8181         (eq:SI (match_operand:SI 1 "register_operand" "d")
8182                (const_int 0)))]
8183   "!TARGET_MIPS16"
8184   "sltu\\t%0,%1,1"
8185   [(set_attr "type"     "arith")
8186    (set_attr "mode"     "SI")])
8188 (define_insn ""
8189   [(set (match_operand:SI 0 "register_operand" "=t")
8190         (eq:SI (match_operand:SI 1 "register_operand" "d")
8191                (const_int 0)))]
8192   "TARGET_MIPS16"
8193   "sltu\\t%1,1"
8194   [(set_attr "type"     "arith")
8195    (set_attr "mode"     "SI")])
8197 (define_insn "seq_di_zero"
8198   [(set (match_operand:DI 0 "register_operand" "=d")
8199         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8200                (const_int 0)))]
8201   "TARGET_64BIT && !TARGET_MIPS16"
8202   "sltu\\t%0,%1,1"
8203   [(set_attr "type"     "arith")
8204    (set_attr "mode"     "DI")])
8206 (define_insn ""
8207   [(set (match_operand:DI 0 "register_operand" "=t")
8208         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8209                (const_int 0)))]
8210   "TARGET_64BIT && TARGET_MIPS16"
8211   "sltu\\t%1,1"
8212   [(set_attr "type"     "arith")
8213    (set_attr "mode"     "DI")])
8215 (define_insn "seq_si"
8216   [(set (match_operand:SI 0 "register_operand" "=d,d")
8217         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8218                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8219   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8220   "@
8221    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8222    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8223   [(set_attr "type"     "arith")
8224    (set_attr "mode"     "SI")
8225    (set_attr "length"   "8")])
8227 (define_split
8228   [(set (match_operand:SI 0 "register_operand" "")
8229         (eq:SI (match_operand:SI 1 "register_operand" "")
8230                (match_operand:SI 2 "uns_arith_operand" "")))]
8231   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8232     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8233   [(set (match_dup 0)
8234         (xor:SI (match_dup 1)
8235                 (match_dup 2)))
8236    (set (match_dup 0)
8237         (ltu:SI (match_dup 0)
8238                 (const_int 1)))]
8239   "")
8241 (define_insn "seq_di"
8242   [(set (match_operand:DI 0 "register_operand" "=d,d")
8243         (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8244                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8245   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8246   "@
8247    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8248    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8249   [(set_attr "type"     "arith")
8250    (set_attr "mode"     "DI")
8251    (set_attr "length"   "8")])
8253 (define_split
8254   [(set (match_operand:DI 0 "register_operand" "")
8255         (eq:DI (match_operand:DI 1 "se_register_operand" "")
8256                (match_operand:DI 2 "se_uns_arith_operand" "")))]
8257   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8258     && !TARGET_MIPS16
8259     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8260   [(set (match_dup 0)
8261         (xor:DI (match_dup 1)
8262                 (match_dup 2)))
8263    (set (match_dup 0)
8264         (ltu:DI (match_dup 0)
8265                 (const_int 1)))]
8266   "")
8268 ;; On the mips16 the default code is better than using sltu.
8270 (define_expand "sne"
8271   [(set (match_operand:SI 0 "register_operand" "=d")
8272         (ne:SI (match_dup 1)
8273                (match_dup 2)))]
8274   "!TARGET_MIPS16"
8275   "
8277   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8278     FAIL;
8280   /* set up operands from compare.  */
8281   operands[1] = branch_cmp[0];
8282   operands[2] = branch_cmp[1];
8284   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
8285     {
8286       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8287       DONE;
8288     }
8290   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8291     operands[2] = force_reg (SImode, operands[2]);
8293   /* fall through and generate default code */
8296 (define_insn "sne_si_zero"
8297   [(set (match_operand:SI 0 "register_operand" "=d")
8298         (ne:SI (match_operand:SI 1 "register_operand" "d")
8299                (const_int 0)))]
8300   "!TARGET_MIPS16"
8301   "sltu\\t%0,%.,%1"
8302   [(set_attr "type"     "arith")
8303    (set_attr "mode"     "SI")])
8305 (define_insn "sne_di_zero"
8306   [(set (match_operand:DI 0 "register_operand" "=d")
8307         (ne:DI (match_operand:DI 1 "se_register_operand" "d")
8308                (const_int 0)))]
8309   "TARGET_64BIT && !TARGET_MIPS16"
8310   "sltu\\t%0,%.,%1"
8311   [(set_attr "type"     "arith")
8312    (set_attr "mode"     "DI")])
8314 (define_insn "sne_si"
8315   [(set (match_operand:SI 0 "register_operand" "=d,d")
8316         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8317                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8318   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8319   "@
8320     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8321     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8322   [(set_attr "type"     "arith")
8323    (set_attr "mode"     "SI")
8324    (set_attr "length"   "8")])
8326 (define_split
8327   [(set (match_operand:SI 0 "register_operand" "")
8328         (ne:SI (match_operand:SI 1 "register_operand" "")
8329                (match_operand:SI 2 "uns_arith_operand" "")))]
8330   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8331     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8332   [(set (match_dup 0)
8333         (xor:SI (match_dup 1)
8334                 (match_dup 2)))
8335    (set (match_dup 0)
8336         (gtu:SI (match_dup 0)
8337                 (const_int 0)))]
8338   "")
8340 (define_insn "sne_di"
8341   [(set (match_operand:DI 0 "register_operand" "=d,d")
8342         (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8343                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8344   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8345   "@
8346     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8347     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8348   [(set_attr "type"     "arith")
8349    (set_attr "mode"     "DI")
8350    (set_attr "length"   "8")])
8352 (define_split
8353   [(set (match_operand:DI 0 "register_operand" "")
8354         (ne:DI (match_operand:DI 1 "se_register_operand" "")
8355                (match_operand:DI 2 "se_uns_arith_operand" "")))]
8356   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8357     && !TARGET_MIPS16
8358     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8359   [(set (match_dup 0)
8360         (xor:DI (match_dup 1)
8361                 (match_dup 2)))
8362    (set (match_dup 0)
8363         (gtu:DI (match_dup 0)
8364                 (const_int 0)))]
8365   "")
8367 (define_expand "sgt"
8368   [(set (match_operand:SI 0 "register_operand" "=d")
8369         (gt:SI (match_dup 1)
8370                (match_dup 2)))]
8371   ""
8372   "
8374   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8375     FAIL;
8377   /* set up operands from compare.  */
8378   operands[1] = branch_cmp[0];
8379   operands[2] = branch_cmp[1];
8381   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8382     {
8383       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8384       DONE;
8385     }
8387   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8388     operands[2] = force_reg (SImode, operands[2]);
8390   /* fall through and generate default code */
8393 (define_insn "sgt_si"
8394   [(set (match_operand:SI 0 "register_operand" "=d")
8395         (gt:SI (match_operand:SI 1 "register_operand" "d")
8396                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8397   "!TARGET_MIPS16"
8398   "slt\\t%0,%z2,%1"
8399   [(set_attr "type"     "arith")
8400    (set_attr "mode"     "SI")])
8402 (define_insn ""
8403   [(set (match_operand:SI 0 "register_operand" "=t")
8404         (gt:SI (match_operand:SI 1 "register_operand" "d")
8405                (match_operand:SI 2 "register_operand" "d")))]
8406   "TARGET_MIPS16"
8407   "slt\\t%2,%1"
8408   [(set_attr "type"     "arith")
8409    (set_attr "mode"     "SI")])
8411 (define_insn "sgt_di"
8412   [(set (match_operand:DI 0 "register_operand" "=d")
8413         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8414                (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8415   "TARGET_64BIT && !TARGET_MIPS16"
8416   "slt\\t%0,%z2,%1"
8417   [(set_attr "type"     "arith")
8418    (set_attr "mode"     "DI")])
8420 (define_insn ""
8421   [(set (match_operand:DI 0 "register_operand" "=d")
8422         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8423                (match_operand:DI 2 "se_register_operand" "d")))]
8424   "TARGET_64BIT && TARGET_MIPS16"
8425   "slt\\t%2,%1"
8426   [(set_attr "type"     "arith")
8427    (set_attr "mode"     "DI")])
8429 (define_expand "sge"
8430   [(set (match_operand:SI 0 "register_operand" "=d")
8431         (ge:SI (match_dup 1)
8432                (match_dup 2)))]
8433   ""
8434   "
8436   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8437     FAIL;
8439   /* set up operands from compare.  */
8440   operands[1] = branch_cmp[0];
8441   operands[2] = branch_cmp[1];
8443   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8444     {
8445       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8446       DONE;
8447     }
8449   /* fall through and generate default code */
8452 (define_insn "sge_si"
8453   [(set (match_operand:SI 0 "register_operand" "=d")
8454         (ge:SI (match_operand:SI 1 "register_operand" "d")
8455                (match_operand:SI 2 "arith_operand" "dI")))]
8456   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8457   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8458   [(set_attr "type"     "arith")
8459    (set_attr "mode"     "SI")
8460    (set_attr "length"   "8")])
8462 (define_split
8463   [(set (match_operand:SI 0 "register_operand" "")
8464         (ge:SI (match_operand:SI 1 "register_operand" "")
8465                (match_operand:SI 2 "arith_operand" "")))]
8466   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8467   [(set (match_dup 0)
8468         (lt:SI (match_dup 1)
8469                (match_dup 2)))
8470    (set (match_dup 0)
8471         (xor:SI (match_dup 0)
8472                 (const_int 1)))]
8473   "")
8475 (define_insn "sge_di"
8476   [(set (match_operand:DI 0 "register_operand" "=d")
8477         (ge:DI (match_operand:DI 1 "se_register_operand" "d")
8478                (match_operand:DI 2 "se_arith_operand" "dI")))]
8479   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8480   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8481   [(set_attr "type"     "arith")
8482    (set_attr "mode"     "DI")
8483    (set_attr "length"   "8")])
8485 (define_split
8486   [(set (match_operand:DI 0 "register_operand" "")
8487         (ge:DI (match_operand:DI 1 "se_register_operand" "")
8488                (match_operand:DI 2 "se_arith_operand" "")))]
8489   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8490    && !TARGET_MIPS16"
8491   [(set (match_dup 0)
8492         (lt:DI (match_dup 1)
8493                (match_dup 2)))
8494    (set (match_dup 0)
8495         (xor:DI (match_dup 0)
8496                 (const_int 1)))]
8497   "")
8499 (define_expand "slt"
8500   [(set (match_operand:SI 0 "register_operand" "=d")
8501         (lt:SI (match_dup 1)
8502                (match_dup 2)))]
8503   ""
8504   "
8506   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8507     FAIL;
8509   /* set up operands from compare.  */
8510   operands[1] = branch_cmp[0];
8511   operands[2] = branch_cmp[1];
8513   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8514     {
8515       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8516       DONE;
8517     }
8519   /* fall through and generate default code */
8522 (define_insn "slt_si"
8523   [(set (match_operand:SI 0 "register_operand" "=d")
8524         (lt:SI (match_operand:SI 1 "register_operand" "d")
8525                (match_operand:SI 2 "arith_operand" "dI")))]
8526   "!TARGET_MIPS16"
8527   "slt\\t%0,%1,%2"
8528   [(set_attr "type"     "arith")
8529    (set_attr "mode"     "SI")])
8531 (define_insn ""
8532   [(set (match_operand:SI 0 "register_operand" "=t,t")
8533         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8534                (match_operand:SI 2 "arith_operand" "d,I")))]
8535   "TARGET_MIPS16"
8536   "slt\\t%1,%2"
8537   [(set_attr "type"     "arith")
8538    (set_attr "mode"     "SI")
8539    (set_attr_alternative "length"
8540                 [(const_int 4)
8541                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8542                                (const_int 4)
8543                                (const_int 8))])])
8545 (define_insn "slt_di"
8546   [(set (match_operand:DI 0 "register_operand" "=d")
8547         (lt:DI (match_operand:DI 1 "se_register_operand" "d")
8548                (match_operand:DI 2 "se_arith_operand" "dI")))]
8549   "TARGET_64BIT && !TARGET_MIPS16"
8550   "slt\\t%0,%1,%2"
8551   [(set_attr "type"     "arith")
8552    (set_attr "mode"     "DI")])
8554 (define_insn ""
8555   [(set (match_operand:DI 0 "register_operand" "=t,t")
8556         (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
8557                (match_operand:DI 2 "se_arith_operand" "d,I")))]
8558   "TARGET_64BIT && TARGET_MIPS16"
8559   "slt\\t%1,%2"
8560   [(set_attr "type"     "arith")
8561    (set_attr "mode"     "DI")
8562    (set_attr_alternative "length"
8563                 [(const_int 4)
8564                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8565                                (const_int 4)
8566                                (const_int 8))])])
8568 (define_expand "sle"
8569   [(set (match_operand:SI 0 "register_operand" "=d")
8570         (le:SI (match_dup 1)
8571                (match_dup 2)))]
8572   ""
8573   "
8575   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8576     FAIL;
8578   /* set up operands from compare.  */
8579   operands[1] = branch_cmp[0];
8580   operands[2] = branch_cmp[1];
8582   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8583     {
8584       gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8585       DONE;
8586     }
8588   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8589     operands[2] = force_reg (SImode, operands[2]);
8591   /* fall through and generate default code */
8594 (define_insn "sle_si_const"
8595   [(set (match_operand:SI 0 "register_operand" "=d")
8596         (le:SI (match_operand:SI 1 "register_operand" "d")
8597                (match_operand:SI 2 "small_int" "I")))]
8598   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8599   "*
8601   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8602   return \"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")
8609         (le:SI (match_operand:SI 1 "register_operand" "d")
8610                (match_operand:SI 2 "small_int" "I")))]
8611   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8612   "*
8614   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8615   return \"slt\\t%1,%2\";
8617   [(set_attr "type"     "arith")
8618    (set_attr "mode"     "SI")
8619    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8620                                       (const_int 4)
8621                                       (const_int 8)))])
8623 (define_insn "sle_di_const"
8624   [(set (match_operand:DI 0 "register_operand" "=d")
8625         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8626                (match_operand:DI 2 "small_int" "I")))]
8627   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8628   "*
8630   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8631   return \"slt\\t%0,%1,%2\";
8633   [(set_attr "type"     "arith")
8634    (set_attr "mode"     "DI")])
8636 (define_insn ""
8637   [(set (match_operand:DI 0 "register_operand" "=t")
8638         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8639                (match_operand:DI 2 "small_int" "I")))]
8640   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8641   "*
8643   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8644   return \"slt\\t%1,%2\";
8646   [(set_attr "type"     "arith")
8647    (set_attr "mode"     "DI")
8648    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8649                                       (const_int 4)
8650                                       (const_int 8)))])
8652 (define_insn "sle_si_reg"
8653   [(set (match_operand:SI 0 "register_operand" "=d")
8654         (le:SI (match_operand:SI 1 "register_operand" "d")
8655                (match_operand:SI 2 "register_operand" "d")))]
8656   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8657   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8658   [(set_attr "type"     "arith")
8659    (set_attr "mode"     "SI")
8660    (set_attr "length"   "8")])
8662 (define_split
8663   [(set (match_operand:SI 0 "register_operand" "")
8664         (le:SI (match_operand:SI 1 "register_operand" "")
8665                (match_operand:SI 2 "register_operand" "")))]
8666   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8667   [(set (match_dup 0)
8668         (lt:SI (match_dup 2)
8669                (match_dup 1)))
8670    (set (match_dup 0)
8671         (xor:SI (match_dup 0)
8672                 (const_int 1)))]
8673   "")
8675 (define_insn "sle_di_reg"
8676   [(set (match_operand:DI 0 "register_operand" "=d")
8677         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8678                (match_operand:DI 2 "se_register_operand" "d")))]
8679   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8680   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8681   [(set_attr "type"     "arith")
8682    (set_attr "mode"     "DI")
8683    (set_attr "length"   "8")])
8685 (define_split
8686   [(set (match_operand:DI 0 "register_operand" "")
8687         (le:DI (match_operand:DI 1 "se_register_operand" "")
8688                (match_operand:DI 2 "se_register_operand" "")))]
8689   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8690    && !TARGET_MIPS16"
8691   [(set (match_dup 0)
8692         (lt:DI (match_dup 2)
8693                (match_dup 1)))
8694    (set (match_dup 0)
8695         (xor:DI (match_dup 0)
8696                 (const_int 1)))]
8697   "")
8699 (define_expand "sgtu"
8700   [(set (match_operand:SI 0 "register_operand" "=d")
8701         (gtu:SI (match_dup 1)
8702                 (match_dup 2)))]
8703   ""
8704   "
8706   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8707     FAIL;
8709   /* set up operands from compare.  */
8710   operands[1] = branch_cmp[0];
8711   operands[2] = branch_cmp[1];
8713   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8714     {
8715       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8716       DONE;
8717     }
8719   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8720     operands[2] = force_reg (SImode, operands[2]);
8722   /* fall through and generate default code */
8725 (define_insn "sgtu_si"
8726   [(set (match_operand:SI 0 "register_operand" "=d")
8727         (gtu:SI (match_operand:SI 1 "register_operand" "d")
8728                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8729   ""
8730   "sltu\\t%0,%z2,%1"
8731   [(set_attr "type"     "arith")
8732    (set_attr "mode"     "SI")])
8734 (define_insn ""
8735   [(set (match_operand:SI 0 "register_operand" "=t")
8736         (gtu:SI (match_operand:SI 1 "register_operand" "d")
8737                 (match_operand:SI 2 "register_operand" "d")))]
8738   ""
8739   "sltu\\t%2,%1"
8740   [(set_attr "type"     "arith")
8741    (set_attr "mode"     "SI")])
8743 (define_insn "sgtu_di"
8744   [(set (match_operand:DI 0 "register_operand" "=d")
8745         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8746                 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8747   "TARGET_64BIT"
8748   "sltu\\t%0,%z2,%1"
8749   [(set_attr "type"     "arith")
8750    (set_attr "mode"     "DI")])
8752 (define_insn ""
8753   [(set (match_operand:DI 0 "register_operand" "=t")
8754         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8755                 (match_operand:DI 2 "se_register_operand" "d")))]
8756   "TARGET_64BIT"
8757   "sltu\\t%2,%1"
8758   [(set_attr "type"     "arith")
8759    (set_attr "mode"     "DI")])
8761 (define_expand "sgeu"
8762   [(set (match_operand:SI 0 "register_operand" "=d")
8763         (geu:SI (match_dup 1)
8764                 (match_dup 2)))]
8765   ""
8766   "
8768   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8769     FAIL;
8771   /* set up operands from compare.  */
8772   operands[1] = branch_cmp[0];
8773   operands[2] = branch_cmp[1];
8775   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8776     {
8777       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8778       DONE;
8779     }
8781   /* fall through and generate default code */
8784 (define_insn "sgeu_si"
8785   [(set (match_operand:SI 0 "register_operand" "=d")
8786         (geu:SI (match_operand:SI 1 "register_operand" "d")
8787                 (match_operand:SI 2 "arith_operand" "dI")))]
8788   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8789   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8790   [(set_attr "type"     "arith")
8791    (set_attr "mode"     "SI")
8792    (set_attr "length"   "8")])
8794 (define_split
8795   [(set (match_operand:SI 0 "register_operand" "")
8796         (geu:SI (match_operand:SI 1 "register_operand" "")
8797                 (match_operand:SI 2 "arith_operand" "")))]
8798   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8799   [(set (match_dup 0)
8800         (ltu:SI (match_dup 1)
8801                 (match_dup 2)))
8802    (set (match_dup 0)
8803         (xor:SI (match_dup 0)
8804                 (const_int 1)))]
8805   "")
8807 (define_insn "sgeu_di"
8808   [(set (match_operand:DI 0 "register_operand" "=d")
8809         (geu:DI (match_operand:DI 1 "se_register_operand" "d")
8810                 (match_operand:DI 2 "se_arith_operand" "dI")))]
8811   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8812   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8813   [(set_attr "type"     "arith")
8814    (set_attr "mode"     "DI")
8815    (set_attr "length"   "8")])
8817 (define_split
8818   [(set (match_operand:DI 0 "register_operand" "")
8819         (geu:DI (match_operand:DI 1 "se_register_operand" "")
8820                 (match_operand:DI 2 "se_arith_operand" "")))]
8821   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8822    && !TARGET_MIPS16"
8823   [(set (match_dup 0)
8824         (ltu:DI (match_dup 1)
8825                 (match_dup 2)))
8826    (set (match_dup 0)
8827         (xor:DI (match_dup 0)
8828                 (const_int 1)))]
8829   "")
8831 (define_expand "sltu"
8832   [(set (match_operand:SI 0 "register_operand" "=d")
8833         (ltu:SI (match_dup 1)
8834                 (match_dup 2)))]
8835   ""
8836   "
8838   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8839     FAIL;
8841   /* set up operands from compare.  */
8842   operands[1] = branch_cmp[0];
8843   operands[2] = branch_cmp[1];
8845   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8846     {
8847       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8848       DONE;
8849     }
8851   /* fall through and generate default code */
8854 (define_insn "sltu_si"
8855   [(set (match_operand:SI 0 "register_operand" "=d")
8856         (ltu:SI (match_operand:SI 1 "register_operand" "d")
8857                 (match_operand:SI 2 "arith_operand" "dI")))]
8858   "!TARGET_MIPS16"
8859   "sltu\\t%0,%1,%2"
8860   [(set_attr "type"     "arith")
8861    (set_attr "mode"     "SI")])
8863 (define_insn ""
8864   [(set (match_operand:SI 0 "register_operand" "=t,t")
8865         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8866                 (match_operand:SI 2 "arith_operand" "d,I")))]
8867   "TARGET_MIPS16"
8868   "sltu\\t%1,%2"
8869   [(set_attr "type"     "arith")
8870    (set_attr "mode"     "SI")
8871    (set_attr_alternative "length"
8872                 [(const_int 4)
8873                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8874                                (const_int 4)
8875                                (const_int 8))])])
8877 (define_insn "sltu_di"
8878   [(set (match_operand:DI 0 "register_operand" "=d")
8879         (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
8880                 (match_operand:DI 2 "se_arith_operand" "dI")))]
8881   "TARGET_64BIT && !TARGET_MIPS16"
8882   "sltu\\t%0,%1,%2"
8883   [(set_attr "type"     "arith")
8884    (set_attr "mode"     "DI")])
8886 (define_insn ""
8887   [(set (match_operand:DI 0 "register_operand" "=t,t")
8888         (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
8889                 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8890   "TARGET_64BIT && TARGET_MIPS16"
8891   "sltu\\t%1,%2"
8892   [(set_attr "type"     "arith")
8893    (set_attr "mode"     "DI")
8894    (set_attr_alternative "length"
8895                 [(const_int 4)
8896                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8897                                (const_int 4)
8898                                (const_int 8))])])
8900 (define_expand "sleu"
8901   [(set (match_operand:SI 0 "register_operand" "=d")
8902         (leu:SI (match_dup 1)
8903                 (match_dup 2)))]
8904   ""
8905   "
8907   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8908     FAIL;
8910   /* set up operands from compare.  */
8911   operands[1] = branch_cmp[0];
8912   operands[2] = branch_cmp[1];
8914   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8915     {
8916       gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
8917       DONE;
8918     }
8920   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8921     operands[2] = force_reg (SImode, operands[2]);
8923   /* fall through and generate default code */
8926 (define_insn "sleu_si_const"
8927   [(set (match_operand:SI 0 "register_operand" "=d")
8928         (leu:SI (match_operand:SI 1 "register_operand" "d")
8929                 (match_operand:SI 2 "small_int" "I")))]
8930   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8931   "*
8933   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
8934   return \"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")
8941         (leu:SI (match_operand:SI 1 "register_operand" "d")
8942                 (match_operand:SI 2 "small_int" "I")))]
8943   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8944   "*
8946   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8947   return \"sltu\\t%1,%2\";
8949   [(set_attr "type"     "arith")
8950    (set_attr "mode"     "SI")
8951    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8952                                       (const_int 4)
8953                                       (const_int 8)))])
8955 (define_insn "sleu_di_const"
8956   [(set (match_operand:DI 0 "register_operand" "=d")
8957         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8958                 (match_operand:DI 2 "small_int" "I")))]
8959   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8960   "*
8962   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
8963   return \"sltu\\t%0,%1,%2\";
8965   [(set_attr "type"     "arith")
8966    (set_attr "mode"     "DI")])
8968 (define_insn ""
8969   [(set (match_operand:DI 0 "register_operand" "=t")
8970         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8971                 (match_operand:DI 2 "small_int" "I")))]
8972   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8973   "*
8975   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8976   return \"sltu\\t%1,%2\";
8978   [(set_attr "type"     "arith")
8979    (set_attr "mode"     "DI")
8980    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8981                                       (const_int 4)
8982                                       (const_int 8)))])
8984 (define_insn "sleu_si_reg"
8985   [(set (match_operand:SI 0 "register_operand" "=d")
8986         (leu:SI (match_operand:SI 1 "register_operand" "d")
8987                 (match_operand:SI 2 "register_operand" "d")))]
8988   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8989   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8990   [(set_attr "type"     "arith")
8991    (set_attr "mode"     "SI")
8992    (set_attr "length"   "8")])
8994 (define_split
8995   [(set (match_operand:SI 0 "register_operand" "")
8996         (leu:SI (match_operand:SI 1 "register_operand" "")
8997                 (match_operand:SI 2 "register_operand" "")))]
8998   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8999   [(set (match_dup 0)
9000         (ltu:SI (match_dup 2)
9001                 (match_dup 1)))
9002    (set (match_dup 0)
9003         (xor:SI (match_dup 0)
9004                 (const_int 1)))]
9005   "")
9007 (define_insn "sleu_di_reg"
9008   [(set (match_operand:DI 0 "register_operand" "=d")
9009         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9010                 (match_operand:DI 2 "se_register_operand" "d")))]
9011   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9012   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9013   [(set_attr "type"     "arith")
9014    (set_attr "mode"     "DI")
9015    (set_attr "length"   "8")])
9017 (define_split
9018   [(set (match_operand:DI 0 "register_operand" "")
9019         (leu:DI (match_operand:DI 1 "se_register_operand" "")
9020                 (match_operand:DI 2 "se_register_operand" "")))]
9021   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9022    && !TARGET_MIPS16"
9023   [(set (match_dup 0)
9024         (ltu:DI (match_dup 2)
9025                 (match_dup 1)))
9026    (set (match_dup 0)
9027         (xor:DI (match_dup 0)
9028                 (const_int 1)))]
9029   "")
9033 ;;  ....................
9035 ;;      FLOATING POINT COMPARISONS
9037 ;;  ....................
9039 (define_insn "seq_df"
9040   [(set (match_operand:CC 0 "register_operand" "=z")
9041         (eq:CC (match_operand:DF 1 "register_operand" "f")
9042                (match_operand:DF 2 "register_operand" "f")))]
9043   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9044   "*
9046   return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9048  [(set_attr "type"      "fcmp")
9049   (set_attr "mode"      "FPSW")])
9051 (define_insn "slt_df"
9052   [(set (match_operand:CC 0 "register_operand" "=z")
9053         (lt:CC (match_operand:DF 1 "register_operand" "f")
9054                (match_operand:DF 2 "register_operand" "f")))]
9055   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9056   "*
9058   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9060  [(set_attr "type"      "fcmp")
9061   (set_attr "mode"      "FPSW")])
9063 (define_insn "sle_df"
9064   [(set (match_operand:CC 0 "register_operand" "=z")
9065         (le:CC (match_operand:DF 1 "register_operand" "f")
9066                (match_operand:DF 2 "register_operand" "f")))]
9067   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9068   "*
9070   return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9072  [(set_attr "type"      "fcmp")
9073   (set_attr "mode"      "FPSW")])
9075 (define_insn "sgt_df"
9076   [(set (match_operand:CC 0 "register_operand" "=z")
9077         (gt:CC (match_operand:DF 1 "register_operand" "f")
9078                (match_operand:DF 2 "register_operand" "f")))]
9079   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9080   "*
9082   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9084  [(set_attr "type"      "fcmp")
9085   (set_attr "mode"      "FPSW")])
9087 (define_insn "sge_df"
9088   [(set (match_operand:CC 0 "register_operand" "=z")
9089         (ge:CC (match_operand:DF 1 "register_operand" "f")
9090                (match_operand:DF 2 "register_operand" "f")))]
9091   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9092   "*
9094   return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9096  [(set_attr "type"      "fcmp")
9097   (set_attr "mode"      "FPSW")])
9099 (define_insn "seq_sf"
9100   [(set (match_operand:CC 0 "register_operand" "=z")
9101         (eq:CC (match_operand:SF 1 "register_operand" "f")
9102                (match_operand:SF 2 "register_operand" "f")))]
9103   "TARGET_HARD_FLOAT"
9104   "*
9106   return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9108  [(set_attr "type"      "fcmp")
9109   (set_attr "mode"      "FPSW")])
9111 (define_insn "slt_sf"
9112   [(set (match_operand:CC 0 "register_operand" "=z")
9113         (lt:CC (match_operand:SF 1 "register_operand" "f")
9114                (match_operand:SF 2 "register_operand" "f")))]
9115   "TARGET_HARD_FLOAT"
9116   "*
9118   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9120  [(set_attr "type"      "fcmp")
9121   (set_attr "mode"      "FPSW")])
9123 (define_insn "sle_sf"
9124   [(set (match_operand:CC 0 "register_operand" "=z")
9125         (le:CC (match_operand:SF 1 "register_operand" "f")
9126                (match_operand:SF 2 "register_operand" "f")))]
9127   "TARGET_HARD_FLOAT"
9128   "*
9130   return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9132  [(set_attr "type"      "fcmp")
9133   (set_attr "mode"      "FPSW")])
9135 (define_insn "sgt_sf"
9136   [(set (match_operand:CC 0 "register_operand" "=z")
9137         (gt:CC (match_operand:SF 1 "register_operand" "f")
9138                (match_operand:SF 2 "register_operand" "f")))]
9139   "TARGET_HARD_FLOAT"
9140   "*
9142   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9144  [(set_attr "type"      "fcmp")
9145   (set_attr "mode"      "FPSW")])
9147 (define_insn "sge_sf"
9148   [(set (match_operand:CC 0 "register_operand" "=z")
9149         (ge:CC (match_operand:SF 1 "register_operand" "f")
9150                (match_operand:SF 2 "register_operand" "f")))]
9151   "TARGET_HARD_FLOAT"
9152   "*
9154   return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9156  [(set_attr "type"      "fcmp")
9157   (set_attr "mode"      "FPSW")])
9161 ;;  ....................
9163 ;;      UNCONDITIONAL BRANCHES
9165 ;;  ....................
9167 ;; Unconditional branches.
9169 (define_insn "jump"
9170   [(set (pc)
9171         (label_ref (match_operand 0 "" "")))]
9172   "!TARGET_MIPS16"
9173   "*
9175   if (GET_CODE (operands[0]) == REG)
9176     return \"%*j\\t%0\";
9177   /* ??? I don't know why this is necessary.  This works around an
9178      assembler problem that appears when a label is defined, then referenced
9179      in a switch table, then used in a `j' instruction.  */
9180   else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
9181     return \"%*b\\t%l0\";
9182   else
9183     return \"%*j\\t%l0\";
9185   [(set_attr "type"     "jump")
9186    (set_attr "mode"     "none")])
9188 ;; We need a different insn for the mips16, because a mips16 branch
9189 ;; does not have a delay slot.
9191 (define_insn ""
9192   [(set (pc)
9193         (label_ref (match_operand 0 "" "")))]
9194   "TARGET_MIPS16 && GET_CODE (operands[0]) != REG"
9195   "b\\t%l0"
9196   [(set_attr "type"     "branch")
9197    (set_attr "mode"     "none")
9198    (set_attr "length"   "8")])
9200 (define_expand "indirect_jump"
9201   [(set (pc) (match_operand 0 "register_operand" "d"))]
9202   ""
9203   "
9205   rtx dest;
9207   if (operands[0])              /* eliminate unused code warnings */
9208     {
9209       dest = operands[0];
9210       if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9211         operands[0] = copy_to_mode_reg (Pmode, dest);
9213       if (!(Pmode == DImode))
9214         emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9215       else
9216         emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9218       DONE;
9219     }
9222 (define_insn "indirect_jump_internal1"
9223   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
9224   "!(Pmode == DImode)"
9225   "%*j\\t%0"
9226   [(set_attr "type"     "jump")
9227    (set_attr "mode"     "none")])
9229 (define_insn "indirect_jump_internal2"
9230   [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
9231   "Pmode == DImode"
9232   "%*j\\t%0"
9233   [(set_attr "type"     "jump")
9234    (set_attr "mode"     "none")])
9236 (define_expand "tablejump"
9237   [(set (pc)
9238         (match_operand 0 "register_operand" "d"))
9239    (use (label_ref (match_operand 1 "" "")))]
9240   ""
9241   "
9243   if (operands[0])              /* eliminate unused code warnings */
9244     {
9245       if (TARGET_MIPS16)
9246         {
9247           if (GET_MODE (operands[0]) != HImode)
9248             abort ();
9249           if (!(Pmode == DImode))
9250             emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
9251           else
9252             emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
9253           DONE;
9254         }
9256       if (GET_MODE (operands[0]) != Pmode)
9257         abort ();
9259       if (! flag_pic)
9260         {
9261           if (!(Pmode == DImode))
9262             emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9263           else
9264             emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
9265         }
9266       else
9267         {
9268           if (!(Pmode == DImode))
9269             emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
9270           else
9271             emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
9272         }
9274       DONE;
9275     }
9278 (define_insn "tablejump_internal1"
9279   [(set (pc)
9280         (match_operand:SI 0 "register_operand" "d"))
9281    (use (label_ref (match_operand 1 "" "")))]
9282   "!(Pmode == DImode)"
9283   "%*j\\t%0"
9284   [(set_attr "type"     "jump")
9285    (set_attr "mode"     "none")])
9287 (define_insn "tablejump_internal2"
9288   [(set (pc)
9289         (match_operand:DI 0 "se_register_operand" "d"))
9290    (use (label_ref (match_operand 1 "" "")))]
9291   "Pmode == DImode"
9292   "%*j\\t%0"
9293   [(set_attr "type"     "jump")
9294    (set_attr "mode"     "none")])
9296 (define_expand "tablejump_internal3"
9297   [(parallel [(set (pc)
9298                    (plus:SI (match_operand:SI 0 "register_operand" "d")
9299                             (label_ref:SI (match_operand 1 "" ""))))
9300               (use (label_ref:SI (match_dup 1)))])]
9301   ""
9302   "")
9304 (define_expand "tablejump_mips161"
9305   [(set (pc) (plus:SI (sign_extend:SI
9306                        (match_operand:HI 0 "register_operand" "d"))
9307                       (label_ref:SI (match_operand 1 "" ""))))]
9308   "TARGET_MIPS16 && !(Pmode == DImode)"
9309   "
9311   if (operands[0])      /* eliminate unused code warnings.  */
9312     {
9313       rtx t1, t2, t3;
9315       t1 = gen_reg_rtx (SImode);
9316       t2 = gen_reg_rtx (SImode);
9317       t3 = gen_reg_rtx (SImode);
9318       emit_insn (gen_extendhisi2 (t1, operands[0]));
9319       emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
9320       emit_insn (gen_addsi3 (t3, t1, t2));
9321       emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
9322       DONE;
9323     }
9326 (define_expand "tablejump_mips162"
9327   [(set (pc) (plus:DI (sign_extend:DI
9328                        (match_operand:HI 0 "register_operand" "d"))
9329                       (label_ref:DI (match_operand 1 "" ""))))]
9330   "TARGET_MIPS16 && Pmode == DImode"
9331   "
9333   if (operands[0])      /* eliminate unused code warnings.  */
9334     {
9335       rtx t1, t2, t3;
9337       t1 = gen_reg_rtx (DImode);
9338       t2 = gen_reg_rtx (DImode);
9339       t3 = gen_reg_rtx (DImode);
9340       emit_insn (gen_extendhidi2 (t1, operands[0]));
9341       emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
9342       emit_insn (gen_adddi3 (t3, t1, t2));
9343       emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
9344       DONE;
9345     }
9348 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
9349 ;;; it is not valid.  ??? With the USE, the condition tests may not be required
9350 ;;; any longer.
9352 ;;; ??? The length depends on the ABI.  It is two for o32, and one for n32.
9353 ;;; We just use the conservative number here.
9355 (define_insn ""
9356   [(set (pc)
9357         (plus:SI (match_operand:SI 0 "register_operand" "d")
9358                  (label_ref:SI (match_operand 1 "" ""))))
9359    (use (label_ref:SI (match_dup 1)))]
9360   "!(Pmode == DImode) && next_active_insn (insn) != 0
9361    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9362    && PREV_INSN (next_active_insn (insn)) == operands[1]"
9363   "*
9365   /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic.  */
9366   if (mips_abi == ABI_32 || mips_abi == ABI_O64)
9367     output_asm_insn (\".cpadd\\t%0\", operands);
9368   return \"%*j\\t%0\";
9370   [(set_attr "type"     "jump")
9371    (set_attr "mode"     "none")
9372    (set_attr "length"   "8")])
9374 (define_expand "tablejump_internal4"
9375   [(parallel [(set (pc)
9376                    (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9377                             (label_ref:DI (match_operand 1 "" ""))))
9378               (use (label_ref:DI (match_dup 1)))])]
9379   ""
9380   "")
9382 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
9383 ;;; it is not valid.  ??? With the USE, the condition tests may not be required
9384 ;;; any longer.
9386 (define_insn ""
9387   [(set (pc)
9388         (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9389                  (label_ref:DI (match_operand 1 "" ""))))
9390    (use (label_ref:DI (match_dup 1)))]
9391   "Pmode == DImode && next_active_insn (insn) != 0
9392    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9393    && PREV_INSN (next_active_insn (insn)) == operands[1]"
9394   "%*j\\t%0"
9395   [(set_attr "type"     "jump")
9396    (set_attr "mode"     "none")])
9398 ;; Implement a switch statement when generating embedded PIC code.
9399 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
9401 (define_expand "casesi"
9402   [(set (match_dup 5)
9403         (minus:SI (match_operand:SI 0 "register_operand" "d")
9404                   (match_operand:SI 1 "arith_operand" "dI")))
9405    (set (cc0)
9406         (compare:CC (match_dup 5)
9407                     (match_operand:SI 2 "arith_operand" "")))
9408    (set (pc)
9409         (if_then_else (gtu (cc0)
9410                            (const_int 0))
9411                       (label_ref (match_operand 4 "" ""))
9412                       (pc)))
9413    (parallel
9414     [(set (pc)
9415           (mem:SI (plus:SI (mult:SI (match_dup 5)
9416                                     (const_int 4))
9417                            (label_ref (match_operand 3 "" "")))))
9418      (clobber (match_scratch:SI 6 ""))
9419      (clobber (reg:SI 31))])]
9420   "TARGET_EMBEDDED_PIC"
9421   "
9423   if (operands[0])
9424     {
9425       rtx reg = gen_reg_rtx (SImode);
9427       /* If the index is too large, go to the default label.  */
9428       emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9429       emit_insn (gen_cmpsi (reg, operands[2]));
9430       emit_insn (gen_bgtu (operands[4]));
9432       /* Do the PIC jump.  */
9433       if (Pmode != DImode)
9434         emit_jump_insn (gen_casesi_internal (reg, operands[3],
9435                                              gen_reg_rtx (SImode)));
9436       else
9437         emit_jump_insn (gen_casesi_internal_di (reg, operands[3],
9438                                                 gen_reg_rtx (DImode)));
9440       DONE;
9441     }
9444 ;; An embedded PIC switch statement looks like this:
9445 ;;      bal     $LS1
9446 ;;      sll     $reg,$index,2
9447 ;; $LS1:
9448 ;;      addu    $reg,$reg,$31
9449 ;;      lw      $reg,$L1-$LS1($reg)
9450 ;;      addu    $reg,$reg,$31
9451 ;;      j       $reg
9452 ;; $L1:
9453 ;;      .word   case1-$LS1
9454 ;;      .word   case2-$LS1
9455 ;;      ...
9457 (define_insn "casesi_internal"
9458   [(set (pc)
9459         (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9460                                   (const_int 4))
9461                          (label_ref (match_operand 1 "" "")))))
9462    (clobber (match_operand:SI 2 "register_operand" "=d"))
9463    (clobber (reg:SI 31))]
9464   "TARGET_EMBEDDED_PIC"
9465   "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9466 lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\;j\\t%2"
9467   [(set_attr "type"     "jump")
9468    (set_attr "mode"     "none")
9469    (set_attr "length"   "24")])
9471 (define_insn "casesi_internal_di"
9472   [(set (pc)
9473         (mem:DI (plus:DI (sign_extend:DI
9474                           (mult:SI (match_operand:SI 0 "register_operand" "d")
9475                                   (const_int 4)))
9476                          (label_ref (match_operand 1 "" "")))))
9477    (clobber (match_operand:DI 2 "register_operand" "=d"))
9478    (clobber (reg:DI 31))]
9479   "TARGET_EMBEDDED_PIC"
9480   "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9481 ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\;j\\t%2"
9482   [(set_attr "type"     "jump")
9483    (set_attr "mode"     "none")
9484    (set_attr "length"   "24")])
9486 ;; For o32/n32/n64, we save the gp in the jmp_buf as well.  While it is
9487 ;; possible to either pull it off the stack (in the o32 case) or recalculate
9488 ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9489 ;; this is easy.
9491 (define_expand "builtin_setjmp_setup"
9492   [(unspec [(match_operand 0 "register_operand" "r")] 20)]
9493   "TARGET_ABICALLS"
9494   "
9496   if (Pmode == DImode)
9497     emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9498   else
9499     emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9500   DONE;
9503 (define_expand "builtin_setjmp_setup_32"
9504   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9505                    (const_int 12)))
9506       (reg:SI 28))]
9507   "TARGET_ABICALLS && ! (Pmode == DImode)"
9508   "")
9510 (define_expand "builtin_setjmp_setup_64"
9511   [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9512                    (const_int 24)))
9513       (reg:DI 28))]
9514   "TARGET_ABICALLS && Pmode == DImode"
9515   "")
9517 ;; For o32/n32/n64, we need to arrange for longjmp to put the
9518 ;; target address in t9 so that we can use it for loading $gp.
9520 (define_expand "builtin_longjmp"
9521   [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
9522   "TARGET_ABICALLS"
9523   "
9525   /* The elements of the buffer are, in order:  */
9526   int W = (Pmode == DImode ? 8 : 4);
9527   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9528   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9529   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9530   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9531   rtx pv = gen_rtx_REG (Pmode, 25);
9532   rtx gp = gen_rtx_REG (Pmode, 28);
9534   /* This bit is the same as expand_builtin_longjmp.  */
9535   emit_move_insn (hard_frame_pointer_rtx, fp);
9536   emit_move_insn (pv, lab);
9537   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9538   emit_move_insn (gp, gpv);
9539   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9540   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9541   emit_insn (gen_rtx_USE (VOIDmode, gp));
9542   emit_indirect_jump (pv);
9543   DONE;
9547 ;;  ....................
9549 ;;      Function prologue/epilogue
9551 ;;  ....................
9554 (define_expand "prologue"
9555   [(const_int 1)]
9556   ""
9557   "
9559   if (mips_isa >= 0)            /* avoid unused code warnings */
9560     {
9561       mips_expand_prologue ();
9562       DONE;
9563     }
9566 ;; Block any insns from being moved before this point, since the
9567 ;; profiling call to mcount can use various registers that aren't
9568 ;; saved or used to pass arguments.
9570 (define_insn "blockage"
9571   [(unspec_volatile [(const_int 0)] 0)]
9572   ""
9573   ""
9574   [(set_attr "type"     "unknown")
9575    (set_attr "mode"     "none")
9576    (set_attr "length"   "0")])
9578 (define_expand "epilogue"
9579   [(const_int 2)]
9580   ""
9581   "
9583   if (mips_isa >= 0)            /* avoid unused code warnings */
9584     {
9585       mips_expand_epilogue ();
9586       DONE;
9587     }
9590 ;; Trivial return.  Make it look like a normal return insn as that
9591 ;; allows jump optimizations to work better .
9592 (define_insn "return"
9593   [(return)]
9594   "mips_can_use_return_insn ()"
9595   "%*j\\t$31"
9596   [(set_attr "type"     "jump")
9597    (set_attr "mode"     "none")])
9599 ;; Normal return.
9601 (define_insn "return_internal"
9602   [(use (match_operand 0 "pmode_register_operand" ""))
9603    (return)]
9604   ""
9605   "*
9607   return \"%*j\\t%0\";
9609   [(set_attr "type"     "jump")
9610    (set_attr "mode"     "none")])
9612 ;; When generating embedded PIC code we need to get the address of the
9613 ;; current function.  This specialized instruction does just that.
9615 (define_insn "get_fnaddr"
9616   [(set (match_operand 0 "register_operand" "=d")
9617         (unspec [(match_operand 1 "" "")] 1))
9618    (clobber (reg:SI 31))]
9619   "TARGET_EMBEDDED_PIC
9620    && GET_CODE (operands[1]) == SYMBOL_REF"
9621   "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
9622   [(set_attr "type"     "call")
9623    (set_attr "mode"     "none")
9624    (set_attr "length"   "16")])
9626 ;; This is used in compiling the unwind routines.
9627 (define_expand "eh_return"
9628   [(use (match_operand 0 "general_operand" ""))
9629    (use (match_operand 1 "general_operand" ""))]
9630   ""
9631   "
9633   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
9635   if (GET_MODE (operands[1]) != gpr_mode)
9636     operands[1] = convert_to_mode (gpr_mode, operands[1], 0);
9637   if (TARGET_64BIT)
9638     emit_insn (gen_eh_set_lr_di (operands[1]));
9639   else
9640     emit_insn (gen_eh_set_lr_si (operands[1]));
9642   emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]);
9643   DONE;
9646 ;; Clobber the return address on the stack.  We can't expand this
9647 ;; until we know where it will be put in the stack frame.
9649 (define_insn "eh_set_lr_si"
9650   [(unspec [(match_operand:SI 0 "register_operand" "r")] 3)
9651    (clobber (match_scratch:SI 1 "=&r"))]
9652   "! TARGET_64BIT"
9653   "#")
9655 (define_insn "eh_set_lr_di"
9656   [(unspec [(match_operand:DI 0 "register_operand" "r")] 3)
9657    (clobber (match_scratch:DI 1 "=&r"))]
9658   "TARGET_64BIT"
9659   "#")
9661 (define_split
9662   [(unspec [(match_operand 0 "register_operand" "")] 3)
9663    (clobber (match_scratch 1 ""))]
9664   "reload_completed && !TARGET_DEBUG_D_MODE"
9665   [(const_int 0)]
9666   "
9668   HOST_WIDE_INT gp_offset;
9669   rtx base;
9671   compute_frame_size (get_frame_size ());
9672   if (((current_frame_info.mask >> 31) & 1) == 0)
9673     abort ();
9674   gp_offset = current_frame_info.gp_sp_offset;
9676   if (gp_offset < 32768)
9677     base = stack_pointer_rtx;
9678   else
9679     {
9680       base = operands[1];
9681       emit_move_insn (base, GEN_INT (gp_offset));
9682       if (Pmode == DImode)
9683         emit_insn (gen_adddi3 (base, base, stack_pointer_rtx));
9684       else
9685         emit_insn (gen_addsi3 (base, base, stack_pointer_rtx));
9686       gp_offset = 0;
9687     }
9688   emit_move_insn (gen_rtx_MEM (GET_MODE (operands[0]),
9689                                plus_constant (base, gp_offset)),
9690                   operands[0]);
9691   DONE;
9694 (define_insn "exception_receiver"
9695   [(unspec_volatile [(const_int 0)] 4)]
9696   "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
9697   "*
9699   rtx loc;
9701   operands[0] = pic_offset_table_rtx;
9702   if (frame_pointer_needed)
9703     loc = hard_frame_pointer_rtx;
9704   else
9705     loc = stack_pointer_rtx;
9706   loc = plus_constant (loc, current_frame_info.args_size);
9707   operands[1] = gen_rtx_MEM (Pmode, loc);
9709   return mips_move_1word (operands, insn, 0);
9711   [(set_attr "type"   "load")
9712    (set_attr "length" "8")])
9715 ;;  ....................
9717 ;;      FUNCTION CALLS
9719 ;;  ....................
9721 ;; calls.c now passes a third argument, make saber happy
9723 (define_expand "call"
9724   [(parallel [(call (match_operand 0 "memory_operand" "m")
9725                     (match_operand 1 "" "i"))
9726               (clobber (reg:SI 31))
9727               (use (match_operand 2 "" ""))             ;; next_arg_reg
9728               (use (match_operand 3 "" ""))])]          ;; struct_value_size_rtx
9729   ""
9730   "
9732   rtx addr;
9734   if (operands[0])              /* eliminate unused code warnings */
9735     {
9736       addr = XEXP (operands[0], 0);
9737       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9738           || ! call_insn_operand (addr, VOIDmode))
9739         XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
9741       /* In order to pass small structures by value in registers
9742          compatibly with the MIPS compiler, we need to shift the value
9743          into the high part of the register.  Function_arg has encoded
9744          a PARALLEL rtx, holding a vector of adjustments to be made
9745          as the next_arg_reg variable, so we split up the insns,
9746          and emit them separately.  */
9748       if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
9749         {
9750           rtvec adjust = XVEC (operands[2], 0);
9751           int num = GET_NUM_ELEM (adjust);
9752           int i;
9754           for (i = 0; i < num; i++)
9755             emit_insn (RTVEC_ELT (adjust, i));
9756         }
9758       if (TARGET_MIPS16
9759           && mips16_hard_float
9760           && operands[2] != 0
9761           && (int) GET_MODE (operands[2]) != 0)
9762         {
9763           if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
9764                                       (int) GET_MODE (operands[2])))
9765             DONE;
9766         }
9768       emit_call_insn (gen_call_internal0 (operands[0], operands[1],
9769                                           gen_rtx_REG (SImode,
9770                                                        GP_REG_FIRST + 31)));
9771       DONE;
9772     }
9775 (define_expand "call_internal0"
9776   [(parallel [(call (match_operand 0 "" "")
9777                     (match_operand 1 "" ""))
9778               (clobber (match_operand:SI 2 "" ""))])]
9779   ""
9780   "")
9782 ;; We need to recognize reg:SI 31 specially for the mips16, because we
9783 ;; don't have a constraint letter for it.
9785 (define_insn ""
9786   [(call (mem (match_operand 0 "call_insn_operand" "ei"))
9787          (match_operand 1 "" "i"))
9788    (clobber (match_operand:SI 2 "register_operand" "=y"))]
9789   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9790    && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9791   "%*jal\\t%0"
9792   [(set_attr "type"     "call")
9793    (set_attr "mode"     "none")
9794    (set_attr "length"   "8")])
9796 (define_insn "call_internal1"
9797   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9798          (match_operand 1 "" "i"))
9799    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9800   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9801   "*
9803   register rtx target = operands[0];
9805   if (GET_CODE (target) == CONST_INT)
9806     return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
9807   else if (CONSTANT_ADDRESS_P (target))
9808     return \"%*jal\\t%0\";
9809   else
9810     return \"%*jal\\t%2,%0\";
9812   [(set_attr "type"     "call")
9813    (set_attr "mode"     "none")])
9815 (define_insn "call_internal2"
9816   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9817          (match_operand 1 "" "i"))
9818    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9819   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9820   "*
9822   register rtx target = operands[0];
9824   if (GET_CODE (target) == CONST_INT)
9825     return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
9826   else if (CONSTANT_ADDRESS_P (target))
9827     {
9828       if (GET_MODE (target) == SImode)
9829         return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
9830       else
9831         return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
9832     }
9833   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9834     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9835   else
9836     return \"jal\\t%2,%0\";
9838   [(set_attr "type"     "call")
9839    (set_attr "mode"     "none")
9840    (set_attr "length"   "8")])
9842 (define_insn "call_internal3a"
9843   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9844          (match_operand 1 "" "i"))
9845    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9846   "!TARGET_MIPS16
9847    && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9848   "%*jal\\t%2,%0"
9849   [(set_attr "type"     "call")
9850    (set_attr "mode"     "none")])
9852 (define_insn "call_internal3b"
9853   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9854          (match_operand 1 "" "i"))
9855    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9856   "!TARGET_MIPS16
9857    && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9858   "%*jal\\t%2,%0"
9859   [(set_attr "type"     "call")
9860    (set_attr "mode"     "none")
9861    (set_attr "length"   "1")])
9863 (define_insn "call_internal3c"
9864   [(call (mem:SI (match_operand:SI 0 "register_operand" "e"))
9865          (match_operand 1 "" "i"))
9866    (clobber (match_operand:SI 2 "register_operand" "=y"))]
9867   "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
9868    && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9869   "%*jal\\t%2,%0"
9870   [(set_attr "type"     "call")
9871    (set_attr "mode"     "none")])
9873 (define_insn "call_internal4a"
9874   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9875          (match_operand 1 "" "i"))
9876    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9877   "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
9878   "*
9880   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9881     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9882   else
9883     return \"jal\\t%2,%0\";
9885   [(set_attr "type"     "call")
9886    (set_attr "mode"     "none")
9887    (set_attr "length"   "8")])
9889 (define_insn "call_internal4b"
9890   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9891          (match_operand 1 "" "i"))
9892    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9893   "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
9894   "*
9896   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9897     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9898   else
9899     return \"jal\\t%2,%0\";
9901   [(set_attr "type"     "call")
9902    (set_attr "mode"     "none")
9903    (set_attr "length"   "8")])
9905 ;; calls.c now passes a fourth argument, make saber happy
9907 (define_expand "call_value"
9908   [(parallel [(set (match_operand 0 "register_operand" "=df")
9909                    (call (match_operand 1 "memory_operand" "m")
9910                          (match_operand 2 "" "i")))
9911               (clobber (reg:SI 31))
9912               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
9913   ""
9914   "
9916   rtx addr;
9918   if (operands[0])              /* eliminate unused code warning */
9919     {
9920       addr = XEXP (operands[1], 0);
9921       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9922           || ! call_insn_operand (addr, VOIDmode))
9923         XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
9925       /* In order to pass small structures by value in registers
9926          compatibly with the MIPS compiler, we need to shift the value
9927          into the high part of the register.  Function_arg has encoded
9928          a PARALLEL rtx, holding a vector of adjustments to be made
9929          as the next_arg_reg variable, so we split up the insns,
9930          and emit them separately.  */
9932       if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
9933         {
9934           rtvec adjust = XVEC (operands[3], 0);
9935           int num = GET_NUM_ELEM (adjust);
9936           int i;
9938           for (i = 0; i < num; i++)
9939             emit_insn (RTVEC_ELT (adjust, i));
9940         }
9942       if (TARGET_MIPS16
9943           && mips16_hard_float
9944           && ((operands[3] != 0
9945                && (int) GET_MODE (operands[3]) != 0)
9946               || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
9947         {
9948           if (build_mips16_call_stub (operands[0], operands[1], operands[2],
9949                                       (operands[3] == 0 ? 0
9950                                        : (int) GET_MODE (operands[3]))))
9951             DONE;
9952         }
9954       /* Handle Irix6 function calls that have multiple non-contiguous
9955          results.  */
9956       if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
9957         {
9958           emit_call_insn (gen_call_value_multiple_internal0
9959                           (XEXP (XVECEXP (operands[0], 0, 0), 0),
9960                            operands[1], operands[2],
9961                            XEXP (XVECEXP (operands[0], 0, 1), 0),
9962                            gen_rtx_REG (SImode, GP_REG_FIRST + 31)));
9963           DONE;
9964         }
9966       /* We have a call returning a DImode structure in an FP reg.
9967          Strip off the now unnecessary PARALLEL.  */
9968       if (GET_CODE (operands[0]) == PARALLEL)
9969         operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
9971       emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
9972                                                 gen_rtx_REG (SImode,
9973                                                              GP_REG_FIRST + 31)));
9975       DONE;
9976     }
9979 (define_expand "call_value_internal0"
9980   [(parallel [(set (match_operand 0 "" "")
9981                    (call (match_operand 1 "" "")
9982                          (match_operand 2 "" "")))
9983               (clobber (match_operand:SI 3 "" ""))])]
9984   ""
9985   "")
9987 ;; Recognize $31 specially on the mips16, because we don't have a
9988 ;; constraint letter for it.
9990 (define_insn ""
9991   [(set (match_operand 0 "register_operand" "=d")
9992         (call (mem (match_operand 1 "call_insn_operand" "ei"))
9993               (match_operand 2 "" "i")))
9994    (clobber (match_operand:SI 3 "register_operand" "=y"))]
9995   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9996    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
9997   "%*jal\\t%1"
9998   [(set_attr "type"     "call")
9999    (set_attr "mode"     "none")
10000    (set_attr "length"   "8")])
10002 (define_insn "call_value_internal1"
10003   [(set (match_operand 0 "register_operand" "=df")
10004         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10005               (match_operand 2 "" "i")))
10006    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10007   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10008   "*
10010   register rtx target = operands[1];
10012   if (GET_CODE (target) == CONST_INT)
10013     return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
10014   else if (CONSTANT_ADDRESS_P (target))
10015     return \"%*jal\\t%1\";
10016   else
10017     return \"%*jal\\t%3,%1\";
10019   [(set_attr "type"     "call")
10020    (set_attr "mode"     "none")])
10022 (define_insn "call_value_internal2"
10023   [(set (match_operand 0 "register_operand" "=df")
10024         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10025               (match_operand 2 "" "i")))
10026    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10027   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10028   "*
10030   register rtx target = operands[1];
10032   if (GET_CODE (target) == CONST_INT)
10033     return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
10034   else if (CONSTANT_ADDRESS_P (target))
10035     {
10036       if (GET_MODE (target) == SImode)
10037         return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
10038       else
10039         return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
10040     }
10041   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10042     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10043   else
10044     return \"jal\\t%3,%1\";
10046   [(set_attr "type"     "call")
10047    (set_attr "mode"     "none")
10048    (set_attr "length"   "8")])
10050 (define_insn "call_value_internal3a"
10051   [(set (match_operand 0 "register_operand" "=df")
10052         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10053               (match_operand 2 "" "i")))
10054    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10055   "!TARGET_MIPS16
10056    && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10057   "%*jal\\t%3,%1"
10058   [(set_attr "type"     "call")
10059    (set_attr "mode"     "none")])
10061 (define_insn "call_value_internal3b"
10062   [(set (match_operand 0 "register_operand" "=df")
10063         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10064               (match_operand 2 "" "i")))
10065    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10066   "!TARGET_MIPS16
10067    && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10068   "%*jal\\t%3,%1"
10069   [(set_attr "type"     "call")
10070    (set_attr "mode"     "none")])
10072 (define_insn "call_value_internal3c"
10073   [(set (match_operand 0 "register_operand" "=df")
10074         (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
10075               (match_operand 2 "" "i")))
10076    (clobber (match_operand:SI 3 "register_operand" "=y"))]
10077   "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
10078    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10079   "%*jal\\t%3,%1"
10080   [(set_attr "type"     "call")
10081    (set_attr "mode"     "none")])
10083 (define_insn "call_value_internal4a"
10084   [(set (match_operand 0 "register_operand" "=df")
10085         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10086               (match_operand 2 "" "i")))
10087    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10088   "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
10089   "*
10091   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10092     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10093   else
10094     return \"jal\\t%3,%1\";
10096   [(set_attr "type"     "call")
10097    (set_attr "mode"     "none")
10098    (set_attr "length"   "8")])
10100 (define_insn "call_value_internal4b"
10101   [(set (match_operand 0 "register_operand" "=df")
10102         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10103               (match_operand 2 "" "i")))
10104    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10105   "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
10106   "*
10108   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10109     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10110   else
10111     return \"jal\\t%3,%1\";
10113   [(set_attr "type"     "call")
10114    (set_attr "mode"     "none")
10115    (set_attr "length"   "8")])
10117 (define_expand "call_value_multiple_internal0"
10118   [(parallel [(set (match_operand 0 "" "")
10119                    (call (match_operand 1 "" "")
10120                          (match_operand 2 "" "")))
10121               (set (match_operand 3 "" "")
10122                    (call (match_dup 1)
10123                          (match_dup 2)))
10124               (clobber (match_operand:SI 4 "" ""))])]
10125   ""
10126   "")
10128 ;; ??? May eventually need all 6 versions of the call patterns with multiple
10129 ;; return values.
10131 (define_insn "call_value_multiple_internal1"
10132   [(set (match_operand 0 "register_operand" "=df")
10133         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10134               (match_operand 2 "" "i")))
10135    (set (match_operand 3 "register_operand" "=df")
10136         (call (mem (match_dup 1))
10137               (match_dup 2)))
10138   (clobber (match_operand:SI 4 "register_operand" "=d"))]
10139   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10140   "*
10142   register rtx target = operands[1];
10144   if (GET_CODE (target) == CONST_INT)
10145     return \"%[li\\t%@,%1\\n\\t%*jal\\t%4,%@%]\";
10146   else if (CONSTANT_ADDRESS_P (target))
10147     return \"%*jal\\t%1\";
10148   else
10149     return \"%*jal\\t%4,%1\";
10151   [(set_attr "type"     "call")
10152    (set_attr "mode"     "none")])
10154 (define_insn "call_value_multiple_internal2"
10155   [(set (match_operand 0 "register_operand" "=df")
10156         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10157               (match_operand 2 "" "i")))
10158    (set (match_operand 3 "register_operand" "=df")
10159         (call (mem (match_dup 1))
10160               (match_dup 2)))
10161    (clobber (match_operand:SI 4 "register_operand" "=d"))]
10162   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10163   "*
10165   register rtx target = operands[1];
10167   if (GET_CODE (target) == CONST_INT)
10168     return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
10169   else if (CONSTANT_ADDRESS_P (target))
10170     {
10171       if (GET_MODE (target) == SImode)
10172         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10173       else
10174         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10175     }
10176   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10177     return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
10178   else
10179     return \"jal\\t%4,%1\";
10181   [(set_attr "type"     "call")
10182    (set_attr "mode"     "none")
10183    (set_attr "length"   "8")])
10186 ;; Call subroutine returning any type.
10188 (define_expand "untyped_call"
10189   [(parallel [(call (match_operand 0 "" "")
10190                     (const_int 0))
10191               (match_operand 1 "" "")
10192               (match_operand 2 "" "")])]
10193   ""
10194   "
10196   if (operands[0])              /* silence statement not reached warnings */
10197     {
10198       int i;
10200       emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
10202       for (i = 0; i < XVECLEN (operands[2], 0); i++)
10203         {
10204           rtx set = XVECEXP (operands[2], 0, i);
10205           emit_move_insn (SET_DEST (set), SET_SRC (set));
10206         }
10208       emit_insn (gen_blockage ());
10209       DONE;
10210     }
10214 ;;  ....................
10216 ;;      MISC.
10218 ;;  ....................
10221 (define_insn "nop"
10222   [(const_int 0)]
10223   ""
10224   "%(nop%)"
10225   [(set_attr "type"     "nop")
10226    (set_attr "mode"     "none")])
10228 ;; The MIPS chip does not seem to require stack probes.
10230 ;; (define_expand "probe"
10231 ;;   [(set (match_dup 0)
10232 ;;      (match_dup 1))]
10233 ;;   ""
10234 ;;   "
10235 ;; {
10236 ;;   operands[0] = gen_reg_rtx (SImode);
10237 ;;   operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
10238 ;;   MEM_VOLATILE_P (operands[1]) = TRUE;
10240 ;;   /* fall through and generate default code */
10241 ;; }")
10245 ;; MIPS4 Conditional move instructions.
10247 (define_insn ""
10248   [(set (match_operand:SI 0 "register_operand" "=d,d")
10249         (if_then_else:SI
10250          (match_operator 4 "equality_op"
10251                          [(match_operand:SI 1 "register_operand" "d,d")
10252                           (const_int 0)])
10253          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10254          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10255   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10256   "@
10257     mov%B4\\t%0,%z2,%1
10258     mov%b4\\t%0,%z3,%1"
10259   [(set_attr "type" "move")
10260    (set_attr "mode" "SI")])
10262 (define_insn ""
10263   [(set (match_operand:SI 0 "register_operand" "=d,d")
10264         (if_then_else:SI
10265          (match_operator 4 "equality_op"
10266                          [(match_operand:DI 1 "se_register_operand" "d,d")
10267                           (const_int 0)])
10268          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10269          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10270   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10271   "@
10272     mov%B4\\t%0,%z2,%1
10273     mov%b4\\t%0,%z3,%1"
10274   [(set_attr "type" "move")
10275    (set_attr "mode" "SI")])
10277 (define_insn ""
10278   [(set (match_operand:SI 0 "register_operand" "=d,d")
10279         (if_then_else:SI
10280          (match_operator 3 "equality_op" [(match_operand:CC 4
10281                                                             "register_operand"
10282                                                             "z,z")
10283                                           (const_int 0)])
10284          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
10285          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
10286   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10287   "@
10288     mov%T3\\t%0,%z1,%4
10289     mov%t3\\t%0,%z2,%4"
10290   [(set_attr "type" "move")
10291    (set_attr "mode" "SI")])
10293 (define_insn ""
10294   [(set (match_operand:DI 0 "register_operand" "=d,d")
10295         (if_then_else:DI
10296          (match_operator 4 "equality_op"
10297                          [(match_operand:SI 1 "register_operand" "d,d")
10298                           (const_int 0)])
10299          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10300          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10301   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10302   "@
10303     mov%B4\\t%0,%z2,%1
10304     mov%b4\\t%0,%z3,%1"
10305   [(set_attr "type" "move")
10306    (set_attr "mode" "DI")])
10308 (define_insn ""
10309   [(set (match_operand:DI 0 "register_operand" "=d,d")
10310         (if_then_else:DI
10311          (match_operator 4 "equality_op"
10312                          [(match_operand:DI 1 "se_register_operand" "d,d")
10313                           (const_int 0)])
10314          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10315          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10316   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10317   "@
10318     mov%B4\\t%0,%z2,%1
10319     mov%b4\\t%0,%z3,%1"
10320   [(set_attr "type" "move")
10321    (set_attr "mode" "DI")])
10323 (define_insn ""
10324   [(set (match_operand:DI 0 "register_operand" "=d,d")
10325         (if_then_else:DI
10326          (match_operator 3 "equality_op" [(match_operand:CC 4
10327                                                             "register_operand"
10328                                                             "z,z")
10329                                           (const_int 0)])
10330          (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
10331          (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
10332   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
10333   "@
10334     mov%T3\\t%0,%z1,%4
10335     mov%t3\\t%0,%z2,%4"
10336   [(set_attr "type" "move")
10337    (set_attr "mode" "DI")])
10339 (define_insn ""
10340   [(set (match_operand:SF 0 "register_operand" "=f,f")
10341         (if_then_else:SF
10342          (match_operator 4 "equality_op"
10343                          [(match_operand:SI 1 "register_operand" "d,d")
10344                           (const_int 0)])
10345          (match_operand:SF 2 "register_operand" "f,0")
10346          (match_operand:SF 3 "register_operand" "0,f")))]
10347   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10348   "@
10349     mov%B4.s\\t%0,%2,%1
10350     mov%b4.s\\t%0,%3,%1"
10351   [(set_attr "type" "move")
10352    (set_attr "mode" "SF")])
10354 (define_insn ""
10355   [(set (match_operand:SF 0 "register_operand" "=f,f")
10356         (if_then_else:SF
10357          (match_operator 4 "equality_op"
10358                          [(match_operand:DI 1 "se_register_operand" "d,d")
10359                           (const_int 0)])
10360          (match_operand:SF 2 "register_operand" "f,0")
10361          (match_operand:SF 3 "register_operand" "0,f")))]
10362   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10363   "@
10364     mov%B4.s\\t%0,%2,%1
10365     mov%b4.s\\t%0,%3,%1"
10366   [(set_attr "type" "move")
10367    (set_attr "mode" "SF")])
10369 (define_insn ""
10370   [(set (match_operand:SF 0 "register_operand" "=f,f")
10371         (if_then_else:SF
10372          (match_operator 3 "equality_op" [(match_operand:CC 4
10373                                                             "register_operand"
10374                                                             "z,z")
10375                                           (const_int 0)])
10376          (match_operand:SF 1 "register_operand" "f,0")
10377          (match_operand:SF 2 "register_operand" "0,f")))]
10378   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10379   "@
10380     mov%T3.s\\t%0,%1,%4
10381     mov%t3.s\\t%0,%2,%4"
10382   [(set_attr "type" "move")
10383    (set_attr "mode" "SF")])
10385 (define_insn ""
10386   [(set (match_operand:DF 0 "register_operand" "=f,f")
10387         (if_then_else:DF
10388          (match_operator 4 "equality_op"
10389                          [(match_operand:SI 1 "register_operand" "d,d")
10390                           (const_int 0)])
10391          (match_operand:DF 2 "register_operand" "f,0")
10392          (match_operand:DF 3 "register_operand" "0,f")))]
10393   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10394   "@
10395     mov%B4.d\\t%0,%2,%1
10396     mov%b4.d\\t%0,%3,%1"
10397   [(set_attr "type" "move")
10398    (set_attr "mode" "DF")])
10400 (define_insn ""
10401   [(set (match_operand:DF 0 "register_operand" "=f,f")
10402         (if_then_else:DF
10403          (match_operator 4 "equality_op"
10404                          [(match_operand:DI 1 "se_register_operand" "d,d")
10405                           (const_int 0)])
10406          (match_operand:DF 2 "register_operand" "f,0")
10407          (match_operand:DF 3 "register_operand" "0,f")))]
10408   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10409   "@
10410     mov%B4.d\\t%0,%2,%1
10411     mov%b4.d\\t%0,%3,%1"
10412   [(set_attr "type" "move")
10413    (set_attr "mode" "DF")])
10415 (define_insn ""
10416   [(set (match_operand:DF 0 "register_operand" "=f,f")
10417         (if_then_else:DF
10418          (match_operator 3 "equality_op" [(match_operand:CC 4
10419                                                             "register_operand"
10420                                                             "z,z")
10421                                           (const_int 0)])
10422          (match_operand:DF 1 "register_operand" "f,0")
10423          (match_operand:DF 2 "register_operand" "0,f")))]
10424   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10425   "@
10426     mov%T3.d\\t%0,%1,%4
10427     mov%t3.d\\t%0,%2,%4"
10428   [(set_attr "type" "move")
10429    (set_attr "mode" "DF")])
10431 ;; These are the main define_expand's used to make conditional moves.
10433 (define_expand "movsicc"
10434   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10435    (set (match_operand:SI 0 "register_operand" "")
10436         (if_then_else:SI (match_dup 5)
10437                          (match_operand:SI 2 "reg_or_0_operand" "")
10438                          (match_operand:SI 3 "reg_or_0_operand" "")))]
10439   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10440   "
10442   gen_conditional_move (operands);
10443   DONE;
10446 (define_expand "movdicc"
10447   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10448    (set (match_operand:DI 0 "register_operand" "")
10449         (if_then_else:DI (match_dup 5)
10450                          (match_operand:DI 2 "se_reg_or_0_operand" "")
10451                          (match_operand:DI 3 "se_reg_or_0_operand" "")))]
10452   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10453   "
10455   if (mips_isa == 32)
10456     FAIL;
10457   gen_conditional_move (operands);
10458   DONE;
10461 (define_expand "movsfcc"
10462   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10463    (set (match_operand:SF 0 "register_operand" "")
10464         (if_then_else:SF (match_dup 5)
10465                          (match_operand:SF 2 "register_operand" "")
10466                          (match_operand:SF 3 "register_operand" "")))]
10467   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10468   "
10470   gen_conditional_move (operands);
10471   DONE;
10474 (define_expand "movdfcc"
10475   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10476    (set (match_operand:DF 0 "register_operand" "")
10477         (if_then_else:DF (match_dup 5)
10478                          (match_operand:DF 2 "register_operand" "")
10479                          (match_operand:DF 3 "register_operand" "")))]
10480   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10481   "
10483   gen_conditional_move (operands);
10484   DONE;
10488 ;;  ....................
10490 ;;      mips16 inline constant tables
10492 ;;  ....................
10495 (define_insn "consttable_qi"
10496   [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")] 10)]
10497   "TARGET_MIPS16"
10498   "*
10500   assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
10501   return \"\";
10503   [(set_attr "type"     "unknown")
10504    (set_attr "mode"     "QI")
10505    (set_attr "length"   "8")])
10507 (define_insn "consttable_hi"
10508   [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")] 11)]
10509   "TARGET_MIPS16"
10510   "*
10512   assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10513   return \"\";
10515   [(set_attr "type"     "unknown")
10516    (set_attr "mode"     "HI")
10517    (set_attr "length"   "8")])
10519 (define_insn "consttable_si"
10520   [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")] 12)]
10521   "TARGET_MIPS16"
10522   "*
10524   assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10525   return \"\";
10527   [(set_attr "type"     "unknown")
10528    (set_attr "mode"     "SI")
10529    (set_attr "length"   "8")])
10531 (define_insn "consttable_di"
10532   [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")] 13)]
10533   "TARGET_MIPS16"
10534   "*
10536   assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10537   return \"\";
10539   [(set_attr "type"     "unknown")
10540    (set_attr "mode"     "DI")
10541    (set_attr "length"   "16")])
10543 (define_insn "consttable_sf"
10544   [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")] 14)]
10545   "TARGET_MIPS16"
10546   "*
10548   union real_extract u;
10550   if (GET_CODE (operands[0]) != CONST_DOUBLE)
10551     abort ();
10552   memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
10553   assemble_real (u.d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10554   return \"\";
10556   [(set_attr "type"     "unknown")
10557    (set_attr "mode"     "SF")
10558    (set_attr "length"   "8")])
10560 (define_insn "consttable_df"
10561   [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")] 15)]
10562   "TARGET_MIPS16"
10563   "*
10565   union real_extract u;
10567   if (GET_CODE (operands[0]) != CONST_DOUBLE)
10568     abort ();
10569   memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
10570   assemble_real (u.d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10571   return \"\";
10573   [(set_attr "type"     "unknown")
10574    (set_attr "mode"     "DF")
10575    (set_attr "length"   "16")])
10577 (define_insn "align_2"
10578   [(unspec_volatile [(const_int 0)] 16)]
10579   "TARGET_MIPS16"
10580   ".align 1"
10581   [(set_attr "type"     "unknown")
10582    (set_attr "mode"     "HI")
10583    (set_attr "length"   "8")])
10585 (define_insn "align_4"
10586   [(unspec_volatile [(const_int 0)] 17)]
10587   "TARGET_MIPS16"
10588   ".align 2"
10589   [(set_attr "type"     "unknown")
10590    (set_attr "mode"     "SI")
10591    (set_attr "length"   "8")])
10593 (define_insn "align_8"
10594   [(unspec_volatile [(const_int 0)] 18)]
10595   "TARGET_MIPS16"
10596   ".align 3"
10597   [(set_attr "type"     "unknown")
10598    (set_attr "mode"     "DI")
10599    (set_attr "length"   "12")])
10602 ;;  ....................
10604 ;;      mips16 peepholes
10606 ;;  ....................
10609 ;; On the mips16, reload will sometimes decide that a pseudo register
10610 ;; should go into $24, and then later on have to reload that register.
10611 ;; When that happens, we get a load of a general register followed by
10612 ;; a move from the general register to $24 followed by a branch.
10613 ;; These peepholes catch the common case, and fix it to just use the
10614 ;; general register for the branch.
10616 (define_peephole
10617   [(set (match_operand:SI 0 "register_operand" "=t")
10618         (match_operand:SI 1 "register_operand" "d"))
10619    (set (pc)
10620         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10621                                                           (const_int 0)])
10622                       (match_operand 3 "pc_or_label_operand" "")
10623                       (match_operand 4 "pc_or_label_operand" "")))]
10624   "TARGET_MIPS16
10625    && GET_CODE (operands[0]) == REG
10626    && REGNO (operands[0]) == 24
10627    && dead_or_set_p (insn, operands[0])
10628    && GET_CODE (operands[1]) == REG
10629    && M16_REG_P (REGNO (operands[1]))"
10630   "*
10632   if (operands[3] != pc_rtx)
10633     return \"%*b%C2z\\t%1,%3\";
10634   else
10635     return \"%*b%N2z\\t%1,%4\";
10637   [(set_attr "type"     "branch")
10638    (set_attr "mode"     "none")
10639    (set_attr "length"   "8")])
10641 (define_peephole
10642   [(set (match_operand:DI 0 "register_operand" "=t")
10643         (match_operand:DI 1 "register_operand" "d"))
10644    (set (pc)
10645         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10646                                                           (const_int 0)])
10647                       (match_operand 3 "pc_or_label_operand" "")
10648                       (match_operand 4 "pc_or_label_operand" "")))]
10649   "TARGET_MIPS16 && TARGET_64BIT
10650    && GET_CODE (operands[0]) == REG
10651    && REGNO (operands[0]) == 24
10652    && dead_or_set_p (insn, operands[0])
10653    && GET_CODE (operands[1]) == REG
10654    && M16_REG_P (REGNO (operands[1]))"
10655   "*
10657   if (operands[3] != pc_rtx)
10658     return \"%*b%C2z\\t%1,%3\";
10659   else
10660     return \"%*b%N2z\\t%1,%4\";
10662   [(set_attr "type"     "branch")
10663    (set_attr "mode"     "none")
10664    (set_attr "length"   "8")])
10666 ;; We can also have the reverse reload: reload will spill $24 into
10667 ;; another register, and then do a branch on that register when it
10668 ;; could have just stuck with $24.
10670 (define_peephole
10671   [(set (match_operand:SI 0 "register_operand" "=d")
10672         (match_operand:SI 1 "register_operand" "t"))
10673    (set (pc)
10674         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10675                                                           (const_int 0)])
10676                       (match_operand 3 "pc_or_label_operand" "")
10677                       (match_operand 4 "pc_or_label_operand" "")))]
10678   "TARGET_MIPS16
10679    && GET_CODE (operands[1]) == REG
10680    && REGNO (operands[1]) == 24
10681    && GET_CODE (operands[0]) == REG
10682    && M16_REG_P (REGNO (operands[0]))
10683    && dead_or_set_p (insn, operands[0])"
10684   "*
10686   if (operands[3] != pc_rtx)
10687     return \"%*bt%C2z\\t%3\";
10688   else
10689     return \"%*bt%N2z\\t%4\";
10691   [(set_attr "type"     "branch")
10692    (set_attr "mode"     "none")
10693    (set_attr "length"   "8")])
10695 (define_peephole
10696   [(set (match_operand:DI 0 "register_operand" "=d")
10697         (match_operand:DI 1 "register_operand" "t"))
10698    (set (pc)
10699         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10700                                                           (const_int 0)])
10701                       (match_operand 3 "pc_or_label_operand" "")
10702                       (match_operand 4 "pc_or_label_operand" "")))]
10703   "TARGET_MIPS16 && TARGET_64BIT
10704    && GET_CODE (operands[1]) == REG
10705    && REGNO (operands[1]) == 24
10706    && GET_CODE (operands[0]) == REG
10707    && M16_REG_P (REGNO (operands[0]))
10708    && dead_or_set_p (insn, operands[0])"
10709   "*
10711   if (operands[3] != pc_rtx)
10712     return \"%*bt%C2z\\t%3\";
10713   else
10714     return \"%*bt%N2z\\t%4\";
10716   [(set_attr "type"     "branch")
10717    (set_attr "mode"     "none")
10718    (set_attr "length"   "8")])
10720 ;; For the rare case where we need to load an address into a register
10721 ;; that can not be recognized by the normal movsi/addsi instructions.
10722 ;; I have no idea how many insns this can actually generate.  It should
10723 ;; be rare, so over-estimating as 10 instructions should not have any
10724 ;; real performance impact.
10725 (define_insn "leasi"
10726   [(set (match_operand:SI 0 "register_operand" "=d")
10727         (match_operand:SI 1 "address_operand" "p"))]
10728   "Pmode == SImode"
10729   "la %0,%a1"
10730   [(set_attr "type"     "arith")
10731    (set_attr "mode"     "SI")
10732    (set_attr "length"   "40")])
10734 ;; Similarly for targets where we have 64bit pointers.
10735 (define_insn "leadi"
10736   [(set (match_operand:DI 0 "register_operand" "=d")
10737         (match_operand:DI 1 "address_operand" "p"))]
10738   "Pmode == DImode"
10739   "la %0,%a1"
10740   [(set_attr "type"     "arith")
10741    (set_attr "mode"     "DI")
10742    (set_attr "length"   "40")])