2003-01-06 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / config / mips / mips.md
blob4ada75fde8eb122b576960ed48172731228b2c2a
1 ;;  Mips.md          Machine Description for MIPS based processors
2 ;;  Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 ;;  Contributed by   A. Lichnewsky, lich@inria.inria.fr
5 ;;  Changes by       Michael Meissner, meissner@osf.org
6 ;;  64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7 ;;  Brendan Eich, brendan@microunity.com.
9 ;; This file is part of GNU CC.
11 ;; GNU CC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
16 ;; GNU CC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU CC; see the file COPYING.  If not, write to
23 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
26 ;; ??? Currently does not have define_function_unit support for the R8000.
27 ;; Must include new entries for fmadd in addition to existing entries.
29 (define_constants
30   [(UNSPEC_ULW                   0)
31    (UNSPEC_USW                   1)
32    (UNSPEC_ULD                   2)
33    (UNSPEC_USD                   3)
34    (UNSPEC_GET_FNADDR            4)
35    (UNSPEC_HILO_DELAY            5)
36    (UNSPEC_BLOCKAGE              6)
37    (UNSPEC_LOADGP                7)
38    (UNSPEC_SETJMP                8)
39    (UNSPEC_LONGJMP               9)
40    (UNSPEC_EH_RECEIVER          10)
41    (UNSPEC_EH_RETURN            11)
42    (UNSPEC_CONSTTABLE_QI        12)
43    (UNSPEC_CONSTTABLE_HI        13)
44    (UNSPEC_CONSTTABLE_SI        14)
45    (UNSPEC_CONSTTABLE_DI        15)
46    (UNSPEC_CONSTTABLE_SF        16)
47    (UNSPEC_CONSTTABLE_DF        17)
48    (UNSPEC_ALIGN_2              18)
49    (UNSPEC_ALIGN_4              19)
50    (UNSPEC_ALIGN_8              20)])
53 ;; ....................
55 ;;      Attributes
57 ;; ....................
59 ;; Classification of each insn.
60 ;; branch       conditional branch
61 ;; jump         unconditional jump
62 ;; call         unconditional call
63 ;; load         load instruction(s)
64 ;; store        store instruction(s)
65 ;; move         data movement within same register set
66 ;; xfer         transfer to/from coprocessor
67 ;; hilo         transfer of hi/lo registers
68 ;; arith        integer arithmetic instruction
69 ;; darith       double precision integer arithmetic instructions
70 ;; imul         integer multiply
71 ;; imadd        integer multiply-add
72 ;; idiv         integer divide
73 ;; icmp         integer compare
74 ;; fadd         floating point add/subtract
75 ;; fmul         floating point multiply
76 ;; fmadd        floating point multiply-add
77 ;; fdiv         floating point divide
78 ;; fabs         floating point absolute value
79 ;; fneg         floating point negation
80 ;; fcmp         floating point compare
81 ;; fcvt         floating point convert
82 ;; fsqrt        floating point square root
83 ;; frsqrt       floating point reciprocal square root
84 ;; multi        multiword sequence (or user asm statements)
85 ;; nop          no operation
87 (define_attr "type"
88   "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
89   (const_string "unknown"))
91 ;; Main data type used by the insn
92 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
94 ;; Length (in # of bytes).  A conditional branch is allowed only to a
95 ;; location within a signed 18-bit offset of the delay slot.  If that
96 ;; provides too smal a range, we use the `j' instruction.  This
97 ;; instruction takes a 28-bit value, but that value is not an offset.
98 ;; Instead, it's bitwise-ored with the high-order four bits of the
99 ;; instruction in the delay slot, which means it cannot be used to
100 ;; cross a 256MB boundary.  We could fall back back on the jr,
101 ;; instruction which allows full access to the entire address space,
102 ;; but we do not do so at present.
104 (define_attr "length" ""
105    (cond [(eq_attr "type" "branch")
106           (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
107                      (const_int 131072))
108                  (const_int 4)
109                  (ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
110                      (const_int 0))
111                  (const_int 24)
112                  ] (const_int 12))
113           ] (const_int 4)))
115 ;; Attribute describing the processor.  This attribute must match exactly
116 ;; with the processor_type enumeration in mips.h.
118 ;; Attribute describing the processor
119 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
120 ;;   (const
121 ;;    (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000"))   (const_string "r3000")
122 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000"))   (const_string "r4000")
123 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000"))   (const_string "r6000")]
124 ;;          (const_string "default"))))
126 ;; ??? Fix everything that tests this attribute.
127 (define_attr "cpu"
128   "default,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4300,r4600,r4650,r5000,r5400,r5500,r8000,sr71000,r4kc,r5kc,r20kc"
129   (const (symbol_ref "mips_cpu_attr")))
131 ;; Does the instruction have a mandatory delay slot?
132 ;;   The 3900, is (mostly) mips1, but does not have a mandatory load delay
133 ;;   slot.
134 (define_attr "dslot" "no,yes"
135   (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp")
136                      (and (eq_attr "type" "load")
137                           (and (eq (symbol_ref "mips_isa") (const_int 1))
138                                (and (eq (symbol_ref "mips16") (const_int 0))
139                                     (eq_attr "cpu" "!r3900")))))
140                 (const_string "yes")
141                 (const_string "no")))
143 ;; Can the instruction be put into a delay slot?
144 (define_attr "can_delay" "no,yes"
145   (if_then_else (and (eq_attr "dslot" "no")
146                      ; ADJUST_INSN_LENGTH divides length by 2 on mips16,
147                      ; so cope with it here.
148                      (ior (and (eq (symbol_ref "mips16") (const_int 0))
149                                    (eq_attr "length" "4"))
150                           (and (ne (symbol_ref "mips16") (const_int 0))
151                                (eq_attr "length" "2"))))
152                 (const_string "yes")
153                 (const_string "no")))
155 ;; Attribute defining whether or not we can use the branch-likely instructions
157 (define_attr "branch_likely" "no,yes"
158   (const
159    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
160                  (const_string "yes")
161                  (const_string "no"))))
164 ;; Describe a user's asm statement.
165 (define_asm_attributes
166   [(set_attr "type" "multi")])
168 ;; whether or not generating calls to position independent functions
169 (define_attr "abicalls" "no,yes"
170   (const (symbol_ref "mips_abicalls_attr")))
174 ;; .........................
176 ;;      Delay slots, can't describe load/fcmp/xfer delay slots here
178 ;; .........................
180 (define_delay (and (eq_attr "type" "branch")
181                    (eq (symbol_ref "mips16") (const_int 0)))
182   [(eq_attr "can_delay" "yes")
183    (nil)
184    (and (eq_attr "branch_likely" "yes")
185         (and (eq_attr "dslot" "no")
186              (eq_attr "length" "4")))])
188 (define_delay (eq_attr "type" "jump")
189   [(eq_attr "can_delay" "yes")
190    (nil)
191    (nil)])
193 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
194   [(eq_attr "can_delay" "yes")
195    (nil)
196    (nil)])
200 ;; .........................
202 ;;      Functional units
204 ;; .........................
206 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
207 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
209 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
211 (define_function_unit "memory" 1 0
212   (and (eq_attr "type" "load")
213        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
214   3 0)
216 (define_function_unit "memory" 1 0
217   (and (eq_attr "type" "load")
218        (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
219   2 0)
221 (define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
223 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
225 (define_function_unit "imuldiv"  1 0
226   (eq_attr "type" "hilo")
227   1 3)
229 (define_function_unit "imuldiv"  1 0
230   (and (eq_attr "type" "imul,imadd")
231        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
232   17 17)
234 ;; On them mips16, we want to stronly discourage a mult from appearing
235 ;; after an mflo, since that requires explicit nop instructions.  We
236 ;; do this by pretending that mflo ties up the function unit for long
237 ;; enough that the scheduler will ignore load stalls and the like when
238 ;; selecting instructions to between the two instructions.
240 (define_function_unit "imuldiv" 1 0
241   (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
242   1 5)
244 (define_function_unit "imuldiv"  1 0
245   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r3000,r3900"))
246   12 12)
248 (define_function_unit "imuldiv"  1 0
249   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4000,r4600"))
250   10 10)
252 (define_function_unit "imuldiv"  1 0
253   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4650"))
254   4 4)
256 (define_function_unit "imuldiv"  1 0
257   (and (eq_attr "type" "imul,imadd")
258        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
259   1 1)
261 (define_function_unit "imuldiv"  1 0
262   (and (eq_attr "type" "imul,imadd")
263        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
264   4 4)
266 (define_function_unit "imuldiv"  1 0
267   (and (eq_attr "type" "imul,imadd")
268        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
269   5 5)
271 (define_function_unit "imuldiv"  1 0
272   (and (eq_attr "type" "imul,imadd")
273        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
274   8 8)
276 (define_function_unit "imuldiv"  1 0
277   (and (eq_attr "type" "imul,imadd")
278        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
279   9 9)
281 (define_function_unit "imuldiv"  1 0
282   (and (eq_attr "type" "idiv")
283        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
284   38 38)
286 (define_function_unit "imuldiv"  1 0
287   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
288   35 35)
290 (define_function_unit "imuldiv"  1 0
291   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
292   42 42)
294 (define_function_unit "imuldiv"  1 0
295   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
296   36 36)
298 (define_function_unit "imuldiv"  1 0
299   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
300   69 69)
302 (define_function_unit "imuldiv" 1 0
303   (and (eq_attr "type" "idiv")
304        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
305   35 35)
307 (define_function_unit "imuldiv" 1 0
308   (and (eq_attr "type" "idiv")
309        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
310   67 67)
312 (define_function_unit "imuldiv" 1 0
313   (and (eq_attr "type" "idiv")
314        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
315   37 37)
317 (define_function_unit "imuldiv" 1 0
318   (and (eq_attr "type" "idiv")
319        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
320   69 69)
322 (define_function_unit "imuldiv" 1 0
323   (and (eq_attr "type" "idiv")
324        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
325   36 36)
327 (define_function_unit "imuldiv" 1 0
328   (and (eq_attr "type" "idiv")
329        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
330   68 68)
332 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
333 ;; the FP hardware is part of the normal ALU circuitry.  This means FP
334 ;; instructions affect the pipe-line, and no functional unit
335 ;; parallelism can occur on R4300 processors.  To force GCC into coding
336 ;; for only a single functional unit, we force the R4300 FP
337 ;; instructions to be processed in the "imuldiv" unit.
339 (define_function_unit "adder" 1 1
340   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
341   3 0)
343 (define_function_unit "adder" 1 1
344   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
345   2 0)
347 (define_function_unit "adder" 1 1
348   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
349   1 0)
351 (define_function_unit "adder" 1 1
352   (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
353   4 0)
355 (define_function_unit "adder" 1 1
356   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
357   2 0)
359 (define_function_unit "adder" 1 1
360   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
361   3 0)
363 (define_function_unit "adder" 1 1
364   (and (eq_attr "type" "fabs,fneg")
365        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
366   2 0)
368 (define_function_unit "adder" 1 1
369   (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
370   1 0)
372 (define_function_unit "mult" 1 1
373   (and (eq_attr "type" "fmul")
374        (and (eq_attr "mode" "SF")
375             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
376   7 0)
378 (define_function_unit "mult" 1 1
379   (and (eq_attr "type" "fmul")
380        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
381   4 0)
383 (define_function_unit "mult" 1 1
384   (and (eq_attr "type" "fmul")
385        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
386   5 0)
388 (define_function_unit "mult" 1 1
389   (and (eq_attr "type" "fmul")
390        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
391   8 0)
393 (define_function_unit "mult" 1 1
394   (and (eq_attr "type" "fmul")
395        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
396   8 0)
398 (define_function_unit "mult" 1 1
399   (and (eq_attr "type" "fmul")
400        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
401   5 0)
403 (define_function_unit "mult" 1 1
404   (and (eq_attr "type" "fmul")
405        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
406   6 0)
408 (define_function_unit "divide" 1 1
409   (and (eq_attr "type" "fdiv")
410        (and (eq_attr "mode" "SF")
411             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
412   23 0)
414 (define_function_unit "divide" 1 1
415   (and (eq_attr "type" "fdiv")
416        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
417   12 0)
419 (define_function_unit "divide" 1 1
420   (and (eq_attr "type" "fdiv")
421        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
422   15 0)
424 (define_function_unit "divide" 1 1
425   (and (eq_attr "type" "fdiv")
426        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
427   32 0)
429 (define_function_unit "divide" 1 1
430   (and (eq_attr "type" "fdiv")
431        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
432   21 0)
434 (define_function_unit "divide" 1 1
435   (and (eq_attr "type" "fdiv")
436        (and (eq_attr "mode" "DF")
437             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
438   36 0)
440 (define_function_unit "divide" 1 1
441   (and (eq_attr "type" "fdiv")
442        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
443   19 0)
445 (define_function_unit "divide" 1 1
446   (and (eq_attr "type" "fdiv")
447        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
448   16 0)
450 (define_function_unit "divide" 1 1
451   (and (eq_attr "type" "fdiv")
452        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
453   61 0)
455 ;;; ??? Is this number right?
456 (define_function_unit "divide" 1 1
457   (and (eq_attr "type" "fsqrt,frsqrt")
458        (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
459   54 0)
461 (define_function_unit "divide" 1 1
462   (and (eq_attr "type" "fsqrt,frsqrt")
463        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
464   31 0)
466 (define_function_unit "divide" 1 1
467   (and (eq_attr "type" "fsqrt,frsqrt")
468        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
469   21 0)
471 ;;; ??? Is this number right?
472 (define_function_unit "divide" 1 1
473   (and (eq_attr "type" "fsqrt,frsqrt")
474        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
475   112 0)
477 (define_function_unit "divide" 1 1
478   (and (eq_attr "type" "fsqrt,frsqrt")
479        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
480   60 0)
482 (define_function_unit "divide" 1 1
483   (and (eq_attr "type" "fsqrt,frsqrt")
484        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
485   36 0)
487 ;; R4300 FP instruction classes treated as part of the "imuldiv"
488 ;; functional unit:
490 (define_function_unit "imuldiv" 1 0
491   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
492   3 3)
494 (define_function_unit "imuldiv" 1 0
495   (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
496   1 1)
498 (define_function_unit "imuldiv" 1 0
499   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
500   5 5)
501 (define_function_unit "imuldiv" 1 0
502   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
503   8 8)
505 (define_function_unit "imuldiv" 1 0
506   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
507        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
508   29 29)
509 (define_function_unit "imuldiv" 1 0
510   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
511        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
512   58 58)
514 ;; The following functional units do not use the cpu type, and use
515 ;; much less memory in genattrtab.c.
517 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "load")                                3 0)
518 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "store")                               1 0)
520 ;; (define_function_unit "fp_comp"  1 0 (eq_attr "type" "fcmp")                                2 0)
522 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer")                                2 0)
523 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo")                                3 0)
525 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "imul")                               17 0)
526 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "idiv")                               38 0)
528 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fadd")                                4 0)
529 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fabs,fneg")                           2 0)
531 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF"))    7 0)
532 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF"))    8 0)
534 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF"))   23 0)
535 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF"))   36 0)
537 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF"))  54 0)
538 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
540 ;; Include scheduling descriptions.
542 (include "5400.md")
543 (include "5500.md")
544 (include "sr71k.md")
548 ;;  ....................
550 ;;      CONDITIONAL TRAPS
552 ;;  ....................
555 (define_insn "trap"
556   [(trap_if (const_int 1) (const_int 0))]
557   ""
558   "*
560   if (ISA_HAS_COND_TRAP)
561     return \"teq\\t$0,$0\";
562   else if (TARGET_MIPS16)
563     return \"break 0\";
564   else
565     return \"break\";
568 (define_expand "conditional_trap"
569   [(trap_if (match_operator 0 "cmp_op"
570                             [(match_dup 2) (match_dup 3)])
571             (match_operand 1 "const_int_operand" ""))]
572   "ISA_HAS_COND_TRAP"
573   "
575   mips_gen_conditional_trap (operands);
576   DONE;
579 ;; Match a TRAP_IF with 2nd arg of 0.  The div_trap_* insns match a
580 ;; 2nd arg of any CONST_INT, so this insn must appear first.
581 ;; gen_div_trap always generates TRAP_IF with 2nd arg of 6 or 7.
583 (define_insn ""
584   [(trap_if (match_operator 0 "trap_cmp_op"
585                             [(match_operand:SI 1 "reg_or_0_operand" "d")
586                              (match_operand:SI 2 "nonmemory_operand" "dI")])
587             (const_int 0))]
588   "ISA_HAS_COND_TRAP"
589   "t%C0\\t%z1,%z2")
592 ;;  ....................
594 ;;      ADDITION
596 ;;  ....................
599 (define_insn "adddf3"
600   [(set (match_operand:DF 0 "register_operand" "=f")
601         (plus:DF (match_operand:DF 1 "register_operand" "f")
602                  (match_operand:DF 2 "register_operand" "f")))]
603   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
604   "add.d\\t%0,%1,%2"
605   [(set_attr "type"     "fadd")
606    (set_attr "mode"     "DF")])
608 (define_insn "addsf3"
609   [(set (match_operand:SF 0 "register_operand" "=f")
610         (plus:SF (match_operand:SF 1 "register_operand" "f")
611                  (match_operand:SF 2 "register_operand" "f")))]
612   "TARGET_HARD_FLOAT"
613   "add.s\\t%0,%1,%2"
614   [(set_attr "type"     "fadd")
615    (set_attr "mode"     "SF")])
617 (define_expand "addsi3"
618   [(set (match_operand:SI 0 "register_operand" "=d")
619         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
620                  (match_operand:SI 2 "arith_operand" "dI")))]
621   ""
622   "
624   /* The mips16 assembler handles -32768 correctly, and so does gas,
625      but some other MIPS assemblers think that -32768 needs to be
626      loaded into a register before it can be added in.  */
627   if (! TARGET_MIPS16
628       && ! TARGET_GAS
629       && GET_CODE (operands[2]) == CONST_INT
630       && INTVAL (operands[2]) == -32768)
631     operands[2] = force_reg (SImode, operands[2]);
633   /* If a large stack adjustment was forced into a register, we may be
634      asked to generate rtx such as:
636         (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
638      but no such instruction is available in mips16.  Handle it by
639      using a temporary.  */
640   if (TARGET_MIPS16
641       && REGNO (operands[0]) == STACK_POINTER_REGNUM
642       && ((GET_CODE (operands[1]) == REG
643            && REGNO (operands[1]) != STACK_POINTER_REGNUM)
644           || GET_CODE (operands[2]) != CONST_INT))
645     {
646       rtx tmp = gen_reg_rtx (SImode);
648       emit_move_insn (tmp, operands[1]);
649       emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
650       emit_move_insn (operands[0], tmp);
651       DONE;
652     }
655 (define_insn "addsi3_internal"
656   [(set (match_operand:SI 0 "register_operand" "=d")
657         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
658                  (match_operand:SI 2 "arith_operand" "dI")))]
659   "! TARGET_MIPS16
660    && (TARGET_GAS
661        || GET_CODE (operands[2]) != CONST_INT
662        || INTVAL (operands[2]) != -32768)"
663   "addu\\t%0,%z1,%2"
664   [(set_attr "type"     "arith")
665    (set_attr "mode"     "SI")])
667 ;; For the mips16, we need to recognize stack pointer additions
668 ;; explicitly, since we don't have a constraint for $sp.  These insns
669 ;; will be generated by the save_restore_insns functions.
671 (define_insn ""
672   [(set (reg:SI 29)
673         (plus:SI (reg:SI 29)
674                  (match_operand:SI 0 "small_int" "I")))]
675   "TARGET_MIPS16"
676   "addu\\t%$,%$,%0"
677   [(set_attr "type"     "arith")
678    (set_attr "mode"     "SI")
679    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
680                                       (const_int 4)
681                                       (const_int 8)))])
683 (define_insn ""
684   [(set (match_operand:SI 0 "register_operand" "=d")
685         (plus:SI (reg:SI 29)
686                  (match_operand:SI 1 "small_int" "I")))]
687   "TARGET_MIPS16"
688   "addu\\t%0,%$,%1"
689   [(set_attr "type"     "arith")
690    (set_attr "mode"     "SI")
691    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
692                                       (const_int 4)
693                                       (const_int 8)))])
695 (define_insn ""
696   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
697         (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
698                  (match_operand:SI 2 "arith_operand" "IQ,O,d")))]
699   "TARGET_MIPS16
700    && (GET_CODE (operands[1]) != REG
701        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
702        || M16_REG_P (REGNO (operands[1]))
703        || REGNO (operands[1]) == ARG_POINTER_REGNUM
704        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
705        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
706    && (GET_CODE (operands[2]) != REG
707        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
708        || M16_REG_P (REGNO (operands[2]))
709        || REGNO (operands[2]) == ARG_POINTER_REGNUM
710        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
711        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
712   "*
714   if (REGNO (operands[0]) == REGNO (operands[1]))
715     return \"addu\\t%0,%2\";
716   return \"addu\\t%0,%1,%2\";
718   [(set_attr "type"     "arith")
719    (set_attr "mode"     "SI")
720    (set_attr_alternative "length"
721                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
722                                (const_int 4)
723                                (const_int 8))
724                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
725                                (const_int 4)
726                                (const_int 8))
727                  (const_int 4)])])
730 ;; On the mips16, we can sometimes split an add of a constant which is
731 ;; a 4 byte instruction into two adds which are both 2 byte
732 ;; instructions.  There are two cases: one where we are adding a
733 ;; constant plus a register to another register, and one where we are
734 ;; simply adding a constant to a register.
736 (define_split
737   [(set (match_operand:SI 0 "register_operand" "")
738         (plus:SI (match_dup 0)
739                  (match_operand:SI 1 "const_int_operand" "")))]
740   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
741    && GET_CODE (operands[0]) == REG
742    && M16_REG_P (REGNO (operands[0]))
743    && GET_CODE (operands[1]) == CONST_INT
744    && ((INTVAL (operands[1]) > 0x7f
745         && INTVAL (operands[1]) <= 0x7f + 0x7f)
746        || (INTVAL (operands[1]) < - 0x80
747            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
748   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
749    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
750   "
752   HOST_WIDE_INT val = INTVAL (operands[1]);
754   if (val >= 0)
755     {
756       operands[1] = GEN_INT (0x7f);
757       operands[2] = GEN_INT (val - 0x7f);
758     }
759   else
760     {
761       operands[1] = GEN_INT (- 0x80);
762       operands[2] = GEN_INT (val + 0x80);
763     }
766 (define_split
767   [(set (match_operand:SI 0 "register_operand" "")
768         (plus:SI (match_operand:SI 1 "register_operand" "")
769                  (match_operand:SI 2 "const_int_operand" "")))]
770   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
771    && GET_CODE (operands[0]) == REG
772    && M16_REG_P (REGNO (operands[0]))
773    && GET_CODE (operands[1]) == REG
774    && M16_REG_P (REGNO (operands[1]))
775    && REGNO (operands[0]) != REGNO (operands[1])
776    && GET_CODE (operands[2]) == CONST_INT
777    && ((INTVAL (operands[2]) > 0x7
778         && INTVAL (operands[2]) <= 0x7 + 0x7f)
779        || (INTVAL (operands[2]) < - 0x8
780            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
781   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
782    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
783   "
785   HOST_WIDE_INT val = INTVAL (operands[2]);
787   if (val >= 0)
788     {
789       operands[2] = GEN_INT (0x7);
790       operands[3] = GEN_INT (val - 0x7);
791     }
792   else
793     {
794       operands[2] = GEN_INT (- 0x8);
795       operands[3] = GEN_INT (val + 0x8);
796     }
799 (define_expand "adddi3"
800   [(parallel [(set (match_operand:DI 0 "register_operand" "")
801                    (plus:DI (match_operand:DI 1 "se_register_operand" "")
802                             (match_operand:DI 2 "se_arith_operand" "")))
803               (clobber (match_dup 3))])]
804   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
805   "
807   /* The mips16 assembler handles -32768 correctly, and so does gas,
808      but some other MIPS assemblers think that -32768 needs to be
809      loaded into a register before it can be added in.  */
810   if (! TARGET_MIPS16
811       && ! TARGET_GAS
812       && GET_CODE (operands[2]) == CONST_INT
813       && INTVAL (operands[2]) == -32768)
814     operands[2] = force_reg (DImode, operands[2]);
816   /* If a large stack adjustment was forced into a register, we may be
817      asked to generate rtx such as:
819         (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
821      but no such instruction is available in mips16.  Handle it by
822      using a temporary.  */
823   if (TARGET_MIPS16
824       && REGNO (operands[0]) == STACK_POINTER_REGNUM
825       && ((GET_CODE (operands[1]) == REG
826            && REGNO (operands[1]) != STACK_POINTER_REGNUM)
827           || GET_CODE (operands[2]) != CONST_INT))
828     {
829       rtx tmp = gen_reg_rtx (DImode);
831       emit_move_insn (tmp, operands[1]);
832       emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
833       emit_move_insn (operands[0], tmp);
834       DONE;
835     }
837   if (TARGET_64BIT)
838     {
839       emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
840                                         operands[2]));
841       DONE;
842     }
844   operands[3] = gen_reg_rtx (SImode);
847 (define_insn "adddi3_internal_1"
848   [(set (match_operand:DI 0 "register_operand" "=d,&d")
849         (plus:DI (match_operand:DI 1 "register_operand" "0,d")
850                  (match_operand:DI 2 "register_operand" "d,d")))
851    (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
852   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
853   "*
855   return (REGNO (operands[0]) == REGNO (operands[1])
856           && REGNO (operands[0]) == REGNO (operands[2]))
857     ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
858     : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
860   [(set_attr "type"     "darith")
861    (set_attr "mode"     "DI")
862    (set_attr "length"   "16")])
864 (define_split
865   [(set (match_operand:DI 0 "register_operand" "")
866         (plus:DI (match_operand:DI 1 "register_operand" "")
867                  (match_operand:DI 2 "register_operand" "")))
868    (clobber (match_operand:SI 3 "register_operand" ""))]
869   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
870    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
871    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
872    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
873    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
874    && (REGNO (operands[0]) != REGNO (operands[1])
875        || REGNO (operands[0]) != REGNO (operands[2]))"
877   [(set (subreg:SI (match_dup 0) 0)
878         (plus:SI (subreg:SI (match_dup 1) 0)
879                  (subreg:SI (match_dup 2) 0)))
881    (set (match_dup 3)
882         (ltu:SI (subreg:SI (match_dup 0) 0)
883                 (subreg:SI (match_dup 2) 0)))
885    (set (subreg:SI (match_dup 0) 4)
886         (plus:SI (subreg:SI (match_dup 1) 4)
887                  (subreg:SI (match_dup 2) 4)))
889    (set (subreg:SI (match_dup 0) 4)
890         (plus:SI (subreg:SI (match_dup 0) 4)
891                  (match_dup 3)))]
892   "")
894 (define_split
895   [(set (match_operand:DI 0 "register_operand" "")
896         (plus:DI (match_operand:DI 1 "register_operand" "")
897                  (match_operand:DI 2 "register_operand" "")))
898    (clobber (match_operand:SI 3 "register_operand" ""))]
899   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
900    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
901    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
902    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
903    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
904    && (REGNO (operands[0]) != REGNO (operands[1])
905        || REGNO (operands[0]) != REGNO (operands[2]))"
907   [(set (subreg:SI (match_dup 0) 4)
908         (plus:SI (subreg:SI (match_dup 1) 4)
909                  (subreg:SI (match_dup 2) 4)))
911    (set (match_dup 3)
912         (ltu:SI (subreg:SI (match_dup 0) 4)
913                 (subreg:SI (match_dup 2) 4)))
915    (set (subreg:SI (match_dup 0) 0)
916         (plus:SI (subreg:SI (match_dup 1) 0)
917                  (subreg:SI (match_dup 2) 0)))
919    (set (subreg:SI (match_dup 0) 0)
920         (plus:SI (subreg:SI (match_dup 0) 0)
921                  (match_dup 3)))]
922   "")
924 (define_insn "adddi3_internal_2"
925   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
926         (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
927                  (match_operand:DI 2 "small_int" "P,J,N")))
928    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
929   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
930    && (TARGET_GAS
931        || GET_CODE (operands[2]) != CONST_INT
932        || INTVAL (operands[2]) != -32768)"
933   "@
934    addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
935    move\\t%L0,%L1\;move\\t%M0,%M1
936    subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
937   [(set_attr "type"     "darith")
938    (set_attr "mode"     "DI")
939    (set_attr "length"   "12,8,16")])
941 (define_split
942   [(set (match_operand:DI 0 "register_operand" "")
943         (plus:DI (match_operand:DI 1 "register_operand" "")
944                  (match_operand:DI 2 "small_int" "")))
945    (clobber (match_operand:SI 3 "register_operand" ""))]
946   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
947    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
948    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
949    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
950    && INTVAL (operands[2]) > 0"
952   [(set (subreg:SI (match_dup 0) 0)
953         (plus:SI (subreg:SI (match_dup 1) 0)
954                  (match_dup 2)))
956    (set (match_dup 3)
957         (ltu:SI (subreg:SI (match_dup 0) 0)
958                 (match_dup 2)))
960    (set (subreg:SI (match_dup 0) 4)
961         (plus:SI (subreg:SI (match_dup 1) 4)
962                  (match_dup 3)))]
963   "")
965 (define_split
966   [(set (match_operand:DI 0 "register_operand" "")
967         (plus:DI (match_operand:DI 1 "register_operand" "")
968                  (match_operand:DI 2 "small_int" "")))
969    (clobber (match_operand:SI 3 "register_operand" ""))]
970   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
971    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
972    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
973    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
974    && INTVAL (operands[2]) > 0"
976   [(set (subreg:SI (match_dup 0) 4)
977         (plus:SI (subreg:SI (match_dup 1) 4)
978                  (match_dup 2)))
980    (set (match_dup 3)
981         (ltu:SI (subreg:SI (match_dup 0) 4)
982                 (match_dup 2)))
984    (set (subreg:SI (match_dup 0) 0)
985         (plus:SI (subreg:SI (match_dup 1) 0)
986                  (match_dup 3)))]
987   "")
989 (define_insn "adddi3_internal_3"
990   [(set (match_operand:DI 0 "register_operand" "=d")
991         (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
992                  (match_operand:DI 2 "se_arith_operand" "dI")))]
993   "TARGET_64BIT
994    && !TARGET_MIPS16
995    && (TARGET_GAS
996        || GET_CODE (operands[2]) != CONST_INT
997        || INTVAL (operands[2]) != -32768)"
998   "*
1000   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1001     ? \"dsubu\\t%0,%z1,%n2\"
1002     : \"daddu\\t%0,%z1,%2\";
1004   [(set_attr "type"     "darith")
1005    (set_attr "mode"     "DI")])
1007 ;; For the mips16, we need to recognize stack pointer additions
1008 ;; explicitly, since we don't have a constraint for $sp.  These insns
1009 ;; will be generated by the save_restore_insns functions.
1011 (define_insn ""
1012   [(set (reg:DI 29)
1013         (plus:DI (reg:DI 29)
1014                  (match_operand:DI 0 "small_int" "I")))]
1015   "TARGET_MIPS16 && TARGET_64BIT"
1016   "daddu\\t%$,%$,%0"
1017   [(set_attr "type"     "arith")
1018    (set_attr "mode"     "DI")
1019    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
1020                                       (const_int 4)
1021                                       (const_int 8)))])
1023 (define_insn ""
1024   [(set (match_operand:DI 0 "register_operand" "=d")
1025         (plus:DI (reg:DI 29)
1026                  (match_operand:DI 1 "small_int" "I")))]
1027   "TARGET_MIPS16 && TARGET_64BIT"
1028   "daddu\\t%0,%$,%1"
1029   [(set_attr "type"     "arith")
1030    (set_attr "mode"     "DI")
1031    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
1032                                       (const_int 4)
1033                                       (const_int 8)))])
1035 (define_insn ""
1036   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1037         (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1038                  (match_operand:DI 2 "arith_operand" "IQ,O,d")))]
1039   "TARGET_MIPS16 && TARGET_64BIT
1040    && (GET_CODE (operands[1]) != REG
1041        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
1042        || M16_REG_P (REGNO (operands[1]))
1043        || REGNO (operands[1]) == ARG_POINTER_REGNUM
1044        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
1045        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
1046    && (GET_CODE (operands[2]) != REG
1047        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
1048        || M16_REG_P (REGNO (operands[2]))
1049        || REGNO (operands[2]) == ARG_POINTER_REGNUM
1050        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
1051        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
1052   "*
1054   if (REGNO (operands[0]) == REGNO (operands[1]))
1055     return \"daddu\\t%0,%2\";
1056   return \"daddu\\t%0,%1,%2\";
1058   [(set_attr "type"     "arith")
1059    (set_attr "mode"     "DI")
1060    (set_attr_alternative "length"
1061                 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
1062                                (const_int 4)
1063                                (const_int 8))
1064                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1065                                (const_int 4)
1066                                (const_int 8))
1067                  (const_int 4)])])
1070 ;; On the mips16, we can sometimes split an add of a constant which is
1071 ;; a 4 byte instruction into two adds which are both 2 byte
1072 ;; instructions.  There are two cases: one where we are adding a
1073 ;; constant plus a register to another register, and one where we are
1074 ;; simply adding a constant to a register.
1076 (define_split
1077   [(set (match_operand:DI 0 "register_operand" "")
1078         (plus:DI (match_dup 0)
1079                  (match_operand:DI 1 "const_int_operand" "")))]
1080   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1081    && GET_CODE (operands[0]) == REG
1082    && M16_REG_P (REGNO (operands[0]))
1083    && GET_CODE (operands[1]) == CONST_INT
1084    && ((INTVAL (operands[1]) > 0xf
1085         && INTVAL (operands[1]) <= 0xf + 0xf)
1086        || (INTVAL (operands[1]) < - 0x10
1087            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1088   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1089    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1090   "
1092   HOST_WIDE_INT val = INTVAL (operands[1]);
1094   if (val >= 0)
1095     {
1096       operands[1] = GEN_INT (0xf);
1097       operands[2] = GEN_INT (val - 0xf);
1098     }
1099   else
1100     {
1101       operands[1] = GEN_INT (- 0x10);
1102       operands[2] = GEN_INT (val + 0x10);
1103     }
1106 (define_split
1107   [(set (match_operand:DI 0 "register_operand" "")
1108         (plus:DI (match_operand:DI 1 "register_operand" "")
1109                  (match_operand:DI 2 "const_int_operand" "")))]
1110   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1111    && GET_CODE (operands[0]) == REG
1112    && M16_REG_P (REGNO (operands[0]))
1113    && GET_CODE (operands[1]) == REG
1114    && M16_REG_P (REGNO (operands[1]))
1115    && REGNO (operands[0]) != REGNO (operands[1])
1116    && GET_CODE (operands[2]) == CONST_INT
1117    && ((INTVAL (operands[2]) > 0x7
1118         && INTVAL (operands[2]) <= 0x7 + 0xf)
1119        || (INTVAL (operands[2]) < - 0x8
1120            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1121   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1122    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1123   "
1125   HOST_WIDE_INT val = INTVAL (operands[2]);
1127   if (val >= 0)
1128     {
1129       operands[2] = GEN_INT (0x7);
1130       operands[3] = GEN_INT (val - 0x7);
1131     }
1132   else
1133     {
1134       operands[2] = GEN_INT (- 0x8);
1135       operands[3] = GEN_INT (val + 0x8);
1136     }
1139 (define_insn "addsi3_internal_2"
1140   [(set (match_operand:DI 0 "register_operand" "=d")
1141         (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1142                                  (match_operand:SI 2 "arith_operand" "dI"))))]
1143   "TARGET_64BIT
1144    && !TARGET_MIPS16
1145    && (TARGET_GAS
1146        || GET_CODE (operands[2]) != CONST_INT
1147        || INTVAL (operands[2]) != -32768)"
1148   "*
1150   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1151     ? \"subu\\t%0,%z1,%n2\"
1152     : \"addu\\t%0,%z1,%2\";
1154   [(set_attr "type"     "arith")
1155    (set_attr "mode"     "SI")])
1157 (define_insn ""
1158   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1159         (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1160                                  (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1161   "TARGET_MIPS16 && TARGET_64BIT"
1162   "*
1164   if (REGNO (operands[0]) == REGNO (operands[1]))
1165     return \"addu\\t%0,%2\";
1166   return \"addu\\t%0,%1,%2\";
1168   [(set_attr "type"     "arith")
1169    (set_attr "mode"     "SI")
1170    (set_attr_alternative "length"
1171                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1172                                (const_int 4)
1173                                (const_int 8))
1174                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1175                                (const_int 4)
1176                                (const_int 8))
1177                  (const_int 4)])])
1181 ;;  ....................
1183 ;;      SUBTRACTION
1185 ;;  ....................
1188 (define_insn "subdf3"
1189   [(set (match_operand:DF 0 "register_operand" "=f")
1190         (minus:DF (match_operand:DF 1 "register_operand" "f")
1191                   (match_operand:DF 2 "register_operand" "f")))]
1192   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1193   "sub.d\\t%0,%1,%2"
1194   [(set_attr "type"     "fadd")
1195    (set_attr "mode"     "DF")])
1197 (define_insn "subsf3"
1198   [(set (match_operand:SF 0 "register_operand" "=f")
1199         (minus:SF (match_operand:SF 1 "register_operand" "f")
1200                   (match_operand:SF 2 "register_operand" "f")))]
1201   "TARGET_HARD_FLOAT"
1202   "sub.s\\t%0,%1,%2"
1203   [(set_attr "type"     "fadd")
1204    (set_attr "mode"     "SF")])
1206 (define_expand "subsi3"
1207   [(set (match_operand:SI 0 "register_operand" "=d")
1208         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1209                   (match_operand:SI 2 "arith_operand" "dI")))]
1210   ""
1211   "
1213   if (GET_CODE (operands[2]) == CONST_INT
1214       && (INTVAL (operands[2]) == -32768
1215           || (TARGET_MIPS16
1216               && INTVAL (operands[2]) == -0x4000)))
1217     operands[2] = force_reg (SImode, operands[2]);
1220 (define_insn "subsi3_internal"
1221   [(set (match_operand:SI 0 "register_operand" "=d")
1222         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1223                   (match_operand:SI 2 "arith_operand" "dI")))]
1224   "!TARGET_MIPS16
1225    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1226   "subu\\t%0,%z1,%2"
1227   [(set_attr "type"     "arith")
1228    (set_attr "mode"     "SI")])
1230 ;; For the mips16, we need to recognize stack pointer subtractions
1231 ;; explicitly, since we don't have a constraint for $sp.  These insns
1232 ;; will be generated by the save_restore_insns functions.
1234 (define_insn ""
1235   [(set (reg:SI 29)
1236         (minus:SI (reg:SI 29)
1237                   (match_operand:SI 0 "small_int" "I")))]
1238   "TARGET_MIPS16
1239    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1240   "addu\\t%$,%$,%n0"
1241   [(set_attr "type"     "arith")
1242    (set_attr "mode"     "SI")
1243    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1244                                       (const_int 4)
1245                                       (const_int 8)))])
1247 (define_insn ""
1248   [(set (match_operand:SI 0 "register_operand" "=d")
1249         (minus:SI (reg:SI 29)
1250                   (match_operand:SI 1 "small_int" "I")))]
1251   "TARGET_MIPS16
1252    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1253   "addu\\t%0,%$,%n1"
1254   [(set_attr "type"     "arith")
1255    (set_attr "mode"     "SI")
1256    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
1257                                       (const_int 4)
1258                                       (const_int 8)))])
1261 (define_insn ""
1262   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1263         (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1264                   (match_operand:SI 2 "arith_operand" "I,O,d")))]
1265   "TARGET_MIPS16
1266    && (GET_CODE (operands[2]) != CONST_INT
1267        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1268   "*
1270   if (REGNO (operands[0]) == REGNO (operands[1]))
1271     return \"subu\\t%0,%2\";
1272   return \"subu\\t%0,%1,%2\";
1274   [(set_attr "type"     "arith")
1275    (set_attr "mode"     "SI")
1276    (set_attr_alternative "length"
1277                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1278                                (const_int 4)
1279                                (const_int 8))
1280                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1281                                (const_int 4)
1282                                (const_int 8))
1283                  (const_int 4)])])
1285 ;; On the mips16, we can sometimes split a subtract of a constant
1286 ;; which is a 4 byte instruction into two adds which are both 2 byte
1287 ;; instructions.  There are two cases: one where we are setting a
1288 ;; register to a register minus a constant, and one where we are
1289 ;; simply subtracting a constant from a register.
1291 (define_split
1292   [(set (match_operand:SI 0 "register_operand" "")
1293         (minus:SI (match_dup 0)
1294                   (match_operand:SI 1 "const_int_operand" "")))]
1295   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1296    && GET_CODE (operands[0]) == REG
1297    && M16_REG_P (REGNO (operands[0]))
1298    && GET_CODE (operands[1]) == CONST_INT
1299    && ((INTVAL (operands[1]) > 0x80
1300         && INTVAL (operands[1]) <= 0x80 + 0x80)
1301        || (INTVAL (operands[1]) < - 0x7f
1302            && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1303   [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1304    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1305   "
1307   HOST_WIDE_INT val = INTVAL (operands[1]);
1309   if (val >= 0)
1310     {
1311       operands[1] = GEN_INT (0x80);
1312       operands[2] = GEN_INT (val - 0x80);
1313     }
1314   else
1315     {
1316       operands[1] = GEN_INT (- 0x7f);
1317       operands[2] = GEN_INT (val + 0x7f);
1318     }
1321 (define_split
1322   [(set (match_operand:SI 0 "register_operand" "")
1323         (minus:SI (match_operand:SI 1 "register_operand" "")
1324                   (match_operand:SI 2 "const_int_operand" "")))]
1325   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1326    && GET_CODE (operands[0]) == REG
1327    && M16_REG_P (REGNO (operands[0]))
1328    && GET_CODE (operands[1]) == REG
1329    && M16_REG_P (REGNO (operands[1]))
1330    && REGNO (operands[0]) != REGNO (operands[1])
1331    && GET_CODE (operands[2]) == CONST_INT
1332    && ((INTVAL (operands[2]) > 0x8
1333         && INTVAL (operands[2]) <= 0x8 + 0x80)
1334        || (INTVAL (operands[2]) < - 0x7
1335            && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1336   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1337    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1338   "
1340   HOST_WIDE_INT val = INTVAL (operands[2]);
1342   if (val >= 0)
1343     {
1344       operands[2] = GEN_INT (0x8);
1345       operands[3] = GEN_INT (val - 0x8);
1346     }
1347   else
1348     {
1349       operands[2] = GEN_INT (- 0x7);
1350       operands[3] = GEN_INT (val + 0x7);
1351     }
1354 (define_expand "subdi3"
1355   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1356                    (minus:DI (match_operand:DI 1 "se_register_operand" "d")
1357                              (match_operand:DI 2 "se_register_operand" "d")))
1358               (clobber (match_dup 3))])]
1359   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1360   "
1362   if (TARGET_64BIT)
1363     {
1364       emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1365                                         operands[2]));
1366       DONE;
1367     }
1369   operands[3] = gen_reg_rtx (SImode);
1372 (define_insn "subdi3_internal"
1373   [(set (match_operand:DI 0 "register_operand" "=d")
1374         (minus:DI (match_operand:DI 1 "register_operand" "d")
1375                   (match_operand:DI 2 "register_operand" "d")))
1376    (clobber (match_operand:SI 3 "register_operand" "=d"))]
1377   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1378   "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1379   [(set_attr "type"     "darith")
1380    (set_attr "mode"     "DI")
1381    (set_attr "length"   "16")])
1383 (define_split
1384   [(set (match_operand:DI 0 "register_operand" "")
1385         (minus:DI (match_operand:DI 1 "register_operand" "")
1386                   (match_operand:DI 2 "register_operand" "")))
1387    (clobber (match_operand:SI 3 "register_operand" ""))]
1388   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1389    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1390    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1391    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1392    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1394   [(set (match_dup 3)
1395         (ltu:SI (subreg:SI (match_dup 1) 0)
1396                 (subreg:SI (match_dup 2) 0)))
1398    (set (subreg:SI (match_dup 0) 0)
1399         (minus:SI (subreg:SI (match_dup 1) 0)
1400                   (subreg:SI (match_dup 2) 0)))
1402    (set (subreg:SI (match_dup 0) 4)
1403         (minus:SI (subreg:SI (match_dup 1) 4)
1404                   (subreg:SI (match_dup 2) 4)))
1406    (set (subreg:SI (match_dup 0) 4)
1407         (minus:SI (subreg:SI (match_dup 0) 4)
1408                   (match_dup 3)))]
1409   "")
1411 (define_split
1412   [(set (match_operand:DI 0 "register_operand" "")
1413         (minus:DI (match_operand:DI 1 "register_operand" "")
1414                   (match_operand:DI 2 "register_operand" "")))
1415    (clobber (match_operand:SI 3 "register_operand" ""))]
1416   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1417    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1418    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1419    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1420    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1422   [(set (match_dup 3)
1423         (ltu:SI (subreg:SI (match_dup 1) 4)
1424                 (subreg:SI (match_dup 2) 4)))
1426    (set (subreg:SI (match_dup 0) 4)
1427         (minus:SI (subreg:SI (match_dup 1) 4)
1428                   (subreg:SI (match_dup 2) 4)))
1430    (set (subreg:SI (match_dup 0) 0)
1431         (minus:SI (subreg:SI (match_dup 1) 0)
1432                   (subreg:SI (match_dup 2) 0)))
1434    (set (subreg:SI (match_dup 0) 0)
1435         (minus:SI (subreg:SI (match_dup 0) 0)
1436                   (match_dup 3)))]
1437   "")
1439 (define_insn "subdi3_internal_2"
1440   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1441         (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1442                   (match_operand:DI 2 "small_int" "P,J,N")))
1443    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1444   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1445    && INTVAL (operands[2]) != -32768"
1446   "@
1447    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1448    move\\t%L0,%L1\;move\\t%M0,%M1
1449    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1450   [(set_attr "type"     "darith")
1451    (set_attr "mode"     "DI")
1452    (set_attr "length"   "12,8,16")])
1454 (define_split
1455   [(set (match_operand:DI 0 "register_operand" "")
1456         (minus:DI (match_operand:DI 1 "register_operand" "")
1457                   (match_operand:DI 2 "small_int" "")))
1458    (clobber (match_operand:SI 3 "register_operand" ""))]
1459   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1460    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1461    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1462    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1463    && INTVAL (operands[2]) > 0"
1465   [(set (match_dup 3)
1466         (ltu:SI (subreg:SI (match_dup 1) 0)
1467                 (match_dup 2)))
1469    (set (subreg:SI (match_dup 0) 0)
1470         (minus:SI (subreg:SI (match_dup 1) 0)
1471                   (match_dup 2)))
1473    (set (subreg:SI (match_dup 0) 4)
1474         (minus:SI (subreg:SI (match_dup 1) 4)
1475                   (match_dup 3)))]
1476   "")
1478 (define_split
1479   [(set (match_operand:DI 0 "register_operand" "")
1480         (minus:DI (match_operand:DI 1 "register_operand" "")
1481                   (match_operand:DI 2 "small_int" "")))
1482    (clobber (match_operand:SI 3 "register_operand" ""))]
1483   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1484    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1485    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1486    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1487    && INTVAL (operands[2]) > 0"
1489   [(set (match_dup 3)
1490         (ltu:SI (subreg:SI (match_dup 1) 4)
1491                 (match_dup 2)))
1493    (set (subreg:SI (match_dup 0) 4)
1494         (minus:SI (subreg:SI (match_dup 1) 4)
1495                   (match_dup 2)))
1497    (set (subreg:SI (match_dup 0) 0)
1498         (minus:SI (subreg:SI (match_dup 1) 0)
1499                   (match_dup 3)))]
1500   "")
1502 (define_insn "subdi3_internal_3"
1503   [(set (match_operand:DI 0 "register_operand" "=d")
1504         (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
1505                   (match_operand:DI 2 "se_arith_operand" "dI")))]
1506   "TARGET_64BIT && !TARGET_MIPS16
1507    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1508   "*
1510   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1511     ? \"daddu\\t%0,%z1,%n2\"
1512     : \"dsubu\\t%0,%z1,%2\";
1514   [(set_attr "type"     "darith")
1515    (set_attr "mode"     "DI")])
1517 ;; For the mips16, we need to recognize stack pointer subtractions
1518 ;; explicitly, since we don't have a constraint for $sp.  These insns
1519 ;; will be generated by the save_restore_insns functions.
1521 (define_insn ""
1522   [(set (reg:DI 29)
1523         (minus:DI (reg:DI 29)
1524                   (match_operand:DI 0 "small_int" "I")))]
1525   "TARGET_MIPS16
1526    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1527   "daddu\\t%$,%$,%n0"
1528   [(set_attr "type"     "arith")
1529    (set_attr "mode"     "DI")
1530    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1531                                       (const_int 4)
1532                                       (const_int 8)))])
1534 (define_insn ""
1535   [(set (match_operand:DI 0 "register_operand" "=d")
1536         (minus:DI (reg:DI 29)
1537                   (match_operand:DI 1 "small_int" "I")))]
1538   "TARGET_MIPS16
1539    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1540   "daddu\\t%0,%$,%n1"
1541   [(set_attr "type"     "arith")
1542    (set_attr "mode"     "DI")
1543    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
1544                                       (const_int 4)
1545                                       (const_int 8)))])
1547 (define_insn ""
1548   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1549         (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1550                   (match_operand:DI 2 "arith_operand" "I,O,d")))]
1551   "TARGET_MIPS16
1552    && (GET_CODE (operands[2]) != CONST_INT
1553        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1554   "*
1556   if (REGNO (operands[0]) == REGNO (operands[1]))
1557     return \"dsubu\\t%0,%2\";
1558   return \"dsubu\\t%0,%1,%2\";
1560   [(set_attr "type"     "arith")
1561    (set_attr "mode"     "DI")
1562    (set_attr_alternative "length"
1563                 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
1564                                (const_int 4)
1565                                (const_int 8))
1566                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1567                                (const_int 4)
1568                                (const_int 8))
1569                  (const_int 4)])])
1571 ;; On the mips16, we can sometimes split an add of a constant which is
1572 ;; a 4 byte instruction into two adds which are both 2 byte
1573 ;; instructions.  There are two cases: one where we are adding a
1574 ;; constant plus a register to another register, and one where we are
1575 ;; simply adding a constant to a register.
1577 (define_split
1578   [(set (match_operand:DI 0 "register_operand" "")
1579         (minus:DI (match_dup 0)
1580                   (match_operand:DI 1 "const_int_operand" "")))]
1581   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1582    && GET_CODE (operands[0]) == REG
1583    && M16_REG_P (REGNO (operands[0]))
1584    && GET_CODE (operands[1]) == CONST_INT
1585    && ((INTVAL (operands[1]) > 0x10
1586         && INTVAL (operands[1]) <= 0x10 + 0x10)
1587        || (INTVAL (operands[1]) < - 0xf
1588            && INTVAL (operands[1]) >= - 0xf - 0xf))"
1589   [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1590    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1591   "
1593   HOST_WIDE_INT val = INTVAL (operands[1]);
1595   if (val >= 0)
1596     {
1597       operands[1] = GEN_INT (0xf);
1598       operands[2] = GEN_INT (val - 0xf);
1599     }
1600   else
1601     {
1602       operands[1] = GEN_INT (- 0x10);
1603       operands[2] = GEN_INT (val + 0x10);
1604     }
1607 (define_split
1608   [(set (match_operand:DI 0 "register_operand" "")
1609         (minus:DI (match_operand:DI 1 "register_operand" "")
1610                   (match_operand:DI 2 "const_int_operand" "")))]
1611   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1612    && GET_CODE (operands[0]) == REG
1613    && M16_REG_P (REGNO (operands[0]))
1614    && GET_CODE (operands[1]) == REG
1615    && M16_REG_P (REGNO (operands[1]))
1616    && REGNO (operands[0]) != REGNO (operands[1])
1617    && GET_CODE (operands[2]) == CONST_INT
1618    && ((INTVAL (operands[2]) > 0x8
1619         && INTVAL (operands[2]) <= 0x8 + 0x10)
1620        || (INTVAL (operands[2]) < - 0x7
1621            && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1622   [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1623    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1624   "
1626   HOST_WIDE_INT val = INTVAL (operands[2]);
1628   if (val >= 0)
1629     {
1630       operands[2] = GEN_INT (0x8);
1631       operands[3] = GEN_INT (val - 0x8);
1632     }
1633   else
1634     {
1635       operands[2] = GEN_INT (- 0x7);
1636       operands[3] = GEN_INT (val + 0x7);
1637     }
1640 (define_insn "subsi3_internal_2"
1641   [(set (match_operand:DI 0 "register_operand" "=d")
1642         (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1643                                   (match_operand:SI 2 "arith_operand" "dI"))))]
1644   "TARGET_64BIT && !TARGET_MIPS16
1645    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1646   "*
1648   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1649     ? \"addu\\t%0,%z1,%n2\"
1650     : \"subu\\t%0,%z1,%2\";
1652   [(set_attr "type"     "arith")
1653    (set_attr "mode"     "DI")])
1655 (define_insn ""
1656   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1657         (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1658                                   (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1659   "TARGET_64BIT && TARGET_MIPS16
1660    && (GET_CODE (operands[2]) != CONST_INT
1661        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1662   "*
1664   if (REGNO (operands[0]) == REGNO (operands[1]))
1665     return \"subu\\t%0,%2\";
1666   return \"subu\\t%0,%1,%2\";
1668   [(set_attr "type"     "arith")
1669    (set_attr "mode"     "SI")
1670    (set_attr_alternative "length"
1671                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1672                                (const_int 4)
1673                                (const_int 8))
1674                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1675                                (const_int 4)
1676                                (const_int 8))
1677                  (const_int 4)])])
1682 ;;  ....................
1684 ;;      MULTIPLICATION
1686 ;;  ....................
1689 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1690 ;; operands may corrupt immediately following multiplies. This is a
1691 ;; simple fix to insert NOPs.
1693 (define_expand "muldf3"
1694   [(set (match_operand:DF 0 "register_operand" "=f")
1695         (mult:DF (match_operand:DF 1 "register_operand" "f")
1696                  (match_operand:DF 2 "register_operand" "f")))]
1697   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1698   "
1700   if (!TARGET_MIPS4300)
1701     emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1702   else
1703     emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1704   DONE;
1707 (define_insn "muldf3_internal"
1708   [(set (match_operand:DF 0 "register_operand" "=f")
1709         (mult:DF (match_operand:DF 1 "register_operand" "f")
1710                  (match_operand:DF 2 "register_operand" "f")))]
1711   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_MIPS4300"
1712   "mul.d\\t%0,%1,%2"
1713   [(set_attr "type"     "fmul")
1714    (set_attr "mode"     "DF")])
1716 (define_insn "muldf3_r4300"
1717   [(set (match_operand:DF 0 "register_operand" "=f")
1718         (mult:DF (match_operand:DF 1 "register_operand" "f")
1719                  (match_operand:DF 2 "register_operand" "f")))]
1720   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_MIPS4300"
1721   "*
1723   output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1724   if (TARGET_4300_MUL_FIX)
1725     output_asm_insn (\"nop\", operands);
1726   return \"\";
1728   [(set_attr "type"     "fmul")
1729    (set_attr "mode"     "DF")
1730    (set_attr "length"   "8")])  ;; mul.d + nop
1732 (define_expand "mulsf3"
1733   [(set (match_operand:SF 0 "register_operand" "=f")
1734         (mult:SF (match_operand:SF 1 "register_operand" "f")
1735                  (match_operand:SF 2 "register_operand" "f")))]
1736   "TARGET_HARD_FLOAT"
1737   "
1739   if (!TARGET_MIPS4300)
1740     emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1741   else
1742     emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1743   DONE;
1746 (define_insn "mulsf3_internal"
1747   [(set (match_operand:SF 0 "register_operand" "=f")
1748         (mult:SF (match_operand:SF 1 "register_operand" "f")
1749                  (match_operand:SF 2 "register_operand" "f")))]
1750   "TARGET_HARD_FLOAT && !TARGET_MIPS4300"
1751   "mul.s\\t%0,%1,%2"
1752   [(set_attr "type"     "fmul")
1753    (set_attr "mode"     "SF")])
1755 (define_insn "mulsf3_r4300"
1756   [(set (match_operand:SF 0 "register_operand" "=f")
1757         (mult:SF (match_operand:SF 1 "register_operand" "f")
1758                  (match_operand:SF 2 "register_operand" "f")))]
1759   "TARGET_HARD_FLOAT && TARGET_MIPS4300"
1760   "*
1762   output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1763   if (TARGET_4300_MUL_FIX)
1764     output_asm_insn (\"nop\", operands);
1765   return \"\";
1767   [(set_attr "type"     "fmul")
1768    (set_attr "mode"     "SF")
1769    (set_attr "length"   "8")])  ;; mul.s + nop
1772 ;; ??? The R4000 (only) has a cpu bug.  If a double-word shift executes while
1773 ;; a multiply is in progress, it may give an incorrect result.  Avoid
1774 ;; this by keeping the mflo with the mult on the R4000.
1776 (define_expand "mulsi3"
1777   [(set (match_operand:SI 0 "register_operand" "=l")
1778         (mult:SI (match_operand:SI 1 "register_operand" "d")
1779                  (match_operand:SI 2 "register_operand" "d")))
1780    (clobber (match_scratch:SI 3 "=h"))
1781    (clobber (match_scratch:SI 4 "=a"))]
1782   ""
1783   "
1785   if (GENERATE_MULT3_SI || TARGET_MAD)
1786     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1787   else if (!TARGET_MIPS4000 || TARGET_MIPS16)
1788     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1789   else
1790     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1791   DONE;
1794 (define_insn "mulsi3_mult3"
1795   [(set (match_operand:SI 0 "register_operand" "=d,l")
1796         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1797                  (match_operand:SI 2 "register_operand" "d,d")))
1798    (clobber (match_scratch:SI 3 "=h,h"))
1799    (clobber (match_scratch:SI 4 "=l,X"))
1800    (clobber (match_scratch:SI 5 "=a,a"))]
1801   "GENERATE_MULT3_SI
1802    || TARGET_MAD"
1803   "*
1805   if (which_alternative == 1)
1806     return \"mult\\t%1,%2\";
1807   if (TARGET_MAD
1808       || TARGET_MIPS5400
1809       || TARGET_MIPS5500
1810       || ISA_MIPS32
1811       || ISA_MIPS64)
1812     return \"mul\\t%0,%1,%2\";
1813   return \"mult\\t%0,%1,%2\";
1815   [(set_attr "type"     "imul")
1816    (set_attr "mode"     "SI")])
1818 (define_insn "mulsi3_internal"
1819   [(set (match_operand:SI 0 "register_operand" "=l")
1820         (mult:SI (match_operand:SI 1 "register_operand" "d")
1821                  (match_operand:SI 2 "register_operand" "d")))
1822    (clobber (match_scratch:SI 3 "=h"))
1823    (clobber (match_scratch:SI 4 "=a"))]
1824   "!TARGET_MIPS4000 || TARGET_MIPS16"
1825   "mult\\t%1,%2"
1826   [(set_attr "type"     "imul")
1827    (set_attr "mode"     "SI")])
1829 (define_insn "mulsi3_r4000"
1830   [(set (match_operand:SI 0 "register_operand" "=d")
1831         (mult:SI (match_operand:SI 1 "register_operand" "d")
1832                  (match_operand:SI 2 "register_operand" "d")))
1833    (clobber (match_scratch:SI 3 "=h"))
1834    (clobber (match_scratch:SI 4 "=l"))
1835    (clobber (match_scratch:SI 5 "=a"))]
1836   "TARGET_MIPS4000 && !TARGET_MIPS16"
1837   "*
1839   rtx xoperands[10];
1841   xoperands[0] = operands[0];
1842   xoperands[1] = gen_rtx_REG (SImode, LO_REGNUM);
1844   output_asm_insn (\"mult\\t%1,%2\", operands);
1845   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1846   return \"\";
1848   [(set_attr "type"     "imul")
1849    (set_attr "mode"     "SI")
1850    (set_attr "length"   "12")])         ;; mult + mflo + delay
1852 ;; Multiply-accumulate patterns
1854 ;; For processors that can copy the output to a general register:
1856 ;; The all-d alternative is needed because the combiner will find this
1857 ;; pattern and then register alloc/reload will move registers around to
1858 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1860 ;; The last alternative should be made slightly less desirable, but adding
1861 ;; "?" to the constraint is too strong, and causes values to be loaded into
1862 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1863 ;; trick.
1864 (define_insn "*mul_acc_si"
1865   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1866         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1867                           (match_operand:SI 2 "register_operand" "d,d,d"))
1868                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1869    (clobber (match_scratch:SI 4 "=h,h,h"))
1870    (clobber (match_scratch:SI 5 "=X,3,l"))
1871    (clobber (match_scratch:SI 6 "=a,a,a"))
1872    (clobber (match_scratch:SI 7 "=X,X,d"))]
1873   "(TARGET_MIPS3900
1874    || TARGET_MIPS5400
1875    || TARGET_MIPS5500
1876    || ISA_HAS_MADD_MSUB)
1877    && !TARGET_MIPS16"
1878   "*
1880   static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
1881   static const char *const macc[] = { \"macc\\t$0,%1,%2\", \"macc\\t%0,%1,%2\" };
1882   if (which_alternative == 2)
1883     return \"#\";
1884   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1885     return \"#\";
1887   if (TARGET_MIPS5400)
1888     return macc[which_alternative];
1890   if (TARGET_MIPS5500)
1891     {
1892       if (which_alternative == 0)
1893         return madd[0];
1894       else
1895         return macc[which_alternative];
1896     }
1898   return madd[which_alternative];
1900   [(set_attr "type"     "imadd,imadd,multi")
1901    (set_attr "mode"     "SI")
1902    (set_attr "length"   "4,4,8")])
1904 ;; Split the above insn if we failed to get LO allocated.
1905 (define_split
1906   [(set (match_operand:SI 0 "register_operand" "")
1907         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1908                           (match_operand:SI 2 "register_operand" ""))
1909                  (match_operand:SI 3 "register_operand" "")))
1910    (clobber (match_scratch:SI 4 ""))
1911    (clobber (match_scratch:SI 5 ""))
1912    (clobber (match_scratch:SI 6 ""))
1913    (clobber (match_scratch:SI 7 ""))]
1914   "reload_completed && !TARGET_DEBUG_D_MODE
1915    && GP_REG_P (true_regnum (operands[0]))
1916    && GP_REG_P (true_regnum (operands[3]))"
1917   [(parallel [(set (match_dup 7)
1918                    (mult:SI (match_dup 1) (match_dup 2)))
1919               (clobber (match_dup 4))
1920               (clobber (match_dup 5))
1921               (clobber (match_dup 6))])
1922    (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
1923   "")
1925 ;; Splitter to copy result of MADD to a general register
1926 (define_split
1927   [(set (match_operand:SI                   0 "register_operand" "")
1928         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1929                           (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    && true_regnum (operands[3]) == LO_REGNUM"
1938   [(parallel [(set (match_dup 3)
1939                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1940                             (match_dup 3)))
1941               (clobber (match_dup 4))
1942               (clobber (match_dup 5))
1943               (clobber (match_dup 6))
1944               (clobber (match_dup 7))])
1945    (set (match_dup 0) (match_dup 3))]
1946   "")
1948 (define_insn "*mul_sub_si"
1949   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1950         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1951                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1952                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1953    (clobber (match_scratch:SI 4 "=h,h,h"))
1954    (clobber (match_scratch:SI 5 "=X,3,l"))
1955    (clobber (match_scratch:SI 6 "=a,a,a"))
1956    (clobber (match_scratch:SI 7 "=X,X,d"))]
1957   "ISA_HAS_MADD_MSUB"
1958   "*
1960   if (which_alternative != 0)
1961     return \"#\";
1962   return \"msub\\t%2,%3\";
1964   [(set_attr "type"     "imadd,multi,multi")
1965    (set_attr "mode"     "SI")
1966    (set_attr "length"   "4,8,8")])
1968 ;; Split the above insn if we failed to get LO allocated.
1969 (define_split
1970   [(set (match_operand:SI 0 "register_operand" "")
1971         (minus:SI (match_operand:SI 1 "register_operand" "")
1972                   (mult:SI (match_operand:SI 2 "register_operand" "")
1973                            (match_operand:SI 3 "register_operand" ""))))
1974    (clobber (match_scratch:SI 4 ""))
1975    (clobber (match_scratch:SI 5 ""))
1976    (clobber (match_scratch:SI 6 ""))
1977    (clobber (match_scratch:SI 7 ""))]
1978   "reload_completed && !TARGET_DEBUG_D_MODE
1979    && GP_REG_P (true_regnum (operands[0]))
1980    && GP_REG_P (true_regnum (operands[1]))"
1981   [(parallel [(set (match_dup 7)
1982                    (mult:SI (match_dup 2) (match_dup 3)))
1983               (clobber (match_dup 4))
1984               (clobber (match_dup 5))
1985               (clobber (match_dup 6))])
1986    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
1987   "")
1989 ;; Splitter to copy result of MSUB to a general register
1990 (define_split
1991   [(set (match_operand:SI 0 "register_operand" "")
1992         (minus:SI (match_operand:SI 1 "register_operand" "")
1993                   (mult:SI (match_operand:SI 2 "register_operand" "")
1994                            (match_operand:SI 3 "register_operand" ""))))
1995    (clobber (match_scratch:SI 4 ""))
1996    (clobber (match_scratch:SI 5 ""))
1997    (clobber (match_scratch:SI 6 ""))
1998    (clobber (match_scratch:SI 7 ""))]
1999   "reload_completed && !TARGET_DEBUG_D_MODE
2000    && GP_REG_P (true_regnum (operands[0]))
2001    && true_regnum (operands[1]) == LO_REGNUM"
2002   [(parallel [(set (match_dup 1)
2003                    (minus:SI (match_dup 1)
2004                              (mult:SI (match_dup 2) (match_dup 3))))
2005               (clobber (match_dup 4))
2006               (clobber (match_dup 5))
2007               (clobber (match_dup 6))
2008               (clobber (match_dup 7))])
2009    (set (match_dup 0) (match_dup 1))]
2010   "")
2012 (define_insn "*muls"
2013   [(set (match_operand:SI                  0 "register_operand" "=l,d")
2014         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
2015                          (match_operand:SI 2 "register_operand" "d,d"))))
2016    (clobber (match_scratch:SI              3                    "=h,h"))
2017    (clobber (match_scratch:SI              4                    "=a,a"))
2018    (clobber (match_scratch:SI              5                    "=X,l"))]
2019   "ISA_HAS_MULS && TARGET_64BIT"
2020   "@
2021    muls\\t$0,%1,%2
2022    muls\\t%0,%1,%2"
2023   [(set_attr "type"     "imul")
2024    (set_attr "mode"     "SI")])
2026 ;; See comments above for mul_acc_si.
2027 (define_insn "*msac"
2028   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
2029         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
2030                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
2031                            (match_operand:SI 3 "register_operand" "d,d,d"))))
2032    (clobber (match_scratch:SI 4 "=h,h,h"))
2033    (clobber (match_scratch:SI 5 "=X,1,l"))
2034    (clobber (match_scratch:SI 6 "=a,a,a"))
2035    (clobber (match_scratch:SI 7 "=X,X,d"))]
2036   "ISA_HAS_MSAC && TARGET_64BIT"
2037   "@
2038    msac\\t$0,%2,%3
2039    msac\\t%0,%2,%3
2040    #"
2041   [(set_attr "type"     "imadd,imadd,multi")
2042    (set_attr "mode"     "SI")
2043    (set_attr "length"   "4,4,8")])
2045 (define_split
2046   [(set (match_operand:SI 0 "register_operand" "")
2047         (minus:SI (match_operand:SI 1 "register_operand" "")
2048                   (mult:SI (match_operand:SI 2 "register_operand" "")
2049                            (match_operand:SI 3 "register_operand" ""))))
2050    (clobber (match_scratch:SI 4 ""))
2051    (clobber (match_scratch:SI 5 ""))
2052    (clobber (match_scratch:SI 6 ""))
2053    (clobber (match_scratch:SI 7 ""))]
2054   "reload_completed && !TARGET_DEBUG_D_MODE
2055    && GP_REG_P (true_regnum (operands[0]))
2056    && GP_REG_P (true_regnum (operands[1]))"
2057   [(parallel [(set (match_dup 7)
2058                    (mult:SI (match_dup 2) (match_dup 3)))
2059               (clobber (match_dup 4))
2060               (clobber (match_dup 5))
2061               (clobber (match_dup 6))])
2062    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
2063   "")
2065 (define_expand "muldi3"
2066   [(set (match_operand:DI 0 "register_operand" "=l")
2067         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
2068                  (match_operand:DI 2 "register_operand" "d")))
2069    (clobber (match_scratch:DI 3 "=h"))
2070    (clobber (match_scratch:DI 4 "=a"))]
2071   "TARGET_64BIT"
2073   "
2075   if (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)
2076     emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
2077   else
2078     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
2079   DONE;
2082 ;; Don't accept both operands using se_register_operand, because if
2083 ;; both operands are sign extended we would prefer to use mult in the
2084 ;; mulsidi3 pattern.  Commutativity should permit either operand to be
2085 ;; sign extended.
2087 (define_insn "muldi3_internal"
2088   [(set (match_operand:DI 0 "register_operand" "=l")
2089         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
2090                  (match_operand:DI 2 "register_operand" "d")))
2091    (clobber (match_scratch:DI 3 "=h"))
2092    (clobber (match_scratch:DI 4 "=a"))]
2093   "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16"
2094   "dmult\\t%1,%2"
2095   [(set_attr "type"     "imul")
2096    (set_attr "mode"     "DI")])
2098 (define_insn "muldi3_internal2"
2099   [(set (match_operand:DI 0 "register_operand" "=d")
2100         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
2101                  (match_operand:DI 2 "register_operand" "d")))
2102    (clobber (match_scratch:DI 3 "=h"))
2103    (clobber (match_scratch:DI 4 "=l"))
2104    (clobber (match_scratch:DI 5 "=a"))]
2105   "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)"
2106   "*
2108   if (GENERATE_MULT3_DI)
2109     output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
2110   else
2111     {
2112       rtx xoperands[10];
2114       xoperands[0] = operands[0];
2115       xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM);
2117       output_asm_insn (\"dmult\\t%1,%2\", operands);
2118       output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2119     }
2120   return \"\";
2122   [(set_attr "type"     "imul")
2123    (set_attr "mode"     "DI")
2124    (set (attr "length")
2125         (if_then_else (ne (symbol_ref "GENERATE_MULT3_DI") (const_int 0))
2126                        (const_int 4)
2127                        (const_int 12)))])       ;; mult + mflo + delay
2129 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
2131 (define_expand "mulsidi3"
2132   [(set (match_operand:DI 0 "register_operand" "=x")
2133         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2134                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2135   ""
2136   "
2138   rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
2139   if (TARGET_64BIT)
2140     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
2141                                    dummy, dummy));
2142   else
2143     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
2144                                       dummy, dummy));
2145   DONE;
2148 (define_expand "umulsidi3"
2149   [(set (match_operand:DI 0 "register_operand" "=x")
2150         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2151                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2152   ""
2153   "
2155   rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
2156   if (TARGET_64BIT)
2157     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
2158                                    dummy, dummy));
2159   else
2160     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
2161                                       dummy, dummy));
2162   DONE;
2165 (define_insn "mulsidi3_internal"
2166   [(set (match_operand:DI 0 "register_operand" "=x")
2167         (mult:DI (match_operator:DI 3 "extend_operator"
2168                                     [(match_operand:SI 1 "register_operand" "d")])
2169                  (match_operator:DI 4 "extend_operator"
2170                                     [(match_operand:SI 2 "register_operand" "d")])))
2171    (clobber (match_scratch:SI 5 "=a"))]
2172   "!TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2173   "*
2175   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2176     return \"mult\\t%1,%2\";
2177   return \"multu\\t%1,%2\";
2179   [(set_attr "type"     "imul")
2180    (set_attr "mode"     "SI")])
2182 (define_insn "mulsidi3_64bit"
2183   [(set (match_operand:DI 0 "register_operand" "=a")
2184         (mult:DI (match_operator:DI 3 "extend_operator"
2185                                     [(match_operand:SI 1 "register_operand" "d")])
2186                  (match_operator:DI 4 "extend_operator"
2187                                     [(match_operand:SI 2 "register_operand" "d")])))
2188    (clobber (match_scratch:DI 5 "=l"))
2189    (clobber (match_scratch:DI 6 "=h"))]
2190   "TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2191   "*
2193   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2194     return \"mult\\t%1,%2\";
2195   return \"multu\\t%1,%2\";
2197   [(set_attr "type"     "imul")
2198    (set_attr "mode"     "SI")])
2200 ;; widening multiply with accumulator and/or negation
2201 ;; These don't match yet for zero-extending; too complex for combine?
2202 ;; Possible additions we should have:
2203 ;;  "=x" variants for when !TARGET_64BIT ?
2204 ;;  all-d alternatives with splits like pure SImode versions
2205 (define_insn "*muls_di"
2206   [(set (match_operand:DI 0 "register_operand" "=a")
2207         (neg:DI
2208          (mult:DI (match_operator:DI 3 "extend_operator"
2209                                      [(match_operand:SI 1 "register_operand" "d")])
2210                   (match_operator:DI 4 "extend_operator"
2211                                      [(match_operand:SI 2 "register_operand" "d")]))))
2212    (clobber (match_scratch:SI 5 "=h"))
2213    (clobber (match_scratch:SI 6 "=l"))]
2214   "TARGET_64BIT
2215    && ISA_HAS_MULS
2216    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2217   "*
2219   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2220     return \"muls\\t$0,%1,%2\";
2221   else
2222     return \"mulsu\\t$0,%1,%2\";
2224   [(set_attr "type"     "imul")
2225    (set_attr "length"   "4")
2226    (set_attr "mode"     "SI")])
2228 (define_insn "*msac_di"
2229   [(set (match_operand:DI 0 "register_operand" "=a")
2230         (minus:DI (match_operand:DI 3 "register_operand" "0")
2231                   (mult:DI (match_operator:DI 4 "extend_operator"
2232                                               [(match_operand:SI 1 "register_operand" "d")])
2233                            (match_operator:DI 5 "extend_operator"
2234                                               [(match_operand:SI 2 "register_operand" "d")]))))
2235    (clobber (match_scratch:SI 6 "=h"))
2236    (clobber (match_scratch:SI 7 "=l"))]
2237   "TARGET_64BIT
2238    && ISA_HAS_MSAC
2239    && GET_CODE (operands[4]) == GET_CODE (operands[5])"
2240   "*
2242   if (GET_CODE (operands[4]) == SIGN_EXTEND)
2243      {
2244        if (TARGET_MIPS5500)
2245          return \"msub\\t%1,%2\";
2246        else
2247     return \"msac\\t$0,%1,%2\";
2248     }
2249   else
2250      {
2251        if (TARGET_MIPS5500)
2252          return \"msubu\\t%1,%2\";
2253        else
2254     return \"msacu\\t$0,%1,%2\";
2255     }
2257   [(set_attr "type"     "imadd")
2258    (set_attr "length"   "4")
2259    (set_attr "mode"     "SI")])
2261 ;; _highpart patterns
2262 (define_expand "smulsi3_highpart"
2263   [(set (match_operand:SI 0 "register_operand" "=h")
2264         (truncate:SI
2265          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2266                                (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2267                       (const_int 32))))]
2268   ""
2269   "
2271   rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
2272   rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
2273 #ifndef NO_MD_PROTOTYPES
2274   rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
2275 #else
2276   rtx (*genfn) ();
2277 #endif
2278  if (ISA_HAS_MULHI && TARGET_64BIT)
2279     genfn = gen_xmulsi3_highpart_mulhi;
2280  else
2281     genfn = gen_xmulsi3_highpart_internal;
2282   emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2283                        dummy, dummy2));
2284   DONE;
2287 (define_expand "umulsi3_highpart"
2288   [(set (match_operand:SI 0 "register_operand" "=h")
2289         (truncate:SI
2290          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2291                                (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2292                       (const_int 32))))]
2293   ""
2294   "
2296   rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
2297   rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
2298 #ifndef NO_MD_PROTOTYPES
2299   rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
2300 #else
2301   rtx (*genfn) ();
2302 #endif
2303   if (ISA_HAS_MULHI && TARGET_64BIT)
2304     genfn = gen_xmulsi3_highpart_mulhi;
2305   else
2306     genfn = gen_xmulsi3_highpart_internal;
2307   emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2308                        dummy, dummy2));
2309   DONE;
2312 (define_insn "xmulsi3_highpart_internal"
2313   [(set (match_operand:SI 0 "register_operand" "=h")
2314         (truncate:SI
2315          (match_operator:DI 5 "highpart_shift_operator"
2316                             [(mult:DI (match_operator:DI 3 "extend_operator"
2317                                                          [(match_operand:SI 1 "register_operand" "d")])
2318                                       (match_operator:DI 4 "extend_operator"
2319                                                          [(match_operand:SI 2 "register_operand" "d")]))
2320                              (const_int 32)])))
2321    (clobber (match_scratch:SI 6 "=l"))
2322    (clobber (match_scratch:SI 7 "=a"))]
2323   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
2324   "*
2326   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2327     return \"mult\\t%1,%2\";
2328   else
2329     return \"multu\\t%1,%2\";
2331   [(set_attr "type"     "imul")
2332    (set_attr "mode"     "SI")])
2334 (define_insn "xmulsi3_highpart_mulhi"
2335   [(set (match_operand:SI 0 "register_operand" "=h,d")
2336         (truncate:SI
2337          (match_operator:DI 5 "highpart_shift_operator"
2338                             [(mult:DI (match_operator:DI 3 "extend_operator"
2339                                                          [(match_operand:SI 1 "register_operand" "d,d")])
2340                                       (match_operator:DI 4 "extend_operator"
2341                                                          [(match_operand:SI 2 "register_operand" "d,d")]))
2342                              (const_int 32)])))
2343    (clobber (match_scratch:SI 6 "=l,l"))
2344    (clobber (match_scratch:SI 7 "=a,a"))
2345    (clobber (match_scratch:SI 8 "=X,h"))]
2346   "ISA_HAS_MULHI
2347    && TARGET_64BIT
2348    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2349   "*
2351   static char const *const sign[] = { \"mult\\t%1,%2\",  \"mulhi\\t%0,%1,%2\"  };
2352   static char const *const zero[] = { \"multu\\t%1,%2\", \"mulhiu\\t%0,%1,%2\" };
2353   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2354     return sign[which_alternative];
2355   else
2356     return zero[which_alternative];
2358   [(set_attr "type"     "imul")
2359    (set_attr "mode"     "SI")
2360    (set_attr "length"   "4")])
2362 (define_insn "*xmulsi3_neg_highpart_mulhi"
2363   [(set (match_operand:SI 0 "register_operand" "=h,d")
2364         (truncate:SI
2365          (match_operator:DI 5 "highpart_shift_operator"
2366                             [(neg:DI
2367                               (mult:DI (match_operator:DI 3 "extend_operator"
2368                                                           [(match_operand:SI 1 "register_operand" "d,d")])
2369                                        (match_operator:DI 4 "extend_operator"
2370                                                           [(match_operand:SI 2 "register_operand" "d,d")])))
2371                              (const_int 32)])))
2372    (clobber (match_scratch:SI 6 "=l,l"))
2373    (clobber (match_scratch:SI 7 "=a,a"))
2374    (clobber (match_scratch:SI 8 "=X,h"))]
2375   "ISA_HAS_MULHI
2376    && TARGET_64BIT
2377    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2378   "*
2380   static char const *const sign[] = { \"mulshi\\t$0,%1,%2\",  \"mulshi\\t%0,%1,%2\"  };
2381   static char const *const zero[] = { \"mulshiu\\t$0,%1,%2\", \"mulshiu\\t%0,%1,%2\" };
2382   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2383     return sign[which_alternative];
2384   else
2385     return zero[which_alternative];
2387   [(set_attr "type"     "imul")
2388    (set_attr "mode"     "SI")
2389    (set_attr "length"   "4")])
2392 (define_insn "smuldi3_highpart"
2393   [(set (match_operand:DI 0 "register_operand" "=h")
2394         (truncate:DI
2395          (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2396                                (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2397                       (const_int 64))))
2398    (clobber (match_scratch:DI 3 "=l"))
2399    (clobber (match_scratch:DI 4 "=a"))]
2400   "TARGET_64BIT"
2401   "dmult\\t%1,%2"
2402   [(set_attr "type"     "imul")
2403    (set_attr "mode"     "DI")])
2405 (define_insn "umuldi3_highpart"
2406   [(set (match_operand:DI 0 "register_operand" "=h")
2407         (truncate:DI
2408          (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2409                                (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2410                       (const_int 64))))
2411    (clobber (match_scratch:DI 3 "=l"))
2412    (clobber (match_scratch:DI 4 "=a"))]
2413   "TARGET_64BIT"
2414   "dmultu\\t%1,%2"
2415   [(set_attr "type"     "imul")
2416    (set_attr "mode"     "DI")])
2418 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2419 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
2421 (define_insn "madsi"
2422   [(set (match_operand:SI 0 "register_operand" "+l")
2423         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2424                           (match_operand:SI 2 "register_operand" "d"))
2425                  (match_dup 0)))
2426    (clobber (match_scratch:SI 3 "=h"))
2427    (clobber (match_scratch:SI 4 "=a"))]
2428   "TARGET_MAD"
2429   "mad\\t%1,%2"
2430   [(set_attr "type"     "imadd")
2431    (set_attr "mode"     "SI")])
2433 (define_insn "*mul_acc_di"
2434   [(set (match_operand:DI 0 "register_operand" "+x")
2435         (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2436                            [(match_operand:SI 1 "register_operand" "d")])
2437                           (match_operator:DI 4 "extend_operator"
2438                            [(match_operand:SI 2 "register_operand" "d")]))
2439                  (match_dup 0)))
2440    (clobber (match_scratch:SI 5 "=a"))]
2441   "TARGET_MAD
2442    && ! TARGET_64BIT
2443    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2444   "*
2446   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2447     return \"mad\\t%1,%2\";
2448   else
2449     return \"madu\\t%1,%2\";
2451   [(set_attr "type"     "imadd")
2452    (set_attr "mode"     "SI")])
2454 (define_insn "*mul_acc_64bit_di"
2455   [(set (match_operand:DI 0 "register_operand" "+a")
2456         (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2457                            [(match_operand:SI 1 "register_operand" "d")])
2458                           (match_operator:DI 4 "extend_operator"
2459                            [(match_operand:SI 2 "register_operand" "d")]))
2460                  (match_dup 0)))
2461    (clobber (match_scratch:SI 5 "=h"))
2462    (clobber (match_scratch:SI 6 "=l"))]
2463   "TARGET_MAD
2464    && TARGET_64BIT
2465    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2466   "*
2468   if (TARGET_MAD)
2469     {
2470       if (GET_CODE (operands[3]) == SIGN_EXTEND)
2471         return \"mad\\t%1,%2\";
2472       else
2473         return \"madu\\t%1,%2\";
2474     }
2475   else if (ISA_HAS_MACC)
2476     {
2477       if (GET_CODE (operands[3]) == SIGN_EXTEND)
2478         {
2479           if (TARGET_MIPS5500)
2480             return \"madd\\t%1,%2\";
2481           else
2482         return \"macc\\t$0,%1,%2\";
2483         }
2484       else
2485         {
2486           if (TARGET_MIPS5500)
2487             return \"maddu\\t%1,%2\";
2488           else
2489         return \"maccu\\t$0,%1,%2\";
2490         }
2491     }
2492   else
2493     abort ();
2496   [(set_attr "type"     "imadd")
2497    (set_attr "mode"     "SI")])
2499 ;; Floating point multiply accumulate instructions.
2501 (define_insn ""
2502   [(set (match_operand:DF 0 "register_operand" "=f")
2503         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2504                           (match_operand:DF 2 "register_operand" "f"))
2505                  (match_operand:DF 3 "register_operand" "f")))]
2506   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2507   "madd.d\\t%0,%3,%1,%2"
2508   [(set_attr "type"     "fmadd")
2509    (set_attr "mode"     "DF")])
2511 (define_insn ""
2512   [(set (match_operand:SF 0 "register_operand" "=f")
2513         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2514                           (match_operand:SF 2 "register_operand" "f"))
2515                  (match_operand:SF 3 "register_operand" "f")))]
2516   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2517   "madd.s\\t%0,%3,%1,%2"
2518   [(set_attr "type"     "fmadd")
2519    (set_attr "mode"     "SF")])
2521 (define_insn ""
2522   [(set (match_operand:DF 0 "register_operand" "=f")
2523         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2524                            (match_operand:DF 2 "register_operand" "f"))
2525                   (match_operand:DF 3 "register_operand" "f")))]
2526   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2527   "msub.d\\t%0,%3,%1,%2"
2528   [(set_attr "type"     "fmadd")
2529    (set_attr "mode"     "DF")])
2531 (define_insn ""
2532   [(set (match_operand:SF 0 "register_operand" "=f")
2533         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2534                            (match_operand:SF 2 "register_operand" "f"))
2535                   (match_operand:SF 3 "register_operand" "f")))]
2537   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2538   "msub.s\\t%0,%3,%1,%2"
2539   [(set_attr "type"     "fmadd")
2540    (set_attr "mode"     "SF")])
2542 (define_insn ""
2543   [(set (match_operand:DF 0 "register_operand" "=f")
2544         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2545                                   (match_operand:DF 2 "register_operand" "f"))
2546                          (match_operand:DF 3 "register_operand" "f"))))]
2547   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2548   "nmadd.d\\t%0,%3,%1,%2"
2549   [(set_attr "type"     "fmadd")
2550    (set_attr "mode"     "DF")])
2552 (define_insn ""
2553   [(set (match_operand:SF 0 "register_operand" "=f")
2554         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2555                                   (match_operand:SF 2 "register_operand" "f"))
2556                          (match_operand:SF 3 "register_operand" "f"))))]
2557   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2558   "nmadd.s\\t%0,%3,%1,%2"
2559   [(set_attr "type"     "fmadd")
2560    (set_attr "mode"     "SF")])
2562 (define_insn ""
2563   [(set (match_operand:DF 0 "register_operand" "=f")
2564         (minus:DF (match_operand:DF 1 "register_operand" "f")
2565                   (mult:DF (match_operand:DF 2 "register_operand" "f")
2566                            (match_operand:DF 3 "register_operand" "f"))))]
2567   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2568   "nmsub.d\\t%0,%1,%2,%3"
2569   [(set_attr "type"     "fmadd")
2570    (set_attr "mode"     "DF")])
2572 (define_insn ""
2573   [(set (match_operand:SF 0 "register_operand" "=f")
2574         (minus:SF (match_operand:SF 1 "register_operand" "f")
2575                   (mult:SF (match_operand:SF 2 "register_operand" "f")
2576                            (match_operand:SF 3 "register_operand" "f"))))]
2577   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2578   "nmsub.s\\t%0,%1,%2,%3"
2579   [(set_attr "type"     "fmadd")
2580    (set_attr "mode"     "SF")])
2583 ;;  ....................
2585 ;;      DIVISION and REMAINDER
2587 ;;  ....................
2590 (define_insn "divdf3"
2591   [(set (match_operand:DF 0 "register_operand" "=f")
2592         (div:DF (match_operand:DF 1 "register_operand" "f")
2593                 (match_operand:DF 2 "register_operand" "f")))]
2594   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2595   "div.d\\t%0,%1,%2"
2596   [(set_attr "type"     "fdiv")
2597    (set_attr "mode"     "DF")])
2599 (define_insn "divsf3"
2600   [(set (match_operand:SF 0 "register_operand" "=f")
2601         (div:SF (match_operand:SF 1 "register_operand" "f")
2602                 (match_operand:SF 2 "register_operand" "f")))]
2603   "TARGET_HARD_FLOAT"
2604   "div.s\\t%0,%1,%2"
2605   [(set_attr "type"     "fdiv")
2606    (set_attr "mode"     "SF")])
2608 (define_insn ""
2609   [(set (match_operand:DF 0 "register_operand" "=f")
2610         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2611                 (match_operand:DF 2 "register_operand" "f")))]
2612   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2613   "recip.d\\t%0,%2"
2614   [(set_attr "type"     "fdiv")
2615    (set_attr "mode"     "DF")])
2617 (define_insn ""
2618   [(set (match_operand:SF 0 "register_operand" "=f")
2619         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2620                 (match_operand:SF 2 "register_operand" "f")))]
2621   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2622   "recip.s\\t%0,%2"
2623   [(set_attr "type"     "fdiv")
2624    (set_attr "mode"     "SF")])
2626 ;; If optimizing, prefer the divmod functions over separate div and
2627 ;; mod functions, since this will allow using one instruction for both
2628 ;; the quotient and remainder.  At present, the divmod is not moved out
2629 ;; of loops if it is constant within the loop, so allow -mdebugc to
2630 ;; use the old method of doing things.
2632 ;; 64 is the multiply/divide hi register
2633 ;; 65 is the multiply/divide lo register
2635 ;; ??? We can't accept constants here, because the MIPS assembler will replace
2636 ;; a divide by power of 2 with a shift, and then the remainder is no longer
2637 ;; available.
2639 (define_expand "divmodsi4"
2640   [(set (match_operand:SI 0 "register_operand" "=d")
2641         (div:SI (match_operand:SI 1 "register_operand" "d")
2642                 (match_operand:SI 2 "register_operand" "d")))
2643    (set (match_operand:SI 3 "register_operand" "=d")
2644         (mod:SI (match_dup 1)
2645                 (match_dup 2)))
2646    (clobber (match_scratch:SI 4 "=l"))
2647    (clobber (match_scratch:SI 5 "=h"))
2648    (clobber (match_scratch:SI 6 "=a"))]
2649   "optimize"
2650   "
2652   emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
2653              operands[3]));
2654   if (!TARGET_NO_CHECK_ZERO_DIV)
2655     {
2656       emit_insn (gen_div_trap (operands[2],
2657                                GEN_INT (0),
2658                                GEN_INT (0x7)));
2659     }
2660   if (TARGET_CHECK_RANGE_DIV)
2661     {
2662       emit_insn (gen_div_trap (operands[2],
2663                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2664                                GEN_INT (0x6)));
2665       emit_insn (gen_div_trap (operands[2],
2666                                copy_to_mode_reg (SImode,
2667                                                  GEN_INT
2668                                                  (trunc_int_for_mode
2669                                                   (BITMASK_HIGH, SImode))),
2670                                GEN_INT (0x6)));
2671     }
2673   DONE;
2676 (define_insn "divmodsi4_internal"
2677   [(set (match_operand:SI 0 "register_operand" "=l")
2678         (div:SI (match_operand:SI 1 "register_operand" "d")
2679                 (match_operand:SI 2 "register_operand" "d")))
2680    (set (match_operand:SI 3 "register_operand" "=h")
2681         (mod:SI (match_dup 1)
2682                 (match_dup 2)))
2683    (clobber (match_scratch:SI 4 "=a"))]
2684   "optimize"
2685   "div\\t$0,%1,%2"
2686   [(set_attr "type"     "idiv")
2687    (set_attr "mode"     "SI")])
2689 (define_expand "divmoddi4"
2690   [(set (match_operand:DI 0 "register_operand" "=d")
2691         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2692                 (match_operand:DI 2 "se_register_operand" "d")))
2693    (set (match_operand:DI 3 "register_operand" "=d")
2694         (mod:DI (match_dup 1)
2695                 (match_dup 2)))
2696    (clobber (match_scratch:DI 4 "=l"))
2697    (clobber (match_scratch:DI 5 "=h"))
2698    (clobber (match_scratch:DI 6 "=a"))]
2699   "TARGET_64BIT && optimize"
2700   "
2702   emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
2703              operands[3]));
2704   if (!TARGET_NO_CHECK_ZERO_DIV)
2705     {
2706       emit_insn (gen_div_trap (operands[2],
2707                                GEN_INT (0),
2708                                GEN_INT (0x7)));
2709     }
2710   if (TARGET_CHECK_RANGE_DIV)
2711     {
2712       emit_insn (gen_div_trap (operands[2],
2713                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2714                                GEN_INT (0x6)));
2715       emit_insn (gen_div_trap (operands[2],
2716                                copy_to_mode_reg (DImode,
2717                                                  GEN_INT (BITMASK_HIGH)),
2718                                GEN_INT (0x6)));
2719     }
2721   DONE;
2724 (define_insn "divmoddi4_internal"
2725   [(set (match_operand:DI 0 "register_operand" "=l")
2726         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2727                 (match_operand:DI 2 "se_register_operand" "d")))
2728    (set (match_operand:DI 3 "register_operand" "=h")
2729         (mod:DI (match_dup 1)
2730                 (match_dup 2)))
2731    (clobber (match_scratch:DI 4 "=a"))]
2732   "TARGET_64BIT && optimize"
2733   "ddiv\\t$0,%1,%2"
2734   [(set_attr "type"     "idiv")
2735    (set_attr "mode"     "SI")])
2737 (define_expand "udivmodsi4"
2738   [(set (match_operand:SI 0 "register_operand" "=d")
2739         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2740                  (match_operand:SI 2 "register_operand" "d")))
2741    (set (match_operand:SI 3 "register_operand" "=d")
2742         (umod:SI (match_dup 1)
2743                  (match_dup 2)))
2744    (clobber (match_scratch:SI 4 "=l"))
2745    (clobber (match_scratch:SI 5 "=h"))
2746    (clobber (match_scratch:SI 6 "=a"))]
2747   "optimize"
2748   "
2750   emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
2751                                       operands[3]));
2752   if (!TARGET_NO_CHECK_ZERO_DIV)
2753     {
2754       emit_insn (gen_div_trap (operands[2],
2755                                GEN_INT (0),
2756                                GEN_INT (0x7)));
2757     }
2759   DONE;
2762 (define_insn "udivmodsi4_internal"
2763   [(set (match_operand:SI 0 "register_operand" "=l")
2764         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2765                  (match_operand:SI 2 "register_operand" "d")))
2766    (set (match_operand:SI 3 "register_operand" "=h")
2767         (umod:SI (match_dup 1)
2768                  (match_dup 2)))
2769    (clobber (match_scratch:SI 4 "=a"))]
2770   "optimize"
2771   "divu\\t$0,%1,%2"
2772   [(set_attr "type"     "idiv")
2773    (set_attr "mode"     "SI")])
2775 (define_expand "udivmoddi4"
2776   [(set (match_operand:DI 0 "register_operand" "=d")
2777         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2778                  (match_operand:DI 2 "se_register_operand" "d")))
2779    (set (match_operand:DI 3 "register_operand" "=d")
2780         (umod:DI (match_dup 1)
2781                  (match_dup 2)))
2782    (clobber (match_scratch:DI 4 "=l"))
2783    (clobber (match_scratch:DI 5 "=h"))
2784    (clobber (match_scratch:DI 6 "=a"))]
2785   "TARGET_64BIT && optimize"
2786   "
2788   emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
2789                                       operands[3]));
2790   if (!TARGET_NO_CHECK_ZERO_DIV)
2791     {
2792       emit_insn (gen_div_trap (operands[2],
2793                                GEN_INT (0),
2794                                GEN_INT (0x7)));
2795     }
2797   DONE;
2800 (define_insn "udivmoddi4_internal"
2801   [(set (match_operand:DI 0 "register_operand" "=l")
2802         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2803                  (match_operand:DI 2 "se_register_operand" "d")))
2804    (set (match_operand:DI 3 "register_operand" "=h")
2805         (umod:DI (match_dup 1)
2806                  (match_dup 2)))
2807    (clobber (match_scratch:DI 4 "=a"))]
2808   "TARGET_64BIT && optimize"
2809   "ddivu\\t$0,%1,%2"
2810   [(set_attr "type"     "idiv")
2811    (set_attr "mode"     "SI")])
2813 ;; Division trap
2815 (define_expand "div_trap"
2816   [(trap_if (eq (match_operand 0 "register_operand" "d")
2817                 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2818             (match_operand 2 "immediate_operand" ""))]
2819   ""
2820   "
2822   if (TARGET_MIPS16)
2823     emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
2824   else
2825     emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
2826   DONE;
2829 (define_insn "div_trap_normal"
2830   [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2831                 (match_operand 1 "true_reg_or_0_operand" "d,J"))
2832             (match_operand 2 "immediate_operand" ""))]
2833   "!TARGET_MIPS16"
2834   "*
2836   rtx link;
2837   int have_dep_anti = 0;
2839   /* For divmod if one division is not needed then we don't need an extra
2840      divide by zero trap, which is anti dependent on previous trap */
2841   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2843     if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2844         && GET_CODE (XEXP (link, 0)) == INSN
2845         && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2846         && which_alternative == 1)
2847       have_dep_anti = 1;
2848   if (! have_dep_anti)
2849     {
2850       if (GENERATE_BRANCHLIKELY)
2851         {
2852           if (which_alternative == 1)
2853             return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2854           else
2855             return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2856         }
2857       else
2858         {
2859           if (which_alternative == 1)
2860             return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2861           else
2862             return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2863         }
2864     }
2865   return \"\";
2867   [(set_attr "type" "unknown")
2868    (set_attr "length" "12")])
2871 ;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
2873 (define_insn "div_trap_mips16"
2874   [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2875                 (match_operand 1 "true_reg_or_0_operand" "d,J"))
2876             (match_operand 2 "immediate_operand" ""))
2877    (clobber (reg:SI 24))]
2878   "TARGET_MIPS16"
2879   "*
2881   rtx link;
2882   int have_dep_anti = 0;
2884   /* For divmod if one division is not needed then we don't need an extra
2885      divide by zero trap, which is anti dependent on previous trap */
2886   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2888     if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2889         && GET_CODE (XEXP (link, 0)) == INSN
2890         && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2891         && which_alternative == 1)
2892       have_dep_anti = 1;
2893   if (! have_dep_anti)
2894     {
2895       /* No branch delay slots on mips16.  */
2896       if (which_alternative == 1)
2897         return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2898       else
2899         return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2900     }
2901   return \"\";
2903   [(set_attr "type" "unknown")
2904    (set_attr "length" "12")])
2906 (define_expand "divsi3"
2907   [(set (match_operand:SI 0 "register_operand" "=l")
2908         (div:SI (match_operand:SI 1 "register_operand" "d")
2909                 (match_operand:SI 2 "register_operand" "d")))
2910    (clobber (match_scratch:SI 3 "=h"))
2911    (clobber (match_scratch:SI 4 "=a"))]
2912   "!optimize"
2913   "
2915   emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
2916   if (!TARGET_NO_CHECK_ZERO_DIV)
2917     {
2918       emit_insn (gen_div_trap (operands[2],
2919                                GEN_INT (0),
2920                                GEN_INT (0x7)));
2921     }
2922   if (TARGET_CHECK_RANGE_DIV)
2923     {
2924       emit_insn (gen_div_trap (operands[2],
2925                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2926                                GEN_INT (0x6)));
2927       emit_insn (gen_div_trap (operands[2],
2928                                copy_to_mode_reg (SImode,
2929                                                  GEN_INT
2930                                                  (trunc_int_for_mode
2931                                                   (BITMASK_HIGH, SImode))),
2932                                GEN_INT (0x6)));
2933     }
2935   DONE;
2938 (define_insn "divsi3_internal"
2939   [(set (match_operand:SI 0 "register_operand" "=l")
2940         (div:SI (match_operand:SI 1 "register_operand" "d")
2941                 (match_operand:SI 2 "nonmemory_operand" "di")))
2942    (clobber (match_scratch:SI 3 "=h"))
2943    (clobber (match_scratch:SI 4 "=a"))]
2944   "!optimize"
2945   "div\\t$0,%1,%2"
2946   [(set_attr "type"     "idiv")
2947    (set_attr "mode"     "SI")])
2949 (define_expand "divdi3"
2950   [(set (match_operand:DI 0 "register_operand" "=l")
2951         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2952                 (match_operand:DI 2 "se_register_operand" "d")))
2953    (clobber (match_scratch:DI 3 "=h"))
2954    (clobber (match_scratch:DI 4 "=a"))]
2955   "TARGET_64BIT && !optimize"
2956   "
2958   emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
2959   if (!TARGET_NO_CHECK_ZERO_DIV)
2960     {
2961       emit_insn (gen_div_trap (operands[2],
2962                                GEN_INT (0),
2963                                GEN_INT (0x7)));
2964     }
2965   if (TARGET_CHECK_RANGE_DIV)
2966     {
2967       emit_insn (gen_div_trap (operands[2],
2968                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2969                                GEN_INT (0x6)));
2970       emit_insn (gen_div_trap (operands[2],
2971                                copy_to_mode_reg (DImode,
2972                                                  GEN_INT (BITMASK_HIGH)),
2973                                GEN_INT (0x6)));
2974     }
2976   DONE;
2979 (define_insn "divdi3_internal"
2980   [(set (match_operand:DI 0 "register_operand" "=l")
2981         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2982                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2983    (clobber (match_scratch:SI 3 "=h"))
2984    (clobber (match_scratch:SI 4 "=a"))]
2985   "TARGET_64BIT && !optimize"
2986   "ddiv\\t$0,%1,%2"
2987   [(set_attr "type"     "idiv")
2988    (set_attr "mode"     "DI")])
2990 (define_expand "modsi3"
2991   [(set (match_operand:SI 0 "register_operand" "=h")
2992         (mod:SI (match_operand:SI 1 "register_operand" "d")
2993                 (match_operand:SI 2 "register_operand" "d")))
2994    (clobber (match_scratch:SI 3 "=l"))
2995    (clobber (match_scratch:SI 4 "=a"))]
2996   "!optimize"
2997   "
2999   emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
3000   if (!TARGET_NO_CHECK_ZERO_DIV)
3001     {
3002       emit_insn (gen_div_trap (operands[2],
3003                                GEN_INT (0),
3004                                GEN_INT (0x7)));
3005     }
3006   if (TARGET_CHECK_RANGE_DIV)
3007     {
3008       emit_insn (gen_div_trap (operands[2],
3009                                copy_to_mode_reg (SImode, GEN_INT (-1)),
3010                                GEN_INT (0x6)));
3011       emit_insn (gen_div_trap (operands[2],
3012                                copy_to_mode_reg (SImode,
3013                                                  GEN_INT
3014                                                  (trunc_int_for_mode
3015                                                   (BITMASK_HIGH, SImode))),
3016                                GEN_INT (0x6)));
3017     }
3019   DONE;
3022 (define_insn "modsi3_internal"
3023   [(set (match_operand:SI 0 "register_operand" "=h")
3024         (mod:SI (match_operand:SI 1 "register_operand" "d")
3025                 (match_operand:SI 2 "nonmemory_operand" "di")))
3026    (clobber (match_scratch:SI 3 "=l"))
3027    (clobber (match_scratch:SI 4 "=a"))]
3028   "!optimize"
3029   "div\\t$0,%1,%2"
3030   [(set_attr "type"     "idiv")
3031    (set_attr "mode"     "SI")])
3033 (define_expand "moddi3"
3034   [(set (match_operand:DI 0 "register_operand" "=h")
3035         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
3036                 (match_operand:DI 2 "se_register_operand" "d")))
3037    (clobber (match_scratch:DI 3 "=l"))
3038    (clobber (match_scratch:DI 4 "=a"))]
3039   "TARGET_64BIT && !optimize"
3040   "
3042   emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
3043   if (!TARGET_NO_CHECK_ZERO_DIV)
3044     {
3045       emit_insn (gen_div_trap (operands[2],
3046                                GEN_INT (0),
3047                                GEN_INT (0x7)));
3048     }
3049   if (TARGET_CHECK_RANGE_DIV)
3050     {
3051       emit_insn (gen_div_trap (operands[2],
3052                                copy_to_mode_reg (DImode, GEN_INT (-1)),
3053                                GEN_INT (0x6)));
3054       emit_insn (gen_div_trap (operands[2],
3055                                copy_to_mode_reg (DImode,
3056                                                  GEN_INT (BITMASK_HIGH)),
3057                                GEN_INT (0x6)));
3058     }
3060   DONE;
3063 (define_insn "moddi3_internal"
3064   [(set (match_operand:DI 0 "register_operand" "=h")
3065         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
3066                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
3067    (clobber (match_scratch:SI 3 "=l"))
3068    (clobber (match_scratch:SI 4 "=a"))]
3069   "TARGET_64BIT && !optimize"
3070   "ddiv\\t$0,%1,%2"
3071   [(set_attr "type"     "idiv")
3072    (set_attr "mode"     "DI")])
3074 (define_expand "udivsi3"
3075   [(set (match_operand:SI 0 "register_operand" "=l")
3076         (udiv:SI (match_operand:SI 1 "register_operand" "d")
3077                  (match_operand:SI 2 "register_operand" "d")))
3078    (clobber (match_scratch:SI 3 "=h"))
3079    (clobber (match_scratch:SI 4 "=a"))]
3080   "!optimize"
3081   "
3083   emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
3084   if (!TARGET_NO_CHECK_ZERO_DIV)
3085     {
3086       emit_insn (gen_div_trap (operands[2],
3087                                GEN_INT (0),
3088                                GEN_INT (0x7)));
3089     }
3091   DONE;
3094 (define_insn "udivsi3_internal"
3095   [(set (match_operand:SI 0 "register_operand" "=l")
3096         (udiv:SI (match_operand:SI 1 "register_operand" "d")
3097                  (match_operand:SI 2 "nonmemory_operand" "di")))
3098    (clobber (match_scratch:SI 3 "=h"))
3099    (clobber (match_scratch:SI 4 "=a"))]
3100   "!optimize"
3101   "divu\\t$0,%1,%2"
3102   [(set_attr "type"     "idiv")
3103    (set_attr "mode"     "SI")])
3105 (define_expand "udivdi3"
3106   [(set (match_operand:DI 0 "register_operand" "=l")
3107         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
3108                  (match_operand:DI 2 "se_register_operand" "di")))
3109    (clobber (match_scratch:DI 3 "=h"))
3110    (clobber (match_scratch:DI 4 "=a"))]
3111   "TARGET_64BIT && !optimize"
3112   "
3114   emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
3115   if (!TARGET_NO_CHECK_ZERO_DIV)
3116     {
3117       emit_insn (gen_div_trap (operands[2],
3118                                GEN_INT (0),
3119                                GEN_INT (0x7)));
3120     }
3122   DONE;
3125 (define_insn "udivdi3_internal"
3126   [(set (match_operand:DI 0 "register_operand" "=l")
3127         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
3128                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
3129    (clobber (match_scratch:SI 3 "=h"))
3130    (clobber (match_scratch:SI 4 "=a"))]
3131   "TARGET_64BIT && !optimize"
3132   "ddivu\\t$0,%1,%2"
3133   [(set_attr "type"     "idiv")
3134    (set_attr "mode"     "DI")])
3136 (define_expand "umodsi3"
3137   [(set (match_operand:SI 0 "register_operand" "=h")
3138         (umod:SI (match_operand:SI 1 "register_operand" "d")
3139                  (match_operand:SI 2 "register_operand" "d")))
3140    (clobber (match_scratch:SI 3 "=l"))
3141    (clobber (match_scratch:SI 4 "=a"))]
3142   "!optimize"
3143   "
3145   emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
3146   if (!TARGET_NO_CHECK_ZERO_DIV)
3147     {
3148       emit_insn (gen_div_trap (operands[2],
3149                                GEN_INT (0),
3150                                GEN_INT (0x7)));
3151     }
3153   DONE;
3156 (define_insn "umodsi3_internal"
3157   [(set (match_operand:SI 0 "register_operand" "=h")
3158         (umod:SI (match_operand:SI 1 "register_operand" "d")
3159                  (match_operand:SI 2 "nonmemory_operand" "di")))
3160    (clobber (match_scratch:SI 3 "=l"))
3161    (clobber (match_scratch:SI 4 "=a"))]
3162   "!optimize"
3163   "divu\\t$0,%1,%2"
3164   [(set_attr "type"     "idiv")
3165    (set_attr "mode"     "SI")])
3167 (define_expand "umoddi3"
3168   [(set (match_operand:DI 0 "register_operand" "=h")
3169         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
3170                  (match_operand:DI 2 "se_register_operand" "di")))
3171    (clobber (match_scratch:DI 3 "=l"))
3172    (clobber (match_scratch:DI 4 "=a"))]
3173   "TARGET_64BIT && !optimize"
3174   "
3176   emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
3177   if (!TARGET_NO_CHECK_ZERO_DIV)
3178     {
3179       emit_insn (gen_div_trap (operands[2],
3180                                GEN_INT (0),
3181                                GEN_INT (0x7)));
3182     }
3184   DONE;
3187 (define_insn "umoddi3_internal"
3188   [(set (match_operand:DI 0 "register_operand" "=h")
3189         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
3190                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
3191    (clobber (match_scratch:SI 3 "=l"))
3192    (clobber (match_scratch:SI 4 "=a"))]
3193   "TARGET_64BIT && !optimize"
3194   "ddivu\\t$0,%1,%2"
3195   [(set_attr "type"     "idiv")
3196    (set_attr "mode"     "DI")])
3199 ;;  ....................
3201 ;;      SQUARE ROOT
3203 ;;  ....................
3205 (define_insn "sqrtdf2"
3206   [(set (match_operand:DF 0 "register_operand" "=f")
3207         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
3208   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
3209   "sqrt.d\\t%0,%1"
3210   [(set_attr "type"     "fsqrt")
3211    (set_attr "mode"     "DF")])
3213 (define_insn "sqrtsf2"
3214   [(set (match_operand:SF 0 "register_operand" "=f")
3215         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
3216   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
3217   "sqrt.s\\t%0,%1"
3218   [(set_attr "type"     "fsqrt")
3219    (set_attr "mode"     "SF")])
3221 (define_insn ""
3222   [(set (match_operand:DF 0 "register_operand" "=f")
3223         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
3224                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
3225   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
3226   "rsqrt.d\\t%0,%2"
3227   [(set_attr "type"     "frsqrt")
3228    (set_attr "mode"     "DF")])
3230 (define_insn ""
3231   [(set (match_operand:SF 0 "register_operand" "=f")
3232         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
3233                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
3234   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
3235   "rsqrt.s\\t%0,%2"
3236   [(set_attr "type"     "frsqrt")
3237    (set_attr "mode"     "SF")])
3241 ;;  ....................
3243 ;;      ABSOLUTE VALUE
3245 ;;  ....................
3247 ;; Do not use the integer abs macro instruction, since that signals an
3248 ;; exception on -2147483648 (sigh).
3250 (define_insn "abssi2"
3251   [(set (match_operand:SI 0 "register_operand" "=d")
3252         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
3253   "!TARGET_MIPS16"
3254   "*
3256   dslots_jump_total++;
3257   dslots_jump_filled++;
3258   operands[2] = const0_rtx;
3260   if (REGNO (operands[0]) == REGNO (operands[1]))
3261     {
3262       if (GENERATE_BRANCHLIKELY)
3263         return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
3264       else
3265         return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
3266     }
3267   else
3268     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
3270   [(set_attr "type"     "multi")
3271    (set_attr "mode"     "SI")
3272    (set_attr "length"   "12")])
3274 (define_insn "absdi2"
3275   [(set (match_operand:DI 0 "register_operand" "=d")
3276         (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
3277   "TARGET_64BIT && !TARGET_MIPS16"
3278   "*
3280   unsigned int regno1;
3281   dslots_jump_total++;
3282   dslots_jump_filled++;
3283   operands[2] = const0_rtx;
3285   if (GET_CODE (operands[1]) == REG)
3286     regno1 = REGNO (operands[1]);
3287   else
3288     regno1 = REGNO (XEXP (operands[1], 0));
3290   if (REGNO (operands[0]) == regno1)
3291     return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3292   else
3293     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3295   [(set_attr "type"     "multi")
3296    (set_attr "mode"     "DI")
3297    (set_attr "length"   "12")])
3299 (define_insn "absdf2"
3300   [(set (match_operand:DF 0 "register_operand" "=f")
3301         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
3302   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3303   "abs.d\\t%0,%1"
3304   [(set_attr "type"     "fabs")
3305    (set_attr "mode"     "DF")])
3307 (define_insn "abssf2"
3308   [(set (match_operand:SF 0 "register_operand" "=f")
3309         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
3310   "TARGET_HARD_FLOAT"
3311   "abs.s\\t%0,%1"
3312   [(set_attr "type"     "fabs")
3313    (set_attr "mode"     "SF")])
3317 ;;  ....................
3319 ;;      FIND FIRST BIT INSTRUCTION
3321 ;;  ....................
3324 (define_insn "ffssi2"
3325   [(set (match_operand:SI 0 "register_operand" "=&d")
3326         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
3327    (clobber (match_scratch:SI 2 "=&d"))
3328    (clobber (match_scratch:SI 3 "=&d"))]
3329   "!TARGET_MIPS16"
3330   "*
3332   dslots_jump_total += 2;
3333   dslots_jump_filled += 2;
3334   operands[4] = const0_rtx;
3336   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3337     return \"%(\\
3338 move\\t%0,%z4\\n\\
3339 \\tbeq\\t%1,%z4,2f\\n\\
3340 %~1:\\tand\\t%2,%1,0x0001\\n\\
3341 \\taddu\\t%0,%0,1\\n\\
3342 \\tbeq\\t%2,%z4,1b\\n\\
3343 \\tsrl\\t%1,%1,1\\n\\
3344 %~2:%)\";
3346   return \"%(\\
3347 move\\t%0,%z4\\n\\
3348 \\tmove\\t%3,%1\\n\\
3349 \\tbeq\\t%3,%z4,2f\\n\\
3350 %~1:\\tand\\t%2,%3,0x0001\\n\\
3351 \\taddu\\t%0,%0,1\\n\\
3352 \\tbeq\\t%2,%z4,1b\\n\\
3353 \\tsrl\\t%3,%3,1\\n\\
3354 %~2:%)\";
3356   [(set_attr "type"     "multi")
3357    (set_attr "mode"     "SI")
3358    (set_attr "length"   "12")])
3360 (define_insn "ffsdi2"
3361   [(set (match_operand:DI 0 "register_operand" "=&d")
3362         (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
3363    (clobber (match_scratch:DI 2 "=&d"))
3364    (clobber (match_scratch:DI 3 "=&d"))]
3365   "TARGET_64BIT && !TARGET_MIPS16"
3366   "*
3368   dslots_jump_total += 2;
3369   dslots_jump_filled += 2;
3370   operands[4] = const0_rtx;
3372   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3373     return \"%(\\
3374 move\\t%0,%z4\\n\\
3375 \\tbeq\\t%1,%z4,2f\\n\\
3376 %~1:\\tand\\t%2,%1,0x0001\\n\\
3377 \\tdaddu\\t%0,%0,1\\n\\
3378 \\tbeq\\t%2,%z4,1b\\n\\
3379 \\tdsrl\\t%1,%1,1\\n\\
3380 %~2:%)\";
3382   return \"%(\\
3383 move\\t%0,%z4\\n\\
3384 \\tmove\\t%3,%1\\n\\
3385 \\tbeq\\t%3,%z4,2f\\n\\
3386 %~1:\\tand\\t%2,%3,0x0001\\n\\
3387 \\tdaddu\\t%0,%0,1\\n\\
3388 \\tbeq\\t%2,%z4,1b\\n\\
3389 \\tdsrl\\t%3,%3,1\\n\\
3390 %~2:%)\";
3392   [(set_attr "type"     "multi")
3393    (set_attr "mode"     "DI")
3394    (set_attr "length"   "24")])
3398 ;;  ....................
3400 ;;      NEGATION and ONE'S COMPLEMENT
3402 ;;  ....................
3404 (define_insn "negsi2"
3405   [(set (match_operand:SI 0 "register_operand" "=d")
3406         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
3407   ""
3408   "*
3410   if (TARGET_MIPS16)
3411     return \"neg\\t%0,%1\";
3412   operands[2] = const0_rtx;
3413   return \"subu\\t%0,%z2,%1\";
3415   [(set_attr "type"     "arith")
3416    (set_attr "mode"     "SI")])
3418 (define_expand "negdi2"
3419   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
3420                    (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
3421               (clobber (match_dup 2))])]
3422   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3423   "
3425   if (TARGET_64BIT)
3426     {
3427       emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
3428       DONE;
3429     }
3431   operands[2] = gen_reg_rtx (SImode);
3434 (define_insn "negdi2_internal"
3435   [(set (match_operand:DI 0 "register_operand" "=d")
3436         (neg:DI (match_operand:DI 1 "register_operand" "d")))
3437    (clobber (match_operand:SI 2 "register_operand" "=d"))]
3438   "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
3439   "*
3441   operands[3] = const0_rtx;
3442   return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
3444   [(set_attr "type"     "darith")
3445    (set_attr "mode"     "DI")
3446    (set_attr "length"   "16")])
3448 (define_insn "negdi2_internal_2"
3449   [(set (match_operand:DI 0 "register_operand" "=d")
3450         (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
3451   "TARGET_64BIT && !TARGET_MIPS16"
3452   "*
3454   operands[2] = const0_rtx;
3455   return \"dsubu\\t%0,%z2,%1\";
3457   [(set_attr "type"     "arith")
3458    (set_attr "mode"     "DI")])
3460 (define_insn "negdf2"
3461   [(set (match_operand:DF 0 "register_operand" "=f")
3462         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3463   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3464   "neg.d\\t%0,%1"
3465   [(set_attr "type"     "fneg")
3466    (set_attr "mode"     "DF")])
3468 (define_insn "negsf2"
3469   [(set (match_operand:SF 0 "register_operand" "=f")
3470         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3471   "TARGET_HARD_FLOAT"
3472   "neg.s\\t%0,%1"
3473   [(set_attr "type"     "fneg")
3474    (set_attr "mode"     "SF")])
3476 (define_insn "one_cmplsi2"
3477   [(set (match_operand:SI 0 "register_operand" "=d")
3478         (not:SI (match_operand:SI 1 "register_operand" "d")))]
3479   ""
3480   "*
3482   if (TARGET_MIPS16)
3483     return \"not\\t%0,%1\";
3484   operands[2] = const0_rtx;
3485   return \"nor\\t%0,%z2,%1\";
3487   [(set_attr "type"     "arith")
3488    (set_attr "mode"     "SI")])
3490 (define_insn "one_cmpldi2"
3491   [(set (match_operand:DI 0 "register_operand" "=d")
3492         (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
3493   ""
3494   "*
3496   if (TARGET_MIPS16)
3497     {
3498       if (TARGET_64BIT)
3499         return \"not\\t%0,%1\";
3500       return \"not\\t%M0,%M1\;not\\t%L0,%L1\";
3501     }
3502   operands[2] = const0_rtx;
3503   if (TARGET_64BIT)
3504     return \"nor\\t%0,%z2,%1\";
3505   return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
3507   [(set_attr "type"     "darith")
3508    (set_attr "mode"     "DI")
3509    (set (attr "length")
3510         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3511                        (const_int 4)
3512                        (const_int 8)))])
3514 (define_split
3515   [(set (match_operand:DI 0 "register_operand" "")
3516         (not:DI (match_operand:DI 1 "register_operand" "")))]
3517   "reload_completed && !TARGET_64BIT
3518    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3519    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3520    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3522   [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
3523    (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))]
3524   "")
3528 ;;  ....................
3530 ;;      LOGICAL
3532 ;;  ....................
3535 ;; Many of these instructions uses trivial define_expands, because we
3536 ;; want to use a different set of constraints when TARGET_MIPS16.
3538 (define_expand "andsi3"
3539   [(set (match_operand:SI 0 "register_operand" "=d,d")
3540         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3541                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3542   ""
3543   "
3545   if (TARGET_MIPS16)
3546     {
3547       operands[1] = force_reg (SImode, operands[1]);
3548       operands[2] = force_reg (SImode, operands[2]);
3549     }
3552 (define_insn ""
3553   [(set (match_operand:SI 0 "register_operand" "=d,d")
3554         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3555                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3556   "!TARGET_MIPS16"
3557   "@
3558    and\\t%0,%1,%2
3559    andi\\t%0,%1,%x2"
3560   [(set_attr "type"     "arith")
3561    (set_attr "mode"     "SI")])
3563 (define_insn ""
3564   [(set (match_operand:SI 0 "register_operand" "=d")
3565         (and:SI (match_operand:SI 1 "register_operand" "%0")
3566                 (match_operand:SI 2 "register_operand" "d")))]
3567   "TARGET_MIPS16"
3568   "and\\t%0,%2"
3569   [(set_attr "type"     "arith")
3570    (set_attr "mode"     "SI")])
3572 (define_expand "anddi3"
3573   [(set (match_operand:DI 0 "register_operand" "=d")
3574         (and:DI (match_operand:DI 1 "se_register_operand" "d")
3575                 (match_operand:DI 2 "se_register_operand" "d")))]
3576   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3577   "
3579   if (TARGET_MIPS16)
3580     {
3581       operands[1] = force_reg (DImode, operands[1]);
3582       operands[2] = force_reg (DImode, operands[2]);
3583     }
3586 (define_insn ""
3587   [(set (match_operand:DI 0 "register_operand" "=d")
3588         (and:DI (match_operand:DI 1 "se_register_operand" "d")
3589                 (match_operand:DI 2 "se_register_operand" "d")))]
3590   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3591   "*
3593   if (TARGET_64BIT)
3594     return \"and\\t%0,%1,%2\";
3595   return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
3597   [(set_attr "type"     "darith")
3598    (set_attr "mode"     "DI")
3599    (set (attr "length")
3600         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3601                        (const_int 4)
3602                        (const_int 8)))])
3604 (define_insn ""
3605   [(set (match_operand:DI 0 "register_operand" "=d")
3606         (and:DI (match_operand:DI 1 "se_register_operand" "0")
3607                 (match_operand:DI 2 "se_register_operand" "d")))]
3608   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3609   "*
3611   if (TARGET_64BIT)
3612     return \"and\\t%0,%2\";
3613   return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
3615   [(set_attr "type"     "darith")
3616    (set_attr "mode"     "DI")
3617    (set (attr "length")
3618         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3619                        (const_int 4)
3620                        (const_int 8)))])
3622 (define_split
3623   [(set (match_operand:DI 0 "register_operand" "")
3624         (and:DI (match_operand:DI 1 "register_operand" "")
3625                 (match_operand:DI 2 "register_operand" "")))]
3626   "reload_completed && !TARGET_64BIT
3627    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3628    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3629    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3630    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3632   [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3633    (set (subreg:SI (match_dup 0) 4) (and:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3634   "")
3636 (define_insn "anddi3_internal1"
3637   [(set (match_operand:DI 0 "register_operand" "=d,d")
3638         (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
3639                 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
3640   "TARGET_64BIT && !TARGET_MIPS16"
3641   "@
3642    and\\t%0,%1,%2
3643    andi\\t%0,%1,%x2"
3644   [(set_attr "type"     "arith")
3645    (set_attr "mode"     "DI")])
3647 (define_expand "iorsi3"
3648   [(set (match_operand:SI 0 "register_operand" "=d,d")
3649         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3650                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3651   ""
3652   "
3654   if (TARGET_MIPS16)
3655     {
3656       operands[1] = force_reg (SImode, operands[1]);
3657       operands[2] = force_reg (SImode, operands[2]);
3658     }
3661 (define_insn ""
3662   [(set (match_operand:SI 0 "register_operand" "=d,d")
3663         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3664                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3665   "!TARGET_MIPS16"
3666   "@
3667    or\\t%0,%1,%2
3668    ori\\t%0,%1,%x2"
3669   [(set_attr "type"     "arith")
3670    (set_attr "mode"     "SI")])
3672 (define_insn ""
3673   [(set (match_operand:SI 0 "register_operand" "=d")
3674         (ior:SI (match_operand:SI 1 "register_operand" "%0")
3675                 (match_operand:SI 2 "register_operand" "d")))]
3676   "TARGET_MIPS16"
3677   "or\\t%0,%2"
3678   [(set_attr "type"     "arith")
3679    (set_attr "mode"     "SI")])
3681 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
3682 ;;; TARGET_64BIT
3684 (define_expand "iordi3"
3685   [(set (match_operand:DI 0 "register_operand" "=d")
3686         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3687                 (match_operand:DI 2 "se_register_operand" "d")))]
3688   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3689   "")
3691 (define_insn ""
3692   [(set (match_operand:DI 0 "register_operand" "=d")
3693         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3694                 (match_operand:DI 2 "se_register_operand" "d")))]
3695   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3696   "*
3698   if (TARGET_64BIT)
3699     return \"or\\t%0,%1,%2\";
3700   return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
3702   [(set_attr "type"     "darith")
3703    (set_attr "mode"     "DI")
3704    (set (attr "length")
3705         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3706                        (const_int 4)
3707                        (const_int 8)))])
3709 (define_insn ""
3710   [(set (match_operand:DI 0 "register_operand" "=d")
3711         (ior:DI (match_operand:DI 1 "se_register_operand" "0")
3712                 (match_operand:DI 2 "se_register_operand" "d")))]
3713   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3714   "*
3716   if (TARGET_64BIT)
3717     return \"or\\t%0,%2\";
3718   return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
3720   [(set_attr "type"     "darith")
3721    (set_attr "mode"     "DI")
3722    (set (attr "length")
3723         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3724                        (const_int 4)
3725                        (const_int 8)))])
3727 (define_split
3728   [(set (match_operand:DI 0 "register_operand" "")
3729         (ior:DI (match_operand:DI 1 "register_operand" "")
3730                 (match_operand:DI 2 "register_operand" "")))]
3731   "reload_completed && !TARGET_64BIT
3732    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3733    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3734    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3735    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3737   [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3738    (set (subreg:SI (match_dup 0) 4) (ior:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3739   "")
3741 (define_expand "xorsi3"
3742   [(set (match_operand:SI 0 "register_operand" "=d,d")
3743         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3744                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3745   ""
3746   "")
3748 (define_insn ""
3749   [(set (match_operand:SI 0 "register_operand" "=d,d")
3750         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3751                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3752   "!TARGET_MIPS16"
3753   "@
3754    xor\\t%0,%1,%2
3755    xori\\t%0,%1,%x2"
3756   [(set_attr "type"     "arith")
3757    (set_attr "mode"     "SI")])
3759 (define_insn ""
3760   [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3761         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3762                 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3763   "TARGET_MIPS16"
3764   "@
3765    xor\\t%0,%2
3766    cmpi\\t%1,%2
3767    cmp\\t%1,%2"
3768   [(set_attr "type"     "arith")
3769    (set_attr "mode"     "SI")
3770    (set_attr_alternative "length"
3771                 [(const_int 4)
3772                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3773                                (const_int 4)
3774                                (const_int 8))
3775                  (const_int 4)])])
3777 ;; ??? If delete the 32-bit long long patterns, then could merge this with
3778 ;; the following xordi3_internal pattern.
3779 (define_expand "xordi3"
3780   [(set (match_operand:DI 0 "register_operand" "=d")
3781         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3782                 (match_operand:DI 2 "se_register_operand" "d")))]
3783   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3784   "")
3786 (define_insn ""
3787   [(set (match_operand:DI 0 "register_operand" "=d")
3788         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3789                 (match_operand:DI 2 "se_register_operand" "d")))]
3790   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3791   "*
3793   if (TARGET_64BIT)
3794     return \"xor\\t%0,%1,%2\";
3795   return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
3797   [(set_attr "type"     "darith")
3798    (set_attr "mode"     "DI")
3799    (set (attr "length")
3800         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3801                        (const_int 4)
3802                        (const_int 8)))])
3804 (define_insn ""
3805   [(set (match_operand:DI 0 "register_operand" "=d")
3806         (xor:DI (match_operand:DI 1 "se_register_operand" "0")
3807                 (match_operand:DI 2 "se_register_operand" "d")))]
3808   "!TARGET_64BIT && TARGET_MIPS16"
3809   "xor\\t%M0,%M2\;xor\\t%L0,%L2"
3810   [(set_attr "type"     "darith")
3811    (set_attr "mode"     "DI")
3812    (set_attr "length"   "8")])
3814 (define_insn ""
3815   [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3816         (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
3817                 (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
3818   "TARGET_64BIT && TARGET_MIPS16"
3819   "@
3820    xor\\t%0,%2
3821    cmpi\\t%1,%2
3822    cmp\\t%1,%2"
3823   [(set_attr "type"     "arith")
3824    (set_attr "mode"     "DI")
3825    (set_attr_alternative "length"
3826                 [(const_int 4)
3827                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3828                                (const_int 4)
3829                                (const_int 8))
3830                  (const_int 4)])])
3832 (define_split
3833   [(set (match_operand:DI 0 "register_operand" "")
3834         (xor:DI (match_operand:DI 1 "register_operand" "")
3835                 (match_operand:DI 2 "register_operand" "")))]
3836   "reload_completed && !TARGET_64BIT
3837    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3838    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3839    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3840    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3842   [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3843    (set (subreg:SI (match_dup 0) 4) (xor:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3844   "")
3846 (define_insn "xordi3_immed"
3847   [(set (match_operand:DI 0 "register_operand" "=d")
3848         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3849                 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
3850   "TARGET_64BIT && !TARGET_MIPS16"
3851   "xori\\t%0,%1,%x2"
3852   [(set_attr "type"     "arith")
3853    (set_attr "mode"     "DI")])
3855 (define_insn "*norsi3"
3856   [(set (match_operand:SI 0 "register_operand" "=d")
3857         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3858                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3859   "!TARGET_MIPS16"
3860   "nor\\t%0,%z1,%z2"
3861   [(set_attr "type"     "arith")
3862    (set_attr "mode"     "SI")])
3864 (define_insn "*nordi3"
3865   [(set (match_operand:DI 0 "register_operand" "=d")
3866         (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
3867                 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
3868   "!TARGET_MIPS16"
3869   "*
3871   if (TARGET_64BIT)
3872     return \"nor\\t%0,%z1,%z2\";
3873   return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
3875   [(set_attr "type"     "darith")
3876    (set_attr "mode"     "DI")
3877    (set (attr "length")
3878         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3879                        (const_int 4)
3880                        (const_int 8)))])
3882 (define_split
3883   [(set (match_operand:DI 0 "register_operand" "")
3884         (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
3885                 (not:DI (match_operand:DI 2 "register_operand" ""))))]
3886   "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT
3887    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3888    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3889    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3890    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3892   [(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))))
3893    (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))))]
3894   "")
3897 ;;  ....................
3899 ;;      TRUNCATION
3901 ;;  ....................
3903 (define_insn "truncdfsf2"
3904   [(set (match_operand:SF 0 "register_operand" "=f")
3905         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3906   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3907   "cvt.s.d\\t%0,%1"
3908   [(set_attr "type"     "fcvt")
3909    (set_attr "mode"     "SF")])
3911 (define_insn "truncdisi2"
3912   [(set (match_operand:SI 0 "register_operand" "=d")
3913         (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
3914   "TARGET_64BIT"
3915   "*
3917   if (TARGET_MIPS16)
3918     return \"dsll\\t%0,%1,32\;dsra\\t%0,32\";
3919   return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
3921   [(set_attr "type"     "darith")
3922    (set_attr "mode"     "SI")
3923    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3924                                       (const_int 8)
3925                                       (const_int 16)))])
3927 (define_insn "truncdihi2"
3928   [(set (match_operand:HI 0 "register_operand" "=d")
3929         (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
3930   "TARGET_64BIT"
3931   "*
3933   if (TARGET_MIPS16)
3934     return \"dsll\\t%0,%1,48\;dsra\\t%0,48\";
3935   return \"andi\\t%0,%1,0xffff\";
3937   [(set_attr "type"     "darith")
3938    (set_attr "mode"     "HI")
3939    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3940                                       (const_int 4)
3941                                       (const_int 16)))])
3942 (define_insn "truncdiqi2"
3943   [(set (match_operand:QI 0 "register_operand" "=d")
3944         (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
3945   "TARGET_64BIT"
3946   "*
3948   if (TARGET_MIPS16)
3949     return \"dsll\\t%0,%1,56\;dsra\\t%0,56\";
3950   return \"andi\\t%0,%1,0x00ff\";
3952   [(set_attr "type"     "darith")
3953    (set_attr "mode"     "QI")
3954    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3955                                       (const_int 4)
3956                                       (const_int 16)))])
3958 ;; Combiner patterns to optimize shift/truncate combinations.
3959 (define_insn ""
3960   [(set (match_operand:SI 0 "register_operand" "=d")
3961         (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3962                                   (match_operand:DI 2 "small_int" "I"))))]
3963   "TARGET_64BIT && !TARGET_MIPS16"
3964   "*
3966   int shift_amt = INTVAL (operands[2]) & 0x3f;
3968   if (shift_amt < 32)
3969     {
3970       operands[2] = GEN_INT (32 - shift_amt);
3971       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3972     }
3973   else
3974     {
3975       operands[2] = GEN_INT (shift_amt);
3976       return \"dsra\\t%0,%1,%2\";
3977     }
3979   [(set_attr "type"     "darith")
3980    (set_attr "mode"     "SI")
3981    (set_attr "length"   "8")])
3983 (define_insn ""
3984   [(set (match_operand:SI 0 "register_operand" "=d")
3985         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3986                                   (match_operand:DI 2 "small_int" "I"))))]
3987   "TARGET_64BIT && !TARGET_MIPS16"
3988   "*
3990   int shift_amt = INTVAL (operands[2]) & 0x3f;
3992   if (shift_amt < 32)
3993     {
3994       operands[2] = GEN_INT (32 - shift_amt);
3995       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3996     }
3997   else if (shift_amt == 32)
3998     return \"dsra\\t%0,%1,32\";
3999   else
4000     {
4001       operands[2] = GEN_INT (shift_amt);
4002       return \"dsrl\\t%0,%1,%2\";
4003     }
4005   [(set_attr "type"     "darith")
4006    (set_attr "mode"     "SI")
4007    (set_attr "length"   "8")])
4009 (define_insn ""
4010   [(set (match_operand:SI 0 "register_operand" "=d")
4011         (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
4012                                 (match_operand:DI 2 "small_int" "I"))))]
4013   "TARGET_64BIT"
4014   "*
4016   int shift_amt = INTVAL (operands[2]) & 0x3f;
4018   if (shift_amt < 32)
4019     {
4020       operands[2] = GEN_INT (32 + shift_amt);
4021       if (TARGET_MIPS16)
4022         return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\";
4023       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
4024     }
4025   else
4026     return \"move\\t%0,%.\";
4028   [(set_attr "type"     "darith")
4029    (set_attr "mode"     "SI")
4030    (set_attr "length"   "8")])
4032 ;; Combiner patterns to optimize truncate/zero_extend combinations.
4034 (define_insn ""
4035   [(set (match_operand:SI 0 "register_operand" "=d")
4036         (zero_extend:SI (truncate:HI
4037                          (match_operand:DI 1 "se_register_operand" "d"))))]
4038   "TARGET_64BIT && !TARGET_MIPS16"
4039   "andi\\t%0,%1,0xffff"
4040   [(set_attr "type"     "darith")
4041    (set_attr "mode"     "SI")])
4043 (define_insn ""
4044   [(set (match_operand:SI 0 "register_operand" "=d")
4045         (zero_extend:SI (truncate:QI
4046                          (match_operand:DI 1 "se_register_operand" "d"))))]
4047   "TARGET_64BIT && !TARGET_MIPS16"
4048   "andi\\t%0,%1,0xff"
4049   [(set_attr "type"     "darith")
4050    (set_attr "mode"     "SI")])
4052 (define_insn ""
4053   [(set (match_operand:HI 0 "register_operand" "=d")
4054         (zero_extend:HI (truncate:QI
4055                          (match_operand:DI 1 "se_register_operand" "d"))))]
4056   "TARGET_64BIT && !TARGET_MIPS16"
4057   "andi\\t%0,%1,0xff"
4058   [(set_attr "type"     "darith")
4059    (set_attr "mode"     "HI")])
4062 ;;  ....................
4064 ;;      ZERO EXTENSION
4066 ;;  ....................
4068 ;; Extension insns.
4069 ;; Those for integer source operand are ordered widest source type first.
4071 (define_expand "zero_extendsidi2"
4072   [(set (match_operand:DI 0 "register_operand" "")
4073         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4074   "TARGET_64BIT"
4075   "
4077   if ((optimize || TARGET_MIPS16) && GET_CODE (operands[1]) == MEM)
4078     operands[1] = force_not_mem (operands[1]);
4080   if (GET_CODE (operands[1]) != MEM)
4081     {
4082       rtx op1   = gen_lowpart (DImode, operands[1]);
4083       rtx temp  = gen_reg_rtx (DImode);
4084       rtx shift = GEN_INT (32);
4086       emit_insn (gen_ashldi3 (temp, op1, shift));
4087       emit_insn (gen_lshrdi3 (operands[0], temp, shift));
4088       DONE;
4089     }
4092 (define_insn "zero_extendsidi2_internal"
4093   [(set (match_operand:DI 0 "register_operand" "=d,d")
4094         (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
4095   "TARGET_64BIT && !TARGET_MIPS16"
4096   "* return mips_move_1word (operands, insn, TRUE);"
4097   [(set_attr "type"     "load")
4098    (set_attr "mode"     "DI")
4099    (set_attr "length"   "4,8")])
4101 (define_expand "zero_extendhisi2"
4102   [(set (match_operand:SI 0 "register_operand" "")
4103         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4104   ""
4105   "
4107   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4108     {
4109       rtx op = gen_lowpart (SImode, operands[1]);
4110       rtx temp = force_reg (SImode, GEN_INT (0xffff));
4112       emit_insn (gen_andsi3 (operands[0], op, temp));
4113       DONE;
4114     }
4117 (define_insn ""
4118   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
4119         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
4120   "!TARGET_MIPS16"
4121   "*
4123   if (which_alternative == 0)
4124     return \"andi\\t%0,%1,0xffff\";
4125   else
4126     return mips_move_1word (operands, insn, TRUE);
4128   [(set_attr "type"     "arith,load,load")
4129    (set_attr "mode"     "SI")
4130    (set_attr "length"   "4,4,8")])
4132 (define_insn ""
4133   [(set (match_operand:SI 0 "register_operand" "=d,d")
4134         (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
4135   "TARGET_MIPS16"
4136   "* return mips_move_1word (operands, insn, TRUE);"
4137   [(set_attr "type"     "load,load")
4138    (set_attr "mode"     "SI")
4139    (set_attr "length"   "4,8")])
4141 (define_expand "zero_extendhidi2"
4142   [(set (match_operand:DI 0 "register_operand" "")
4143         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
4144   "TARGET_64BIT"
4145   "
4147   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4148     {
4149       rtx op = gen_lowpart (DImode, operands[1]);
4150       rtx temp = force_reg (DImode, GEN_INT (0xffff));
4152       emit_insn (gen_anddi3 (operands[0], op, temp));
4153       DONE;
4154     }
4157 (define_insn ""
4158   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4159         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
4160   "TARGET_64BIT && !TARGET_MIPS16"
4161   "*
4163   if (which_alternative == 0)
4164     return \"andi\\t%0,%1,0xffff\";
4165   else
4166     return mips_move_1word (operands, insn, TRUE);
4168   [(set_attr "type"     "arith,load,load")
4169    (set_attr "mode"     "DI")
4170    (set_attr "length"   "4,4,8")])
4172 (define_insn ""
4173   [(set (match_operand:DI 0 "register_operand" "=d,d")
4174         (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
4175   "TARGET_64BIT && TARGET_MIPS16"
4176   "* return mips_move_1word (operands, insn, TRUE);"
4177   [(set_attr "type"     "load,load")
4178    (set_attr "mode"     "DI")
4179    (set_attr "length"   "4,8")])
4181 (define_expand "zero_extendqihi2"
4182   [(set (match_operand:HI 0 "register_operand" "")
4183         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
4184   ""
4185   "
4187   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4188     {
4189       rtx op0 = gen_lowpart (SImode, operands[0]);
4190       rtx op1 = gen_lowpart (SImode, operands[1]);
4191       rtx temp = force_reg (SImode, GEN_INT (0xff));
4193       emit_insn (gen_andsi3 (op0, op1, temp));
4194       DONE;
4195     }
4198 (define_insn ""
4199   [(set (match_operand:HI 0 "register_operand" "=d,d,d")
4200         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
4201   "!TARGET_MIPS16"
4202   "*
4204   if (which_alternative == 0)
4205     return \"andi\\t%0,%1,0x00ff\";
4206   else
4207     return mips_move_1word (operands, insn, TRUE);
4209   [(set_attr "type"     "arith,load,load")
4210    (set_attr "mode"     "HI")
4211    (set_attr "length"   "4,4,8")])
4213 (define_insn ""
4214   [(set (match_operand:HI 0 "register_operand" "=d,d")
4215         (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
4216   "TARGET_MIPS16"
4217   "* return mips_move_1word (operands, insn, TRUE);"
4218   [(set_attr "type"     "load,load")
4219    (set_attr "mode"     "HI")
4220    (set_attr "length"   "4,8")])
4222 (define_expand "zero_extendqisi2"
4223   [(set (match_operand:SI 0 "register_operand" "")
4224         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4225   ""
4226   "
4228   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4229     {
4230       rtx op = gen_lowpart (SImode, operands[1]);
4231       rtx temp = force_reg (SImode, GEN_INT (0xff));
4233       emit_insn (gen_andsi3 (operands[0], op, temp));
4234       DONE;
4235     }
4238 (define_insn ""
4239   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
4240         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
4241   "!TARGET_MIPS16"
4242   "*
4244   if (which_alternative == 0)
4245     return \"andi\\t%0,%1,0x00ff\";
4246   else
4247     return mips_move_1word (operands, insn, TRUE);
4249   [(set_attr "type"     "arith,load,load")
4250    (set_attr "mode"     "SI")
4251    (set_attr "length"   "4,4,8")])
4253 (define_insn ""
4254   [(set (match_operand:SI 0 "register_operand" "=d,d")
4255         (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4256   "TARGET_MIPS16"
4257   "* return mips_move_1word (operands, insn, TRUE);"
4258   [(set_attr "type"     "load,load")
4259    (set_attr "mode"     "SI")
4260    (set_attr "length"   "4,8")])
4262 (define_expand "zero_extendqidi2"
4263   [(set (match_operand:DI 0 "register_operand" "")
4264         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4265   "TARGET_64BIT"
4266   "
4268   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4269     {
4270       rtx op = gen_lowpart (DImode, operands[1]);
4271       rtx temp = force_reg (DImode, GEN_INT (0xff));
4273       emit_insn (gen_anddi3 (operands[0], op, temp));
4274       DONE;
4275     }
4278 (define_insn ""
4279   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4280         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
4281   "TARGET_64BIT && !TARGET_MIPS16"
4282   "*
4284   if (which_alternative == 0)
4285     return \"andi\\t%0,%1,0x00ff\";
4286   else
4287     return mips_move_1word (operands, insn, TRUE);
4289   [(set_attr "type"     "arith,load,load")
4290    (set_attr "mode"     "DI")
4291    (set_attr "length"   "4,4,8")])
4293 ;; These can be created when a paradoxical subreg operand with an implicit
4294 ;; sign_extend operator is reloaded.  Because of the subreg, this is really
4295 ;; a zero extend.
4296 ;; ??? It might be possible to eliminate the need for these patterns by adding
4297 ;; more support to reload for implicit sign_extend operators.
4298 (define_insn "*paradoxical_extendhidi2"
4299   [(set (match_operand:DI 0 "register_operand" "=d,d")
4300         (sign_extend:DI
4301          (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
4302   "TARGET_64BIT"
4303   "*
4305   return mips_move_1word (operands, insn, TRUE);
4307   [(set_attr "type"     "load,load")
4308    (set_attr "mode"     "DI")
4309    (set_attr "length"   "4,8")])
4311 (define_insn ""
4312   [(set (match_operand:DI 0 "register_operand" "=d,d")
4313         (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4314   "TARGET_64BIT && TARGET_MIPS16"
4315   "* return mips_move_1word (operands, insn, TRUE);"
4316   [(set_attr "type"     "load,load")
4317    (set_attr "mode"     "DI")
4318    (set_attr "length"   "4,8")])
4321 ;;  ....................
4323 ;;      SIGN EXTENSION
4325 ;;  ....................
4327 ;; Extension insns.
4328 ;; Those for integer source operand are ordered widest source type first.
4330 ;; In 64 bit mode, 32 bit values in general registers are always
4331 ;; correctly sign extended.  That means that if the target is a
4332 ;; general register, we can sign extend from SImode to DImode just by
4333 ;; doing a move.  The matching define_insns are *movdi_internal2_extend
4334 ;; and *movdi_internal2_mips16.
4336 (define_expand "extendsidi2"
4337   [(set (match_operand:DI 0 "register_operand" "")
4338         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4339   "TARGET_64BIT"
4340   "")
4342 ;; These patterns originally accepted general_operands, however, slightly
4343 ;; better code is generated by only accepting register_operands, and then
4344 ;; letting combine generate the lh and lb insns.
4346 (define_expand "extendhidi2"
4347   [(set (match_operand:DI 0 "register_operand" "")
4348         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
4349   "TARGET_64BIT"
4350   "
4352   if (optimize && GET_CODE (operands[1]) == MEM)
4353     operands[1] = force_not_mem (operands[1]);
4355   if (GET_CODE (operands[1]) != MEM)
4356     {
4357       rtx op1   = gen_lowpart (DImode, operands[1]);
4358       rtx temp  = gen_reg_rtx (DImode);
4359       rtx shift = GEN_INT (48);
4361       emit_insn (gen_ashldi3 (temp, op1, shift));
4362       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4363       DONE;
4364     }
4367 (define_insn "extendhidi2_internal"
4368   [(set (match_operand:DI 0 "register_operand" "=d,d")
4369         (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
4370   "TARGET_64BIT"
4371   "* return mips_move_1word (operands, insn, FALSE);"
4372   [(set_attr "type"     "load")
4373    (set_attr "mode"     "DI")
4374    (set_attr "length"   "4,8")])
4376 (define_expand "extendhisi2"
4377   [(set (match_operand:SI 0 "register_operand" "")
4378         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4379   ""
4380   "
4382   if (optimize && GET_CODE (operands[1]) == MEM)
4383     operands[1] = force_not_mem (operands[1]);
4385   if (GET_CODE (operands[1]) != MEM)
4386     {
4387       rtx op1   = gen_lowpart (SImode, operands[1]);
4388       rtx temp  = gen_reg_rtx (SImode);
4389       rtx shift = GEN_INT (16);
4391       emit_insn (gen_ashlsi3 (temp, op1, shift));
4392       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4393       DONE;
4394     }
4397 (define_insn "extendhisi2_internal"
4398   [(set (match_operand:SI 0 "register_operand" "=d,d")
4399         (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
4400   ""
4401   "* return mips_move_1word (operands, insn, FALSE);"
4402   [(set_attr "type"     "load")
4403    (set_attr "mode"     "SI")
4404    (set_attr "length"   "4,8")])
4406 (define_expand "extendqihi2"
4407   [(set (match_operand:HI 0 "register_operand" "")
4408         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
4409   ""
4410   "
4412   if (optimize && GET_CODE (operands[1]) == MEM)
4413     operands[1] = force_not_mem (operands[1]);
4415   if (GET_CODE (operands[1]) != MEM)
4416     {
4417       rtx op0   = gen_lowpart (SImode, operands[0]);
4418       rtx op1   = gen_lowpart (SImode, operands[1]);
4419       rtx temp  = gen_reg_rtx (SImode);
4420       rtx shift = GEN_INT (24);
4422       emit_insn (gen_ashlsi3 (temp, op1, shift));
4423       emit_insn (gen_ashrsi3 (op0, temp, shift));
4424       DONE;
4425     }
4428 (define_insn "extendqihi2_internal"
4429   [(set (match_operand:HI 0 "register_operand" "=d,d")
4430         (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
4431   ""
4432   "* return mips_move_1word (operands, insn, FALSE);"
4433   [(set_attr "type"     "load")
4434    (set_attr "mode"     "SI")
4435    (set_attr "length"   "4,8")])
4438 (define_expand "extendqisi2"
4439   [(set (match_operand:SI 0 "register_operand" "")
4440         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4441   ""
4442   "
4444   if (optimize && GET_CODE (operands[1]) == MEM)
4445     operands[1] = force_not_mem (operands[1]);
4447   if (GET_CODE (operands[1]) != MEM)
4448     {
4449       rtx op1   = gen_lowpart (SImode, operands[1]);
4450       rtx temp  = gen_reg_rtx (SImode);
4451       rtx shift = GEN_INT (24);
4453       emit_insn (gen_ashlsi3 (temp, op1, shift));
4454       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4455       DONE;
4456     }
4459 (define_insn "extendqisi2_insn"
4460   [(set (match_operand:SI 0 "register_operand" "=d,d")
4461         (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4462   ""
4463   "* return mips_move_1word (operands, insn, FALSE);"
4464   [(set_attr "type"     "load")
4465    (set_attr "mode"     "SI")
4466    (set_attr "length"   "4,8")])
4468 (define_expand "extendqidi2"
4469   [(set (match_operand:DI 0 "register_operand" "")
4470         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4471   "TARGET_64BIT"
4472   "
4474   if (optimize && GET_CODE (operands[1]) == MEM)
4475     operands[1] = force_not_mem (operands[1]);
4477   if (GET_CODE (operands[1]) != MEM)
4478     {
4479       rtx op1   = gen_lowpart (DImode, operands[1]);
4480       rtx temp  = gen_reg_rtx (DImode);
4481       rtx shift = GEN_INT (56);
4483       emit_insn (gen_ashldi3 (temp, op1, shift));
4484       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4485       DONE;
4486     }
4489 (define_insn "extendqidi2_insn"
4490   [(set (match_operand:DI 0 "register_operand" "=d,d")
4491         (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4492   "TARGET_64BIT"
4493   "* return mips_move_1word (operands, insn, FALSE);"
4494   [(set_attr "type"     "load")
4495    (set_attr "mode"     "DI")
4496    (set_attr "length"   "4,8")])
4499 (define_insn "extendsfdf2"
4500   [(set (match_operand:DF 0 "register_operand" "=f")
4501         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
4502   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4503   "cvt.d.s\\t%0,%1"
4504   [(set_attr "type"     "fcvt")
4505    (set_attr "mode"     "DF")])
4510 ;;  ....................
4512 ;;      CONVERSIONS
4514 ;;  ....................
4516 (define_expand "fix_truncdfsi2"
4517   [(set (match_operand:SI 0 "register_operand" "=f")
4518         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
4519   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4521   if (!ISA_HAS_TRUNC_W)
4522     {
4523       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
4524       DONE;
4525     }
4528 (define_insn "fix_truncdfsi2_insn"
4529   [(set (match_operand:SI 0 "register_operand" "=f")
4530         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
4531   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
4532   "trunc.w.d %0,%1"
4533   [(set_attr "type"     "fcvt")
4534    (set_attr "mode"     "DF")
4535    (set_attr "length"   "4")])
4537 (define_insn "fix_truncdfsi2_macro"
4538   [(set (match_operand:SI 0 "register_operand" "=f")
4539         (fix:SI (match_operand:DF 1 "register_operand" "f")))
4540    (clobber (match_scratch:DF 2 "=d"))]
4541   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
4542   "trunc.w.d %0,%1,%2"
4543   [(set_attr "type"     "fcvt")
4544    (set_attr "mode"     "DF")
4545    (set_attr "length"   "36")])
4547 (define_expand "fix_truncsfsi2"
4548   [(set (match_operand:SI 0 "register_operand" "=f")
4549         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
4550   "TARGET_HARD_FLOAT"
4552   if (!ISA_HAS_TRUNC_W)
4553     {
4554       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
4555       DONE;
4556     }
4559 (define_insn "fix_truncsfsi2_insn"
4560   [(set (match_operand:SI 0 "register_operand" "=f")
4561         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
4562   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
4563   "trunc.w.s %0,%1"
4564   [(set_attr "type"     "fcvt")
4565    (set_attr "mode"     "DF")
4566    (set_attr "length"   "4")])
4568 (define_insn "fix_truncsfsi2_macro"
4569   [(set (match_operand:SI 0 "register_operand" "=f")
4570         (fix:SI (match_operand:SF 1 "register_operand" "f")))
4571    (clobber (match_scratch:SF 2 "=d"))]
4572   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
4573   "trunc.w.s %0,%1,%2"
4574   [(set_attr "type"     "fcvt")
4575    (set_attr "mode"     "DF")
4576    (set_attr "length"   "36")])
4578 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
4579 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
4580 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
4582 ;;; Deleting this means that we now need two libgcc2.a libraries.  One for
4583 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
4585 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
4587 (define_insn "fix_truncdfdi2"
4588   [(set (match_operand:DI 0 "register_operand" "=f")
4589         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
4590   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4591   "trunc.l.d %0,%1"
4592   [(set_attr "type"     "fcvt")
4593    (set_attr "mode"     "DF")
4594    (set_attr "length"   "4")])
4597 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
4598 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
4599 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
4600 (define_insn "fix_truncsfdi2"
4601   [(set (match_operand:DI 0 "register_operand" "=f")
4602         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
4603   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4604   "trunc.l.s %0,%1"
4605   [(set_attr "type"     "fcvt")
4606    (set_attr "mode"     "SF")
4607    (set_attr "length"   "4")])
4610 (define_insn "floatsidf2"
4611   [(set (match_operand:DF 0 "register_operand" "=f")
4612         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4613   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4614   "cvt.d.w\\t%0,%1"
4615   [(set_attr "type"     "fcvt")
4616    (set_attr "mode"     "DF")
4617    (set_attr "length"   "4")])
4620 (define_insn "floatdidf2"
4621   [(set (match_operand:DF 0 "register_operand" "=f")
4622         (float:DF (match_operand:DI 1 "register_operand" "f")))]
4623   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4624   "cvt.d.l\\t%0,%1"
4625   [(set_attr "type"     "fcvt")
4626    (set_attr "mode"     "DF")
4627    (set_attr "length"   "4")])
4630 (define_insn "floatsisf2"
4631   [(set (match_operand:SF 0 "register_operand" "=f")
4632         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4633   "TARGET_HARD_FLOAT"
4634   "cvt.s.w\\t%0,%1"
4635   [(set_attr "type"     "fcvt")
4636    (set_attr "mode"     "SF")
4637    (set_attr "length"   "4")])
4640 (define_insn "floatdisf2"
4641   [(set (match_operand:SF 0 "register_operand" "=f")
4642         (float:SF (match_operand:DI 1 "register_operand" "f")))]
4643   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4644   "cvt.s.l\\t%0,%1"
4645   [(set_attr "type"     "fcvt")
4646    (set_attr "mode"     "SF")
4647    (set_attr "length"   "4")])
4650 (define_expand "fixuns_truncdfsi2"
4651   [(set (match_operand:SI 0 "register_operand" "")
4652         (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
4653   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4654   "
4656   rtx reg1 = gen_reg_rtx (DFmode);
4657   rtx reg2 = gen_reg_rtx (DFmode);
4658   rtx reg3 = gen_reg_rtx (SImode);
4659   rtx label1 = gen_label_rtx ();
4660   rtx label2 = gen_label_rtx ();
4661   REAL_VALUE_TYPE offset;
4663   real_2expN (&offset, 31);
4665   if (reg1)                     /* turn off complaints about unreached code */
4666     {
4667       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
4668       do_pending_stack_adjust ();
4670       emit_insn (gen_cmpdf (operands[1], reg1));
4671       emit_jump_insn (gen_bge (label1));
4673       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
4674       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4675                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4676       emit_barrier ();
4678       emit_label (label1);
4679       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4680       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4681                                      (BITMASK_HIGH, SImode)));
4683       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4684       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4686       emit_label (label2);
4688       /* allow REG_NOTES to be set on last insn (labels don't have enough
4689          fields, and can't be used for REG_NOTES anyway).  */
4690       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4691       DONE;
4692     }
4696 (define_expand "fixuns_truncdfdi2"
4697   [(set (match_operand:DI 0 "register_operand" "")
4698         (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
4699   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4700   "
4702   rtx reg1 = gen_reg_rtx (DFmode);
4703   rtx reg2 = gen_reg_rtx (DFmode);
4704   rtx reg3 = gen_reg_rtx (DImode);
4705   rtx label1 = gen_label_rtx ();
4706   rtx label2 = gen_label_rtx ();
4707   REAL_VALUE_TYPE offset;
4709   real_2expN (&offset, 63);
4711   if (reg1)                     /* turn off complaints about unreached code */
4712     {
4713       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
4714       do_pending_stack_adjust ();
4716       emit_insn (gen_cmpdf (operands[1], reg1));
4717       emit_jump_insn (gen_bge (label1));
4719       emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
4720       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4721                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4722       emit_barrier ();
4724       emit_label (label1);
4725       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4726       emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4727       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4729       emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4730       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4732       emit_label (label2);
4734       /* allow REG_NOTES to be set on last insn (labels don't have enough
4735          fields, and can't be used for REG_NOTES anyway).  */
4736       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4737       DONE;
4738     }
4742 (define_expand "fixuns_truncsfsi2"
4743   [(set (match_operand:SI 0 "register_operand" "")
4744         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4745   "TARGET_HARD_FLOAT"
4746   "
4748   rtx reg1 = gen_reg_rtx (SFmode);
4749   rtx reg2 = gen_reg_rtx (SFmode);
4750   rtx reg3 = gen_reg_rtx (SImode);
4751   rtx label1 = gen_label_rtx ();
4752   rtx label2 = gen_label_rtx ();
4753   REAL_VALUE_TYPE offset;
4755   real_2expN (&offset, 31);
4757   if (reg1)                     /* turn off complaints about unreached code */
4758     {
4759       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
4760       do_pending_stack_adjust ();
4762       emit_insn (gen_cmpsf (operands[1], reg1));
4763       emit_jump_insn (gen_bge (label1));
4765       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4766       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4767                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4768       emit_barrier ();
4770       emit_label (label1);
4771       emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4772       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4773                                      (BITMASK_HIGH, SImode)));
4775       emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4776       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4778       emit_label (label2);
4780       /* allow REG_NOTES to be set on last insn (labels don't have enough
4781          fields, and can't be used for REG_NOTES anyway).  */
4782       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4783       DONE;
4784     }
4788 (define_expand "fixuns_truncsfdi2"
4789   [(set (match_operand:DI 0 "register_operand" "")
4790         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4791   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4792   "
4794   rtx reg1 = gen_reg_rtx (SFmode);
4795   rtx reg2 = gen_reg_rtx (SFmode);
4796   rtx reg3 = gen_reg_rtx (DImode);
4797   rtx label1 = gen_label_rtx ();
4798   rtx label2 = gen_label_rtx ();
4799   REAL_VALUE_TYPE offset;
4801   real_2expN (&offset, 63);
4803   if (reg1)                     /* turn off complaints about unreached code */
4804     {
4805       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
4806       do_pending_stack_adjust ();
4808       emit_insn (gen_cmpsf (operands[1], reg1));
4809       emit_jump_insn (gen_bge (label1));
4811       emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4812       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4813                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4814       emit_barrier ();
4816       emit_label (label1);
4817       emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4818       emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4819       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4821       emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4822       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4824       emit_label (label2);
4826       /* allow REG_NOTES to be set on last insn (labels don't have enough
4827          fields, and can't be used for REG_NOTES anyway).  */
4828       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4829       DONE;
4830     }
4835 ;;  ....................
4837 ;;      DATA MOVEMENT
4839 ;;  ....................
4841 ;; Bit field extract patterns which use lwl/lwr.
4843 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4844 ;; It isn't clear whether this will give better code.
4846 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4847 (define_expand "extv"
4848   [(set (match_operand 0 "register_operand" "")
4849         (sign_extract (match_operand:QI 1 "memory_operand" "")
4850                       (match_operand 2 "immediate_operand" "")
4851                       (match_operand 3 "immediate_operand" "")))]
4852   "!TARGET_MIPS16"
4853   "
4855   /* If the field does not start on a byte boundary, then fail.  */
4856   if (INTVAL (operands[3]) % 8 != 0)
4857     FAIL;
4859   /* MIPS I and MIPS II can only handle a 32bit field.  */
4860   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4861     FAIL;
4863   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4864   if (TARGET_64BIT
4865       && INTVAL (operands[2]) != 64
4866       && INTVAL (operands[2]) != 32)
4867     FAIL;
4869   /* This can happen for a 64 bit target, when extracting a value from
4870      a 64 bit union member.  extract_bit_field doesn't verify that our
4871      source matches the predicate, so we force it to be a MEM here.  */
4872   if (GET_CODE (operands[1]) != MEM)
4873     FAIL;
4875   /* Change the mode to BLKmode for aliasing purposes.  */
4876   operands[1] = adjust_address (operands[1], BLKmode, 0);
4877   set_mem_size (operands[1], GEN_INT (INTVAL (operands[2]) / BITS_PER_UNIT));
4879   /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value.  */
4880   if (INTVAL (operands[2]) == 64)
4881     emit_insn (gen_movdi_uld (operands[0], operands[1]));
4882   else
4883     {
4884       if (TARGET_64BIT)
4885         {
4886           operands[0] = gen_lowpart (SImode, operands[0]);
4887           if (operands[0] == NULL_RTX)
4888             FAIL;
4889         }
4890       emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4891     }
4892   DONE;
4895 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4896 (define_expand "extzv"
4897   [(set (match_operand 0 "register_operand" "")
4898         (zero_extract (match_operand:QI 1 "memory_operand" "")
4899                       (match_operand 2 "immediate_operand" "")
4900                       (match_operand 3 "immediate_operand" "")))]
4901   "!TARGET_MIPS16"
4902   "
4904   /* If the field does not start on a byte boundary, then fail.  */
4905   if (INTVAL (operands[3]) % 8 != 0)
4906     FAIL;
4908   /* MIPS I and MIPS II can only handle a 32bit field.  */
4909   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4910     FAIL;
4912   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4913   if (TARGET_64BIT
4914       && INTVAL (operands[2]) != 64
4915       && INTVAL (operands[2]) != 32)
4916     FAIL;
4918   /* This can happen for a 64 bit target, when extracting a value from
4919      a 64 bit union member.  extract_bit_field doesn't verify that our
4920      source matches the predicate, so we force it to be a MEM here.  */
4921   if (GET_CODE (operands[1]) != MEM)
4922     FAIL;
4924   /* Change the mode to BLKmode for aliasing purposes.  */
4925   operands[1] = adjust_address (operands[1], BLKmode, 0);
4926   set_mem_size (operands[1], GEN_INT (INTVAL (operands[2]) / BITS_PER_UNIT));
4928   /* Otherwise, emit a lwl/lwr pair to load the value.  */
4929   if (INTVAL (operands[2]) == 64)
4930     emit_insn (gen_movdi_uld (operands[0], operands[1]));
4931   else
4932     {
4933       if (TARGET_64BIT)
4934         {
4935           operands[0] = gen_lowpart (SImode, operands[0]);
4936           if (operands[0] == NULL_RTX)
4937             FAIL;
4938         }
4939       emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4940     }
4941   DONE;
4944 ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
4945 (define_expand "insv"
4946   [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4947                       (match_operand 1 "immediate_operand" "")
4948                       (match_operand 2 "immediate_operand" ""))
4949         (match_operand 3 "register_operand" ""))]
4950   "!TARGET_MIPS16"
4951   "
4953   /* If the field does not start on a byte boundary, then fail.  */
4954   if (INTVAL (operands[2]) % 8 != 0)
4955     FAIL;
4957   /* MIPS I and MIPS II can only handle a 32bit field.  */
4958   if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
4959     FAIL;
4961   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4962   if (TARGET_64BIT
4963       && INTVAL (operands[1]) != 64
4964       && INTVAL (operands[1]) != 32)
4965     FAIL;
4967   /* This can happen for a 64 bit target, when storing into a 32 bit union
4968      member.  store_bit_field doesn't verify that our target matches the
4969      predicate, so we force it to be a MEM here.  */
4970   if (GET_CODE (operands[0]) != MEM)
4971     FAIL;
4973   /* Change the mode to BLKmode for aliasing purposes.  */
4974   operands[0] = adjust_address (operands[0], BLKmode, 0);
4975   set_mem_size (operands[0], GEN_INT (INTVAL (operands[1]) / BITS_PER_UNIT));
4977   /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value.  */
4978   if (INTVAL (operands[1]) == 64)
4979     emit_insn (gen_movdi_usd (operands[0], operands[3]));
4980   else
4981     {
4982       if (TARGET_64BIT)
4983         {
4984           operands[3] = gen_lowpart (SImode, operands[3]);
4985           if (operands[3] == NULL_RTX)
4986             FAIL;
4987         }
4988       emit_insn (gen_movsi_usw (operands[0], operands[3]));
4989     }
4990   DONE;
4993 ;; unaligned word moves generated by the bit field patterns
4995 (define_insn "movsi_ulw"
4996   [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4997         (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")]
4998                    UNSPEC_ULW))]
4999   "!TARGET_MIPS16"
5000   "*
5002   rtx offset = const0_rtx;
5003   rtx addr = XEXP (operands[1], 0);
5004   rtx mem_addr = eliminate_constant_term (addr, &offset);
5005   const char *ret;
5007   if (TARGET_STATS)
5008     mips_count_memory_refs (operands[1], 2);
5010   /* The stack/frame pointers are always aligned, so we can convert
5011      to the faster lw if we are referencing an aligned stack location.  */
5013   if ((INTVAL (offset) & 3) == 0
5014       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
5015     ret = \"lw\\t%0,%1\";
5016   else
5017     ret = \"ulw\\t%0,%1\";
5019   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
5021   [(set_attr "type"     "load,load")
5022    (set_attr "mode"     "SI")
5023    (set_attr "length"   "8,16")])
5025 (define_insn "movsi_usw"
5026   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
5027         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")]
5028                     UNSPEC_USW))]
5029   "!TARGET_MIPS16"
5030   "*
5032   rtx offset = const0_rtx;
5033   rtx addr = XEXP (operands[0], 0);
5034   rtx mem_addr = eliminate_constant_term (addr, &offset);
5036   if (TARGET_STATS)
5037     mips_count_memory_refs (operands[0], 2);
5039   /* The stack/frame pointers are always aligned, so we can convert
5040      to the faster sw if we are referencing an aligned stack location.  */
5042   if ((INTVAL (offset) & 3) == 0
5043       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
5044     return \"sw\\t%z1,%0\";
5046   return \"usw\\t%z1,%0\";
5048   [(set_attr "type"     "store")
5049    (set_attr "mode"     "SI")
5050    (set_attr "length"   "8,16")])
5052 ;; Bit field extract patterns which use ldl/ldr.
5054 ;; unaligned double word moves generated by the bit field patterns
5056 (define_insn "movdi_uld"
5057   [(set (match_operand:DI 0 "register_operand" "=&d,&d")
5058         (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")]
5059                    UNSPEC_ULD))]
5060   ""
5061   "*
5063   rtx offset = const0_rtx;
5064   rtx addr = XEXP (operands[1], 0);
5065   rtx mem_addr = eliminate_constant_term (addr, &offset);
5066   const char *ret;
5068   if (TARGET_STATS)
5069     mips_count_memory_refs (operands[1], 2);
5071   /* The stack/frame pointers are always aligned, so we can convert
5072      to the faster lw if we are referencing an aligned stack location.  */
5074   if ((INTVAL (offset) & 7) == 0
5075       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
5076     ret = \"ld\\t%0,%1\";
5077   else
5078     ret = \"uld\\t%0,%1\";
5080   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
5082   [(set_attr "type"     "load,load")
5083    (set_attr "mode"     "SI")
5084    (set_attr "length"   "8,16")])
5086 (define_insn "movdi_usd"
5087   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
5088         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")]
5089                     UNSPEC_USD))]
5090   ""
5091   "*
5093   rtx offset = const0_rtx;
5094   rtx addr = XEXP (operands[0], 0);
5095   rtx mem_addr = eliminate_constant_term (addr, &offset);
5097   if (TARGET_STATS)
5098     mips_count_memory_refs (operands[0], 2);
5100   /* The stack/frame pointers are always aligned, so we can convert
5101      to the faster sw if we are referencing an aligned stack location.  */
5103   if ((INTVAL (offset) & 7) == 0
5104       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
5105     return \"sd\\t%z1,%0\";
5107   return \"usd\\t%z1,%0\";
5109   [(set_attr "type"     "store")
5110    (set_attr "mode"     "SI")
5111    (set_attr "length"   "8,16")])
5113 ;; These two patterns support loading addresses with two instructions instead
5114 ;; of using the macro instruction la.
5116 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
5117 ;; unnecessary.
5119 (define_insn "high"
5120   [(set (match_operand:SI 0 "register_operand" "=r")
5121         (high:SI (match_operand:SI 1 "immediate_operand" "")))]
5122   "mips_split_addresses && !TARGET_MIPS16"
5123   "lui\\t%0,%%hi(%1) # high"
5124   [(set_attr "type"     "move")])
5126 (define_insn "low"
5127   [(set (match_operand:SI 0 "register_operand" "=r")
5128         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
5129                    (match_operand:SI 2 "immediate_operand" "")))]
5130   "mips_split_addresses && !TARGET_MIPS16"
5131   "addiu\\t%0,%1,%%lo(%2) # low"
5132   [(set_attr "type"     "arith")
5133    (set_attr "mode"     "SI")])
5135 ;; 64-bit integer moves
5137 ;; Unlike most other insns, the move insns can't be split with
5138 ;; different predicates, because register spilling and other parts of
5139 ;; the compiler, have memoized the insn number already.
5141 (define_expand "movdi"
5142   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5143         (match_operand:DI 1 "general_operand" ""))]
5144   ""
5145   "
5147   if (mips_split_addresses && mips_check_split (operands[1], DImode))
5148     {
5149       enum machine_mode mode = GET_MODE (operands[0]);
5150       rtx tem = ((reload_in_progress | reload_completed)
5151                  ? operands[0] : gen_reg_rtx (mode));
5153       emit_insn (gen_rtx_SET (VOIDmode, tem,
5154                               gen_rtx_HIGH (mode, operands[1])));
5156       operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
5157     }
5159   /* If we are generating embedded PIC code, and we are referring to a
5160      symbol in the .text section, we must use an offset from the start
5161      of the function.  */
5162   if (TARGET_EMBEDDED_PIC
5163       && (GET_CODE (operands[1]) == LABEL_REF
5164           || (GET_CODE (operands[1]) == SYMBOL_REF
5165               && ! SYMBOL_REF_FLAG (operands[1]))))
5166     {
5167       rtx temp;
5169       temp = embedded_pic_offset (operands[1]);
5170       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
5171                            force_reg (DImode, temp));
5172       emit_move_insn (operands[0], force_reg (DImode, temp));
5173       DONE;
5174     }
5176   /* If operands[1] is a constant address illegal for pic, then we need to
5177      handle it just like LEGITIMIZE_ADDRESS does.  */
5178   if (flag_pic && pic_address_needs_scratch (operands[1]))
5179     {
5180       rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
5181       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5183       if (! SMALL_INT (temp2))
5184         temp2 = force_reg (DImode, temp2);
5186       emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
5187       DONE;
5188     }
5190   /* On the mips16, we can handle a GP relative reference by adding in
5191      $gp.  We need to check the name to see whether this is a string
5192      constant.  */
5193   if (TARGET_MIPS16
5194       && register_operand (operands[0], DImode)
5195       && GET_CODE (operands[1]) == SYMBOL_REF
5196       && SYMBOL_REF_FLAG (operands[1]))
5197     {
5198       const char *name = XSTR (operands[1], 0);
5200       if (name[0] != '*'
5201           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5202                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5203         {
5204           rtx base_reg;
5206           if (reload_in_progress || reload_completed)
5207             {
5208               /* In movsi we use the constant table here.  However, in
5209                  this case, we're better off copying $28 into a
5210                  register and adding, because the constant table entry
5211                  would be 8 bytes.  */
5212               base_reg = operands[0];
5213               emit_move_insn (base_reg,
5214                               gen_rtx (CONST, DImode,
5215                                        gen_rtx (REG, DImode,
5216                                                 GP_REG_FIRST + 28)));
5217             }
5218           else
5219             {
5220               base_reg = gen_reg_rtx (Pmode);
5221               emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5222             }
5224           emit_move_insn (operands[0],
5225                           gen_rtx (PLUS, Pmode, base_reg,
5226                                    mips16_gp_offset (operands[1])));
5227           DONE;
5228         }
5229     }
5231   if ((reload_in_progress | reload_completed) == 0
5232       && !register_operand (operands[0], DImode)
5233       && !register_operand (operands[1], DImode)
5234       && (TARGET_MIPS16
5235           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5236                && operands[1] != CONST0_RTX (DImode))))
5237     {
5238       rtx temp = force_reg (DImode, operands[1]);
5239       emit_move_insn (operands[0], temp);
5240       DONE;
5241     }
5244 ;; For mips16, we need a special case to handle storing $31 into
5245 ;; memory, since we don't have a constraint to match $31.  This
5246 ;; instruction can be generated by save_restore_insns.
5248 (define_insn ""
5249   [(set (match_operand:DI 0 "memory_operand" "=R,m")
5250         (reg:DI 31))]
5251   "TARGET_MIPS16 && TARGET_64BIT"
5252   "*
5254   operands[1] = gen_rtx (REG, DImode, 31);
5255   return mips_move_2words (operands, insn);
5257   [(set_attr "type"     "store")
5258    (set_attr "mode"     "DI")
5259    (set_attr "length"   "4,8")])
5261 (define_insn "movdi_internal"
5262   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5263         (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5264   "!TARGET_64BIT && !TARGET_MIPS16
5265    && (register_operand (operands[0], DImode)
5266        || register_operand (operands[1], DImode)
5267        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5268        || operands[1] == CONST0_RTX (DImode))"
5269   "* return mips_move_2words (operands, insn); "
5270   [(set_attr "type"     "move,arith,load,load,store,store,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5271    (set_attr "mode"     "DI")
5272    (set_attr "length"   "8,16,8,16,8,16,8,8,8,8,8,8,8,8,8")])
5274 (define_insn ""
5275   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
5276         (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
5277   "!TARGET_64BIT && TARGET_MIPS16
5278    && (register_operand (operands[0], DImode)
5279        || register_operand (operands[1], DImode))"
5280   "* return mips_move_2words (operands, insn);"
5281   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
5282    (set_attr "mode"     "DI")
5283    (set_attr "length"   "8,8,8,8,12,8,16,8,16,8")])
5285 (define_split
5286   [(set (match_operand:DI 0 "register_operand" "")
5287         (match_operand:DI 1 "register_operand" ""))]
5288   "reload_completed && !TARGET_64BIT
5289    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5290    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
5291    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
5293   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
5294    (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
5295   "")
5297 (define_insn "movdi_internal2"
5298   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*f,*f,*f,*f,*d,*R,*m,*x,*d,*x,*a,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5299         (match_operand:DI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f,*d*J,*R,*m,*f,*f,*f,*J,*x,*d,*J,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5300   "TARGET_64BIT && !TARGET_MIPS16
5301    && (register_operand (operands[0], DImode)
5302        || register_operand (operands[1], DImode)
5303        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5304        || operands[1] == CONST0_RTX (DImode))"
5305   "* return mips_move_2words (operands, insn); "
5306   [(set_attr "type"     "move,arith,arith,load,load,store,store,move,xfer,load,load,xfer,store,store,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5307    (set_attr "mode"     "DI")
5308    (set_attr "length"   "4,4,8,4,8,4,8,4,4,4,8,4,4,8,4,4,4,8,8,8,8,8,8,8")])
5310 ;; Sign-extended operands are reloaded using this instruction, so the
5311 ;; constraints must handle every SImode source operand X and destination
5312 ;; register R for which:
5314 ;;     mips_secondary_reload_class (CLASS_OF (R), DImode, true,
5315 ;;                                  gen_rtx_SIGN_EXTEND (DImode, X))
5317 ;; returns NO_REGS.  Also handle memory destinations, where allowed.
5319 ;; This pattern is essentially a trimmed-down version of movdi_internal2.
5320 ;; The main difference is that dJ -> f and f -> d are the only constraints
5321 ;; involving float registers.  See mips_secondary_reload_class for details.
5322 (define_insn "*movdi_internal2_extend"
5323   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*d,*f,*x,*d,*x,*a,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5324         (sign_extend:DI (match_operand:SI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f,*d*J,*J,*x,*d,*J,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D")))]
5325   "TARGET_64BIT && !TARGET_MIPS16
5326    && (register_operand (operands[0], DImode)
5327        || register_operand (operands[1], DImode)
5328        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5329        || operands[1] == CONST0_RTX (DImode))"
5330   "* return mips_sign_extend (insn, operands[0], operands[1]);"
5331   [(set_attr "type"     "move,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5332    (set_attr "mode"     "DI")
5333    (set_attr "length"   "4,4,8,4,8,4,8,4,4,4,4,4,8,8,8,8,8,8,8")])
5335 (define_insn "*movdi_internal2_mips16"
5336   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
5337         (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
5338   "TARGET_64BIT && TARGET_MIPS16
5339    && (register_operand (operands[0], DImode)
5340        || se_register_operand (operands[1], DImode))"
5341   "* return mips_move_2words (operands, insn);"
5342   [(set_attr "type"     "move,move,move,arith,arith,arith,load,load,store,store,hilo")
5343    (set_attr "mode"     "DI")
5344    (set_attr_alternative "length"
5345                 [(const_int 4)
5346                  (const_int 4)
5347                  (const_int 4)
5348                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5349                                (const_int 4)
5350                                (const_int 8))
5351                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5352                                (const_int 8)
5353                                (const_int 12))
5354                  (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
5355                                (const_int 4)
5356                                (const_int 8))
5357                  (const_int 4)
5358                  (const_int 8)
5359                  (const_int 4)
5360                  (const_int 8)
5361                  (const_int 4)])])
5363 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
5364 ;; when the original load is a 4 byte instruction but the add and the
5365 ;; load are 2 2 byte instructions.
5367 (define_split
5368   [(set (match_operand:DI 0 "register_operand" "")
5369         (mem:DI (plus:DI (match_dup 0)
5370                          (match_operand:DI 1 "const_int_operand" ""))))]
5371   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
5372    && !TARGET_DEBUG_D_MODE
5373    && GET_CODE (operands[0]) == REG
5374    && M16_REG_P (REGNO (operands[0]))
5375    && GET_CODE (operands[1]) == CONST_INT
5376    && ((INTVAL (operands[1]) < 0
5377         && INTVAL (operands[1]) >= -0x10)
5378        || (INTVAL (operands[1]) >= 32 * 8
5379            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
5380        || (INTVAL (operands[1]) >= 0
5381            && INTVAL (operands[1]) < 32 * 8
5382            && (INTVAL (operands[1]) & 7) != 0))"
5383   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
5384    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
5385   "
5387   HOST_WIDE_INT val = INTVAL (operands[1]);
5389   if (val < 0)
5390     operands[2] = GEN_INT (0);
5391   else if (val >= 32 * 8)
5392     {
5393       int off = val & 7;
5395       operands[1] = GEN_INT (0x8 + off);
5396       operands[2] = GEN_INT (val - off - 0x8);
5397     }
5398   else
5399     {
5400       int off = val & 7;
5402       operands[1] = GEN_INT (off);
5403       operands[2] = GEN_INT (val - off);
5404     }
5407 ;; Handle input reloads in DImode.
5408 ;; This is mainly to handle reloading HILO_REGNUM.  Note that we may
5409 ;; see it as the source or the destination, depending upon which way
5410 ;; reload handles the instruction.
5411 ;; Making the second operand TImode is a trick.  The compiler may
5412 ;; reuse the same register for operand 0 and operand 2.  Using TImode
5413 ;; gives us two registers, so we can always use the one which is not
5414 ;; used.
5416 (define_expand "reload_indi"
5417   [(set (match_operand:DI 0 "register_operand" "=b")
5418         (match_operand:DI 1 "" "b"))
5419    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5420   "TARGET_64BIT"
5421   "
5423   rtx scratch = gen_rtx_REG (DImode,
5424                              (REGNO (operands[0]) == REGNO (operands[2])
5425                               ? REGNO (operands[2]) + 1
5426                               : REGNO (operands[2])));
5428   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5429     {
5430       if (GET_CODE (operands[1]) == MEM)
5431         {
5432           rtx memword, offword, hi_word, lo_word;
5433           rtx addr = find_replacement (&XEXP (operands[1], 0));
5434           rtx op1 = replace_equiv_address (operands[1], addr);
5436           scratch = gen_rtx_REG (SImode, REGNO (scratch));
5437           memword = adjust_address (op1, SImode, 0);
5438           offword = adjust_address (op1, SImode, 4);
5440           if (BYTES_BIG_ENDIAN)
5441             {
5442               hi_word = memword;
5443               lo_word = offword;
5444             }
5445           else
5446             {
5447               hi_word = offword;
5448               lo_word = memword;
5449             }
5450           emit_move_insn (scratch, hi_word);
5451           emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
5452           emit_move_insn (scratch, lo_word);
5453           emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
5454           emit_insn (gen_hilo_delay (operands[0]));
5455         }
5456       else
5457         {
5458           emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5459           emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
5460           emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5461           emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5462           emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5463           emit_insn (gen_hilo_delay (operands[0]));
5464         }
5465       DONE;
5466     }
5467   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5468     {
5469       emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
5470       emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5471       emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5472       emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
5473       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5474       emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5475       emit_insn (gen_hilo_delay (operands[1]));
5476       DONE;
5477     }
5478   /* This handles moves between a float register and HI/LO.  */
5479   emit_move_insn (scratch, operands[1]);
5480   emit_move_insn (operands[0], scratch);
5481   DONE;
5484 ;; Handle output reloads in DImode.
5486 ;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5487 ;; use a TImode scratch reg.
5489 (define_expand "reload_outdi"
5490   [(set (match_operand:DI 0 "general_operand" "=b")
5491         (match_operand:DI 1 "se_register_operand" "b"))
5492    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5493   "TARGET_64BIT"
5494   "
5496   rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5498   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5499     {
5500       emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5501       emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5502       emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5503       emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5504       emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5505       emit_insn (gen_hilo_delay (operands[0]));
5506       DONE;
5507     }
5508   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5509     {
5510       if (GET_CODE (operands[0]) == MEM)
5511         {
5512           rtx scratch, memword, offword, hi_word, lo_word;
5513           rtx addr = find_replacement (&XEXP (operands[0], 0));
5514           rtx op0 = replace_equiv_address (operands[0], addr);
5516           scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
5517           memword = adjust_address (op0, SImode, 0);
5518           offword = adjust_address (op0, SImode, 4);
5520           if (BYTES_BIG_ENDIAN)
5521             {
5522               hi_word = memword;
5523               lo_word = offword;
5524             }
5525           else
5526             {
5527               hi_word = offword;
5528               lo_word = memword;
5529             }
5530           emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
5531           emit_move_insn (hi_word, scratch);
5532           emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
5533           emit_move_insn (lo_word, scratch);
5534           emit_insn (gen_hilo_delay (operands[1]));
5535         }
5536       else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
5537         {
5538           /* Handle the case where operand[0] is not a 'd' register,
5539              and hence we can not directly move from the HILO register
5540              into it.  */
5541           rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5542           emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5543           emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5544           emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5545           emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
5546           emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
5547           emit_insn (gen_iordi3 (scratch, scratch, scratch2));
5548           emit_insn (gen_movdi (operands[0], scratch));
5549           emit_insn (gen_hilo_delay (operands[1]));
5550         }
5551       else
5552         {
5553           emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5554           emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5555           emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5556           emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5557           emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5558           emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5559           emit_insn (gen_hilo_delay (operands[1]));
5560         }
5561       DONE;
5562     }
5563   /* This handles moves between a float register and HI/LO.  */
5564   emit_move_insn (scratch, operands[1]);
5565   emit_move_insn (operands[0], scratch);
5566   DONE;
5569 ;; 32-bit Integer moves
5571 (define_split
5572   [(set (match_operand:SI 0 "register_operand" "")
5573         (match_operand:SI 1 "large_int" ""))]
5574   "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
5575   [(set (match_dup 0)
5576         (match_dup 2))
5577    (set (match_dup 0)
5578         (ior:SI (match_dup 0)
5579                 (match_dup 3)))]
5580   "
5582   operands[2] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
5583                                              & BITMASK_UPPER16,
5584                                              SImode));
5585   operands[3] = GEN_INT (INTVAL (operands[1]) & BITMASK_LOWER16);
5588 ;; Unlike most other insns, the move insns can't be split with
5589 ;; different predicates, because register spilling and other parts of
5590 ;; the compiler, have memoized the insn number already.
5592 (define_expand "movsi"
5593   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5594         (match_operand:SI 1 "general_operand" ""))]
5595   ""
5596   "
5598   if (mips_split_addresses && mips_check_split (operands[1], SImode))
5599     {
5600       enum machine_mode mode = GET_MODE (operands[0]);
5601       rtx tem = ((reload_in_progress | reload_completed)
5602                  ? operands[0] : gen_reg_rtx (mode));
5604       emit_insn (gen_rtx_SET (VOIDmode, tem,
5605                               gen_rtx_HIGH (mode, operands[1])));
5607       operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
5608     }
5610   /* If we are generating embedded PIC code, and we are referring to a
5611      symbol in the .text section, we must use an offset from the start
5612      of the function.  */
5613   if (TARGET_EMBEDDED_PIC
5614       && (GET_CODE (operands[1]) == LABEL_REF
5615           || (GET_CODE (operands[1]) == SYMBOL_REF
5616               && ! SYMBOL_REF_FLAG (operands[1]))))
5617     {
5618       rtx temp;
5620       temp = embedded_pic_offset (operands[1]);
5621       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
5622                            force_reg (SImode, temp));
5623       emit_move_insn (operands[0], force_reg (SImode, temp));
5624       DONE;
5625     }
5627   /* If operands[1] is a constant address invalid for pic, then we need to
5628      handle it just like LEGITIMIZE_ADDRESS does.  */
5629   if (flag_pic && pic_address_needs_scratch (operands[1]))
5630     {
5631       rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
5632       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5634       if (! SMALL_INT (temp2))
5635         temp2 = force_reg (SImode, temp2);
5637       emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, temp2));
5638       DONE;
5639     }
5641   /* On the mips16, we can handle a GP relative reference by adding in
5642      $gp.  We need to check the name to see whether this is a string
5643      constant.  */
5644   if (TARGET_MIPS16
5645       && register_operand (operands[0], SImode)
5646       && GET_CODE (operands[1]) == SYMBOL_REF
5647       && SYMBOL_REF_FLAG (operands[1]))
5648     {
5649       const char *name = XSTR (operands[1], 0);
5651       if (name[0] != '*'
5652           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5653                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5654         {
5655           rtx base_reg;
5657           if (reload_in_progress || reload_completed)
5658             {
5659               /* We need to reload this address.  In this case we
5660                  aren't going to have a chance to combine loading the
5661                  address with the load or store.  That means that we
5662                  can either generate a 2 byte move followed by a 4
5663                  byte addition, or a 2 byte load with a 4 byte entry
5664                  in the constant table.  Since the entry in the
5665                  constant table might be shared, we're better off, on
5666                  average, loading the address from the constant table.  */
5667               emit_move_insn (operands[0],
5668                               force_const_mem (SImode, operands[1]));
5669               DONE;
5670             }
5672           base_reg = gen_reg_rtx (Pmode);
5673           emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5675           emit_move_insn (operands[0],
5676                           gen_rtx (PLUS, Pmode, base_reg,
5677                                    mips16_gp_offset (operands[1])));
5678           DONE;
5679         }
5680     }
5682   if ((reload_in_progress | reload_completed) == 0
5683       && !register_operand (operands[0], SImode)
5684       && !register_operand (operands[1], SImode)
5685       && (TARGET_MIPS16
5686           || GET_CODE (operands[1]) != CONST_INT
5687           || INTVAL (operands[1]) != 0))
5688     {
5689       rtx temp = force_reg (SImode, operands[1]);
5690       emit_move_insn (operands[0], temp);
5691       DONE;
5692     }
5695 ;; We can only store $ra directly into a small sp offset.  Should the
5696 ;; offset be too wide, non-constant or not sp-based, leave it up to
5697 ;; reload to choose a scratch register.
5699 (define_insn ""
5700   [(set (mem:SI (plus:SI (reg:SI 29)
5701                          (match_operand:SI 0 "small_int" "n")))
5702         (reg:SI 31))]
5703   "TARGET_MIPS16"
5704   "sw\\t$31,%0($sp)"
5705   [(set_attr "type"     "store")
5706    (set_attr "mode"     "SI")
5707    (set_attr_alternative
5708     "length"
5709     [(if_then_else
5710       (lt (symbol_ref "(unsigned HOST_WIDE_INT) INTVAL (operands[0])")
5711           (const_int 1024))
5712       (const_int 4)
5713       (const_int 8))])])
5715 ;; The difference between these two is whether or not ints are allowed
5716 ;; in FP registers (off by default, use -mdebugh to enable).
5718 (define_insn "movsi_internal"
5719   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*f,*f,*f,?*f,*d,*R,*m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5720         (match_operand:SI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f,*d*J,*R,*m,*f,*f,*f,*z,*d,J,*x,*d,*a,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5721   "!TARGET_MIPS16
5722    && (register_operand (operands[0], SImode)
5723        || register_operand (operands[1], SImode)
5724        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5725   "* return mips_move_1word (operands, insn, FALSE);"
5726   [(set_attr "type"     "move,arith,arith,load,load,store,store,move,xfer,load,load,xfer,store,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5727    (set_attr "mode"     "SI")
5728    (set_attr "length"   "4,4,8,4,8,4,8,4,4,4,8,4,4,8,4,4,4,4,4,4,4,4,8,4,4,8")])
5730 ;; This is the mips16 movsi instruction.  We accept a small integer as
5731 ;; the source if the destination is a GP memory reference.  This is
5732 ;; because we want the combine pass to turn adding a GP reference to a
5733 ;; register into a direct GP reference, but the combine pass will pass
5734 ;; in the source as a constant if it finds an equivalent one.  If the
5735 ;; instruction is recognized, reload will force the constant back out
5736 ;; into a register.
5738 (define_insn ""
5739   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d,*d")
5740         (match_operand:SI 1 "move_operand" "d,d,y,K,N,s,R,m,d,d,*x,*a"))]
5741   "TARGET_MIPS16
5742    && (register_operand (operands[0], SImode)
5743        || register_operand (operands[1], SImode)
5744        || (GET_CODE (operands[0]) == MEM
5745            && GET_CODE (XEXP (operands[0], 0)) == PLUS
5746            && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
5747            && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
5748            && GET_CODE (operands[1]) == CONST_INT
5749            && (SMALL_INT (operands[1])
5750                || SMALL_INT_UNSIGNED (operands[1]))))"
5751   "* return mips_move_1word (operands, insn, FALSE);"
5752   [(set_attr "type"     "move,move,move,arith,arith,arith,load,load,store,store,hilo,hilo")
5753    (set_attr "mode"     "SI")
5754    (set_attr_alternative "length"
5755                 [(const_int 4)
5756                  (const_int 4)
5757                  (const_int 4)
5758                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5759                                (const_int 4)
5760                                (const_int 8))
5761                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5762                                (const_int 8)
5763                                (const_int 12))
5764                  (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
5765                                (const_int 4)
5766                                (const_int 8))
5767                  (const_int 4)
5768                  (const_int 8)
5769                  (const_int 4)
5770                  (const_int 8)
5771                  (const_int 4)
5772                  (const_int 4)])])
5774 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
5775 ;; when the original load is a 4 byte instruction but the add and the
5776 ;; load are 2 2 byte instructions.
5778 (define_split
5779   [(set (match_operand:SI 0 "register_operand" "")
5780         (mem:SI (plus:SI (match_dup 0)
5781                          (match_operand:SI 1 "const_int_operand" ""))))]
5782   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5783    && GET_CODE (operands[0]) == REG
5784    && M16_REG_P (REGNO (operands[0]))
5785    && GET_CODE (operands[1]) == CONST_INT
5786    && ((INTVAL (operands[1]) < 0
5787         && INTVAL (operands[1]) >= -0x80)
5788        || (INTVAL (operands[1]) >= 32 * 4
5789            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5790        || (INTVAL (operands[1]) >= 0
5791            && INTVAL (operands[1]) < 32 * 4
5792            && (INTVAL (operands[1]) & 3) != 0))"
5793   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5794    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
5795   "
5797   HOST_WIDE_INT val = INTVAL (operands[1]);
5799   if (val < 0)
5800     operands[2] = GEN_INT (0);
5801   else if (val >= 32 * 4)
5802     {
5803       int off = val & 3;
5805       operands[1] = GEN_INT (0x7c + off);
5806       operands[2] = GEN_INT (val - off - 0x7c);
5807     }
5808   else
5809     {
5810       int off = val & 3;
5812       operands[1] = GEN_INT (off);
5813       operands[2] = GEN_INT (val - off);
5814     }
5817 ;; On the mips16, we can split a load of certain constants into a load
5818 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
5819 ;; instructions.
5821 (define_split
5822   [(set (match_operand:SI 0 "register_operand" "")
5823         (match_operand:SI 1 "const_int_operand" ""))]
5824   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5825    && GET_CODE (operands[0]) == REG
5826    && M16_REG_P (REGNO (operands[0]))
5827    && GET_CODE (operands[1]) == CONST_INT
5828    && INTVAL (operands[1]) >= 0x100
5829    && INTVAL (operands[1]) <= 0xff + 0x7f"
5830   [(set (match_dup 0) (match_dup 1))
5831    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5832   "
5834   int val = INTVAL (operands[1]);
5836   operands[1] = GEN_INT (0xff);
5837   operands[2] = GEN_INT (val - 0xff);
5840 ;; On the mips16, we can split a load of a negative constant into a
5841 ;; load and a neg.  That's what mips_move_1word will generate anyhow.
5843 (define_split
5844   [(set (match_operand:SI 0 "register_operand" "")
5845         (match_operand:SI 1 "const_int_operand" ""))]
5846   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5847    && GET_CODE (operands[0]) == REG
5848    && M16_REG_P (REGNO (operands[0]))
5849    && GET_CODE (operands[1]) == CONST_INT
5850    && INTVAL (operands[1]) < 0
5851    && INTVAL (operands[1]) > - 0x8000"
5852   [(set (match_dup 0) (match_dup 1))
5853    (set (match_dup 0) (neg:SI (match_dup 0)))]
5854   "
5856   operands[1] = GEN_INT (- INTVAL (operands[1]));
5859 ;; Reload HILO_REGNUM in SI mode.  This needs a scratch register in
5860 ;; order to set the sign bit correctly in the HI register.
5862 (define_expand "reload_outsi"
5863   [(set (match_operand:SI 0 "general_operand" "=b")
5864         (match_operand:SI 1 "register_operand" "b"))
5865    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5866   "TARGET_64BIT || TARGET_MIPS16"
5867   "
5869   if (TARGET_64BIT
5870       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5871     {
5872       emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
5873       emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5874       emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
5875       emit_insn (gen_hilo_delay (operands[0]));
5876       DONE;
5877     }
5878   /* Use a mult to reload LO on mips16.  ??? This is hideous.  */
5879   if (TARGET_MIPS16
5880       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5881     {
5882       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5883       /* This is gen_mulsi3_internal, but we need to fill in the
5884          scratch registers.  */
5885       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5886                           gen_rtvec (3,
5887                                      gen_rtx (SET, VOIDmode,
5888                                               operands[0],
5889                                               gen_rtx (MULT, SImode,
5890                                                        operands[1],
5891                                                        operands[2])),
5892                                      gen_rtx (CLOBBER, VOIDmode,
5893                                               gen_rtx (REG, SImode, 64)),
5894                                      gen_rtx (CLOBBER, VOIDmode,
5895                                               gen_rtx (REG, SImode, 66)))));
5896       DONE;
5897     }
5898   /* FIXME: I don't know how to get a value into the HI register.  */
5899   if (GET_CODE (operands[0]) == REG
5900       && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5901           : GP_REG_P (REGNO (operands[0]))))
5902     {
5903       emit_move_insn (operands[0], operands[1]);
5904       DONE;
5905     }
5906   /* This handles moves between a float register and HI/LO.  */
5907   emit_move_insn (operands[2], operands[1]);
5908   emit_move_insn (operands[0], operands[2]);
5909   DONE;
5912 ;; Reload a value into HI or LO.  There is no mthi or mtlo on mips16,
5913 ;; so we use a mult.  ??? This is hideous, and we ought to figure out
5914 ;; something better.
5916 ;; We use no predicate for operand1, because it may be a PLUS, and there
5917 ;; is no convenient predicate for that.
5919 (define_expand "reload_insi"
5920   [(set (match_operand:SI 0 "register_operand" "=b")
5921         (match_operand:SI 1 "" "b"))
5922    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5923   "TARGET_MIPS16"
5924   "
5926   if (TARGET_MIPS16
5927       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5928     {
5929       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5930       /* This is gen_mulsi3_internal, but we need to fill in the
5931          scratch registers.  */
5932       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5933                           gen_rtvec (3,
5934                                      gen_rtx (SET, VOIDmode,
5935                                               operands[0],
5936                                               gen_rtx (MULT, SImode,
5937                                                        operands[1],
5938                                                        operands[2])),
5939                                      gen_rtx (CLOBBER, VOIDmode,
5940                                               gen_rtx (REG, SImode, 64)),
5941                                      gen_rtx (CLOBBER, VOIDmode,
5942                                               gen_rtx (REG, SImode, 66)))));
5943       DONE;
5944     }
5946   /* If this is a plus, then this must be an add of the stack pointer against
5947      either a hard register or a pseudo.  */
5948   if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5949     {
5950       rtx plus_op;
5952       if (XEXP (operands[1], 0) == stack_pointer_rtx)
5953         plus_op = XEXP (operands[1], 1);
5954       else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5955         plus_op = XEXP (operands[1], 0);
5956       else
5957         abort ();
5959       /* We should have a register now.  */
5960       if (GET_CODE (plus_op) != REG)
5961         abort ();
5963       if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5964         {
5965           /* We have to have at least one temporary register which is not
5966              overlapping plus_op.  */
5967           if (! rtx_equal_p (plus_op, operands[0]))
5968             {
5969               emit_move_insn (operands[0], stack_pointer_rtx);
5970               emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5971             }
5972           else if (! rtx_equal_p (plus_op, operands[2]))
5973             {
5974               emit_move_insn (operands[2], stack_pointer_rtx);
5975               emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5976             }
5977           else
5978             abort ();
5979         }
5980       else
5981         {
5982           /* We need two registers in this case.  */
5983           if (! rtx_equal_p (operands[0], operands[2]))
5984             {
5985               emit_move_insn (operands[0], stack_pointer_rtx);
5986               emit_move_insn (operands[2], plus_op);
5987               emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5988             }
5989           else
5990             abort ();
5991         }
5992       DONE;
5993     }
5995   /* FIXME: I don't know how to get a value into the HI register.  */
5996   emit_move_insn (operands[0], operands[1]);
5997   DONE;
6000 ;; This insn is for the unspec delay for HILO.
6002 (define_insn "hilo_delay"
6003   [(unspec [(match_operand 0 "register_operand" "=b")] UNSPEC_HILO_DELAY)]
6004   ""
6005   ""
6006   [(set_attr "type" "nop")
6007    (set_attr "mode" "none")
6008    (set_attr "can_delay" "no")])
6010 ;; This insn handles moving CCmode values.  It's really just a
6011 ;; slightly simplified copy of movsi_internal2, with additional cases
6012 ;; to move a condition register to a general register and to move
6013 ;; between the general registers and the floating point registers.
6015 (define_insn "movcc"
6016   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
6017         (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
6018   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
6019   "* return mips_move_1word (operands, insn, FALSE);"
6020   [(set_attr "type"     "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
6021    (set_attr "mode"     "SI")
6022    (set_attr "length"   "8,4,4,8,4,8,4,4,4,4,8,4,8")])
6024 ;; Reload condition code registers.  reload_incc and reload_outcc
6025 ;; both handle moves from arbitrary operands into condition code
6026 ;; registers.  reload_incc handles the more common case in which
6027 ;; a source operand is constrained to be in a condition-code
6028 ;; register, but has not been allocated to one.
6030 ;; Sometimes, such as in movcc, we have a CCmode destination whose
6031 ;; constraints do not include 'z'.  reload_outcc handles the case
6032 ;; when such an operand is allocated to a condition-code register.
6034 ;; Note that reloads from a condition code register to some
6035 ;; other location can be done using ordinary moves.  Moving
6036 ;; into a GPR takes a single movcc, moving elsewhere takes
6037 ;; two.  We can leave these cases to the generic reload code.
6038 (define_expand "reload_incc"
6039   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
6040         (match_operand:CC 1 "general_operand" ""))
6041    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
6042   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
6043   "
6045   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
6046   DONE;
6049 (define_expand "reload_outcc"
6050   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
6051         (match_operand:CC 1 "register_operand" ""))
6052    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
6053   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
6054   "
6056   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
6057   DONE;
6060 ;; MIPS4 supports loading and storing a floating point register from
6061 ;; the sum of two general registers.  We use two versions for each of
6062 ;; these four instructions: one where the two general registers are
6063 ;; SImode, and one where they are DImode.  This is because general
6064 ;; registers will be in SImode when they hold 32 bit values, but,
6065 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
6066 ;; instructions will still work correctly.
6068 ;; ??? Perhaps it would be better to support these instructions by
6069 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
6070 ;; these instructions can only be used to load and store floating
6071 ;; point registers, that would probably cause trouble in reload.
6073 (define_insn ""
6074   [(set (match_operand:SF 0 "register_operand" "=f")
6075         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
6076                          (match_operand:SI 2 "register_operand" "d"))))]
6077   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
6078   "lwxc1\\t%0,%1(%2)"
6079   [(set_attr "type"     "load")
6080    (set_attr "mode"     "SF")])
6082 (define_insn ""
6083   [(set (match_operand:SF 0 "register_operand" "=f")
6084         (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
6085                          (match_operand:DI 2 "se_register_operand" "d"))))]
6086   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
6087   "lwxc1\\t%0,%1(%2)"
6088   [(set_attr "type"     "load")
6089    (set_attr "mode"     "SF")])
6091 (define_insn ""
6092   [(set (match_operand:DF 0 "register_operand" "=f")
6093         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
6094                          (match_operand:SI 2 "register_operand" "d"))))]
6095   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6096   "ldxc1\\t%0,%1(%2)"
6097   [(set_attr "type"     "load")
6098    (set_attr "mode"     "DF")])
6100 (define_insn ""
6101   [(set (match_operand:DF 0 "register_operand" "=f")
6102         (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
6103                          (match_operand:DI 2 "se_register_operand" "d"))))]
6104   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6105   "ldxc1\\t%0,%1(%2)"
6106   [(set_attr "type"     "load")
6107    (set_attr "mode"     "DF")])
6109 (define_insn ""
6110   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
6111                          (match_operand:SI 2 "register_operand" "d")))
6112         (match_operand:SF 0 "register_operand" "f"))]
6113   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
6114   "swxc1\\t%0,%1(%2)"
6115   [(set_attr "type"     "store")
6116    (set_attr "mode"     "SF")])
6118 (define_insn ""
6119   [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
6120                          (match_operand:DI 2 "se_register_operand" "d")))
6121         (match_operand:SF 0 "register_operand" "f"))]
6122   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
6123   "swxc1\\t%0,%1(%2)"
6124   [(set_attr "type"     "store")
6125    (set_attr "mode"     "SF")])
6127 (define_insn ""
6128   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
6129                          (match_operand:SI 2 "register_operand" "d")))
6130         (match_operand:DF 0 "register_operand" "f"))]
6131   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6132   "sdxc1\\t%0,%1(%2)"
6133   [(set_attr "type"     "store")
6134    (set_attr "mode"     "DF")])
6136 (define_insn ""
6137   [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
6138                          (match_operand:DI 2 "se_register_operand" "d")))
6139         (match_operand:DF 0 "register_operand" "f"))]
6140   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6141   "sdxc1\\t%0,%1(%2)"
6142   [(set_attr "type"     "store")
6143    (set_attr "mode"     "DF")])
6145 ;; 16-bit Integer moves
6147 ;; Unlike most other insns, the move insns can't be split with
6148 ;; different predicates, because register spilling and other parts of
6149 ;; the compiler, have memoized the insn number already.
6150 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6152 (define_expand "movhi"
6153   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6154         (match_operand:HI 1 "general_operand" ""))]
6155   ""
6156   "
6158   if ((reload_in_progress | reload_completed) == 0
6159       && !register_operand (operands[0], HImode)
6160       && !register_operand (operands[1], HImode)
6161       && (TARGET_MIPS16
6162           || (GET_CODE (operands[1]) != CONST_INT
6163           || INTVAL (operands[1]) != 0)))
6164     {
6165       rtx temp = force_reg (HImode, operands[1]);
6166       emit_move_insn (operands[0], temp);
6167       DONE;
6168     }
6171 ;; The difference between these two is whether or not ints are allowed
6172 ;; in FP registers (off by default, use -mdebugh to enable).
6174 (define_insn "movhi_internal"
6175   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
6176         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6177   "!TARGET_MIPS16
6178    && (register_operand (operands[0], HImode)
6179        || register_operand (operands[1], HImode)
6180        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6181   "* return mips_move_1word (operands, insn, TRUE);"
6182   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6183    (set_attr "mode"     "HI")
6184    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,4")])
6186 (define_insn ""
6187   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6188         (match_operand:HI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
6189   "TARGET_MIPS16
6190    && (register_operand (operands[0], HImode)
6191        || register_operand (operands[1], HImode))"
6192   "* return mips_move_1word (operands, insn, TRUE);"
6193   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
6194    (set_attr "mode"     "HI")
6195    (set_attr_alternative "length"
6196                 [(const_int 4)
6197                  (const_int 4)
6198                  (const_int 4)
6199                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6200                                (const_int 4)
6201                                (const_int 8))
6202                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6203                                (const_int 8)
6204                                (const_int 12))
6205                  (const_int 4)
6206                  (const_int 8)
6207                  (const_int 4)
6208                  (const_int 8)
6209                  (const_int 4)])])
6212 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
6213 ;; when the original load is a 4 byte instruction but the add and the
6214 ;; load are 2 2 byte instructions.
6216 (define_split
6217   [(set (match_operand:HI 0 "register_operand" "")
6218         (mem:HI (plus:SI (match_dup 0)
6219                          (match_operand:SI 1 "const_int_operand" ""))))]
6220   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6221    && GET_CODE (operands[0]) == REG
6222    && M16_REG_P (REGNO (operands[0]))
6223    && GET_CODE (operands[1]) == CONST_INT
6224    && ((INTVAL (operands[1]) < 0
6225         && INTVAL (operands[1]) >= -0x80)
6226        || (INTVAL (operands[1]) >= 32 * 2
6227            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
6228        || (INTVAL (operands[1]) >= 0
6229            && INTVAL (operands[1]) < 32 * 2
6230            && (INTVAL (operands[1]) & 1) != 0))"
6231   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6232    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
6233   "
6235   HOST_WIDE_INT val = INTVAL (operands[1]);
6237   if (val < 0)
6238     operands[2] = GEN_INT (0);
6239   else if (val >= 32 * 2)
6240     {
6241       int off = val & 1;
6243       operands[1] = GEN_INT (0x7e + off);
6244       operands[2] = GEN_INT (val - off - 0x7e);
6245     }
6246   else
6247     {
6248       int off = val & 1;
6250       operands[1] = GEN_INT (off);
6251       operands[2] = GEN_INT (val - off);
6252     }
6255 ;; 8-bit Integer moves
6257 ;; Unlike most other insns, the move insns can't be split with
6258 ;; different predicates, because register spilling and other parts of
6259 ;; the compiler, have memoized the insn number already.
6260 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6262 (define_expand "movqi"
6263   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6264         (match_operand:QI 1 "general_operand" ""))]
6265   ""
6266   "
6268   if ((reload_in_progress | reload_completed) == 0
6269       && !register_operand (operands[0], QImode)
6270       && !register_operand (operands[1], QImode)
6271       && (TARGET_MIPS16
6272           || (GET_CODE (operands[1]) != CONST_INT
6273           || INTVAL (operands[1]) != 0)))
6274     {
6275       rtx temp = force_reg (QImode, operands[1]);
6276       emit_move_insn (operands[0], temp);
6277       DONE;
6278     }
6281 ;; The difference between these two is whether or not ints are allowed
6282 ;; in FP registers (off by default, use -mdebugh to enable).
6284 (define_insn "movqi_internal"
6285   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
6286         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6287   "!TARGET_MIPS16
6288    && (register_operand (operands[0], QImode)
6289        || register_operand (operands[1], QImode)
6290        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6291   "* return mips_move_1word (operands, insn, TRUE);"
6292   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6293    (set_attr "mode"     "QI")
6294    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,4")])
6296 (define_insn ""
6297   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6298         (match_operand:QI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
6299   "TARGET_MIPS16
6300    && (register_operand (operands[0], QImode)
6301        || register_operand (operands[1], QImode))"
6302   "* return mips_move_1word (operands, insn, TRUE);"
6303   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
6304    (set_attr "mode"     "QI")
6305    (set_attr_alternative "length"
6306                 [(const_int 4)
6307                  (const_int 4)
6308                  (const_int 4)
6309                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6310                                (const_int 4)
6311                                (const_int 8))
6312                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6313                                (const_int 8)
6314                                (const_int 12))
6315                  (const_int 4)
6316                  (const_int 8)
6317                  (const_int 4)
6318                  (const_int 8)
6319                  (const_int 4)])])
6322 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
6323 ;; when the original load is a 4 byte instruction but the add and the
6324 ;; load are 2 2 byte instructions.
6326 (define_split
6327   [(set (match_operand:QI 0 "register_operand" "")
6328         (mem:QI (plus:SI (match_dup 0)
6329                          (match_operand:SI 1 "const_int_operand" ""))))]
6330   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6331    && GET_CODE (operands[0]) == REG
6332    && M16_REG_P (REGNO (operands[0]))
6333    && GET_CODE (operands[1]) == CONST_INT
6334    && ((INTVAL (operands[1]) < 0
6335         && INTVAL (operands[1]) >= -0x80)
6336        || (INTVAL (operands[1]) >= 32
6337            && INTVAL (operands[1]) <= 31 + 0x7f))"
6338   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6339    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
6340   "
6342   HOST_WIDE_INT val = INTVAL (operands[1]);
6344   if (val < 0)
6345     operands[2] = GEN_INT (0);
6346   else
6347     {
6348       operands[1] = GEN_INT (0x7f);
6349       operands[2] = GEN_INT (val - 0x7f);
6350     }
6353 ;; 32-bit floating point moves
6355 (define_expand "movsf"
6356   [(set (match_operand:SF 0 "nonimmediate_operand" "")
6357         (match_operand:SF 1 "general_operand" ""))]
6358   ""
6359   "
6361   if ((reload_in_progress | reload_completed) == 0
6362       && !register_operand (operands[0], SFmode)
6363       && !nonmemory_operand (operands[1], SFmode))
6364     operands[1] = force_reg (SFmode, operands[1]);
6367 (define_insn "movsf_internal1"
6368   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
6369         (match_operand:SF 1 "general_operand" "f,G,R,m,fG,fG,*d,*f,*G*d,*R,*m,*d,*d"))]
6370   "TARGET_HARD_FLOAT
6371    && (register_operand (operands[0], SFmode)
6372        || nonmemory_operand (operands[1], SFmode))"
6373   "* return mips_move_1word (operands, insn, FALSE);"
6374   [(set_attr "type"     "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
6375    (set_attr "mode"     "SF")
6376    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,8,4,8")])
6378 (define_insn "movsf_internal2"
6379   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
6380         (match_operand:SF 1 "general_operand" "      Gd,R,m,d,d"))]
6381   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
6382    && (register_operand (operands[0], SFmode)
6383        || nonmemory_operand (operands[1], SFmode))"
6384   "* return mips_move_1word (operands, insn, FALSE);"
6385   [(set_attr "type"     "move,load,load,store,store")
6386    (set_attr "mode"     "SF")
6387    (set_attr "length"   "4,4,8,4,8")])
6389 (define_insn ""
6390   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
6391         (match_operand:SF 1 "nonimmediate_operand" "d,d,y,R,m,d,d"))]
6392   "TARGET_MIPS16
6393    && (register_operand (operands[0], SFmode)
6394        || register_operand (operands[1], SFmode))"
6395   "* return mips_move_1word (operands, insn, FALSE);"
6396   [(set_attr "type"     "move,move,move,load,load,store,store")
6397    (set_attr "mode"     "SF")
6398    (set_attr "length"   "4,4,4,4,8,4,8")])
6401 ;; 64-bit floating point moves
6403 (define_expand "movdf"
6404   [(set (match_operand:DF 0 "nonimmediate_operand" "")
6405         (match_operand:DF 1 "general_operand" ""))]
6406   ""
6407   "
6409   if ((reload_in_progress | reload_completed) == 0
6410       && !register_operand (operands[0], DFmode)
6411       && !nonmemory_operand (operands[1], DFmode))
6412     operands[1] = force_reg (DFmode, operands[1]);
6415 (define_insn "movdf_internal1"
6416   [(set (match_operand:DF 0 "nonimmediate_operand"  "=f,f,f,f,R,To,*f,*d,*d,*d,*d,*R,*T")
6417        (match_operand:DF 1 "general_operand"  "f,G,R,To,fG,fG,*d,*f,*d*G,*R,*T,*d,*d"))]
6418   "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
6419    && TARGET_DOUBLE_FLOAT
6420    && (register_operand (operands[0], DFmode)
6421        || nonmemory_operand (operands[1], DFmode))"
6422   "* return mips_move_2words (operands, insn); "
6423   [(set_attr "type"    "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
6424    (set_attr "mode"    "DF")
6425    (set_attr "length"  "4,8,8,16,8,16,8,8,8,8,16,8,16")])
6427 (define_insn "movdf_internal1a"
6428   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,*d,*d,*To,*R,*d")
6429         (match_operand:DF 1 "general_operand"      " f,To,f,G,f,G,*To,*R,*d,*d,*d"))]
6430   "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
6431    && TARGET_DOUBLE_FLOAT
6432    && (register_operand (operands[0], DFmode)
6433        || nonmemory_operand (operands[1], DFmode))"
6434   "* return mips_move_2words (operands, insn); "
6435   [(set_attr "type"     "move,load,store,store,store,store,load,load,store,store,move")
6436    (set_attr "mode"     "DF")
6437    (set_attr "length"   "4,8,4,4,8,8,8,4,8,4,4")])
6439 (define_insn "movdf_internal2"
6440   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To,d,f,f")
6441         (match_operand:DF 1 "general_operand" "dG,R,To,d,d,f,d,f"))]
6442   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
6443    && (register_operand (operands[0], DFmode)
6444        || nonmemory_operand (operands[1], DFmode))"
6445   "* return mips_move_2words (operands, insn); "
6446   [(set_attr "type"     "move,load,load,store,store,xfer,load,move")
6447    (set_attr "mode"     "DF")
6448    (set_attr "length"   "8,8,16,8,16,8,8,4")])
6450 (define_insn ""
6451   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
6452         (match_operand:DF 1 "nonimmediate_operand" "d,d,y,R,To,d,d"))]
6453   "TARGET_MIPS16
6454    && (register_operand (operands[0], DFmode)
6455        || register_operand (operands[1], DFmode))"
6456   "* return mips_move_2words (operands, insn);"
6457   [(set_attr "type"     "move,move,move,load,load,store,store")
6458    (set_attr "mode"     "DF")
6459    (set_attr "length"   "8,8,8,8,16,8,16")])
6461 (define_split
6462   [(set (match_operand:DF 0 "register_operand" "")
6463         (match_operand:DF 1 "register_operand" ""))]
6464   "reload_completed && !TARGET_64BIT
6465    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6466    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6467    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
6468   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
6469    (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
6470   "")
6472 ;; Instructions to load the global pointer register.
6473 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
6474 ;; uses in front of it.  All symbol_refs implicitly use the gp reg.
6476 (define_insn "loadgp"
6477   [(set (reg:DI 28)
6478         (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
6479                              (match_operand:DI 1 "register_operand" "")]
6480                             UNSPEC_LOADGP))
6481    (clobber (reg:DI 1))]
6482   ""
6483   "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
6484   [(set_attr "type"     "move")
6485    (set_attr "mode"     "DI")
6486    (set_attr "length"   "12")])
6488 ;; Block moves, see mips.c for more details.
6489 ;; Argument 0 is the destination
6490 ;; Argument 1 is the source
6491 ;; Argument 2 is the length
6492 ;; Argument 3 is the alignment
6494 (define_expand "movstrsi"
6495   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6496                    (match_operand:BLK 1 "general_operand" ""))
6497               (use (match_operand:SI 2 "arith32_operand" ""))
6498               (use (match_operand:SI 3 "immediate_operand" ""))])]
6499   "!TARGET_MIPS16"
6500   "
6502   if (operands[0])              /* avoid unused code messages */
6503     {
6504       expand_block_move (operands);
6505       DONE;
6506     }
6509 ;; Insn generated by block moves
6511 (define_insn "movstrsi_internal"
6512   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6513         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6514    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6515    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6516    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6517    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6518    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6519    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6520    (use (const_int 0))]                                 ;; normal block move
6521   ""
6522   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6523   [(set_attr "type"     "store")
6524    (set_attr "mode"     "none")
6525    (set_attr "length"   "80")])
6527 ;; We need mips16 versions, because an offset from the stack pointer
6528 ;; is not offsettable, since the stack pointer can only handle 4 and 8
6529 ;; byte loads.
6531 (define_insn ""
6532   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6533         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6534    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6535    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6536    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6537    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6538    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6539    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6540    (use (const_int 0))]                                 ;; normal block move
6541   "TARGET_MIPS16"
6542   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6543   [(set_attr "type"     "multi")
6544    (set_attr "mode"     "none")
6545    (set_attr "length"   "80")])
6547 ;; Split a block move into 2 parts, the first part is everything
6548 ;; except for the last move, and the second part is just the last
6549 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
6550 ;; fill a delay slot.  This also prevents a bug in delayed branches
6551 ;; from showing up, which reuses one of the registers in our clobbers.
6553 ;; ??? Disabled because it doesn't preserve alias information for
6554 ;; operands 0 and 1.  Also, the rtl for the second insn doesn't mention
6555 ;; that it uses the registers clobbered by the first.
6557 ;; It would probably be better to split the block into individual
6558 ;; instructions instead.
6559 (define_split
6560   [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6561         (mem:BLK (match_operand:SI 1 "register_operand" "")))
6562    (clobber (match_operand:SI 4 "register_operand" ""))
6563    (clobber (match_operand:SI 5 "register_operand" ""))
6564    (clobber (match_operand:SI 6 "register_operand" ""))
6565    (clobber (match_operand:SI 7 "register_operand" ""))
6566    (use (match_operand:SI 2 "small_int" ""))
6567    (use (match_operand:SI 3 "small_int" ""))
6568    (use (const_int 0))]
6570   "reload_completed && 0 && INTVAL (operands[2]) > 0"
6572   ;; All but the last move
6573   [(parallel [(set (mem:BLK (match_dup 0))
6574                    (mem:BLK (match_dup 1)))
6575               (clobber (match_dup 4))
6576               (clobber (match_dup 5))
6577               (clobber (match_dup 6))
6578               (clobber (match_dup 7))
6579               (use (match_dup 2))
6580               (use (match_dup 3))
6581               (use (const_int 1))])
6583    ;; The last store, so it can fill a delay slot
6584    (parallel [(set (mem:BLK (match_dup 0))
6585                    (mem:BLK (match_dup 1)))
6586               (clobber (match_dup 4))
6587               (clobber (match_dup 5))
6588               (clobber (match_dup 6))
6589               (clobber (match_dup 7))
6590               (use (match_dup 2))
6591               (use (match_dup 3))
6592               (use (const_int 2))])]
6594   "")
6596 (define_insn "movstrsi_internal2"
6597   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6598         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6599    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6600    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6601    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6602    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6603    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6604    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6605    (use (const_int 1))]                                 ;; all but last store
6606   ""
6607   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6608   [(set_attr "type"     "store")
6609    (set_attr "mode"     "none")
6610    (set_attr "length"   "80")])
6612 (define_insn ""
6613   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6614         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6615    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6616    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6617    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6618    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6619    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6620    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6621    (use (const_int 1))]                                 ;; all but last store
6622   "TARGET_MIPS16"
6623   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6624   [(set_attr "type"     "multi")
6625    (set_attr "mode"     "none")
6626    (set_attr "length"   "80")])
6628 (define_insn "movstrsi_internal3"
6629   [(set (match_operand:BLK 0 "memory_operand" "=Ro")    ;; destination
6630         (match_operand:BLK 1 "memory_operand" "Ro"))    ;; source
6631    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6632    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6633    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6634    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6635    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6636    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6637    (use (const_int 2))]                                 ;; just last store of block move
6638   ""
6639   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6640   [(set_attr "type"     "store")
6641    (set_attr "mode"     "none")])
6644 ;;  ....................
6646 ;;      SHIFTS
6648 ;;  ....................
6650 ;; Many of these instructions uses trivial define_expands, because we
6651 ;; want to use a different set of constraints when TARGET_MIPS16.
6653 (define_expand "ashlsi3"
6654   [(set (match_operand:SI 0 "register_operand" "=d")
6655         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6656                    (match_operand:SI 2 "arith_operand" "dI")))]
6657   ""
6658   "
6660   /* On the mips16, a shift of more than 8 is a four byte instruction,
6661      so, for a shift between 8 and 16, it is just as fast to do two
6662      shifts of 8 or less.  If there is a lot of shifting going on, we
6663      may win in CSE.  Otherwise combine will put the shifts back
6664      together again.  This can be called by function_arg, so we must
6665      be careful not to allocate a new register if we've reached the
6666      reload pass.  */
6667   if (TARGET_MIPS16
6668       && optimize
6669       && GET_CODE (operands[2]) == CONST_INT
6670       && INTVAL (operands[2]) > 8
6671       && INTVAL (operands[2]) <= 16
6672       && ! reload_in_progress
6673       && ! reload_completed)
6674     {
6675       rtx temp = gen_reg_rtx (SImode);
6677       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6678       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6679                                         GEN_INT (INTVAL (operands[2]) - 8)));
6680       DONE;
6681     }
6684 (define_insn "ashlsi3_internal1"
6685   [(set (match_operand:SI 0 "register_operand" "=d")
6686         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6687                    (match_operand:SI 2 "arith_operand" "dI")))]
6688   "!TARGET_MIPS16"
6689   "*
6691   if (GET_CODE (operands[2]) == CONST_INT)
6692     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6694   return \"sll\\t%0,%1,%2\";
6696   [(set_attr "type"     "arith")
6697    (set_attr "mode"     "SI")])
6699 (define_insn "ashlsi3_internal2"
6700   [(set (match_operand:SI 0 "register_operand" "=d,d")
6701         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6702                    (match_operand:SI 2 "arith_operand" "d,I")))]
6703   "TARGET_MIPS16"
6704   "*
6706   if (which_alternative == 0)
6707     return \"sll\\t%0,%2\";
6709   if (GET_CODE (operands[2]) == CONST_INT)
6710     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6712   return \"sll\\t%0,%1,%2\";
6714   [(set_attr "type"     "arith")
6715    (set_attr "mode"     "SI")
6716    (set_attr_alternative "length"
6717                 [(const_int 4)
6718                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6719                                (const_int 4)
6720                                (const_int 8))])])
6722 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6724 (define_split
6725   [(set (match_operand:SI 0 "register_operand" "")
6726         (ashift:SI (match_operand:SI 1 "register_operand" "")
6727                    (match_operand:SI 2 "const_int_operand" "")))]
6728   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6729    && GET_CODE (operands[2]) == CONST_INT
6730    && INTVAL (operands[2]) > 8
6731    && INTVAL (operands[2]) <= 16"
6732   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6733    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6736   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6739 (define_expand "ashldi3"
6740   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6741                    (ashift:DI (match_operand:DI 1 "se_register_operand" "")
6742                               (match_operand:SI 2 "arith_operand" "")))
6743               (clobber (match_dup  3))])]
6744   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6745   "
6747   if (TARGET_64BIT)
6748     {
6749       /* On the mips16, a shift of more than 8 is a four byte
6750          instruction, so, for a shift between 8 and 16, it is just as
6751          fast to do two shifts of 8 or less.  If there is a lot of
6752          shifting going on, we may win in CSE.  Otherwise combine will
6753          put the shifts back together again.  This can be called by
6754          function_arg, so we must be careful not to allocate a new
6755          register if we've reached the reload pass.  */
6756       if (TARGET_MIPS16
6757           && optimize
6758           && GET_CODE (operands[2]) == CONST_INT
6759           && INTVAL (operands[2]) > 8
6760           && INTVAL (operands[2]) <= 16
6761           && ! reload_in_progress
6762           && ! reload_completed)
6763         {
6764           rtx temp = gen_reg_rtx (DImode);
6766           emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6767           emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6768                                             GEN_INT (INTVAL (operands[2]) - 8)));
6769           DONE;
6770         }
6772       emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6773                                         operands[2]));
6774       DONE;
6775     }
6777   operands[3] = gen_reg_rtx (SImode);
6781 (define_insn "ashldi3_internal"
6782   [(set (match_operand:DI 0 "register_operand" "=&d")
6783         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6784                    (match_operand:SI 2 "register_operand" "d")))
6785    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6786   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6787   "*
6789   operands[4] = const0_rtx;
6790   dslots_jump_total += 3;
6791   dslots_jump_filled += 2;
6793   return \"sll\\t%3,%2,26\\n\\
6794 \\tbgez\\t%3,1f\\n\\
6795 \\tsll\\t%M0,%L1,%2\\n\\
6796 \\t%(b\\t3f\\n\\
6797 \\tmove\\t%L0,%z4%)\\n\\
6798 \\n\\
6799 %~1:\\n\\
6800 \\t%(beq\\t%3,%z4,2f\\n\\
6801 \\tsll\\t%M0,%M1,%2%)\\n\\
6802 \\n\\
6803 \\tsubu\\t%3,%z4,%2\\n\\
6804 \\tsrl\\t%3,%L1,%3\\n\\
6805 \\tor\\t%M0,%M0,%3\\n\\
6806 %~2:\\n\\
6807 \\tsll\\t%L0,%L1,%2\\n\\
6808 %~3:\";
6810   [(set_attr "type"     "darith")
6811    (set_attr "mode"     "SI")
6812    (set_attr "length"   "48")])
6815 (define_insn "ashldi3_internal2"
6816   [(set (match_operand:DI 0 "register_operand" "=d")
6817         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6818                    (match_operand:SI 2 "small_int" "IJK")))
6819    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6820   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6821    && (INTVAL (operands[2]) & 32) != 0"
6822   "*
6824   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6825   operands[4] = const0_rtx;
6826   return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6828   [(set_attr "type"     "darith")
6829    (set_attr "mode"     "DI")
6830    (set_attr "length"   "8")])
6833 (define_split
6834   [(set (match_operand:DI 0 "register_operand" "")
6835         (ashift:DI (match_operand:DI 1 "register_operand" "")
6836                    (match_operand:SI 2 "small_int" "")))
6837    (clobber (match_operand:SI 3 "register_operand" ""))]
6838   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6839    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6840    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6841    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6842    && (INTVAL (operands[2]) & 32) != 0"
6844   [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6845    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6847   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6850 (define_split
6851   [(set (match_operand:DI 0 "register_operand" "")
6852         (ashift:DI (match_operand:DI 1 "register_operand" "")
6853                    (match_operand:SI 2 "small_int" "")))
6854    (clobber (match_operand:SI 3 "register_operand" ""))]
6855   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6856    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6857    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6858    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6859    && (INTVAL (operands[2]) & 32) != 0"
6861   [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6862    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
6864   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6867 (define_insn "ashldi3_internal3"
6868   [(set (match_operand:DI 0 "register_operand" "=d")
6869         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6870                    (match_operand:SI 2 "small_int" "IJK")))
6871    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6872   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6873    && (INTVAL (operands[2]) & 63) < 32
6874    && (INTVAL (operands[2]) & 63) != 0"
6875   "*
6877   int amount = INTVAL (operands[2]);
6879   operands[2] = GEN_INT (amount & 31);
6880   operands[4] = const0_rtx;
6881   operands[5] = GEN_INT ((-amount) & 31);
6883   return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6885   [(set_attr "type"     "darith")
6886    (set_attr "mode"     "DI")
6887    (set_attr "length"   "16")])
6890 (define_split
6891   [(set (match_operand:DI 0 "register_operand" "")
6892         (ashift:DI (match_operand:DI 1 "register_operand" "")
6893                    (match_operand:SI 2 "small_int" "")))
6894    (clobber (match_operand:SI 3 "register_operand" ""))]
6895   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6896    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6897    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6898    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6899    && (INTVAL (operands[2]) & 63) < 32
6900    && (INTVAL (operands[2]) & 63) != 0"
6902   [(set (subreg:SI (match_dup 0) 4)
6903         (ashift:SI (subreg:SI (match_dup 1) 4)
6904                    (match_dup 2)))
6906    (set (match_dup 3)
6907         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6908                      (match_dup 4)))
6910    (set (subreg:SI (match_dup 0) 4)
6911         (ior:SI (subreg:SI (match_dup 0) 4)
6912                 (match_dup 3)))
6914    (set (subreg:SI (match_dup 0) 0)
6915         (ashift:SI (subreg:SI (match_dup 1) 0)
6916                    (match_dup 2)))]
6917   "
6919   int amount = INTVAL (operands[2]);
6920   operands[2] = GEN_INT (amount & 31);
6921   operands[4] = GEN_INT ((-amount) & 31);
6925 (define_split
6926   [(set (match_operand:DI 0 "register_operand" "")
6927         (ashift:DI (match_operand:DI 1 "register_operand" "")
6928                    (match_operand:SI 2 "small_int" "")))
6929    (clobber (match_operand:SI 3 "register_operand" ""))]
6930   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6931    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6932    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6933    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6934    && (INTVAL (operands[2]) & 63) < 32
6935    && (INTVAL (operands[2]) & 63) != 0"
6937   [(set (subreg:SI (match_dup 0) 0)
6938         (ashift:SI (subreg:SI (match_dup 1) 0)
6939                    (match_dup 2)))
6941    (set (match_dup 3)
6942         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6943                      (match_dup 4)))
6945    (set (subreg:SI (match_dup 0) 0)
6946         (ior:SI (subreg:SI (match_dup 0) 0)
6947                 (match_dup 3)))
6949    (set (subreg:SI (match_dup 0) 4)
6950         (ashift:SI (subreg:SI (match_dup 1) 4)
6951                    (match_dup 2)))]
6952   "
6954   int amount = INTVAL (operands[2]);
6955   operands[2] = GEN_INT (amount & 31);
6956   operands[4] = GEN_INT ((-amount) & 31);
6960 (define_insn "ashldi3_internal4"
6961   [(set (match_operand:DI 0 "register_operand" "=d")
6962         (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6963                    (match_operand:SI 2 "arith_operand" "dI")))]
6964   "TARGET_64BIT && !TARGET_MIPS16"
6965   "*
6967   if (GET_CODE (operands[2]) == CONST_INT)
6968     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6970   return \"dsll\\t%0,%1,%2\";
6972   [(set_attr "type"     "arith")
6973    (set_attr "mode"     "DI")])
6975 (define_insn ""
6976   [(set (match_operand:DI 0 "register_operand" "=d,d")
6977         (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
6978                    (match_operand:SI 2 "arith_operand" "d,I")))]
6979   "TARGET_64BIT && TARGET_MIPS16"
6980   "*
6982   if (which_alternative == 0)
6983     return \"dsll\\t%0,%2\";
6985   if (GET_CODE (operands[2]) == CONST_INT)
6986     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6988   return \"dsll\\t%0,%1,%2\";
6990   [(set_attr "type"     "arith")
6991    (set_attr "mode"     "DI")
6992    (set_attr_alternative "length"
6993                 [(const_int 4)
6994                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6995                                (const_int 4)
6996                                (const_int 8))])])
6999 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7001 (define_split
7002   [(set (match_operand:DI 0 "register_operand" "")
7003         (ashift:DI (match_operand:DI 1 "register_operand" "")
7004                    (match_operand:SI 2 "const_int_operand" "")))]
7005   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
7006    && reload_completed
7007    && GET_CODE (operands[2]) == CONST_INT
7008    && INTVAL (operands[2]) > 8
7009    && INTVAL (operands[2]) <= 16"
7010   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
7011    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
7014   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7017 (define_expand "ashrsi3"
7018   [(set (match_operand:SI 0 "register_operand" "=d")
7019         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
7020                      (match_operand:SI 2 "arith_operand" "dI")))]
7021   ""
7022   "
7024   /* On the mips16, a shift of more than 8 is a four byte instruction,
7025      so, for a shift between 8 and 16, it is just as fast to do two
7026      shifts of 8 or less.  If there is a lot of shifting going on, we
7027      may win in CSE.  Otherwise combine will put the shifts back
7028      together again.  */
7029   if (TARGET_MIPS16
7030       && optimize
7031       && GET_CODE (operands[2]) == CONST_INT
7032       && INTVAL (operands[2]) > 8
7033       && INTVAL (operands[2]) <= 16)
7034     {
7035       rtx temp = gen_reg_rtx (SImode);
7037       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7038       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
7039                                         GEN_INT (INTVAL (operands[2]) - 8)));
7040       DONE;
7041     }
7044 (define_insn "ashrsi3_internal1"
7045   [(set (match_operand:SI 0 "register_operand" "=d")
7046         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
7047                      (match_operand:SI 2 "arith_operand" "dI")))]
7048   "!TARGET_MIPS16"
7049   "*
7051   if (GET_CODE (operands[2]) == CONST_INT)
7052     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7054   return \"sra\\t%0,%1,%2\";
7056   [(set_attr "type"     "arith")
7057    (set_attr "mode"     "SI")])
7059 (define_insn "ashrsi3_internal2"
7060   [(set (match_operand:SI 0 "register_operand" "=d,d")
7061         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7062                      (match_operand:SI 2 "arith_operand" "d,I")))]
7063   "TARGET_MIPS16"
7064   "*
7066   if (which_alternative == 0)
7067     return \"sra\\t%0,%2\";
7069   if (GET_CODE (operands[2]) == CONST_INT)
7070     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7072   return \"sra\\t%0,%1,%2\";
7074   [(set_attr "type"     "arith")
7075    (set_attr "mode"     "SI")
7076    (set_attr_alternative "length"
7077                 [(const_int 4)
7078                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7079                                (const_int 4)
7080                                (const_int 8))])])
7083 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7085 (define_split
7086   [(set (match_operand:SI 0 "register_operand" "")
7087         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
7088                      (match_operand:SI 2 "const_int_operand" "")))]
7089   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7090    && GET_CODE (operands[2]) == CONST_INT
7091    && INTVAL (operands[2]) > 8
7092    && INTVAL (operands[2]) <= 16"
7093   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
7094    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
7097   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7100 (define_expand "ashrdi3"
7101   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7102                    (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7103                                 (match_operand:SI 2 "arith_operand" "")))
7104               (clobber (match_dup  3))])]
7105   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7106   "
7108   if (TARGET_64BIT)
7109     {
7110       /* On the mips16, a shift of more than 8 is a four byte
7111          instruction, so, for a shift between 8 and 16, it is just as
7112          fast to do two shifts of 8 or less.  If there is a lot of
7113          shifting going on, we may win in CSE.  Otherwise combine will
7114          put the shifts back together again.  */
7115       if (TARGET_MIPS16
7116           && optimize
7117           && GET_CODE (operands[2]) == CONST_INT
7118           && INTVAL (operands[2]) > 8
7119           && INTVAL (operands[2]) <= 16)
7120         {
7121           rtx temp = gen_reg_rtx (DImode);
7123           emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7124           emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
7125                                             GEN_INT (INTVAL (operands[2]) - 8)));
7126           DONE;
7127         }
7129       emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
7130                                         operands[2]));
7131       DONE;
7132     }
7134   operands[3] = gen_reg_rtx (SImode);
7138 (define_insn "ashrdi3_internal"
7139   [(set (match_operand:DI 0 "register_operand" "=&d")
7140         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7141                      (match_operand:SI 2 "register_operand" "d")))
7142    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7143   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7144   "*
7146   operands[4] = const0_rtx;
7147   dslots_jump_total += 3;
7148   dslots_jump_filled += 2;
7150   return \"sll\\t%3,%2,26\\n\\
7151 \\tbgez\\t%3,1f\\n\\
7152 \\tsra\\t%L0,%M1,%2\\n\\
7153 \\t%(b\\t3f\\n\\
7154 \\tsra\\t%M0,%M1,31%)\\n\\
7155 \\n\\
7156 %~1:\\n\\
7157 \\t%(beq\\t%3,%z4,2f\\n\\
7158 \\tsrl\\t%L0,%L1,%2%)\\n\\
7159 \\n\\
7160 \\tsubu\\t%3,%z4,%2\\n\\
7161 \\tsll\\t%3,%M1,%3\\n\\
7162 \\tor\\t%L0,%L0,%3\\n\\
7163 %~2:\\n\\
7164 \\tsra\\t%M0,%M1,%2\\n\\
7165 %~3:\";
7167   [(set_attr "type"     "darith")
7168    (set_attr "mode"     "DI")
7169    (set_attr "length"   "48")])
7172 (define_insn "ashrdi3_internal2"
7173   [(set (match_operand:DI 0 "register_operand" "=d")
7174         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7175                      (match_operand:SI 2 "small_int" "IJK")))
7176    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7177   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
7178   "*
7180   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7181   return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
7183   [(set_attr "type"     "darith")
7184    (set_attr "mode"     "DI")
7185    (set_attr "length"   "8")])
7188 (define_split
7189   [(set (match_operand:DI 0 "register_operand" "")
7190         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7191                      (match_operand:SI 2 "small_int" "")))
7192    (clobber (match_operand:SI 3 "register_operand" ""))]
7193   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7194    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7195    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7196    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7197    && (INTVAL (operands[2]) & 32) != 0"
7199   [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7200    (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
7202   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7205 (define_split
7206   [(set (match_operand:DI 0 "register_operand" "")
7207         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7208                      (match_operand:SI 2 "small_int" "")))
7209    (clobber (match_operand:SI 3 "register_operand" ""))]
7210   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7211    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7212    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7213    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7214    && (INTVAL (operands[2]) & 32) != 0"
7216   [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7217    (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
7219   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7222 (define_insn "ashrdi3_internal3"
7223   [(set (match_operand:DI 0 "register_operand" "=d")
7224         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7225                      (match_operand:SI 2 "small_int" "IJK")))
7226    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7227   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7228    && (INTVAL (operands[2]) & 63) < 32
7229    && (INTVAL (operands[2]) & 63) != 0"
7230   "*
7232   int amount = INTVAL (operands[2]);
7234   operands[2] = GEN_INT (amount & 31);
7235   operands[4] = GEN_INT ((-amount) & 31);
7237   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
7239   [(set_attr "type"     "darith")
7240    (set_attr "mode"     "DI")
7241    (set_attr "length"   "16")])
7244 (define_split
7245   [(set (match_operand:DI 0 "register_operand" "")
7246         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7247                      (match_operand:SI 2 "small_int" "")))
7248    (clobber (match_operand:SI 3 "register_operand" ""))]
7249   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7250    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7251    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7252    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7253    && (INTVAL (operands[2]) & 63) < 32
7254    && (INTVAL (operands[2]) & 63) != 0"
7256   [(set (subreg:SI (match_dup 0) 0)
7257         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7258                      (match_dup 2)))
7260    (set (match_dup 3)
7261         (ashift:SI (subreg:SI (match_dup 1) 4)
7262                    (match_dup 4)))
7264    (set (subreg:SI (match_dup 0) 0)
7265         (ior:SI (subreg:SI (match_dup 0) 0)
7266                 (match_dup 3)))
7268    (set (subreg:SI (match_dup 0) 4)
7269         (ashiftrt:SI (subreg:SI (match_dup 1) 4)
7270                      (match_dup 2)))]
7271   "
7273   int amount = INTVAL (operands[2]);
7274   operands[2] = GEN_INT (amount & 31);
7275   operands[4] = GEN_INT ((-amount) & 31);
7279 (define_split
7280   [(set (match_operand:DI 0 "register_operand" "")
7281         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7282                      (match_operand:SI 2 "small_int" "")))
7283    (clobber (match_operand:SI 3 "register_operand" ""))]
7284   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7285    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7286    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7287    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7288    && (INTVAL (operands[2]) & 63) < 32
7289    && (INTVAL (operands[2]) & 63) != 0"
7291   [(set (subreg:SI (match_dup 0) 4)
7292         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7293                      (match_dup 2)))
7295    (set (match_dup 3)
7296         (ashift:SI (subreg:SI (match_dup 1) 0)
7297                    (match_dup 4)))
7299    (set (subreg:SI (match_dup 0) 4)
7300         (ior:SI (subreg:SI (match_dup 0) 4)
7301                 (match_dup 3)))
7303    (set (subreg:SI (match_dup 0) 0)
7304         (ashiftrt:SI (subreg:SI (match_dup 1) 0)
7305                      (match_dup 2)))]
7306   "
7308   int amount = INTVAL (operands[2]);
7309   operands[2] = GEN_INT (amount & 31);
7310   operands[4] = GEN_INT ((-amount) & 31);
7314 (define_insn "ashrdi3_internal4"
7315   [(set (match_operand:DI 0 "register_operand" "=d")
7316         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7317                      (match_operand:SI 2 "arith_operand" "dI")))]
7318   "TARGET_64BIT && !TARGET_MIPS16"
7319   "*
7321   if (GET_CODE (operands[2]) == CONST_INT)
7322     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7324   return \"dsra\\t%0,%1,%2\";
7326   [(set_attr "type"     "arith")
7327    (set_attr "mode"     "DI")])
7329 (define_insn ""
7330   [(set (match_operand:DI 0 "register_operand" "=d,d")
7331         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7332                      (match_operand:SI 2 "arith_operand" "d,I")))]
7333   "TARGET_64BIT && TARGET_MIPS16"
7334   "*
7336   if (GET_CODE (operands[2]) == CONST_INT)
7337     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7339   return \"dsra\\t%0,%2\";
7341   [(set_attr "type"     "arith")
7342    (set_attr "mode"     "DI")
7343    (set_attr_alternative "length"
7344                 [(const_int 4)
7345                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7346                                (const_int 4)
7347                                (const_int 8))])])
7349 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7351 (define_split
7352   [(set (match_operand:DI 0 "register_operand" "")
7353         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7354                      (match_operand:SI 2 "const_int_operand" "")))]
7355   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
7356    && reload_completed
7357    && GET_CODE (operands[2]) == CONST_INT
7358    && INTVAL (operands[2]) > 8
7359    && INTVAL (operands[2]) <= 16"
7360   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7361    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7364   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7367 (define_expand "lshrsi3"
7368   [(set (match_operand:SI 0 "register_operand" "=d")
7369         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7370                      (match_operand:SI 2 "arith_operand" "dI")))]
7371   ""
7372   "
7374   /* On the mips16, a shift of more than 8 is a four byte instruction,
7375      so, for a shift between 8 and 16, it is just as fast to do two
7376      shifts of 8 or less.  If there is a lot of shifting going on, we
7377      may win in CSE.  Otherwise combine will put the shifts back
7378      together again.  */
7379   if (TARGET_MIPS16
7380       && optimize
7381       && GET_CODE (operands[2]) == CONST_INT
7382       && INTVAL (operands[2]) > 8
7383       && INTVAL (operands[2]) <= 16)
7384     {
7385       rtx temp = gen_reg_rtx (SImode);
7387       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7388       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7389                                         GEN_INT (INTVAL (operands[2]) - 8)));
7390       DONE;
7391     }
7394 (define_insn "lshrsi3_internal1"
7395   [(set (match_operand:SI 0 "register_operand" "=d")
7396         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7397                      (match_operand:SI 2 "arith_operand" "dI")))]
7398   "!TARGET_MIPS16"
7399   "*
7401   if (GET_CODE (operands[2]) == CONST_INT)
7402     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7404   return \"srl\\t%0,%1,%2\";
7406   [(set_attr "type"     "arith")
7407    (set_attr "mode"     "SI")])
7409 (define_insn "lshrsi3_internal2"
7410   [(set (match_operand:SI 0 "register_operand" "=d,d")
7411         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7412                      (match_operand:SI 2 "arith_operand" "d,I")))]
7413   "TARGET_MIPS16"
7414   "*
7416   if (which_alternative == 0)
7417     return \"srl\\t%0,%2\";
7419   if (GET_CODE (operands[2]) == CONST_INT)
7420     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7422   return \"srl\\t%0,%1,%2\";
7424   [(set_attr "type"     "arith")
7425    (set_attr "mode"     "SI")
7426    (set_attr_alternative "length"
7427                 [(const_int 4)
7428                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7429                                (const_int 4)
7430                                (const_int 8))])])
7433 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7435 (define_split
7436   [(set (match_operand:SI 0 "register_operand" "")
7437         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7438                      (match_operand:SI 2 "const_int_operand" "")))]
7439   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7440    && GET_CODE (operands[2]) == CONST_INT
7441    && INTVAL (operands[2]) > 8
7442    && INTVAL (operands[2]) <= 16"
7443   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7444    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7447   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7450 ;; If we load a byte on the mips16 as a bitfield, the resulting
7451 ;; sequence of instructions is too complicated for combine, because it
7452 ;; involves four instructions: a load, a shift, a constant load into a
7453 ;; register, and an and (the key problem here is that the mips16 does
7454 ;; not have and immediate).  We recognize a shift of a load in order
7455 ;; to make it simple enough for combine to understand.
7457 (define_insn ""
7458   [(set (match_operand:SI 0 "register_operand" "=d,d")
7459         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
7460                      (match_operand:SI 2 "immediate_operand" "I,I")))]
7461   "TARGET_MIPS16"
7462   "lw\\t%0,%1\;srl\\t%0,%2"
7463   [(set_attr "type"     "load")
7464    (set_attr "mode"     "SI")
7465    (set_attr_alternative "length"
7466                 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7467                                (const_int 8)
7468                                (const_int 12))
7469                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7470                                (const_int 12)
7471                                (const_int 16))])])
7473 (define_split
7474   [(set (match_operand:SI 0 "register_operand" "")
7475         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7476                      (match_operand:SI 2 "immediate_operand" "")))]
7477   "TARGET_MIPS16 && !TARGET_DEBUG_D_MODE"
7478   [(set (match_dup 0) (match_dup 1))
7479    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7480   "")
7482 (define_expand "lshrdi3"
7483   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7484                    (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7485                                 (match_operand:SI 2 "arith_operand" "")))
7486               (clobber (match_dup  3))])]
7487   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7488   "
7490   if (TARGET_64BIT)
7491     {
7492       /* On the mips16, a shift of more than 8 is a four byte
7493          instruction, so, for a shift between 8 and 16, it is just as
7494          fast to do two shifts of 8 or less.  If there is a lot of
7495          shifting going on, we may win in CSE.  Otherwise combine will
7496          put the shifts back together again.  */
7497       if (TARGET_MIPS16
7498           && optimize
7499           && GET_CODE (operands[2]) == CONST_INT
7500           && INTVAL (operands[2]) > 8
7501           && INTVAL (operands[2]) <= 16)
7502         {
7503           rtx temp = gen_reg_rtx (DImode);
7505           emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7506           emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7507                                             GEN_INT (INTVAL (operands[2]) - 8)));
7508           DONE;
7509         }
7511       emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7512                                         operands[2]));
7513       DONE;
7514     }
7516   operands[3] = gen_reg_rtx (SImode);
7520 (define_insn "lshrdi3_internal"
7521   [(set (match_operand:DI 0 "register_operand" "=&d")
7522         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7523                      (match_operand:SI 2 "register_operand" "d")))
7524    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7525   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7526   "*
7528   operands[4] = const0_rtx;
7529   dslots_jump_total += 3;
7530   dslots_jump_filled += 2;
7532   return \"sll\\t%3,%2,26\\n\\
7533 \\tbgez\\t%3,1f\\n\\
7534 \\tsrl\\t%L0,%M1,%2\\n\\
7535 \\t%(b\\t3f\\n\\
7536 \\tmove\\t%M0,%z4%)\\n\\
7537 \\n\\
7538 %~1:\\n\\
7539 \\t%(beq\\t%3,%z4,2f\\n\\
7540 \\tsrl\\t%L0,%L1,%2%)\\n\\
7541 \\n\\
7542 \\tsubu\\t%3,%z4,%2\\n\\
7543 \\tsll\\t%3,%M1,%3\\n\\
7544 \\tor\\t%L0,%L0,%3\\n\\
7545 %~2:\\n\\
7546 \\tsrl\\t%M0,%M1,%2\\n\\
7547 %~3:\";
7549   [(set_attr "type"     "darith")
7550    (set_attr "mode"     "DI")
7551    (set_attr "length"   "48")])
7554 (define_insn "lshrdi3_internal2"
7555   [(set (match_operand:DI 0 "register_operand" "=d")
7556         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7557                      (match_operand:SI 2 "small_int" "IJK")))
7558    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7559   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7560    && (INTVAL (operands[2]) & 32) != 0"
7561   "*
7563   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7564   operands[4] = const0_rtx;
7565   return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7567   [(set_attr "type"     "darith")
7568    (set_attr "mode"     "DI")
7569    (set_attr "length"   "8")])
7572 (define_split
7573   [(set (match_operand:DI 0 "register_operand" "")
7574         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7575                      (match_operand:SI 2 "small_int" "")))
7576    (clobber (match_operand:SI 3 "register_operand" ""))]
7577   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7578    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7579    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7580    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7581    && (INTVAL (operands[2]) & 32) != 0"
7583   [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7584    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
7586   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7589 (define_split
7590   [(set (match_operand:DI 0 "register_operand" "")
7591         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7592                      (match_operand:SI 2 "small_int" "")))
7593    (clobber (match_operand:SI 3 "register_operand" ""))]
7594   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7595    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7596    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7597    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7598    && (INTVAL (operands[2]) & 32) != 0"
7600   [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7601    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7603   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7606 (define_insn "lshrdi3_internal3"
7607   [(set (match_operand:DI 0 "register_operand" "=d")
7608         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7609                    (match_operand:SI 2 "small_int" "IJK")))
7610    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7611   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7612    && (INTVAL (operands[2]) & 63) < 32
7613    && (INTVAL (operands[2]) & 63) != 0"
7614   "*
7616   int amount = INTVAL (operands[2]);
7618   operands[2] = GEN_INT (amount & 31);
7619   operands[4] = GEN_INT ((-amount) & 31);
7621   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7623   [(set_attr "type"     "darith")
7624    (set_attr "mode"     "DI")
7625    (set_attr "length"   "16")])
7628 (define_split
7629   [(set (match_operand:DI 0 "register_operand" "")
7630         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7631                      (match_operand:SI 2 "small_int" "")))
7632    (clobber (match_operand:SI 3 "register_operand" ""))]
7633   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7634    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7635    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7636    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7637    && (INTVAL (operands[2]) & 63) < 32
7638    && (INTVAL (operands[2]) & 63) != 0"
7640   [(set (subreg:SI (match_dup 0) 0)
7641         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7642                      (match_dup 2)))
7644    (set (match_dup 3)
7645         (ashift:SI (subreg:SI (match_dup 1) 4)
7646                    (match_dup 4)))
7648    (set (subreg:SI (match_dup 0) 0)
7649         (ior:SI (subreg:SI (match_dup 0) 0)
7650                 (match_dup 3)))
7652    (set (subreg:SI (match_dup 0) 4)
7653         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7654                      (match_dup 2)))]
7655   "
7657   int amount = INTVAL (operands[2]);
7658   operands[2] = GEN_INT (amount & 31);
7659   operands[4] = GEN_INT ((-amount) & 31);
7663 (define_split
7664   [(set (match_operand:DI 0 "register_operand" "")
7665         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7666                      (match_operand:SI 2 "small_int" "")))
7667    (clobber (match_operand:SI 3 "register_operand" ""))]
7668   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7669    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7670    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7671    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7672    && (INTVAL (operands[2]) & 63) < 32
7673    && (INTVAL (operands[2]) & 63) != 0"
7675   [(set (subreg:SI (match_dup 0) 4)
7676         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7677                      (match_dup 2)))
7679    (set (match_dup 3)
7680         (ashift:SI (subreg:SI (match_dup 1) 0)
7681                    (match_dup 4)))
7683    (set (subreg:SI (match_dup 0) 4)
7684         (ior:SI (subreg:SI (match_dup 0) 4)
7685                 (match_dup 3)))
7687    (set (subreg:SI (match_dup 0) 0)
7688         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7689                      (match_dup 2)))]
7690   "
7692   int amount = INTVAL (operands[2]);
7693   operands[2] = GEN_INT (amount & 31);
7694   operands[4] = GEN_INT ((-amount) & 31);
7698 (define_insn "lshrdi3_internal4"
7699   [(set (match_operand:DI 0 "register_operand" "=d")
7700         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7701                      (match_operand:SI 2 "arith_operand" "dI")))]
7702   "TARGET_64BIT && !TARGET_MIPS16"
7703   "*
7705   if (GET_CODE (operands[2]) == CONST_INT)
7706     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7708   return \"dsrl\\t%0,%1,%2\";
7710   [(set_attr "type"     "arith")
7711    (set_attr "mode"     "DI")])
7713 (define_insn ""
7714   [(set (match_operand:DI 0 "register_operand" "=d,d")
7715         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7716                      (match_operand:SI 2 "arith_operand" "d,I")))]
7717   "TARGET_64BIT && TARGET_MIPS16"
7718   "*
7720   if (GET_CODE (operands[2]) == CONST_INT)
7721     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7723   return \"dsrl\\t%0,%2\";
7725   [(set_attr "type"     "arith")
7726    (set_attr "mode"     "DI")
7727    (set_attr_alternative "length"
7728                 [(const_int 4)
7729                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7730                                (const_int 4)
7731                                (const_int 8))])])
7733 (define_insn "rotrsi3"
7734   [(set (match_operand:SI              0 "register_operand" "=d")
7735         (rotatert:SI (match_operand:SI 1 "register_operand" "d")
7736                      (match_operand:SI 2 "arith_operand"    "dn")))]
7737   "ISA_HAS_ROTR_SI"
7738   "*
7740   if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
7741     return \"rorv\\t%0,%1,%2\";
7743   if ((GET_CODE (operands[2]) == CONST_INT)
7744       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
7745     abort ();
7747   return \"ror\\t%0,%1,%2\";
7749   [(set_attr "type"     "arith")
7750    (set_attr "mode"     "SI")])
7752 (define_insn "rotrdi3"
7753   [(set (match_operand:DI              0 "register_operand" "=d")
7754         (rotatert:DI (match_operand:DI 1 "register_operand" "d")
7755                      (match_operand:DI 2 "arith_operand"    "dn")))]
7756   "ISA_HAS_ROTR_DI"
7757   "*
7759    if (TARGET_SR71K)
7760     {
7761       if (GET_CODE (operands[2]) != CONST_INT)
7762         return \"drorv\\t%0,%1,%2\";
7764       if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
7765         return \"dror32\\t%0,%1,%2\";
7766     }
7768   if ((GET_CODE (operands[2]) == CONST_INT)
7769       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
7770     abort ();
7772   return \"dror\\t%0,%1,%2\";
7774   [(set_attr "type"     "arith")
7775    (set_attr "mode"     "DI")])
7778 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7780 (define_split
7781   [(set (match_operand:DI 0 "register_operand" "")
7782         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7783                      (match_operand:SI 2 "const_int_operand" "")))]
7784   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7785    && GET_CODE (operands[2]) == CONST_INT
7786    && INTVAL (operands[2]) > 8
7787    && INTVAL (operands[2]) <= 16"
7788   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7789    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7792   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7797 ;;  ....................
7799 ;;      COMPARISONS
7801 ;;  ....................
7803 ;; Flow here is rather complex:
7805 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the
7806 ;;      arguments into the branch_cmp array, and the type into
7807 ;;      branch_type.  No RTL is generated.
7809 ;;  2)  The appropriate branch define_expand is called, which then
7810 ;;      creates the appropriate RTL for the comparison and branch.
7811 ;;      Different CC modes are used, based on what type of branch is
7812 ;;      done, so that we can constrain things appropriately.  There
7813 ;;      are assumptions in the rest of GCC that break if we fold the
7814 ;;      operands into the branchs for integer operations, and use cc0
7815 ;;      for floating point, so we use the fp status register instead.
7816 ;;      If needed, an appropriate temporary is created to hold the
7817 ;;      of the integer compare.
7819 (define_expand "cmpsi"
7820   [(set (cc0)
7821         (compare:CC (match_operand:SI 0 "register_operand" "")
7822                     (match_operand:SI 1 "arith_operand" "")))]
7823   ""
7824   "
7826   if (operands[0])              /* avoid unused code message */
7827     {
7828       branch_cmp[0] = operands[0];
7829       branch_cmp[1] = operands[1];
7830       branch_type = CMP_SI;
7831       DONE;
7832     }
7835 (define_expand "tstsi"
7836   [(set (cc0)
7837         (match_operand:SI 0 "register_operand" ""))]
7838   ""
7839   "
7841   if (operands[0])              /* avoid unused code message */
7842     {
7843       branch_cmp[0] = operands[0];
7844       branch_cmp[1] = const0_rtx;
7845       branch_type = CMP_SI;
7846       DONE;
7847     }
7850 (define_expand "cmpdi"
7851   [(set (cc0)
7852         (compare:CC (match_operand:DI 0 "se_register_operand" "")
7853                     (match_operand:DI 1 "se_arith_operand" "")))]
7854   "TARGET_64BIT"
7855   "
7857   if (operands[0])              /* avoid unused code message */
7858     {
7859       branch_cmp[0] = operands[0];
7860       branch_cmp[1] = operands[1];
7861       branch_type = CMP_DI;
7862       DONE;
7863     }
7866 (define_expand "tstdi"
7867   [(set (cc0)
7868         (match_operand:DI 0 "se_register_operand" ""))]
7869   "TARGET_64BIT"
7870   "
7872   if (operands[0])              /* avoid unused code message */
7873     {
7874       branch_cmp[0] = operands[0];
7875       branch_cmp[1] = const0_rtx;
7876       branch_type = CMP_DI;
7877       DONE;
7878     }
7881 (define_expand "cmpdf"
7882   [(set (cc0)
7883         (compare:CC (match_operand:DF 0 "register_operand" "")
7884                     (match_operand:DF 1 "register_operand" "")))]
7885   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7886   "
7888   if (operands[0])              /* avoid unused code message */
7889     {
7890       branch_cmp[0] = operands[0];
7891       branch_cmp[1] = operands[1];
7892       branch_type = CMP_DF;
7893       DONE;
7894     }
7897 (define_expand "cmpsf"
7898   [(set (cc0)
7899         (compare:CC (match_operand:SF 0 "register_operand" "")
7900                     (match_operand:SF 1 "register_operand" "")))]
7901   "TARGET_HARD_FLOAT"
7902   "
7904   if (operands[0])              /* avoid unused code message */
7905     {
7906       branch_cmp[0] = operands[0];
7907       branch_cmp[1] = operands[1];
7908       branch_type = CMP_SF;
7909       DONE;
7910     }
7915 ;;  ....................
7917 ;;      CONDITIONAL BRANCHES
7919 ;;  ....................
7921 ;; Conditional branches on floating-point equality tests.
7923 (define_insn "branch_fp"
7924   [(set (pc)
7925         (if_then_else
7926          (match_operator:CC 0 "cmp_op"
7927                             [(match_operand:CC 2 "register_operand" "z")
7928                              (const_int 0)])
7929          (label_ref (match_operand 1 "" ""))
7930          (pc)))]
7931   "TARGET_HARD_FLOAT"
7932   "*
7934   return mips_output_conditional_branch (insn,
7935                                          operands,
7936                                          /*two_operands_p=*/0,
7937                                          /*float_p=*/1,
7938                                          /*inverted_p=*/0,
7939                                          get_attr_length (insn));
7941   [(set_attr "type"     "branch")
7942    (set_attr "mode"     "none")])
7944 (define_insn "branch_fp_inverted"
7945   [(set (pc)
7946         (if_then_else
7947          (match_operator:CC 0 "cmp_op"
7948                             [(match_operand:CC 2 "register_operand" "z")
7949                              (const_int 0)])
7950          (pc)
7951          (label_ref (match_operand 1 "" ""))))]
7952   "TARGET_HARD_FLOAT"
7953   "*
7955   return mips_output_conditional_branch (insn,
7956                                          operands,
7957                                          /*two_operands_p=*/0,
7958                                          /*float_p=*/1,
7959                                          /*inverted_p=*/1,
7960                                          get_attr_length (insn));
7962   [(set_attr "type"     "branch")
7963    (set_attr "mode"     "none")])
7965 ;; Conditional branches on comparisons with zero.
7967 (define_insn "branch_zero"
7968   [(set (pc)
7969         (if_then_else
7970          (match_operator:SI 0 "cmp_op"
7971                             [(match_operand:SI 2 "register_operand" "d")
7972                              (const_int 0)])
7973         (label_ref (match_operand 1 "" ""))
7974         (pc)))]
7975   "!TARGET_MIPS16"
7976   "*
7978   return mips_output_conditional_branch (insn,
7979                                          operands,
7980                                          /*two_operands_p=*/0,
7981                                          /*float_p=*/0,
7982                                          /*inverted_p=*/0,
7983                                          get_attr_length (insn));
7985   [(set_attr "type"     "branch")
7986    (set_attr "mode"     "none")])
7988 (define_insn "branch_zero_inverted"
7989   [(set (pc)
7990         (if_then_else
7991          (match_operator:SI 0 "cmp_op"
7992                             [(match_operand:SI 2 "register_operand" "d")
7993                              (const_int 0)])
7994         (pc)
7995         (label_ref (match_operand 1 "" ""))))]
7996   "!TARGET_MIPS16"
7997   "*
7999   return mips_output_conditional_branch (insn,
8000                                          operands,
8001                                          /*two_operands_p=*/0,
8002                                          /*float_p=*/0,
8003                                          /*inverted_p=*/1,
8004                                          get_attr_length (insn));
8006   [(set_attr "type"     "branch")
8007    (set_attr "mode"     "none")])
8009 (define_insn "branch_zero_di"
8010   [(set (pc)
8011         (if_then_else
8012          (match_operator:DI 0 "cmp_op"
8013                             [(match_operand:DI 2 "se_register_operand" "d")
8014                              (const_int 0)])
8015         (label_ref (match_operand 1 "" ""))
8016         (pc)))]
8017   "!TARGET_MIPS16"
8018   "*
8020   return mips_output_conditional_branch (insn,
8021                                          operands,
8022                                          /*two_operands_p=*/0,
8023                                          /*float_p=*/0,
8024                                          /*inverted_p=*/0,
8025                                          get_attr_length (insn));
8027   [(set_attr "type"     "branch")
8028    (set_attr "mode"     "none")])
8030 (define_insn "branch_zero_di_inverted"
8031   [(set (pc)
8032         (if_then_else
8033          (match_operator:DI 0 "cmp_op"
8034                             [(match_operand:DI 2 "se_register_operand" "d")
8035                              (const_int 0)])
8036         (pc)
8037         (label_ref (match_operand 1 "" ""))))]
8038   "!TARGET_MIPS16"
8039   "*
8041   return mips_output_conditional_branch (insn,
8042                                          operands,
8043                                          /*two_operands_p=*/0,
8044                                          /*float_p=*/0,
8045                                          /*inverted_p=*/1,
8046                                          get_attr_length (insn));
8048   [(set_attr "type"     "branch")
8049    (set_attr "mode"     "none")])
8051 ;; Conditional branch on equality comparision.
8053 (define_insn "branch_equality"
8054   [(set (pc)
8055         (if_then_else
8056          (match_operator:SI 0 "equality_op"
8057                             [(match_operand:SI 2 "register_operand" "d")
8058                              (match_operand:SI 3 "register_operand" "d")])
8059          (label_ref (match_operand 1 "" ""))
8060          (pc)))]
8061   "!TARGET_MIPS16"
8062   "*
8064   return mips_output_conditional_branch (insn,
8065                                          operands,
8066                                          /*two_operands_p=*/1,
8067                                          /*float_p=*/0,
8068                                          /*inverted_p=*/0,
8069                                          get_attr_length (insn));
8071   [(set_attr "type"     "branch")
8072    (set_attr "mode"     "none")])
8074 (define_insn "branch_equality_di"
8075   [(set (pc)
8076         (if_then_else
8077          (match_operator:DI 0 "equality_op"
8078                             [(match_operand:DI 2 "se_register_operand" "d")
8079                              (match_operand:DI 3 "se_register_operand" "d")])
8080         (label_ref (match_operand 1 "" ""))
8081         (pc)))]
8082   "!TARGET_MIPS16"
8083   "*
8085   return mips_output_conditional_branch (insn,
8086                                          operands,
8087                                          /*two_operands_p=*/1,
8088                                          /*float_p=*/0,
8089                                          /*inverted_p=*/0,
8090                                          get_attr_length (insn));
8092   [(set_attr "type"     "branch")
8093    (set_attr "mode"     "none")])
8095 (define_insn "branch_equality_inverted"
8096   [(set (pc)
8097         (if_then_else
8098          (match_operator:SI 0 "equality_op"
8099                             [(match_operand:SI 2 "register_operand" "d")
8100                              (match_operand:SI 3 "register_operand" "d")])
8101          (pc)
8102          (label_ref (match_operand 1 "" ""))))]
8103   "!TARGET_MIPS16"
8104   "*
8106   return mips_output_conditional_branch (insn,
8107                                          operands,
8108                                          /*two_operands_p=*/1,
8109                                          /*float_p=*/0,
8110                                          /*inverted_p=*/1,
8111                                          get_attr_length (insn));
8113   [(set_attr "type"     "branch")
8114    (set_attr "mode"     "none")])
8116 (define_insn "branch_equality_di_inverted"
8117   [(set (pc)
8118         (if_then_else
8119          (match_operator:DI 0 "equality_op"
8120                             [(match_operand:DI 2 "se_register_operand" "d")
8121                              (match_operand:DI 3 "se_register_operand" "d")])
8122         (pc)
8123         (label_ref (match_operand 1 "" ""))))]
8124   "!TARGET_MIPS16"
8125   "*
8127   return mips_output_conditional_branch (insn,
8128                                          operands,
8129                                          /*two_operands_p=*/1,
8130                                          /*float_p=*/0,
8131                                          /*inverted_p=*/1,
8132                                          get_attr_length (insn));
8134   [(set_attr "type"     "branch")
8135    (set_attr "mode"     "none")])
8137 ;; MIPS16 branches
8139 (define_insn ""
8140   [(set (pc)
8141         (if_then_else (match_operator:SI 0 "equality_op"
8142                                          [(match_operand:SI 1 "register_operand" "d,t")
8143                                           (const_int 0)])
8144         (match_operand 2 "pc_or_label_operand" "")
8145         (match_operand 3 "pc_or_label_operand" "")))]
8146   "TARGET_MIPS16"
8147   "*
8149   if (operands[2] != pc_rtx)
8150     {
8151       if (which_alternative == 0)
8152         return \"%*b%C0z\\t%1,%2\";
8153       else
8154         return \"%*bt%C0z\\t%2\";
8155     }
8156   else
8157     {
8158       if (which_alternative == 0)
8159         return \"%*b%N0z\\t%1,%3\";
8160       else
8161         return \"%*bt%N0z\\t%3\";
8162     }
8164   [(set_attr "type"     "branch")
8165    (set_attr "mode"     "none")
8166    (set_attr "length"   "8")])
8168 (define_insn ""
8169   [(set (pc)
8170         (if_then_else (match_operator:DI 0 "equality_op"
8171                                          [(match_operand:DI 1 "se_register_operand" "d,t")
8172                                           (const_int 0)])
8173         (match_operand 2 "pc_or_label_operand" "")
8174         (match_operand 3 "pc_or_label_operand" "")))]
8175   "TARGET_MIPS16"
8176   "*
8178   if (operands[2] != pc_rtx)
8179     {
8180       if (which_alternative == 0)
8181         return \"%*b%C0z\\t%1,%2\";
8182       else
8183         return \"%*bt%C0z\\t%2\";
8184     }
8185   else
8186     {
8187       if (which_alternative == 0)
8188         return \"%*b%N0z\\t%1,%3\";
8189       else
8190         return \"%*bt%N0z\\t%3\";
8191     }
8193   [(set_attr "type"     "branch")
8194    (set_attr "mode"     "none")
8195    (set_attr "length"   "8")])
8197 (define_expand "bunordered"
8198   [(set (pc)
8199         (if_then_else (unordered:CC (cc0)
8200                                     (const_int 0))
8201                       (label_ref (match_operand 0 "" ""))
8202                       (pc)))]
8203   ""
8204   "
8206   if (operands[0])              /* avoid unused code warning */
8207     {
8208       gen_conditional_branch (operands, UNORDERED);
8209       DONE;
8210     }
8213 (define_expand "bordered"
8214   [(set (pc)
8215         (if_then_else (ordered:CC (cc0)
8216                                   (const_int 0))
8217                       (label_ref (match_operand 0 "" ""))
8218                       (pc)))]
8219   ""
8220   "
8222   if (operands[0])              /* avoid unused code warning */
8223      {
8224         gen_conditional_branch (operands, ORDERED);
8225         DONE;
8226      }
8229 (define_expand "bunlt"
8230   [(set (pc)
8231         (if_then_else (unlt:CC (cc0)
8232                                (const_int 0))
8233                       (label_ref (match_operand 0 "" ""))
8234                       (pc)))]
8235   ""
8236   "
8238   if (operands[0])              /* avoid unused code warning */
8239      {
8240         gen_conditional_branch (operands, UNLT);
8241         DONE;
8242      }
8245 (define_expand "bunge"
8246   [(set (pc)
8247         (if_then_else (unge:CC (cc0)
8248                                (const_int 0))
8249                       (label_ref (match_operand 0 "" ""))
8250                       (pc)))]
8251   ""
8252   "
8254   gen_conditional_branch (operands, UNGE);
8255   DONE;
8258 (define_expand "buneq"
8259   [(set (pc)
8260         (if_then_else (uneq:CC (cc0)
8261                                (const_int 0))
8262                       (label_ref (match_operand 0 "" ""))
8263                       (pc)))]
8264   ""
8265   "
8267   if (operands[0])              /* avoid unused code warning */
8268      {
8269         gen_conditional_branch (operands, UNEQ);
8270         DONE;
8271      }
8274 (define_expand "bltgt"
8275   [(set (pc)
8276         (if_then_else (ltgt:CC (cc0)
8277                                (const_int 0))
8278                       (label_ref (match_operand 0 "" ""))
8279                       (pc)))]
8280   ""
8281   "
8283   gen_conditional_branch (operands, LTGT);
8284   DONE;
8287 (define_expand "bunle"
8288   [(set (pc)
8289         (if_then_else (unle:CC (cc0)
8290                                (const_int 0))
8291                       (label_ref (match_operand 0 "" ""))
8292                       (pc)))]
8293   ""
8294   "
8296   if (operands[0])              /* avoid unused code warning */
8297      {
8298         gen_conditional_branch (operands, UNLE);
8299         DONE;
8300      }
8303 (define_expand "bungt"
8304   [(set (pc)
8305         (if_then_else (ungt:CC (cc0)
8306                                (const_int 0))
8307                       (label_ref (match_operand 0 "" ""))
8308                       (pc)))]
8309   ""
8310   "
8312   gen_conditional_branch (operands, UNGT);
8313   DONE;
8316 (define_expand "beq"
8317   [(set (pc)
8318         (if_then_else (eq:CC (cc0)
8319                              (const_int 0))
8320                       (label_ref (match_operand 0 "" ""))
8321                       (pc)))]
8322   ""
8323   "
8325   if (operands[0])              /* avoid unused code warning */
8326     {
8327       gen_conditional_branch (operands, EQ);
8328       DONE;
8329     }
8332 (define_expand "bne"
8333   [(set (pc)
8334         (if_then_else (ne:CC (cc0)
8335                              (const_int 0))
8336                       (label_ref (match_operand 0 "" ""))
8337                       (pc)))]
8338   ""
8339   "
8341   if (operands[0])              /* avoid unused code warning */
8342     {
8343       gen_conditional_branch (operands, NE);
8344       DONE;
8345     }
8348 (define_expand "bgt"
8349   [(set (pc)
8350         (if_then_else (gt:CC (cc0)
8351                              (const_int 0))
8352                       (label_ref (match_operand 0 "" ""))
8353                       (pc)))]
8354   ""
8355   "
8357   if (operands[0])              /* avoid unused code warning */
8358     {
8359       gen_conditional_branch (operands, GT);
8360       DONE;
8361     }
8364 (define_expand "bge"
8365   [(set (pc)
8366         (if_then_else (ge:CC (cc0)
8367                              (const_int 0))
8368                       (label_ref (match_operand 0 "" ""))
8369                       (pc)))]
8370   ""
8371   "
8373   if (operands[0])              /* avoid unused code warning */
8374     {
8375       gen_conditional_branch (operands, GE);
8376       DONE;
8377     }
8380 (define_expand "blt"
8381   [(set (pc)
8382         (if_then_else (lt:CC (cc0)
8383                              (const_int 0))
8384                       (label_ref (match_operand 0 "" ""))
8385                       (pc)))]
8386   ""
8387   "
8389   if (operands[0])              /* avoid unused code warning */
8390     {
8391       gen_conditional_branch (operands, LT);
8392       DONE;
8393     }
8396 (define_expand "ble"
8397   [(set (pc)
8398         (if_then_else (le:CC (cc0)
8399                              (const_int 0))
8400                       (label_ref (match_operand 0 "" ""))
8401                       (pc)))]
8402   ""
8403   "
8405   if (operands[0])              /* avoid unused code warning */
8406     {
8407       gen_conditional_branch (operands, LE);
8408       DONE;
8409     }
8412 (define_expand "bgtu"
8413   [(set (pc)
8414         (if_then_else (gtu:CC (cc0)
8415                               (const_int 0))
8416                       (label_ref (match_operand 0 "" ""))
8417                       (pc)))]
8418   ""
8419   "
8421   if (operands[0])              /* avoid unused code warning */
8422     {
8423       gen_conditional_branch (operands, GTU);
8424       DONE;
8425     }
8428 (define_expand "bgeu"
8429   [(set (pc)
8430         (if_then_else (geu:CC (cc0)
8431                               (const_int 0))
8432                       (label_ref (match_operand 0 "" ""))
8433                       (pc)))]
8434   ""
8435   "
8437   if (operands[0])              /* avoid unused code warning */
8438     {
8439       gen_conditional_branch (operands, GEU);
8440       DONE;
8441     }
8445 (define_expand "bltu"
8446   [(set (pc)
8447         (if_then_else (ltu:CC (cc0)
8448                               (const_int 0))
8449                       (label_ref (match_operand 0 "" ""))
8450                       (pc)))]
8451   ""
8452   "
8454   if (operands[0])              /* avoid unused code warning */
8455     {
8456       gen_conditional_branch (operands, LTU);
8457       DONE;
8458     }
8461 (define_expand "bleu"
8462   [(set (pc)
8463         (if_then_else (leu:CC (cc0)
8464                               (const_int 0))
8465                       (label_ref (match_operand 0 "" ""))
8466                       (pc)))]
8467   ""
8468   "
8470   if (operands[0])              /* avoid unused code warning */
8471     {
8472       gen_conditional_branch (operands, LEU);
8473       DONE;
8474     }
8479 ;;  ....................
8481 ;;      SETTING A REGISTER FROM A COMPARISON
8483 ;;  ....................
8485 (define_expand "seq"
8486   [(set (match_operand:SI 0 "register_operand" "=d")
8487         (eq:SI (match_dup 1)
8488                (match_dup 2)))]
8489   ""
8490   "
8492   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8493     FAIL;
8495   /* set up operands from compare.  */
8496   operands[1] = branch_cmp[0];
8497   operands[2] = branch_cmp[1];
8499   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8500     {
8501       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8502       DONE;
8503     }
8505   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8506     operands[2] = force_reg (SImode, operands[2]);
8508   /* fall through and generate default code */
8512 (define_insn "seq_si_zero"
8513   [(set (match_operand:SI 0 "register_operand" "=d")
8514         (eq:SI (match_operand:SI 1 "register_operand" "d")
8515                (const_int 0)))]
8516   "!TARGET_MIPS16"
8517   "sltu\\t%0,%1,1"
8518   [(set_attr "type"     "arith")
8519    (set_attr "mode"     "SI")])
8521 (define_insn ""
8522   [(set (match_operand:SI 0 "register_operand" "=t")
8523         (eq:SI (match_operand:SI 1 "register_operand" "d")
8524                (const_int 0)))]
8525   "TARGET_MIPS16"
8526   "sltu\\t%1,1"
8527   [(set_attr "type"     "arith")
8528    (set_attr "mode"     "SI")])
8530 (define_insn "seq_di_zero"
8531   [(set (match_operand:DI 0 "register_operand" "=d")
8532         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8533                (const_int 0)))]
8534   "TARGET_64BIT && !TARGET_MIPS16"
8535   "sltu\\t%0,%1,1"
8536   [(set_attr "type"     "arith")
8537    (set_attr "mode"     "DI")])
8539 (define_insn ""
8540   [(set (match_operand:DI 0 "register_operand" "=t")
8541         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8542                (const_int 0)))]
8543   "TARGET_64BIT && TARGET_MIPS16"
8544   "sltu\\t%1,1"
8545   [(set_attr "type"     "arith")
8546    (set_attr "mode"     "DI")])
8548 (define_insn "seq_si"
8549   [(set (match_operand:SI 0 "register_operand" "=d,d")
8550         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8551                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8552   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8553   "@
8554    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8555    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8556   [(set_attr "type"     "arith")
8557    (set_attr "mode"     "SI")
8558    (set_attr "length"   "8")])
8560 (define_split
8561   [(set (match_operand:SI 0 "register_operand" "")
8562         (eq:SI (match_operand:SI 1 "register_operand" "")
8563                (match_operand:SI 2 "uns_arith_operand" "")))]
8564   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8565     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8566   [(set (match_dup 0)
8567         (xor:SI (match_dup 1)
8568                 (match_dup 2)))
8569    (set (match_dup 0)
8570         (ltu:SI (match_dup 0)
8571                 (const_int 1)))]
8572   "")
8574 (define_insn "seq_di"
8575   [(set (match_operand:DI 0 "register_operand" "=d,d")
8576         (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8577                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8578   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8579   "@
8580    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8581    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8582   [(set_attr "type"     "arith")
8583    (set_attr "mode"     "DI")
8584    (set_attr "length"   "8")])
8586 (define_split
8587   [(set (match_operand:DI 0 "register_operand" "")
8588         (eq:DI (match_operand:DI 1 "se_register_operand" "")
8589                (match_operand:DI 2 "se_uns_arith_operand" "")))]
8590   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8591     && !TARGET_MIPS16
8592     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8593   [(set (match_dup 0)
8594         (xor:DI (match_dup 1)
8595                 (match_dup 2)))
8596    (set (match_dup 0)
8597         (ltu:DI (match_dup 0)
8598                 (const_int 1)))]
8599   "")
8601 ;; On the mips16 the default code is better than using sltu.
8603 (define_expand "sne"
8604   [(set (match_operand:SI 0 "register_operand" "=d")
8605         (ne:SI (match_dup 1)
8606                (match_dup 2)))]
8607   "!TARGET_MIPS16"
8608   "
8610   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8611     FAIL;
8613   /* set up operands from compare.  */
8614   operands[1] = branch_cmp[0];
8615   operands[2] = branch_cmp[1];
8617   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
8618     {
8619       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8620       DONE;
8621     }
8623   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8624     operands[2] = force_reg (SImode, operands[2]);
8626   /* fall through and generate default code */
8629 (define_insn "sne_si_zero"
8630   [(set (match_operand:SI 0 "register_operand" "=d")
8631         (ne:SI (match_operand:SI 1 "register_operand" "d")
8632                (const_int 0)))]
8633   "!TARGET_MIPS16"
8634   "sltu\\t%0,%.,%1"
8635   [(set_attr "type"     "arith")
8636    (set_attr "mode"     "SI")])
8638 (define_insn "sne_di_zero"
8639   [(set (match_operand:DI 0 "register_operand" "=d")
8640         (ne:DI (match_operand:DI 1 "se_register_operand" "d")
8641                (const_int 0)))]
8642   "TARGET_64BIT && !TARGET_MIPS16"
8643   "sltu\\t%0,%.,%1"
8644   [(set_attr "type"     "arith")
8645    (set_attr "mode"     "DI")])
8647 (define_insn "sne_si"
8648   [(set (match_operand:SI 0 "register_operand" "=d,d")
8649         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8650                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8651   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8652   "@
8653     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8654     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8655   [(set_attr "type"     "arith")
8656    (set_attr "mode"     "SI")
8657    (set_attr "length"   "8")])
8659 (define_split
8660   [(set (match_operand:SI 0 "register_operand" "")
8661         (ne:SI (match_operand:SI 1 "register_operand" "")
8662                (match_operand:SI 2 "uns_arith_operand" "")))]
8663   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8664     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8665   [(set (match_dup 0)
8666         (xor:SI (match_dup 1)
8667                 (match_dup 2)))
8668    (set (match_dup 0)
8669         (gtu:SI (match_dup 0)
8670                 (const_int 0)))]
8671   "")
8673 (define_insn "sne_di"
8674   [(set (match_operand:DI 0 "register_operand" "=d,d")
8675         (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8676                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8677   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8678   "@
8679     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8680     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
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         (ne:DI (match_operand:DI 1 "se_register_operand" "")
8688                (match_operand:DI 2 "se_uns_arith_operand" "")))]
8689   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8690     && !TARGET_MIPS16
8691     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8692   [(set (match_dup 0)
8693         (xor:DI (match_dup 1)
8694                 (match_dup 2)))
8695    (set (match_dup 0)
8696         (gtu:DI (match_dup 0)
8697                 (const_int 0)))]
8698   "")
8700 (define_expand "sgt"
8701   [(set (match_operand:SI 0 "register_operand" "=d")
8702         (gt:SI (match_dup 1)
8703                (match_dup 2)))]
8704   ""
8705   "
8707   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8708     FAIL;
8710   /* set up operands from compare.  */
8711   operands[1] = branch_cmp[0];
8712   operands[2] = branch_cmp[1];
8714   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8715     {
8716       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8717       DONE;
8718     }
8720   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8721     operands[2] = force_reg (SImode, operands[2]);
8723   /* fall through and generate default code */
8726 (define_insn "sgt_si"
8727   [(set (match_operand:SI 0 "register_operand" "=d")
8728         (gt:SI (match_operand:SI 1 "register_operand" "d")
8729                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8730   "!TARGET_MIPS16"
8731   "slt\\t%0,%z2,%1"
8732   [(set_attr "type"     "arith")
8733    (set_attr "mode"     "SI")])
8735 (define_insn ""
8736   [(set (match_operand:SI 0 "register_operand" "=t")
8737         (gt:SI (match_operand:SI 1 "register_operand" "d")
8738                (match_operand:SI 2 "register_operand" "d")))]
8739   "TARGET_MIPS16"
8740   "slt\\t%2,%1"
8741   [(set_attr "type"     "arith")
8742    (set_attr "mode"     "SI")])
8744 (define_insn "sgt_di"
8745   [(set (match_operand:DI 0 "register_operand" "=d")
8746         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8747                (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8748   "TARGET_64BIT && !TARGET_MIPS16"
8749   "slt\\t%0,%z2,%1"
8750   [(set_attr "type"     "arith")
8751    (set_attr "mode"     "DI")])
8753 (define_insn ""
8754   [(set (match_operand:DI 0 "register_operand" "=d")
8755         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8756                (match_operand:DI 2 "se_register_operand" "d")))]
8757   "TARGET_64BIT && TARGET_MIPS16"
8758   "slt\\t%2,%1"
8759   [(set_attr "type"     "arith")
8760    (set_attr "mode"     "DI")])
8762 (define_expand "sge"
8763   [(set (match_operand:SI 0 "register_operand" "=d")
8764         (ge:SI (match_dup 1)
8765                (match_dup 2)))]
8766   ""
8767   "
8769   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8770     FAIL;
8772   /* set up operands from compare.  */
8773   operands[1] = branch_cmp[0];
8774   operands[2] = branch_cmp[1];
8776   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8777     {
8778       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8779       DONE;
8780     }
8782   /* fall through and generate default code */
8785 (define_insn "sge_si"
8786   [(set (match_operand:SI 0 "register_operand" "=d")
8787         (ge:SI (match_operand:SI 1 "register_operand" "d")
8788                (match_operand:SI 2 "arith_operand" "dI")))]
8789   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8790   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8791   [(set_attr "type"     "arith")
8792    (set_attr "mode"     "SI")
8793    (set_attr "length"   "8")])
8795 (define_split
8796   [(set (match_operand:SI 0 "register_operand" "")
8797         (ge:SI (match_operand:SI 1 "register_operand" "")
8798                (match_operand:SI 2 "arith_operand" "")))]
8799   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8800   [(set (match_dup 0)
8801         (lt:SI (match_dup 1)
8802                (match_dup 2)))
8803    (set (match_dup 0)
8804         (xor:SI (match_dup 0)
8805                 (const_int 1)))]
8806   "")
8808 (define_insn "sge_di"
8809   [(set (match_operand:DI 0 "register_operand" "=d")
8810         (ge:DI (match_operand:DI 1 "se_register_operand" "d")
8811                (match_operand:DI 2 "se_arith_operand" "dI")))]
8812   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8813   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8814   [(set_attr "type"     "arith")
8815    (set_attr "mode"     "DI")
8816    (set_attr "length"   "8")])
8818 (define_split
8819   [(set (match_operand:DI 0 "register_operand" "")
8820         (ge:DI (match_operand:DI 1 "se_register_operand" "")
8821                (match_operand:DI 2 "se_arith_operand" "")))]
8822   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8823    && !TARGET_MIPS16"
8824   [(set (match_dup 0)
8825         (lt:DI (match_dup 1)
8826                (match_dup 2)))
8827    (set (match_dup 0)
8828         (xor:DI (match_dup 0)
8829                 (const_int 1)))]
8830   "")
8832 (define_expand "slt"
8833   [(set (match_operand:SI 0 "register_operand" "=d")
8834         (lt:SI (match_dup 1)
8835                (match_dup 2)))]
8836   ""
8837   "
8839   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8840     FAIL;
8842   /* set up operands from compare.  */
8843   operands[1] = branch_cmp[0];
8844   operands[2] = branch_cmp[1];
8846   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8847     {
8848       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8849       DONE;
8850     }
8852   /* fall through and generate default code */
8855 (define_insn "slt_si"
8856   [(set (match_operand:SI 0 "register_operand" "=d")
8857         (lt:SI (match_operand:SI 1 "register_operand" "d")
8858                (match_operand:SI 2 "arith_operand" "dI")))]
8859   "!TARGET_MIPS16"
8860   "slt\\t%0,%1,%2"
8861   [(set_attr "type"     "arith")
8862    (set_attr "mode"     "SI")])
8864 (define_insn ""
8865   [(set (match_operand:SI 0 "register_operand" "=t,t")
8866         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8867                (match_operand:SI 2 "arith_operand" "d,I")))]
8868   "TARGET_MIPS16"
8869   "slt\\t%1,%2"
8870   [(set_attr "type"     "arith")
8871    (set_attr "mode"     "SI")
8872    (set_attr_alternative "length"
8873                 [(const_int 4)
8874                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8875                                (const_int 4)
8876                                (const_int 8))])])
8878 (define_insn "slt_di"
8879   [(set (match_operand:DI 0 "register_operand" "=d")
8880         (lt:DI (match_operand:DI 1 "se_register_operand" "d")
8881                (match_operand:DI 2 "se_arith_operand" "dI")))]
8882   "TARGET_64BIT && !TARGET_MIPS16"
8883   "slt\\t%0,%1,%2"
8884   [(set_attr "type"     "arith")
8885    (set_attr "mode"     "DI")])
8887 (define_insn ""
8888   [(set (match_operand:DI 0 "register_operand" "=t,t")
8889         (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
8890                (match_operand:DI 2 "se_arith_operand" "d,I")))]
8891   "TARGET_64BIT && TARGET_MIPS16"
8892   "slt\\t%1,%2"
8893   [(set_attr "type"     "arith")
8894    (set_attr "mode"     "DI")
8895    (set_attr_alternative "length"
8896                 [(const_int 4)
8897                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8898                                (const_int 4)
8899                                (const_int 8))])])
8901 (define_expand "sle"
8902   [(set (match_operand:SI 0 "register_operand" "=d")
8903         (le:SI (match_dup 1)
8904                (match_dup 2)))]
8905   ""
8906   "
8908   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8909     FAIL;
8911   /* set up operands from compare.  */
8912   operands[1] = branch_cmp[0];
8913   operands[2] = branch_cmp[1];
8915   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8916     {
8917       gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8918       DONE;
8919     }
8921   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8922     operands[2] = force_reg (SImode, operands[2]);
8924   /* fall through and generate default code */
8927 (define_insn "sle_si_const"
8928   [(set (match_operand:SI 0 "register_operand" "=d")
8929         (le:SI (match_operand:SI 1 "register_operand" "d")
8930                (match_operand:SI 2 "small_int" "I")))]
8931   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8932   "*
8934   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8935   return \"slt\\t%0,%1,%2\";
8937   [(set_attr "type"     "arith")
8938    (set_attr "mode"     "SI")])
8940 (define_insn ""
8941   [(set (match_operand:SI 0 "register_operand" "=t")
8942         (le:SI (match_operand:SI 1 "register_operand" "d")
8943                (match_operand:SI 2 "small_int" "I")))]
8944   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8945   "*
8947   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8948   return \"slt\\t%1,%2\";
8950   [(set_attr "type"     "arith")
8951    (set_attr "mode"     "SI")
8952    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8953                                       (const_int 4)
8954                                       (const_int 8)))])
8956 (define_insn "sle_di_const"
8957   [(set (match_operand:DI 0 "register_operand" "=d")
8958         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8959                (match_operand:DI 2 "small_int" "I")))]
8960   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8961   "*
8963   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8964   return \"slt\\t%0,%1,%2\";
8966   [(set_attr "type"     "arith")
8967    (set_attr "mode"     "DI")])
8969 (define_insn ""
8970   [(set (match_operand:DI 0 "register_operand" "=t")
8971         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8972                (match_operand:DI 2 "small_int" "I")))]
8973   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8974   "*
8976   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8977   return \"slt\\t%1,%2\";
8979   [(set_attr "type"     "arith")
8980    (set_attr "mode"     "DI")
8981    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8982                                       (const_int 4)
8983                                       (const_int 8)))])
8985 (define_insn "sle_si_reg"
8986   [(set (match_operand:SI 0 "register_operand" "=d")
8987         (le:SI (match_operand:SI 1 "register_operand" "d")
8988                (match_operand:SI 2 "register_operand" "d")))]
8989   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8990   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8991   [(set_attr "type"     "arith")
8992    (set_attr "mode"     "SI")
8993    (set_attr "length"   "8")])
8995 (define_split
8996   [(set (match_operand:SI 0 "register_operand" "")
8997         (le:SI (match_operand:SI 1 "register_operand" "")
8998                (match_operand:SI 2 "register_operand" "")))]
8999   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
9000   [(set (match_dup 0)
9001         (lt:SI (match_dup 2)
9002                (match_dup 1)))
9003    (set (match_dup 0)
9004         (xor:SI (match_dup 0)
9005                 (const_int 1)))]
9006   "")
9008 (define_insn "sle_di_reg"
9009   [(set (match_operand:DI 0 "register_operand" "=d")
9010         (le:DI (match_operand:DI 1 "se_register_operand" "d")
9011                (match_operand:DI 2 "se_register_operand" "d")))]
9012   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9013   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9014   [(set_attr "type"     "arith")
9015    (set_attr "mode"     "DI")
9016    (set_attr "length"   "8")])
9018 (define_split
9019   [(set (match_operand:DI 0 "register_operand" "")
9020         (le:DI (match_operand:DI 1 "se_register_operand" "")
9021                (match_operand:DI 2 "se_register_operand" "")))]
9022   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9023    && !TARGET_MIPS16"
9024   [(set (match_dup 0)
9025         (lt:DI (match_dup 2)
9026                (match_dup 1)))
9027    (set (match_dup 0)
9028         (xor:DI (match_dup 0)
9029                 (const_int 1)))]
9030   "")
9032 (define_expand "sgtu"
9033   [(set (match_operand:SI 0 "register_operand" "=d")
9034         (gtu:SI (match_dup 1)
9035                 (match_dup 2)))]
9036   ""
9037   "
9039   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
9040     FAIL;
9042   /* set up operands from compare.  */
9043   operands[1] = branch_cmp[0];
9044   operands[2] = branch_cmp[1];
9046   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
9047     {
9048       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
9049       DONE;
9050     }
9052   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
9053     operands[2] = force_reg (SImode, operands[2]);
9055   /* fall through and generate default code */
9058 (define_insn "sgtu_si"
9059   [(set (match_operand:SI 0 "register_operand" "=d")
9060         (gtu:SI (match_operand:SI 1 "register_operand" "d")
9061                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
9062   "!TARGET_MIPS16"
9063   "sltu\\t%0,%z2,%1"
9064   [(set_attr "type"     "arith")
9065    (set_attr "mode"     "SI")])
9067 (define_insn ""
9068   [(set (match_operand:SI 0 "register_operand" "=t")
9069         (gtu:SI (match_operand:SI 1 "register_operand" "d")
9070                 (match_operand:SI 2 "register_operand" "d")))]
9071   "TARGET_MIPS16"
9072   "sltu\\t%2,%1"
9073   [(set_attr "type"     "arith")
9074    (set_attr "mode"     "SI")])
9076 (define_insn "sgtu_di"
9077   [(set (match_operand:DI 0 "register_operand" "=d")
9078         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
9079                 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
9080   "TARGET_64BIT && !TARGET_MIPS16"
9081   "sltu\\t%0,%z2,%1"
9082   [(set_attr "type"     "arith")
9083    (set_attr "mode"     "DI")])
9085 (define_insn ""
9086   [(set (match_operand:DI 0 "register_operand" "=t")
9087         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
9088                 (match_operand:DI 2 "se_register_operand" "d")))]
9089   "TARGET_64BIT && TARGET_MIPS16"
9090   "sltu\\t%2,%1"
9091   [(set_attr "type"     "arith")
9092    (set_attr "mode"     "DI")])
9094 (define_expand "sgeu"
9095   [(set (match_operand:SI 0 "register_operand" "=d")
9096         (geu:SI (match_dup 1)
9097                 (match_dup 2)))]
9098   ""
9099   "
9101   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
9102     FAIL;
9104   /* set up operands from compare.  */
9105   operands[1] = branch_cmp[0];
9106   operands[2] = branch_cmp[1];
9108   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
9109     {
9110       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
9111       DONE;
9112     }
9114   /* fall through and generate default code */
9117 (define_insn "sgeu_si"
9118   [(set (match_operand:SI 0 "register_operand" "=d")
9119         (geu:SI (match_operand:SI 1 "register_operand" "d")
9120                 (match_operand:SI 2 "arith_operand" "dI")))]
9121   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9122   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
9123   [(set_attr "type"     "arith")
9124    (set_attr "mode"     "SI")
9125    (set_attr "length"   "8")])
9127 (define_split
9128   [(set (match_operand:SI 0 "register_operand" "")
9129         (geu:SI (match_operand:SI 1 "register_operand" "")
9130                 (match_operand:SI 2 "arith_operand" "")))]
9131   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
9132   [(set (match_dup 0)
9133         (ltu:SI (match_dup 1)
9134                 (match_dup 2)))
9135    (set (match_dup 0)
9136         (xor:SI (match_dup 0)
9137                 (const_int 1)))]
9138   "")
9140 (define_insn "sgeu_di"
9141   [(set (match_operand:DI 0 "register_operand" "=d")
9142         (geu:DI (match_operand:DI 1 "se_register_operand" "d")
9143                 (match_operand:DI 2 "se_arith_operand" "dI")))]
9144   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9145   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
9146   [(set_attr "type"     "arith")
9147    (set_attr "mode"     "DI")
9148    (set_attr "length"   "8")])
9150 (define_split
9151   [(set (match_operand:DI 0 "register_operand" "")
9152         (geu:DI (match_operand:DI 1 "se_register_operand" "")
9153                 (match_operand:DI 2 "se_arith_operand" "")))]
9154   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9155    && !TARGET_MIPS16"
9156   [(set (match_dup 0)
9157         (ltu:DI (match_dup 1)
9158                 (match_dup 2)))
9159    (set (match_dup 0)
9160         (xor:DI (match_dup 0)
9161                 (const_int 1)))]
9162   "")
9164 (define_expand "sltu"
9165   [(set (match_operand:SI 0 "register_operand" "=d")
9166         (ltu:SI (match_dup 1)
9167                 (match_dup 2)))]
9168   ""
9169   "
9171   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
9172     FAIL;
9174   /* set up operands from compare.  */
9175   operands[1] = branch_cmp[0];
9176   operands[2] = branch_cmp[1];
9178   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
9179     {
9180       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
9181       DONE;
9182     }
9184   /* fall through and generate default code */
9187 (define_insn "sltu_si"
9188   [(set (match_operand:SI 0 "register_operand" "=d")
9189         (ltu:SI (match_operand:SI 1 "register_operand" "d")
9190                 (match_operand:SI 2 "arith_operand" "dI")))]
9191   "!TARGET_MIPS16"
9192   "sltu\\t%0,%1,%2"
9193   [(set_attr "type"     "arith")
9194    (set_attr "mode"     "SI")])
9196 (define_insn ""
9197   [(set (match_operand:SI 0 "register_operand" "=t,t")
9198         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
9199                 (match_operand:SI 2 "arith_operand" "d,I")))]
9200   "TARGET_MIPS16"
9201   "sltu\\t%1,%2"
9202   [(set_attr "type"     "arith")
9203    (set_attr "mode"     "SI")
9204    (set_attr_alternative "length"
9205                 [(const_int 4)
9206                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
9207                                (const_int 4)
9208                                (const_int 8))])])
9210 (define_insn "sltu_di"
9211   [(set (match_operand:DI 0 "register_operand" "=d")
9212         (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
9213                 (match_operand:DI 2 "se_arith_operand" "dI")))]
9214   "TARGET_64BIT && !TARGET_MIPS16"
9215   "sltu\\t%0,%1,%2"
9216   [(set_attr "type"     "arith")
9217    (set_attr "mode"     "DI")])
9219 (define_insn ""
9220   [(set (match_operand:DI 0 "register_operand" "=t,t")
9221         (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
9222                 (match_operand:DI 2 "se_arith_operand" "d,I")))]
9223   "TARGET_64BIT && TARGET_MIPS16"
9224   "sltu\\t%1,%2"
9225   [(set_attr "type"     "arith")
9226    (set_attr "mode"     "DI")
9227    (set_attr_alternative "length"
9228                 [(const_int 4)
9229                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
9230                                (const_int 4)
9231                                (const_int 8))])])
9233 (define_expand "sleu"
9234   [(set (match_operand:SI 0 "register_operand" "=d")
9235         (leu:SI (match_dup 1)
9236                 (match_dup 2)))]
9237   ""
9238   "
9240   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
9241     FAIL;
9243   /* set up operands from compare.  */
9244   operands[1] = branch_cmp[0];
9245   operands[2] = branch_cmp[1];
9247   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
9248     {
9249       gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
9250       DONE;
9251     }
9253   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
9254     operands[2] = force_reg (SImode, operands[2]);
9256   /* fall through and generate default code */
9259 (define_insn "sleu_si_const"
9260   [(set (match_operand:SI 0 "register_operand" "=d")
9261         (leu:SI (match_operand:SI 1 "register_operand" "d")
9262                 (match_operand:SI 2 "small_int" "I")))]
9263   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9264   "*
9266   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9267   return \"sltu\\t%0,%1,%2\";
9269   [(set_attr "type"     "arith")
9270    (set_attr "mode"     "SI")])
9272 (define_insn ""
9273   [(set (match_operand:SI 0 "register_operand" "=t")
9274         (leu:SI (match_operand:SI 1 "register_operand" "d")
9275                 (match_operand:SI 2 "small_int" "I")))]
9276   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9277   "*
9279   operands[2] = GEN_INT (INTVAL (operands[2])+1);
9280   return \"sltu\\t%1,%2\";
9282   [(set_attr "type"     "arith")
9283    (set_attr "mode"     "SI")
9284    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9285                                       (const_int 4)
9286                                       (const_int 8)))])
9288 (define_insn "sleu_di_const"
9289   [(set (match_operand:DI 0 "register_operand" "=d")
9290         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9291                 (match_operand:DI 2 "small_int" "I")))]
9292   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9293   "*
9295   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9296   return \"sltu\\t%0,%1,%2\";
9298   [(set_attr "type"     "arith")
9299    (set_attr "mode"     "DI")])
9301 (define_insn ""
9302   [(set (match_operand:DI 0 "register_operand" "=t")
9303         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9304                 (match_operand:DI 2 "small_int" "I")))]
9305   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9306   "*
9308   operands[2] = GEN_INT (INTVAL (operands[2])+1);
9309   return \"sltu\\t%1,%2\";
9311   [(set_attr "type"     "arith")
9312    (set_attr "mode"     "DI")
9313    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9314                                       (const_int 4)
9315                                       (const_int 8)))])
9317 (define_insn "sleu_si_reg"
9318   [(set (match_operand:SI 0 "register_operand" "=d")
9319         (leu:SI (match_operand:SI 1 "register_operand" "d")
9320                 (match_operand:SI 2 "register_operand" "d")))]
9321   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9322   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9323   [(set_attr "type"     "arith")
9324    (set_attr "mode"     "SI")
9325    (set_attr "length"   "8")])
9327 (define_split
9328   [(set (match_operand:SI 0 "register_operand" "")
9329         (leu:SI (match_operand:SI 1 "register_operand" "")
9330                 (match_operand:SI 2 "register_operand" "")))]
9331   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
9332   [(set (match_dup 0)
9333         (ltu:SI (match_dup 2)
9334                 (match_dup 1)))
9335    (set (match_dup 0)
9336         (xor:SI (match_dup 0)
9337                 (const_int 1)))]
9338   "")
9340 (define_insn "sleu_di_reg"
9341   [(set (match_operand:DI 0 "register_operand" "=d")
9342         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9343                 (match_operand:DI 2 "se_register_operand" "d")))]
9344   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9345   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9346   [(set_attr "type"     "arith")
9347    (set_attr "mode"     "DI")
9348    (set_attr "length"   "8")])
9350 (define_split
9351   [(set (match_operand:DI 0 "register_operand" "")
9352         (leu:DI (match_operand:DI 1 "se_register_operand" "")
9353                 (match_operand:DI 2 "se_register_operand" "")))]
9354   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9355    && !TARGET_MIPS16"
9356   [(set (match_dup 0)
9357         (ltu:DI (match_dup 2)
9358                 (match_dup 1)))
9359    (set (match_dup 0)
9360         (xor:DI (match_dup 0)
9361                 (const_int 1)))]
9362   "")
9366 ;;  ....................
9368 ;;      FLOATING POINT COMPARISONS
9370 ;;  ....................
9372 (define_insn "sunordered_df"
9373   [(set (match_operand:CC 0 "register_operand" "=z")
9374         (unordered:CC (match_operand:DF 1 "register_operand" "f")
9375                       (match_operand:DF 2 "register_operand" "f")))]
9376   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9377   "*
9379  return mips_fill_delay_slot (\"c.un.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9381  [(set_attr "type"      "fcmp")
9382   (set_attr "mode"      "FPSW")])
9384 (define_insn "sunlt_df"
9385   [(set (match_operand:CC 0 "register_operand" "=z")
9386         (unlt:CC (match_operand:DF 1 "register_operand" "f")
9387                  (match_operand:DF 2 "register_operand" "f")))]
9388   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9389   "*
9391  return mips_fill_delay_slot (\"c.ult.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9393  [(set_attr "type"      "fcmp")
9394   (set_attr "mode"      "FPSW")])
9396 (define_insn "suneq_df"
9397   [(set (match_operand:CC 0 "register_operand" "=z")
9398         (uneq:CC (match_operand:DF 1 "register_operand" "f")
9399                  (match_operand:DF 2 "register_operand" "f")))]
9400   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9401   "*
9403  return mips_fill_delay_slot (\"c.ueq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9405  [(set_attr "type"      "fcmp")
9406   (set_attr "mode"      "FPSW")])
9408 (define_insn "sunle_df"
9409   [(set (match_operand:CC 0 "register_operand" "=z")
9410         (unle:CC (match_operand:DF 1 "register_operand" "f")
9411                  (match_operand:DF 2 "register_operand" "f")))]
9412   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9413   "*
9415  return mips_fill_delay_slot (\"c.ule.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9417  [(set_attr "type"      "fcmp")
9418   (set_attr "mode"      "FPSW")])
9420 (define_insn "seq_df"
9421   [(set (match_operand:CC 0 "register_operand" "=z")
9422         (eq:CC (match_operand:DF 1 "register_operand" "f")
9423                (match_operand:DF 2 "register_operand" "f")))]
9424   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9425   "*
9427   return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9429  [(set_attr "type"      "fcmp")
9430   (set_attr "mode"      "FPSW")])
9432 (define_insn "slt_df"
9433   [(set (match_operand:CC 0 "register_operand" "=z")
9434         (lt:CC (match_operand:DF 1 "register_operand" "f")
9435                (match_operand:DF 2 "register_operand" "f")))]
9436   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9437   "*
9439   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9441  [(set_attr "type"      "fcmp")
9442   (set_attr "mode"      "FPSW")])
9444 (define_insn "sle_df"
9445   [(set (match_operand:CC 0 "register_operand" "=z")
9446         (le:CC (match_operand:DF 1 "register_operand" "f")
9447                (match_operand:DF 2 "register_operand" "f")))]
9448   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9449   "*
9451   return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9453  [(set_attr "type"      "fcmp")
9454   (set_attr "mode"      "FPSW")])
9456 (define_insn "sgt_df"
9457   [(set (match_operand:CC 0 "register_operand" "=z")
9458         (gt:CC (match_operand:DF 1 "register_operand" "f")
9459                (match_operand:DF 2 "register_operand" "f")))]
9460   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9461   "*
9463   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9465  [(set_attr "type"      "fcmp")
9466   (set_attr "mode"      "FPSW")])
9468 (define_insn "sge_df"
9469   [(set (match_operand:CC 0 "register_operand" "=z")
9470         (ge:CC (match_operand:DF 1 "register_operand" "f")
9471                (match_operand:DF 2 "register_operand" "f")))]
9472   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9473   "*
9475   return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9477  [(set_attr "type"      "fcmp")
9478   (set_attr "mode"      "FPSW")])
9480 (define_insn "sunordered_sf"
9481   [(set (match_operand:CC 0 "register_operand" "=z")
9482         (unordered:CC (match_operand:SF 1 "register_operand" "f")
9483                       (match_operand:SF 2 "register_operand" "f")))]
9484   "TARGET_HARD_FLOAT"
9485   "*
9487  return mips_fill_delay_slot (\"c.un.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9489  [(set_attr "type"      "fcmp")
9490   (set_attr "mode"      "FPSW")])
9492 (define_insn "sunlt_sf"
9493   [(set (match_operand:CC 0 "register_operand" "=z")
9494         (unlt:CC (match_operand:SF 1 "register_operand" "f")
9495                  (match_operand:SF 2 "register_operand" "f")))]
9496   "TARGET_HARD_FLOAT"
9497   "*
9499  return mips_fill_delay_slot (\"c.ult.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9501  [(set_attr "type"      "fcmp")
9502   (set_attr "mode"      "FPSW")])
9504 (define_insn "suneq_sf"
9505   [(set (match_operand:CC 0 "register_operand" "=z")
9506         (uneq:CC (match_operand:SF 1 "register_operand" "f")
9507                  (match_operand:SF 2 "register_operand" "f")))]
9508   "TARGET_HARD_FLOAT"
9509   "*
9511  return mips_fill_delay_slot (\"c.ueq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9513  [(set_attr "type"      "fcmp")
9514   (set_attr "mode"      "FPSW")])
9516 (define_insn "sunle_sf"
9517   [(set (match_operand:CC 0 "register_operand" "=z")
9518         (unle:CC (match_operand:SF 1 "register_operand" "f")
9519                  (match_operand:SF 2 "register_operand" "f")))]
9520   "TARGET_HARD_FLOAT"
9521   "*
9523  return mips_fill_delay_slot (\"c.ule.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9525  [(set_attr "type"      "fcmp")
9526   (set_attr "mode"      "FPSW")])
9528 (define_insn "seq_sf"
9529   [(set (match_operand:CC 0 "register_operand" "=z")
9530         (eq:CC (match_operand:SF 1 "register_operand" "f")
9531                (match_operand:SF 2 "register_operand" "f")))]
9532   "TARGET_HARD_FLOAT"
9533   "*
9535   return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9537  [(set_attr "type"      "fcmp")
9538   (set_attr "mode"      "FPSW")])
9540 (define_insn "slt_sf"
9541   [(set (match_operand:CC 0 "register_operand" "=z")
9542         (lt:CC (match_operand:SF 1 "register_operand" "f")
9543                (match_operand:SF 2 "register_operand" "f")))]
9544   "TARGET_HARD_FLOAT"
9545   "*
9547   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9549  [(set_attr "type"      "fcmp")
9550   (set_attr "mode"      "FPSW")])
9552 (define_insn "sle_sf"
9553   [(set (match_operand:CC 0 "register_operand" "=z")
9554         (le:CC (match_operand:SF 1 "register_operand" "f")
9555                (match_operand:SF 2 "register_operand" "f")))]
9556   "TARGET_HARD_FLOAT"
9557   "*
9559   return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9561  [(set_attr "type"      "fcmp")
9562   (set_attr "mode"      "FPSW")])
9564 (define_insn "sgt_sf"
9565   [(set (match_operand:CC 0 "register_operand" "=z")
9566         (gt:CC (match_operand:SF 1 "register_operand" "f")
9567                (match_operand:SF 2 "register_operand" "f")))]
9568   "TARGET_HARD_FLOAT"
9569   "*
9571   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9573  [(set_attr "type"      "fcmp")
9574   (set_attr "mode"      "FPSW")])
9576 (define_insn "sge_sf"
9577   [(set (match_operand:CC 0 "register_operand" "=z")
9578         (ge:CC (match_operand:SF 1 "register_operand" "f")
9579                (match_operand:SF 2 "register_operand" "f")))]
9580   "TARGET_HARD_FLOAT"
9581   "*
9583   return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9585  [(set_attr "type"      "fcmp")
9586   (set_attr "mode"      "FPSW")])
9590 ;;  ....................
9592 ;;      UNCONDITIONAL BRANCHES
9594 ;;  ....................
9596 ;; Unconditional branches.
9598 (define_insn "jump"
9599   [(set (pc)
9600         (label_ref (match_operand 0 "" "")))]
9601   "!TARGET_MIPS16"
9602   "*
9604   if (flag_pic && ! TARGET_EMBEDDED_PIC)
9605     {
9606       if (get_attr_length (insn) <= 8)
9607         return \"%*b\\t%l0\";
9608       else if (Pmode == DImode)
9609         return \"%[dla\\t%@,%l0\;%*jr\\t%@%]\";
9610       else
9611         return \"%[la\\t%@,%l0\;%*jr\\t%@%]\";
9612     }
9613   else
9614     return \"%*j\\t%l0\";
9616   [(set_attr "type"     "jump")
9617    (set_attr "mode"     "none")
9618    (set (attr "length")
9619         ;; we can't use `j' when emitting non-embedded PIC, so we emit
9620         ;; branch, if it's in range, or load the address of the branch
9621         ;; target into $at in a PIC-compatible way and then jump to it.
9622         (if_then_else 
9623          (ior (eq (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
9624                   (const_int 0))
9625               (lt (abs (minus (match_dup 0)
9626                               (plus (pc) (const_int 4))))
9627                   (const_int 131072)))
9628          (const_int 4) (const_int 16)))])
9630 ;; We need a different insn for the mips16, because a mips16 branch
9631 ;; does not have a delay slot.
9633 (define_insn ""
9634   [(set (pc)
9635         (label_ref (match_operand 0 "" "")))]
9636   "TARGET_MIPS16"
9637   "b\\t%l0"
9638   [(set_attr "type"     "branch")
9639    (set_attr "mode"     "none")
9640    (set_attr "length"   "8")])
9642 (define_expand "indirect_jump"
9643   [(set (pc) (match_operand 0 "register_operand" "d"))]
9644   ""
9645   "
9647   rtx dest;
9649   if (operands[0])              /* eliminate unused code warnings */
9650     {
9651       dest = operands[0];
9652       if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9653         operands[0] = copy_to_mode_reg (Pmode, dest);
9655       if (!(Pmode == DImode))
9656         emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9657       else
9658         emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9660       DONE;
9661     }
9664 (define_insn "indirect_jump_internal1"
9665   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
9666   "!(Pmode == DImode)"
9667   "%*j\\t%0"
9668   [(set_attr "type"     "jump")
9669    (set_attr "mode"     "none")])
9671 (define_insn "indirect_jump_internal2"
9672   [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
9673   "Pmode == DImode"
9674   "%*j\\t%0"
9675   [(set_attr "type"     "jump")
9676    (set_attr "mode"     "none")])
9678 (define_expand "tablejump"
9679   [(set (pc)
9680         (match_operand 0 "register_operand" "d"))
9681    (use (label_ref (match_operand 1 "" "")))]
9682   ""
9683   "
9685   if (operands[0])              /* eliminate unused code warnings */
9686     {
9687       if (TARGET_MIPS16)
9688         {
9689           if (GET_MODE (operands[0]) != HImode)
9690             abort ();
9691           if (!(Pmode == DImode))
9692             emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
9693           else
9694             emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
9695           DONE;
9696         }
9698       if (GET_MODE (operands[0]) != Pmode)
9699         abort ();
9701       if (! flag_pic)
9702         {
9703           if (!(Pmode == DImode))
9704             emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9705           else
9706             emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
9707         }
9708       else
9709         {
9710           if (!(Pmode == DImode))
9711             emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
9712           else
9713             emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
9714         }
9716       DONE;
9717     }
9720 (define_insn "tablejump_internal1"
9721   [(set (pc)
9722         (match_operand:SI 0 "register_operand" "d"))
9723    (use (label_ref (match_operand 1 "" "")))]
9724   "!(Pmode == DImode)"
9725   "%*j\\t%0"
9726   [(set_attr "type"     "jump")
9727    (set_attr "mode"     "none")])
9729 (define_insn "tablejump_internal2"
9730   [(set (pc)
9731         (match_operand:DI 0 "se_register_operand" "d"))
9732    (use (label_ref (match_operand 1 "" "")))]
9733   "Pmode == DImode"
9734   "%*j\\t%0"
9735   [(set_attr "type"     "jump")
9736    (set_attr "mode"     "none")])
9738 (define_expand "tablejump_internal3"
9739   [(parallel [(set (pc)
9740                    (plus:SI (match_operand:SI 0 "register_operand" "d")
9741                             (label_ref:SI (match_operand 1 "" ""))))
9742               (use (label_ref:SI (match_dup 1)))])]
9743   ""
9744   "")
9746 (define_expand "tablejump_mips161"
9747   [(set (pc) (plus:SI (sign_extend:SI
9748                        (match_operand:HI 0 "register_operand" "d"))
9749                       (label_ref:SI (match_operand 1 "" ""))))]
9750   "TARGET_MIPS16 && !(Pmode == DImode)"
9751   "
9753   if (operands[0])      /* eliminate unused code warnings.  */
9754     {
9755       rtx t1, t2, t3;
9757       t1 = gen_reg_rtx (SImode);
9758       t2 = gen_reg_rtx (SImode);
9759       t3 = gen_reg_rtx (SImode);
9760       emit_insn (gen_extendhisi2 (t1, operands[0]));
9761       emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
9762       emit_insn (gen_addsi3 (t3, t1, t2));
9763       emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
9764       DONE;
9765     }
9768 (define_expand "tablejump_mips162"
9769   [(set (pc) (plus:DI (sign_extend:DI
9770                        (match_operand:HI 0 "register_operand" "d"))
9771                       (label_ref:DI (match_operand 1 "" ""))))]
9772   "TARGET_MIPS16 && Pmode == DImode"
9773   "
9775   if (operands[0])      /* eliminate unused code warnings.  */
9776     {
9777       rtx t1, t2, t3;
9779       t1 = gen_reg_rtx (DImode);
9780       t2 = gen_reg_rtx (DImode);
9781       t3 = gen_reg_rtx (DImode);
9782       emit_insn (gen_extendhidi2 (t1, operands[0]));
9783       emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
9784       emit_insn (gen_adddi3 (t3, t1, t2));
9785       emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
9786       DONE;
9787     }
9790 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
9791 ;;; it is not valid.  ??? With the USE, the condition tests may not be required
9792 ;;; any longer.
9794 ;;; ??? The length depends on the ABI.  It is two for o32, and one for n32.
9795 ;;; We just use the conservative number here.
9797 (define_insn ""
9798   [(set (pc)
9799         (plus:SI (match_operand:SI 0 "register_operand" "d")
9800                  (label_ref:SI (match_operand 1 "" ""))))
9801    (use (label_ref:SI (match_dup 1)))]
9802   "!(Pmode == DImode) && next_active_insn (insn) != 0
9803    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9804    && PREV_INSN (next_active_insn (insn)) == operands[1]"
9805   "*
9807   /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic.  */
9808   if (mips_abi == ABI_32 || mips_abi == ABI_O64
9809       || (mips_abi == ABI_N32 && TARGET_GAS))
9810     output_asm_insn (\".cpadd\\t%0\", operands);
9811   return \"%*j\\t%0\";
9813   [(set_attr "type"     "jump")
9814    (set_attr "mode"     "none")
9815    (set_attr "length"   "8")])
9817 (define_expand "tablejump_internal4"
9818   [(parallel [(set (pc)
9819                    (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9820                             (label_ref:DI (match_operand 1 "" ""))))
9821               (use (label_ref:DI (match_dup 1)))])]
9822   ""
9823   "")
9825 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
9826 ;;; it is not valid.  ??? With the USE, the condition tests may not be required
9827 ;;; any longer.
9829 (define_insn ""
9830   [(set (pc)
9831         (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9832                  (label_ref:DI (match_operand 1 "" ""))))
9833    (use (label_ref:DI (match_dup 1)))]
9834   "Pmode == DImode && next_active_insn (insn) != 0
9835    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9836    && PREV_INSN (next_active_insn (insn)) == operands[1]"
9837   "*
9839   /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic.  */
9840   if (TARGET_GAS && mips_abi == ABI_64)
9841     output_asm_insn (\".cpadd\\t%0\", operands);
9842   return \"%*j\\t%0\";
9844   [(set_attr "type"     "jump")
9845    (set_attr "mode"     "none")
9846    (set_attr "length"   "8")])
9848 ;; Implement a switch statement when generating embedded PIC code.
9849 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
9851 (define_expand "casesi"
9852   [(set (match_dup 5)
9853         (minus:SI (match_operand:SI 0 "register_operand" "d")
9854                   (match_operand:SI 1 "arith_operand" "dI")))
9855    (set (cc0)
9856         (compare:CC (match_dup 5)
9857                     (match_operand:SI 2 "arith_operand" "")))
9858    (set (pc)
9859         (if_then_else (gtu (cc0)
9860                            (const_int 0))
9861                       (label_ref (match_operand 4 "" ""))
9862                       (pc)))
9863    (parallel
9864     [(set (pc)
9865           (mem:SI (plus:SI (mult:SI (match_dup 5)
9866                                     (const_int 4))
9867                            (label_ref (match_operand 3 "" "")))))
9868      (clobber (match_scratch:SI 6 ""))
9869      (clobber (reg:SI 31))])]
9870   "TARGET_EMBEDDED_PIC"
9871   "
9873   if (operands[0])
9874     {
9875       rtx reg = gen_reg_rtx (SImode);
9877       /* If the index is too large, go to the default label.  */
9878       emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9879       emit_insn (gen_cmpsi (reg, operands[2]));
9880       emit_insn (gen_bgtu (operands[4]));
9882       /* Do the PIC jump.  */
9883       if (Pmode != DImode)
9884         emit_jump_insn (gen_casesi_internal (reg, operands[3],
9885                                              gen_reg_rtx (SImode)));
9886       else
9887         emit_jump_insn (gen_casesi_internal_di (reg, operands[3],
9888                                                 gen_reg_rtx (DImode)));
9890       DONE;
9891     }
9894 ;; An embedded PIC switch statement looks like this:
9895 ;;      bal     $LS1
9896 ;;      sll     $reg,$index,2
9897 ;; $LS1:
9898 ;;      addu    $reg,$reg,$31
9899 ;;      lw      $reg,$L1-$LS1($reg)
9900 ;;      addu    $reg,$reg,$31
9901 ;;      j       $reg
9902 ;; $L1:
9903 ;;      .word   case1-$LS1
9904 ;;      .word   case2-$LS1
9905 ;;      ...
9907 (define_insn "casesi_internal"
9908   [(set (pc)
9909         (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9910                                   (const_int 4))
9911                          (label_ref (match_operand 1 "" "")))))
9912    (clobber (match_operand:SI 2 "register_operand" "=d"))
9913    (clobber (reg:SI 31))]
9914   "TARGET_EMBEDDED_PIC"
9915   "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9916 lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2"
9917   [(set_attr "type"     "jump")
9918    (set_attr "mode"     "none")
9919    (set_attr "length"   "24")])
9921 ;; This code assumes that the table index will never be >= 29 bits wide,
9922 ;; which allows the 'sign extend' from SI to DI be a no-op.
9923 (define_insn "casesi_internal_di"
9924   [(set (pc)
9925         (mem:DI (plus:DI (sign_extend:DI
9926                           (mult:SI (match_operand:SI 0 "register_operand" "d")
9927                                   (const_int 8)))
9928                          (label_ref (match_operand 1 "" "")))))
9929    (clobber (match_operand:DI 2 "register_operand" "=d"))
9930    (clobber (reg:DI 31))]
9931   "TARGET_EMBEDDED_PIC"
9932   "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
9933 ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
9934   [(set_attr "type"     "jump")
9935    (set_attr "mode"     "none")
9936    (set_attr "length"   "24")])
9938 ;; For o32/n32/n64, we save the gp in the jmp_buf as well.  While it is
9939 ;; possible to either pull it off the stack (in the o32 case) or recalculate
9940 ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9941 ;; this is easy.
9943 (define_expand "builtin_setjmp_setup"
9944   [(unspec [(match_operand 0 "register_operand" "r")] UNSPEC_SETJMP)]
9945   "TARGET_ABICALLS"
9946   "
9948   if (Pmode == DImode)
9949     emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9950   else
9951     emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9952   DONE;
9955 (define_expand "builtin_setjmp_setup_32"
9956   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9957                    (const_int 12)))
9958       (reg:SI 28))]
9959   "TARGET_ABICALLS && ! (Pmode == DImode)"
9960   "")
9962 (define_expand "builtin_setjmp_setup_64"
9963   [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9964                    (const_int 24)))
9965       (reg:DI 28))]
9966   "TARGET_ABICALLS && Pmode == DImode"
9967   "")
9969 ;; For o32/n32/n64, we need to arrange for longjmp to put the
9970 ;; target address in t9 so that we can use it for loading $gp.
9972 (define_expand "builtin_longjmp"
9973   [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPEC_LONGJMP)]
9974   "TARGET_ABICALLS"
9975   "
9977   /* The elements of the buffer are, in order:  */
9978   int W = (Pmode == DImode ? 8 : 4);
9979   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9980   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9981   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9982   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9983   rtx pv = gen_rtx_REG (Pmode, 25);
9984   rtx gp = gen_rtx_REG (Pmode, 28);
9986   /* This bit is the same as expand_builtin_longjmp.  */
9987   emit_move_insn (hard_frame_pointer_rtx, fp);
9988   emit_move_insn (pv, lab);
9989   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9990   emit_move_insn (gp, gpv);
9991   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9992   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9993   emit_insn (gen_rtx_USE (VOIDmode, gp));
9994   emit_indirect_jump (pv);
9995   DONE;
9999 ;;  ....................
10001 ;;      Function prologue/epilogue
10003 ;;  ....................
10006 (define_expand "prologue"
10007   [(const_int 1)]
10008   ""
10009   "
10011   if (mips_isa >= 0)            /* avoid unused code warnings */
10012     {
10013       mips_expand_prologue ();
10014       DONE;
10015     }
10018 ;; Block any insns from being moved before this point, since the
10019 ;; profiling call to mcount can use various registers that aren't
10020 ;; saved or used to pass arguments.
10022 (define_insn "blockage"
10023   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
10024   ""
10025   ""
10026   [(set_attr "type"     "unknown")
10027    (set_attr "mode"     "none")
10028    (set_attr "length"   "0")])
10030 (define_expand "epilogue"
10031   [(const_int 2)]
10032   ""
10033   "
10035   if (mips_isa >= 0)            /* avoid unused code warnings */
10036     {
10037       mips_expand_epilogue ();
10038       DONE;
10039     }
10042 ;; Trivial return.  Make it look like a normal return insn as that
10043 ;; allows jump optimizations to work better .
10044 (define_insn "return"
10045   [(return)]
10046   "mips_can_use_return_insn ()"
10047   "%*j\\t$31"
10048   [(set_attr "type"     "jump")
10049    (set_attr "mode"     "none")])
10051 ;; Normal return.
10053 (define_insn "return_internal"
10054   [(use (match_operand 0 "pmode_register_operand" ""))
10055    (return)]
10056   ""
10057   "*
10059   return \"%*j\\t%0\";
10061   [(set_attr "type"     "jump")
10062    (set_attr "mode"     "none")])
10064 ;; When generating embedded PIC code we need to get the address of the
10065 ;; current function.  This specialized instruction does just that.
10067 (define_insn "get_fnaddr"
10068   [(set (match_operand 0 "register_operand" "=d")
10069         (unspec [(match_operand 1 "" "")] UNSPEC_GET_FNADDR))
10070    (clobber (reg:SI 31))]
10071   "TARGET_EMBEDDED_PIC
10072    && GET_CODE (operands[1]) == SYMBOL_REF"
10073   "%($LF%= = . + 8\;bal\\t$LF%=\;nop;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
10074   [(set_attr "type"     "call")
10075    (set_attr "mode"     "none")
10076    (set_attr "length"   "20")])
10078 ;; This is used in compiling the unwind routines.
10079 (define_expand "eh_return"
10080   [(use (match_operand 0 "general_operand" ""))
10081    (use (match_operand 1 "general_operand" ""))]
10082   ""
10083   "
10085   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
10087   if (GET_MODE (operands[1]) != gpr_mode)
10088     operands[1] = convert_to_mode (gpr_mode, operands[1], 0);
10089   if (TARGET_64BIT)
10090     emit_insn (gen_eh_set_lr_di (operands[1]));
10091   else
10092     emit_insn (gen_eh_set_lr_si (operands[1]));
10094   emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]);
10095   DONE;
10098 ;; Clobber the return address on the stack.  We can't expand this
10099 ;; until we know where it will be put in the stack frame.
10101 (define_insn "eh_set_lr_si"
10102   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
10103    (clobber (match_scratch:SI 1 "=&d"))]
10104   "! TARGET_64BIT"
10105   "#")
10107 (define_insn "eh_set_lr_di"
10108   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
10109    (clobber (match_scratch:DI 1 "=&d"))]
10110   "TARGET_64BIT"
10111   "#")
10113 (define_split
10114   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
10115    (clobber (match_scratch 1 ""))]
10116   "reload_completed && !TARGET_DEBUG_D_MODE"
10117   [(const_int 0)]
10118   "
10120   mips_set_return_address (operands[0], operands[1]);
10121   DONE;
10124 (define_insn "exception_receiver"
10125   [(unspec_volatile [(const_int 0)] UNSPEC_EH_RECEIVER)]
10126   "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
10127   "* return mips_restore_gp (operands, insn);"
10128   [(set_attr "type"   "load")
10129    (set_attr "length" "8")])
10132 ;;  ....................
10134 ;;      FUNCTION CALLS
10136 ;;  ....................
10138 ;; calls.c now passes a third argument, make saber happy
10140 (define_expand "call"
10141   [(parallel [(call (match_operand 0 "memory_operand" "m")
10142                     (match_operand 1 "" "i"))
10143               (clobber (reg:SI 31))
10144               (use (match_operand 2 "" ""))             ;; next_arg_reg
10145               (use (match_operand 3 "" ""))])]          ;; struct_value_size_rtx
10146   ""
10147   "
10149   rtx addr;
10151   if (operands[0])              /* eliminate unused code warnings */
10152     {
10153       addr = XEXP (operands[0], 0);
10154       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
10155           || ! call_insn_operand (addr, VOIDmode))
10156         XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
10158       /* In order to pass small structures by value in registers
10159          compatibly with the MIPS compiler, we need to shift the value
10160          into the high part of the register.  Function_arg has encoded
10161          a PARALLEL rtx, holding a vector of adjustments to be made
10162          as the next_arg_reg variable, so we split up the insns,
10163          and emit them separately.  */
10165       if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
10166         {
10167           rtvec adjust = XVEC (operands[2], 0);
10168           int num = GET_NUM_ELEM (adjust);
10169           int i;
10171           for (i = 0; i < num; i++)
10172             emit_insn (RTVEC_ELT (adjust, i));
10173         }
10175       if (TARGET_MIPS16
10176           && mips16_hard_float
10177           && operands[2] != 0
10178           && (int) GET_MODE (operands[2]) != 0)
10179         {
10180           if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
10181                                       (int) GET_MODE (operands[2])))
10182             DONE;
10183         }
10185       emit_call_insn (gen_call_internal0 (operands[0], operands[1],
10186                                           gen_rtx_REG (SImode,
10187                                                        GP_REG_FIRST + 31)));
10188       DONE;
10189     }
10192 (define_expand "call_internal0"
10193   [(parallel [(call (match_operand 0 "" "")
10194                     (match_operand 1 "" ""))
10195               (clobber (match_operand:SI 2 "" ""))])]
10196   ""
10197   "")
10199 ;; We need to recognize reg:SI 31 specially for the mips16, because we
10200 ;; don't have a constraint letter for it.
10202 (define_insn ""
10203   [(call (mem (match_operand 0 "call_insn_operand" "ei"))
10204          (match_operand 1 "" "i"))
10205    (clobber (match_operand:SI 2 "register_operand" "=y"))]
10206   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
10207    && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
10208   "%*jal\\t%0"
10209   [(set_attr "type"     "call")
10210    (set_attr "mode"     "none")
10211    (set_attr "length"   "8")])
10213 (define_insn "call_internal1"
10214   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
10215          (match_operand 1 "" "i"))
10216    (clobber (match_operand:SI 2 "register_operand" "=d"))]
10217   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10218   "*
10220   register rtx target = operands[0];
10222   if (GET_CODE (target) == CONST_INT)
10223     return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
10224   else if (CONSTANT_ADDRESS_P (target))
10225     return \"%*jal\\t%0\";
10226   else
10227     return \"%*jal\\t%2,%0\";
10229   [(set_attr "type"     "call")
10230    (set_attr "mode"     "none")])
10232 (define_insn "call_internal2"
10233   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
10234          (match_operand 1 "" "i"))
10235    (clobber (match_operand:SI 2 "register_operand" "=d"))]
10236   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10237   "*
10239   register rtx target = operands[0];
10241   if (GET_CODE (target) == CONST_INT)
10242     return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
10243   else if (CONSTANT_ADDRESS_P (target))
10244     {
10245       if (GET_MODE (target) == SImode)
10246         return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
10247       else
10248         return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
10249     }
10250   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10251     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
10252   else
10253     return \"jal\\t%2,%0\";
10255   [(set_attr "type"     "call")
10256    (set_attr "mode"     "none")
10257    (set_attr "length"   "8")])
10259 (define_insn "call_internal3a"
10260   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
10261          (match_operand 1 "" "i"))
10262    (clobber (match_operand:SI 2 "register_operand" "=d"))]
10263   "!TARGET_MIPS16
10264    && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10265   "%*jal\\t%2,%0"
10266   [(set_attr "type"     "call")
10267    (set_attr "mode"     "none")])
10269 (define_insn "call_internal3b"
10270   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
10271          (match_operand 1 "" "i"))
10272    (clobber (match_operand:SI 2 "register_operand" "=d"))]
10273   "!TARGET_MIPS16
10274    && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10275   "%*jal\\t%2,%0"
10276   [(set_attr "type"     "call")
10277    (set_attr "mode"     "none")
10278    (set_attr "length"   "1")])
10280 (define_insn "call_internal3c"
10281   [(call (mem:SI (match_operand:SI 0 "register_operand" "e"))
10282          (match_operand 1 "" "i"))
10283    (clobber (match_operand:SI 2 "register_operand" "=y"))]
10284   "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
10285    && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
10286   "%*jal\\t%2,%0"
10287   [(set_attr "type"     "call")
10288    (set_attr "mode"     "none")])
10290 (define_insn "call_internal4a"
10291   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
10292          (match_operand 1 "" "i"))
10293    (clobber (match_operand:SI 2 "register_operand" "=d"))]
10294   "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
10295   "*
10297   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
10298     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
10299   else
10300     return \"jal\\t%2,%0\";
10302   [(set_attr "type"     "call")
10303    (set_attr "mode"     "none")
10304    (set_attr "length"   "8")])
10306 (define_insn "call_internal4b"
10307   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
10308          (match_operand 1 "" "i"))
10309    (clobber (match_operand:SI 2 "register_operand" "=d"))]
10310   "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
10311   "*
10313   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
10314     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
10315   else
10316     return \"jal\\t%2,%0\";
10318   [(set_attr "type"     "call")
10319    (set_attr "mode"     "none")
10320    (set_attr "length"   "8")])
10322 ;; calls.c now passes a fourth argument, make saber happy
10324 (define_expand "call_value"
10325   [(parallel [(set (match_operand 0 "register_operand" "=df")
10326                    (call (match_operand 1 "memory_operand" "m")
10327                          (match_operand 2 "" "i")))
10328               (clobber (reg:SI 31))
10329               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
10330   ""
10331   "
10333   rtx addr;
10335   if (operands[0])              /* eliminate unused code warning */
10336     {
10337       addr = XEXP (operands[1], 0);
10338       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
10339           || ! call_insn_operand (addr, VOIDmode))
10340         XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
10342       /* In order to pass small structures by value in registers
10343          compatibly with the MIPS compiler, we need to shift the value
10344          into the high part of the register.  Function_arg has encoded
10345          a PARALLEL rtx, holding a vector of adjustments to be made
10346          as the next_arg_reg variable, so we split up the insns,
10347          and emit them separately.  */
10349       if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
10350         {
10351           rtvec adjust = XVEC (operands[3], 0);
10352           int num = GET_NUM_ELEM (adjust);
10353           int i;
10355           for (i = 0; i < num; i++)
10356             emit_insn (RTVEC_ELT (adjust, i));
10357         }
10359       if (TARGET_MIPS16
10360           && mips16_hard_float
10361           && ((operands[3] != 0
10362                && (int) GET_MODE (operands[3]) != 0)
10363               || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
10364         {
10365           if (build_mips16_call_stub (operands[0], operands[1], operands[2],
10366                                       (operands[3] == 0 ? 0
10367                                        : (int) GET_MODE (operands[3]))))
10368             DONE;
10369         }
10371       /* Handle Irix6 function calls that have multiple non-contiguous
10372          results.  */
10373       if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
10374         {
10375           emit_call_insn (gen_call_value_multiple_internal0
10376                           (XEXP (XVECEXP (operands[0], 0, 0), 0),
10377                            operands[1], operands[2],
10378                            XEXP (XVECEXP (operands[0], 0, 1), 0),
10379                            gen_rtx_REG (SImode, GP_REG_FIRST + 31)));
10380           DONE;
10381         }
10383       /* We have a call returning a DImode structure in an FP reg.
10384          Strip off the now unnecessary PARALLEL.  */
10385       if (GET_CODE (operands[0]) == PARALLEL)
10386         operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
10388       emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
10389                                                 gen_rtx_REG (SImode,
10390                                                              GP_REG_FIRST + 31)));
10392       DONE;
10393     }
10396 (define_expand "call_value_internal0"
10397   [(parallel [(set (match_operand 0 "" "")
10398                    (call (match_operand 1 "" "")
10399                          (match_operand 2 "" "")))
10400               (clobber (match_operand:SI 3 "" ""))])]
10401   ""
10402   "")
10404 ;; Recognize $31 specially on the mips16, because we don't have a
10405 ;; constraint letter for it.
10407 (define_insn ""
10408   [(set (match_operand 0 "register_operand" "=d")
10409         (call (mem (match_operand 1 "call_insn_operand" "ei"))
10410               (match_operand 2 "" "i")))
10411    (clobber (match_operand:SI 3 "register_operand" "=y"))]
10412   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
10413    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10414   "%*jal\\t%1"
10415   [(set_attr "type"     "call")
10416    (set_attr "mode"     "none")
10417    (set_attr "length"   "8")])
10419 (define_insn "call_value_internal1"
10420   [(set (match_operand 0 "register_operand" "=df")
10421         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10422               (match_operand 2 "" "i")))
10423    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10424   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10425   "*
10427   register rtx target = operands[1];
10429   if (GET_CODE (target) == CONST_INT)
10430     return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
10431   else if (CONSTANT_ADDRESS_P (target))
10432     return \"%*jal\\t%1\";
10433   else
10434     return \"%*jal\\t%3,%1\";
10436   [(set_attr "type"     "call")
10437    (set_attr "mode"     "none")])
10439 (define_insn "call_value_internal2"
10440   [(set (match_operand 0 "register_operand" "=df")
10441         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10442               (match_operand 2 "" "i")))
10443    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10444   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10445   "*
10447   register rtx target = operands[1];
10449   if (GET_CODE (target) == CONST_INT)
10450     return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
10451   else if (CONSTANT_ADDRESS_P (target))
10452     {
10453       if (GET_MODE (target) == SImode)
10454         return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
10455       else
10456         return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
10457     }
10458   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10459     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10460   else
10461     return \"jal\\t%3,%1\";
10463   [(set_attr "type"     "call")
10464    (set_attr "mode"     "none")
10465    (set_attr "length"   "8")])
10467 (define_insn "call_value_internal3a"
10468   [(set (match_operand 0 "register_operand" "=df")
10469         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10470               (match_operand 2 "" "i")))
10471    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10472   "!TARGET_MIPS16
10473    && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10474   "%*jal\\t%3,%1"
10475   [(set_attr "type"     "call")
10476    (set_attr "mode"     "none")])
10478 (define_insn "call_value_internal3b"
10479   [(set (match_operand 0 "register_operand" "=df")
10480         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10481               (match_operand 2 "" "i")))
10482    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10483   "!TARGET_MIPS16
10484    && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10485   "%*jal\\t%3,%1"
10486   [(set_attr "type"     "call")
10487    (set_attr "mode"     "none")])
10489 (define_insn "call_value_internal3c"
10490   [(set (match_operand 0 "register_operand" "=df")
10491         (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
10492               (match_operand 2 "" "i")))
10493    (clobber (match_operand:SI 3 "register_operand" "=y"))]
10494   "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
10495    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10496   "%*jal\\t%3,%1"
10497   [(set_attr "type"     "call")
10498    (set_attr "mode"     "none")])
10500 (define_insn "call_value_internal4a"
10501   [(set (match_operand 0 "register_operand" "=df")
10502         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10503               (match_operand 2 "" "i")))
10504    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10505   "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
10506   "*
10508   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10509     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10510   else
10511     return \"jal\\t%3,%1\";
10513   [(set_attr "type"     "call")
10514    (set_attr "mode"     "none")
10515    (set_attr "length"   "8")])
10517 (define_insn "call_value_internal4b"
10518   [(set (match_operand 0 "register_operand" "=df")
10519         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10520               (match_operand 2 "" "i")))
10521    (clobber (match_operand:SI 3 "register_operand" "=d"))]
10522   "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
10523   "*
10525   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10526     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10527   else
10528     return \"jal\\t%3,%1\";
10530   [(set_attr "type"     "call")
10531    (set_attr "mode"     "none")
10532    (set_attr "length"   "8")])
10534 (define_expand "call_value_multiple_internal0"
10535   [(parallel [(set (match_operand 0 "" "")
10536                    (call (match_operand 1 "" "")
10537                          (match_operand 2 "" "")))
10538               (set (match_operand 3 "" "")
10539                    (call (match_dup 1)
10540                          (match_dup 2)))
10541               (clobber (match_operand:SI 4 "" ""))])]
10542   ""
10543   "")
10545 ;; ??? May eventually need all 6 versions of the call patterns with multiple
10546 ;; return values.
10548 (define_insn "call_value_multiple_internal1"
10549   [(set (match_operand 0 "register_operand" "=df")
10550         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10551               (match_operand 2 "" "i")))
10552    (set (match_operand 3 "register_operand" "=df")
10553         (call (mem (match_dup 1))
10554               (match_dup 2)))
10555   (clobber (match_operand:SI 4 "register_operand" "=d"))]
10556   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10557   "*
10559   register rtx target = operands[1];
10561   if (GET_CODE (target) == CONST_INT)
10562     return \"%[li\\t%@,%1\\n\\t%*jal\\t%4,%@%]\";
10563   else if (CONSTANT_ADDRESS_P (target))
10564     return \"%*jal\\t%1\";
10565   else
10566     return \"%*jal\\t%4,%1\";
10568   [(set_attr "type"     "call")
10569    (set_attr "mode"     "none")])
10571 (define_insn "call_value_multiple_internal2"
10572   [(set (match_operand 0 "register_operand" "=df")
10573         (call (mem (match_operand 1 "call_insn_operand" "ri"))
10574               (match_operand 2 "" "i")))
10575    (set (match_operand 3 "register_operand" "=df")
10576         (call (mem (match_dup 1))
10577               (match_dup 2)))
10578    (clobber (match_operand:SI 4 "register_operand" "=d"))]
10579   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10580   "*
10582   register rtx target = operands[1];
10584   if (GET_CODE (target) == CONST_INT)
10585     return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
10586   else if (CONSTANT_ADDRESS_P (target))
10587     {
10588       if (GET_MODE (target) == SImode)
10589         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10590       else
10591         return \"dla\\t%^,%1\\n\\tjal\\t%4,%^\";
10592     }
10593   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10594     return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
10595   else
10596     return \"jal\\t%4,%1\";
10598   [(set_attr "type"     "call")
10599    (set_attr "mode"     "none")
10600    (set_attr "length"   "8")])
10603 ;; Call subroutine returning any type.
10605 (define_expand "untyped_call"
10606   [(parallel [(call (match_operand 0 "" "")
10607                     (const_int 0))
10608               (match_operand 1 "" "")
10609               (match_operand 2 "" "")])]
10610   ""
10611   "
10613   if (operands[0])              /* silence statement not reached warnings */
10614     {
10615       int i;
10617       emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
10619       for (i = 0; i < XVECLEN (operands[2], 0); i++)
10620         {
10621           rtx set = XVECEXP (operands[2], 0, i);
10622           emit_move_insn (SET_DEST (set), SET_SRC (set));
10623         }
10625       emit_insn (gen_blockage ());
10626       DONE;
10627     }
10631 ;;  ....................
10633 ;;      MISC.
10635 ;;  ....................
10639 (define_expand "prefetch"
10640   [(prefetch (match_operand 0 "address_operand" "")
10641              (match_operand 1 "const_int_operand" "")
10642              (match_operand 2 "const_int_operand" ""))]
10643   "ISA_HAS_PREFETCH"
10645      if (symbolic_operand (operands[0], GET_MODE (operands[0])))
10646         operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
10649 (define_insn "prefetch_si_address"
10650   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
10651                       (match_operand:SI 3 "const_int_operand" "i"))
10652              (match_operand:SI 1 "const_int_operand" "n")
10653              (match_operand:SI 2 "const_int_operand" "n"))]
10654   "ISA_HAS_PREFETCH && Pmode == SImode"
10655   "* return mips_emit_prefetch (operands);"
10656   [(set_attr "type" "load")])
10658 (define_insn "prefetch_si"
10659   [(prefetch (match_operand:SI 0 "register_operand" "r")
10660              (match_operand:SI 1 "const_int_operand" "n")
10661              (match_operand:SI 2 "const_int_operand" "n"))]
10662   "ISA_HAS_PREFETCH && Pmode == SImode"
10663   "* return mips_emit_prefetch (operands);"
10664   [(set_attr "type" "load")])
10666 (define_insn "prefetch_di_address"
10667   [(prefetch (plus:DI (match_operand:DI 0 "se_register_operand" "r")
10668                       (match_operand:DI 3 "const_int_operand" "i"))
10669              (match_operand:DI 1 "const_int_operand" "n")
10670              (match_operand:DI 2 "const_int_operand" "n"))]
10671   "ISA_HAS_PREFETCH && Pmode == DImode"
10672   "* return mips_emit_prefetch (operands);"
10673   [(set_attr "type" "load")])
10675 (define_insn "prefetch_di"
10676   [(prefetch (match_operand:DI 0 "se_register_operand" "r")
10677              (match_operand:DI 1 "const_int_operand" "n")
10678              (match_operand:DI 2 "const_int_operand" "n"))]
10679   "ISA_HAS_PREFETCH && Pmode == DImode"
10680   "* return mips_emit_prefetch (operands);"
10681   [(set_attr "type" "load")])
10683 (define_insn "nop"
10684   [(const_int 0)]
10685   ""
10686   "%(nop%)"
10687   [(set_attr "type"     "nop")
10688    (set_attr "mode"     "none")])
10690 ;; The MIPS chip does not seem to require stack probes.
10692 ;; (define_expand "probe"
10693 ;;   [(set (match_dup 0)
10694 ;;      (match_dup 1))]
10695 ;;   ""
10696 ;;   "
10697 ;; {
10698 ;;   operands[0] = gen_reg_rtx (SImode);
10699 ;;   operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
10700 ;;   MEM_VOLATILE_P (operands[1]) = TRUE;
10702 ;;   /* fall through and generate default code */
10703 ;; }")
10707 ;; MIPS4 Conditional move instructions.
10709 (define_insn ""
10710   [(set (match_operand:SI 0 "register_operand" "=d,d")
10711         (if_then_else:SI
10712          (match_operator 4 "equality_op"
10713                          [(match_operand:SI 1 "register_operand" "d,d")
10714                           (const_int 0)])
10715          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10716          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10717   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10718   "@
10719     mov%B4\\t%0,%z2,%1
10720     mov%b4\\t%0,%z3,%1"
10721   [(set_attr "type" "move")
10722    (set_attr "mode" "SI")])
10724 (define_insn ""
10725   [(set (match_operand:SI 0 "register_operand" "=d,d")
10726         (if_then_else:SI
10727          (match_operator 4 "equality_op"
10728                          [(match_operand:DI 1 "se_register_operand" "d,d")
10729                           (const_int 0)])
10730          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10731          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10732   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10733   "@
10734     mov%B4\\t%0,%z2,%1
10735     mov%b4\\t%0,%z3,%1"
10736   [(set_attr "type" "move")
10737    (set_attr "mode" "SI")])
10739 (define_insn ""
10740   [(set (match_operand:SI 0 "register_operand" "=d,d")
10741         (if_then_else:SI
10742          (match_operator 3 "equality_op" [(match_operand:CC 4
10743                                                             "register_operand"
10744                                                             "z,z")
10745                                           (const_int 0)])
10746          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
10747          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
10748   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10749   "@
10750     mov%T3\\t%0,%z1,%4
10751     mov%t3\\t%0,%z2,%4"
10752   [(set_attr "type" "move")
10753    (set_attr "mode" "SI")])
10755 (define_insn ""
10756   [(set (match_operand:DI 0 "register_operand" "=d,d")
10757         (if_then_else:DI
10758          (match_operator 4 "equality_op"
10759                          [(match_operand:SI 1 "register_operand" "d,d")
10760                           (const_int 0)])
10761          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10762          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10763   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10764   "@
10765     mov%B4\\t%0,%z2,%1
10766     mov%b4\\t%0,%z3,%1"
10767   [(set_attr "type" "move")
10768    (set_attr "mode" "DI")])
10770 (define_insn ""
10771   [(set (match_operand:DI 0 "register_operand" "=d,d")
10772         (if_then_else:DI
10773          (match_operator 4 "equality_op"
10774                          [(match_operand:DI 1 "se_register_operand" "d,d")
10775                           (const_int 0)])
10776          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10777          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10778   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10779   "@
10780     mov%B4\\t%0,%z2,%1
10781     mov%b4\\t%0,%z3,%1"
10782   [(set_attr "type" "move")
10783    (set_attr "mode" "DI")])
10785 (define_insn ""
10786   [(set (match_operand:DI 0 "register_operand" "=d,d")
10787         (if_then_else:DI
10788          (match_operator 3 "equality_op" [(match_operand:CC 4
10789                                                             "register_operand"
10790                                                             "z,z")
10791                                           (const_int 0)])
10792          (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
10793          (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
10794   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
10795   "@
10796     mov%T3\\t%0,%z1,%4
10797     mov%t3\\t%0,%z2,%4"
10798   [(set_attr "type" "move")
10799    (set_attr "mode" "DI")])
10801 (define_insn ""
10802   [(set (match_operand:SF 0 "register_operand" "=f,f")
10803         (if_then_else:SF
10804          (match_operator 4 "equality_op"
10805                          [(match_operand:SI 1 "register_operand" "d,d")
10806                           (const_int 0)])
10807          (match_operand:SF 2 "register_operand" "f,0")
10808          (match_operand:SF 3 "register_operand" "0,f")))]
10809   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10810   "@
10811     mov%B4.s\\t%0,%2,%1
10812     mov%b4.s\\t%0,%3,%1"
10813   [(set_attr "type" "move")
10814    (set_attr "mode" "SF")])
10816 (define_insn ""
10817   [(set (match_operand:SF 0 "register_operand" "=f,f")
10818         (if_then_else:SF
10819          (match_operator 4 "equality_op"
10820                          [(match_operand:DI 1 "se_register_operand" "d,d")
10821                           (const_int 0)])
10822          (match_operand:SF 2 "register_operand" "f,0")
10823          (match_operand:SF 3 "register_operand" "0,f")))]
10824   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10825   "@
10826     mov%B4.s\\t%0,%2,%1
10827     mov%b4.s\\t%0,%3,%1"
10828   [(set_attr "type" "move")
10829    (set_attr "mode" "SF")])
10831 (define_insn ""
10832   [(set (match_operand:SF 0 "register_operand" "=f,f")
10833         (if_then_else:SF
10834          (match_operator 3 "equality_op" [(match_operand:CC 4
10835                                                             "register_operand"
10836                                                             "z,z")
10837                                           (const_int 0)])
10838          (match_operand:SF 1 "register_operand" "f,0")
10839          (match_operand:SF 2 "register_operand" "0,f")))]
10840   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10841   "@
10842     mov%T3.s\\t%0,%1,%4
10843     mov%t3.s\\t%0,%2,%4"
10844   [(set_attr "type" "move")
10845    (set_attr "mode" "SF")])
10847 (define_insn ""
10848   [(set (match_operand:DF 0 "register_operand" "=f,f")
10849         (if_then_else:DF
10850          (match_operator 4 "equality_op"
10851                          [(match_operand:SI 1 "register_operand" "d,d")
10852                           (const_int 0)])
10853          (match_operand:DF 2 "register_operand" "f,0")
10854          (match_operand:DF 3 "register_operand" "0,f")))]
10855   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10856   "@
10857     mov%B4.d\\t%0,%2,%1
10858     mov%b4.d\\t%0,%3,%1"
10859   [(set_attr "type" "move")
10860    (set_attr "mode" "DF")])
10862 (define_insn ""
10863   [(set (match_operand:DF 0 "register_operand" "=f,f")
10864         (if_then_else:DF
10865          (match_operator 4 "equality_op"
10866                          [(match_operand:DI 1 "se_register_operand" "d,d")
10867                           (const_int 0)])
10868          (match_operand:DF 2 "register_operand" "f,0")
10869          (match_operand:DF 3 "register_operand" "0,f")))]
10870   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10871   "@
10872     mov%B4.d\\t%0,%2,%1
10873     mov%b4.d\\t%0,%3,%1"
10874   [(set_attr "type" "move")
10875    (set_attr "mode" "DF")])
10877 (define_insn ""
10878   [(set (match_operand:DF 0 "register_operand" "=f,f")
10879         (if_then_else:DF
10880          (match_operator 3 "equality_op" [(match_operand:CC 4
10881                                                             "register_operand"
10882                                                             "z,z")
10883                                           (const_int 0)])
10884          (match_operand:DF 1 "register_operand" "f,0")
10885          (match_operand:DF 2 "register_operand" "0,f")))]
10886   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10887   "@
10888     mov%T3.d\\t%0,%1,%4
10889     mov%t3.d\\t%0,%2,%4"
10890   [(set_attr "type" "move")
10891    (set_attr "mode" "DF")])
10893 ;; These are the main define_expand's used to make conditional moves.
10895 (define_expand "movsicc"
10896   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10897    (set (match_operand:SI 0 "register_operand" "")
10898         (if_then_else:SI (match_dup 5)
10899                          (match_operand:SI 2 "reg_or_0_operand" "")
10900                          (match_operand:SI 3 "reg_or_0_operand" "")))]
10901   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10902   "
10904   gen_conditional_move (operands);
10905   DONE;
10908 (define_expand "movdicc"
10909   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10910    (set (match_operand:DI 0 "register_operand" "")
10911         (if_then_else:DI (match_dup 5)
10912                          (match_operand:DI 2 "se_reg_or_0_operand" "")
10913                          (match_operand:DI 3 "se_reg_or_0_operand" "")))]
10914   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10915   "
10917   gen_conditional_move (operands);
10918   DONE;
10921 (define_expand "movsfcc"
10922   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10923    (set (match_operand:SF 0 "register_operand" "")
10924         (if_then_else:SF (match_dup 5)
10925                          (match_operand:SF 2 "register_operand" "")
10926                          (match_operand:SF 3 "register_operand" "")))]
10927   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10928   "
10930   gen_conditional_move (operands);
10931   DONE;
10934 (define_expand "movdfcc"
10935   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10936    (set (match_operand:DF 0 "register_operand" "")
10937         (if_then_else:DF (match_dup 5)
10938                          (match_operand:DF 2 "register_operand" "")
10939                          (match_operand:DF 3 "register_operand" "")))]
10940   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10941   "
10943   gen_conditional_move (operands);
10944   DONE;
10948 ;;  ....................
10950 ;;      mips16 inline constant tables
10952 ;;  ....................
10955 (define_insn "consttable_qi"
10956   [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")]
10957                     UNSPEC_CONSTTABLE_QI)]
10958   "TARGET_MIPS16"
10959   "*
10961   assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
10962   return \"\";
10964   [(set_attr "type"     "unknown")
10965    (set_attr "mode"     "QI")
10966    (set_attr "length"   "8")])
10968 (define_insn "consttable_hi"
10969   [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")]
10970                     UNSPEC_CONSTTABLE_HI)]
10971   "TARGET_MIPS16"
10972   "*
10974   assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10975   return \"\";
10977   [(set_attr "type"     "unknown")
10978    (set_attr "mode"     "HI")
10979    (set_attr "length"   "8")])
10981 (define_insn "consttable_si"
10982   [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")]
10983                     UNSPEC_CONSTTABLE_SI)]
10984   "TARGET_MIPS16"
10985   "*
10987   assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10988   return \"\";
10990   [(set_attr "type"     "unknown")
10991    (set_attr "mode"     "SI")
10992    (set_attr "length"   "8")])
10994 (define_insn "consttable_di"
10995   [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")]
10996                     UNSPEC_CONSTTABLE_DI)]
10997   "TARGET_MIPS16"
10998   "*
11000   assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
11001   return \"\";
11003   [(set_attr "type"     "unknown")
11004    (set_attr "mode"     "DI")
11005    (set_attr "length"   "16")])
11007 (define_insn "consttable_sf"
11008   [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")]
11009                     UNSPEC_CONSTTABLE_SF)]
11010   "TARGET_MIPS16"
11011   "*
11013   REAL_VALUE_TYPE d;
11015   if (GET_CODE (operands[0]) != CONST_DOUBLE)
11016     abort ();
11017   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11018   assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
11019   return \"\";
11021   [(set_attr "type"     "unknown")
11022    (set_attr "mode"     "SF")
11023    (set_attr "length"   "8")])
11025 (define_insn "consttable_df"
11026   [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")]
11027                     UNSPEC_CONSTTABLE_DF)]
11028   "TARGET_MIPS16"
11029   "*
11031   REAL_VALUE_TYPE d;
11033   if (GET_CODE (operands[0]) != CONST_DOUBLE)
11034     abort ();
11035   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11036   assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
11037   return \"\";
11039   [(set_attr "type"     "unknown")
11040    (set_attr "mode"     "DF")
11041    (set_attr "length"   "16")])
11043 (define_insn "align_2"
11044   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_2)]
11045   "TARGET_MIPS16"
11046   ".align 1"
11047   [(set_attr "type"     "unknown")
11048    (set_attr "mode"     "HI")
11049    (set_attr "length"   "8")])
11051 (define_insn "align_4"
11052   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_4)]
11053   "TARGET_MIPS16"
11054   ".align 2"
11055   [(set_attr "type"     "unknown")
11056    (set_attr "mode"     "SI")
11057    (set_attr "length"   "8")])
11059 (define_insn "align_8"
11060   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_8)]
11061   "TARGET_MIPS16"
11062   ".align 3"
11063   [(set_attr "type"     "unknown")
11064    (set_attr "mode"     "DI")
11065    (set_attr "length"   "12")])
11068 ;;  ....................
11070 ;;      mips16 peepholes
11072 ;;  ....................
11075 ;; On the mips16, reload will sometimes decide that a pseudo register
11076 ;; should go into $24, and then later on have to reload that register.
11077 ;; When that happens, we get a load of a general register followed by
11078 ;; a move from the general register to $24 followed by a branch.
11079 ;; These peepholes catch the common case, and fix it to just use the
11080 ;; general register for the branch.
11082 (define_peephole
11083   [(set (match_operand:SI 0 "register_operand" "=t")
11084         (match_operand:SI 1 "register_operand" "d"))
11085    (set (pc)
11086         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
11087                                                           (const_int 0)])
11088                       (match_operand 3 "pc_or_label_operand" "")
11089                       (match_operand 4 "pc_or_label_operand" "")))]
11090   "TARGET_MIPS16
11091    && GET_CODE (operands[0]) == REG
11092    && REGNO (operands[0]) == 24
11093    && dead_or_set_p (insn, operands[0])
11094    && GET_CODE (operands[1]) == REG
11095    && M16_REG_P (REGNO (operands[1]))"
11096   "*
11098   if (operands[3] != pc_rtx)
11099     return \"%*b%C2z\\t%1,%3\";
11100   else
11101     return \"%*b%N2z\\t%1,%4\";
11103   [(set_attr "type"     "branch")
11104    (set_attr "mode"     "none")
11105    (set_attr "length"   "8")])
11107 (define_peephole
11108   [(set (match_operand:DI 0 "register_operand" "=t")
11109         (match_operand:DI 1 "register_operand" "d"))
11110    (set (pc)
11111         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
11112                                                           (const_int 0)])
11113                       (match_operand 3 "pc_or_label_operand" "")
11114                       (match_operand 4 "pc_or_label_operand" "")))]
11115   "TARGET_MIPS16 && TARGET_64BIT
11116    && GET_CODE (operands[0]) == REG
11117    && REGNO (operands[0]) == 24
11118    && dead_or_set_p (insn, operands[0])
11119    && GET_CODE (operands[1]) == REG
11120    && M16_REG_P (REGNO (operands[1]))"
11121   "*
11123   if (operands[3] != pc_rtx)
11124     return \"%*b%C2z\\t%1,%3\";
11125   else
11126     return \"%*b%N2z\\t%1,%4\";
11128   [(set_attr "type"     "branch")
11129    (set_attr "mode"     "none")
11130    (set_attr "length"   "8")])
11132 ;; We can also have the reverse reload: reload will spill $24 into
11133 ;; another register, and then do a branch on that register when it
11134 ;; could have just stuck with $24.
11136 (define_peephole
11137   [(set (match_operand:SI 0 "register_operand" "=d")
11138         (match_operand:SI 1 "register_operand" "t"))
11139    (set (pc)
11140         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
11141                                                           (const_int 0)])
11142                       (match_operand 3 "pc_or_label_operand" "")
11143                       (match_operand 4 "pc_or_label_operand" "")))]
11144   "TARGET_MIPS16
11145    && GET_CODE (operands[1]) == REG
11146    && REGNO (operands[1]) == 24
11147    && GET_CODE (operands[0]) == REG
11148    && M16_REG_P (REGNO (operands[0]))
11149    && dead_or_set_p (insn, operands[0])"
11150   "*
11152   if (operands[3] != pc_rtx)
11153     return \"%*bt%C2z\\t%3\";
11154   else
11155     return \"%*bt%N2z\\t%4\";
11157   [(set_attr "type"     "branch")
11158    (set_attr "mode"     "none")
11159    (set_attr "length"   "8")])
11161 (define_peephole
11162   [(set (match_operand:DI 0 "register_operand" "=d")
11163         (match_operand:DI 1 "register_operand" "t"))
11164    (set (pc)
11165         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
11166                                                           (const_int 0)])
11167                       (match_operand 3 "pc_or_label_operand" "")
11168                       (match_operand 4 "pc_or_label_operand" "")))]
11169   "TARGET_MIPS16 && TARGET_64BIT
11170    && GET_CODE (operands[1]) == REG
11171    && REGNO (operands[1]) == 24
11172    && GET_CODE (operands[0]) == REG
11173    && M16_REG_P (REGNO (operands[0]))
11174    && dead_or_set_p (insn, operands[0])"
11175   "*
11177   if (operands[3] != pc_rtx)
11178     return \"%*bt%C2z\\t%3\";
11179   else
11180     return \"%*bt%N2z\\t%4\";
11182   [(set_attr "type"     "branch")
11183    (set_attr "mode"     "none")
11184    (set_attr "length"   "8")])
11186 ;; For the rare case where we need to load an address into a register
11187 ;; that can not be recognized by the normal movsi/addsi instructions.
11188 ;; I have no idea how many insns this can actually generate.  It should
11189 ;; be rare, so over-estimating as 10 instructions should not have any
11190 ;; real performance impact.
11191 (define_insn "leasi"
11192   [(set (match_operand:SI 0 "register_operand" "=d")
11193         (match_operand:SI 1 "address_operand" "p"))]
11194   "Pmode == SImode"
11195   "la %0,%a1"
11196   [(set_attr "type"     "arith")
11197    (set_attr "mode"     "SI")
11198    (set_attr "length"   "40")])
11200 ;; Similarly for targets where we have 64bit pointers.
11201 (define_insn "leadi"
11202   [(set (match_operand:DI 0 "register_operand" "=d")
11203         (match_operand:DI 1 "address_operand" "p"))]
11204   "Pmode == DImode"
11205   "dla %0,%a1"
11206   [(set_attr "type"     "arith")
11207    (set_attr "mode"     "DI")
11208    (set_attr "length"   "40")])