2003-05-23 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / config / mips / mips.md
blob7fff5a37aecbfbeef436b3c7a9568f54fbf24353
1 ;;  Mips.md          Machine Description for MIPS based processors
2 ;;  Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4 ;;  Contributed by   A. Lichnewsky, lich@inria.inria.fr
5 ;;  Changes by       Michael Meissner, meissner@osf.org
6 ;;  64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7 ;;  Brendan Eich, brendan@microunity.com.
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_LOAD_DF_LOW           0)
31    (UNSPEC_LOAD_DF_HIGH          1)
32    (UNSPEC_STORE_DF_HIGH         2)
33    (UNSPEC_GET_FNADDR            4)
34    (UNSPEC_HILO_DELAY            5)
35    (UNSPEC_BLOCKAGE              6)
36    (UNSPEC_LOADGP                7)
37    (UNSPEC_SETJMP                8)
38    (UNSPEC_LONGJMP               9)
39    (UNSPEC_EH_RECEIVER          10)
40    (UNSPEC_EH_RETURN            11)
41    (UNSPEC_CONSTTABLE_QI        12)
42    (UNSPEC_CONSTTABLE_HI        13)
43    (UNSPEC_CONSTTABLE_SI        14)
44    (UNSPEC_CONSTTABLE_DI        15)
45    (UNSPEC_CONSTTABLE_SF        16)
46    (UNSPEC_CONSTTABLE_DF        17)
47    (UNSPEC_ALIGN_2              18)
48    (UNSPEC_ALIGN_4              19)
49    (UNSPEC_ALIGN_8              20)
50    (UNSPEC_HIGH                 22)
51    (UNSPEC_LWL                  23)
52    (UNSPEC_LWR                  24)
53    (UNSPEC_SWL                  25)
54    (UNSPEC_SWR                  26)
55    (UNSPEC_LDL                  27)
56    (UNSPEC_LDR                  28)
57    (UNSPEC_SDL                  29)
58    (UNSPEC_SDR                  30)
60    ;; Constants used in relocation unspecs.  RELOC_GOT_PAGE and RELOC_GOT_DISP
61    ;; are really only available for n32 and n64.  However, it is convenient
62    ;; to reuse them for SVR4 PIC, where they represent the local and global
63    ;; forms of R_MIPS_GOT16.
64    (RELOC_GPREL16               100)
65    (RELOC_GOT_HI                101)
66    (RELOC_GOT_LO                102)
67    (RELOC_GOT_PAGE              103)
68    (RELOC_GOT_DISP              104)
69    (RELOC_CALL16                105)
70    (RELOC_CALL_HI               106)
71    (RELOC_CALL_LO               107)])
74 ;; ....................
76 ;;      Attributes
78 ;; ....................
80 ;; For jal instructions, this attribute is DIRECT when the target address
81 ;; is symbolic and INDIRECT when it is a register.
82 (define_attr "jal" "unset,direct,indirect"
83   (const_string "unset"))
85 ;; True for multi-instruction jal macros.  jal is always a macro
86 ;; in SVR4 PIC since it includes an instruction to restore $gp.
87 ;; Direct jals are also macros in NewABI PIC since they load the
88 ;; target address into $25.
89 (define_attr "jal_macro" "no,yes"
90   (cond [(eq_attr "jal" "direct")
91          (symbol_ref "TARGET_ABICALLS != 0")
92          (eq_attr "jal" "indirect")
93          (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
94         (const_string "no")))
96 ;; Classification of each insn.
97 ;; branch       conditional branch
98 ;; jump         unconditional jump
99 ;; call         unconditional call
100 ;; load         load instruction(s)
101 ;; store        store instruction(s)
102 ;; prefetch     memory prefetch
103 ;; move         data movement within same register set
104 ;; xfer         transfer to/from coprocessor
105 ;; hilo         transfer of hi/lo registers
106 ;; arith        integer arithmetic instruction
107 ;; darith       double precision integer arithmetic instructions
108 ;; const        load constant
109 ;; imul         integer multiply
110 ;; imadd        integer multiply-add
111 ;; idiv         integer divide
112 ;; icmp         integer compare
113 ;; fadd         floating point add/subtract
114 ;; fmul         floating point multiply
115 ;; fmadd        floating point multiply-add
116 ;; fdiv         floating point divide
117 ;; fabs         floating point absolute value
118 ;; fneg         floating point negation
119 ;; fcmp         floating point compare
120 ;; fcvt         floating point convert
121 ;; fsqrt        floating point square root
122 ;; frsqrt       floating point reciprocal square root
123 ;; multi        multiword sequence (or user asm statements)
124 ;; nop          no operation
125 (define_attr "type"
126   "unknown,branch,jump,call,load,store,prefetch,move,xfer,hilo,const,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
127   (cond [(eq_attr "jal" "!unset")
128          (const_string "call")]
129         (const_string "unknown")))
131 ;; Main data type used by the insn
132 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
134 ;; Is this an extended instruction in mips16 mode?
135 (define_attr "extended_mips16" "no,yes"
136   (const_string "no"))
138 ;; Length (in # of bytes).  A conditional branch is allowed only to a
139 ;; location within a signed 18-bit offset of the delay slot.  If that
140 ;; provides too smal a range, we use the `j' instruction.  This
141 ;; instruction takes a 28-bit value, but that value is not an offset.
142 ;; Instead, it's bitwise-ored with the high-order four bits of the
143 ;; instruction in the delay slot, which means it cannot be used to
144 ;; cross a 256MB boundary.  We could fall back back on the jr,
145 ;; instruction which allows full access to the entire address space,
146 ;; but we do not do so at present.
148 (define_attr "length" ""
149    (cond [(eq_attr "type" "branch")
150           (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
151                      (const_int 131072))
152                  (const_int 4)
153                  (ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
154                      (const_int 0))
155                  (const_int 24)
156                  ] (const_int 12))
157           (eq_attr "type" "const")
158           (symbol_ref "mips_const_insns (operands[1]) * 4")
159           (eq_attr "type" "load")
160           (symbol_ref "mips_fetch_insns (operands[1]) * 4")
161           (eq_attr "type" "store")
162           (symbol_ref "mips_fetch_insns (operands[0]) * 4")
163           ;; In the worst case, a call macro will take 8 instructions:
164           ;;
165           ;;     lui $25,%call_hi(FOO)
166           ;;     addu $25,$25,$28
167           ;;     lw $25,%call_lo(FOO)($25)
168           ;;     nop
169           ;;     jalr $25
170           ;;     nop
171           ;;     lw $gp,X($sp)
172           ;;     nop
173           (eq_attr "jal_macro" "yes")
174           (const_int 32)
175           (and (eq_attr "extended_mips16" "yes")
176                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
177           (const_int 8)
178           ] (const_int 4)))
180 ;; Attribute describing the processor.  This attribute must match exactly
181 ;; with the processor_type enumeration in mips.h.
183 ;; Attribute describing the processor
184 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
185 ;;   (const
186 ;;    (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000"))   (const_string "r3000")
187 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000"))   (const_string "r4000")
188 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000"))   (const_string "r6000")]
189 ;;          (const_string "default"))))
191 ;; ??? Fix everything that tests this attribute.
192 (define_attr "cpu"
193   "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4300,r4600,r4650,r5000,r5400,r5500,r8000,sb1,sr71000"
194   (const (symbol_ref "mips_cpu_attr")))
196 ;; The type of hardware hazard associated with this instruction.
197 ;; DELAY means that the next instruction cannot read the result
198 ;; of this one.  HILO means that the next two instructions cannot
199 ;; write to HI or LO.
200 (define_attr "hazard" "none,delay,hilo"
201   (cond [(and (eq_attr "type" "load")
202               (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
203          (const_string "delay")
205          (and (eq_attr "type" "xfer")
206               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
207          (const_string "delay")
209          (and (eq_attr "type" "fcmp")
210               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
211          (const_string "delay")
213          ;; The r4000 multiplication patterns include an mflo instruction.
214          (and (eq_attr "type" "imul")
215               (ne (symbol_ref "TARGET_MIPS4000") (const_int 0)))
216          (const_string "hilo")
218          (and (eq_attr "type" "hilo")
219               (and (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0))
220                    (match_operand 1 "hilo_operand" "")))
221          (const_string "hilo")]
222         (const_string "none")))
224 ;; Is it a single instruction?
225 (define_attr "single_insn" "no,yes"
226   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
228 ;; Can the instruction be put into a delay slot?
229 (define_attr "can_delay" "no,yes"
230   (if_then_else (and (eq_attr "type" "!branch,call,jump")
231                      (and (eq_attr "hazard" "none")
232                           (eq_attr "single_insn" "yes")))
233                 (const_string "yes")
234                 (const_string "no")))
236 ;; Attribute defining whether or not we can use the branch-likely instructions
238 (define_attr "branch_likely" "no,yes"
239   (const
240    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
241                  (const_string "yes")
242                  (const_string "no"))))
245 ;; Describe a user's asm statement.
246 (define_asm_attributes
247   [(set_attr "type" "multi")])
251 ;; .........................
253 ;;      Delay slots, can't describe load/fcmp/xfer delay slots here
255 ;; .........................
257 (define_delay (and (eq_attr "type" "branch")
258                    (eq (symbol_ref "mips16") (const_int 0)))
259   [(eq_attr "can_delay" "yes")
260    (nil)
261    (and (eq_attr "branch_likely" "yes")
262         (eq_attr "can_delay" "yes"))])
264 (define_delay (eq_attr "type" "jump")
265   [(eq_attr "can_delay" "yes")
266    (nil)
267    (nil)])
269 (define_delay (and (eq_attr "type" "call")
270                    (eq_attr "jal_macro" "no"))
271   [(eq_attr "can_delay" "yes")
272    (nil)
273    (nil)])
277 ;; .........................
279 ;;      Functional units
281 ;; .........................
283 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
284 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
286 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
288 (define_function_unit "memory" 1 0
289   (and (eq_attr "type" "load")
290        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
291   3 0)
293 (define_function_unit "memory" 1 0
294   (and (eq_attr "type" "load")
295        (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
296   2 0)
298 (define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
300 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
302 (define_function_unit "imuldiv"  1 0
303   (eq_attr "type" "hilo")
304   1 3)
306 (define_function_unit "imuldiv"  1 0
307   (and (eq_attr "type" "imul,imadd")
308        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
309   17 17)
311 ;; On them mips16, we want to stronly discourage a mult from appearing
312 ;; after an mflo, since that requires explicit nop instructions.  We
313 ;; do this by pretending that mflo ties up the function unit for long
314 ;; enough that the scheduler will ignore load stalls and the like when
315 ;; selecting instructions to between the two instructions.
317 (define_function_unit "imuldiv" 1 0
318   (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
319   1 5)
321 (define_function_unit "imuldiv"  1 0
322   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r3000,r3900"))
323   12 12)
325 (define_function_unit "imuldiv"  1 0
326   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4000,r4600"))
327   10 10)
329 (define_function_unit "imuldiv"  1 0
330   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4650"))
331   4 4)
333 (define_function_unit "imuldiv"  1 0
334   (and (eq_attr "type" "imul,imadd")
335        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
336   1 1)
338 (define_function_unit "imuldiv"  1 0
339   (and (eq_attr "type" "imul,imadd")
340        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
341   4 4)
343 (define_function_unit "imuldiv"  1 0
344   (and (eq_attr "type" "imul,imadd")
345        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
346   5 5)
348 (define_function_unit "imuldiv"  1 0
349   (and (eq_attr "type" "imul,imadd")
350        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
351   8 8)
353 (define_function_unit "imuldiv"  1 0
354   (and (eq_attr "type" "imul,imadd")
355        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
356   9 9)
358 (define_function_unit "imuldiv"  1 0
359   (and (eq_attr "type" "idiv")
360        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
361   38 38)
363 (define_function_unit "imuldiv"  1 0
364   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
365   35 35)
367 (define_function_unit "imuldiv"  1 0
368   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
369   42 42)
371 (define_function_unit "imuldiv"  1 0
372   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
373   36 36)
375 (define_function_unit "imuldiv"  1 0
376   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
377   69 69)
379 (define_function_unit "imuldiv" 1 0
380   (and (eq_attr "type" "idiv")
381        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
382   35 35)
384 (define_function_unit "imuldiv" 1 0
385   (and (eq_attr "type" "idiv")
386        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
387   67 67)
389 (define_function_unit "imuldiv" 1 0
390   (and (eq_attr "type" "idiv")
391        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
392   37 37)
394 (define_function_unit "imuldiv" 1 0
395   (and (eq_attr "type" "idiv")
396        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
397   69 69)
399 (define_function_unit "imuldiv" 1 0
400   (and (eq_attr "type" "idiv")
401        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
402   36 36)
404 (define_function_unit "imuldiv" 1 0
405   (and (eq_attr "type" "idiv")
406        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
407   68 68)
409 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
410 ;; the FP hardware is part of the normal ALU circuitry.  This means FP
411 ;; instructions affect the pipe-line, and no functional unit
412 ;; parallelism can occur on R4300 processors.  To force GCC into coding
413 ;; for only a single functional unit, we force the R4300 FP
414 ;; instructions to be processed in the "imuldiv" unit.
416 (define_function_unit "adder" 1 1
417   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
418   3 0)
420 (define_function_unit "adder" 1 1
421   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
422   2 0)
424 (define_function_unit "adder" 1 1
425   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
426   1 0)
428 (define_function_unit "adder" 1 1
429   (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
430   4 0)
432 (define_function_unit "adder" 1 1
433   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
434   2 0)
436 (define_function_unit "adder" 1 1
437   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
438   3 0)
440 (define_function_unit "adder" 1 1
441   (and (eq_attr "type" "fabs,fneg")
442        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
443   2 0)
445 (define_function_unit "adder" 1 1
446   (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
447   1 0)
449 (define_function_unit "mult" 1 1
450   (and (eq_attr "type" "fmul")
451        (and (eq_attr "mode" "SF")
452             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
453   7 0)
455 (define_function_unit "mult" 1 1
456   (and (eq_attr "type" "fmul")
457        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
458   4 0)
460 (define_function_unit "mult" 1 1
461   (and (eq_attr "type" "fmul")
462        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
463   5 0)
465 (define_function_unit "mult" 1 1
466   (and (eq_attr "type" "fmul")
467        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
468   8 0)
470 (define_function_unit "mult" 1 1
471   (and (eq_attr "type" "fmul")
472        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
473   8 0)
475 (define_function_unit "mult" 1 1
476   (and (eq_attr "type" "fmul")
477        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
478   5 0)
480 (define_function_unit "mult" 1 1
481   (and (eq_attr "type" "fmul")
482        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
483   6 0)
485 (define_function_unit "divide" 1 1
486   (and (eq_attr "type" "fdiv")
487        (and (eq_attr "mode" "SF")
488             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
489   23 0)
491 (define_function_unit "divide" 1 1
492   (and (eq_attr "type" "fdiv")
493        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
494   12 0)
496 (define_function_unit "divide" 1 1
497   (and (eq_attr "type" "fdiv")
498        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
499   15 0)
501 (define_function_unit "divide" 1 1
502   (and (eq_attr "type" "fdiv")
503        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
504   32 0)
506 (define_function_unit "divide" 1 1
507   (and (eq_attr "type" "fdiv")
508        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
509   21 0)
511 (define_function_unit "divide" 1 1
512   (and (eq_attr "type" "fdiv")
513        (and (eq_attr "mode" "DF")
514             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
515   36 0)
517 (define_function_unit "divide" 1 1
518   (and (eq_attr "type" "fdiv")
519        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
520   19 0)
522 (define_function_unit "divide" 1 1
523   (and (eq_attr "type" "fdiv")
524        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
525   16 0)
527 (define_function_unit "divide" 1 1
528   (and (eq_attr "type" "fdiv")
529        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
530   61 0)
532 ;;; ??? Is this number right?
533 (define_function_unit "divide" 1 1
534   (and (eq_attr "type" "fsqrt,frsqrt")
535        (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
536   54 0)
538 (define_function_unit "divide" 1 1
539   (and (eq_attr "type" "fsqrt,frsqrt")
540        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
541   31 0)
543 (define_function_unit "divide" 1 1
544   (and (eq_attr "type" "fsqrt,frsqrt")
545        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
546   21 0)
548 ;;; ??? Is this number right?
549 (define_function_unit "divide" 1 1
550   (and (eq_attr "type" "fsqrt,frsqrt")
551        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
552   112 0)
554 (define_function_unit "divide" 1 1
555   (and (eq_attr "type" "fsqrt,frsqrt")
556        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
557   60 0)
559 (define_function_unit "divide" 1 1
560   (and (eq_attr "type" "fsqrt,frsqrt")
561        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
562   36 0)
564 ;; R4300 FP instruction classes treated as part of the "imuldiv"
565 ;; functional unit:
567 (define_function_unit "imuldiv" 1 0
568   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
569   3 3)
571 (define_function_unit "imuldiv" 1 0
572   (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
573   1 1)
575 (define_function_unit "imuldiv" 1 0
576   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
577   5 5)
578 (define_function_unit "imuldiv" 1 0
579   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
580   8 8)
582 (define_function_unit "imuldiv" 1 0
583   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
584        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
585   29 29)
586 (define_function_unit "imuldiv" 1 0
587   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
588        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
589   58 58)
591 ;; The following functional units do not use the cpu type, and use
592 ;; much less memory in genattrtab.c.
594 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "load")                                3 0)
595 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "store")                               1 0)
597 ;; (define_function_unit "fp_comp"  1 0 (eq_attr "type" "fcmp")                                2 0)
599 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer")                                2 0)
600 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo")                                3 0)
602 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "imul")                               17 0)
603 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "idiv")                               38 0)
605 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fadd")                                4 0)
606 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fabs,fneg")                           2 0)
608 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF"))    7 0)
609 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF"))    8 0)
611 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF"))   23 0)
612 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF"))   36 0)
614 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF"))  54 0)
615 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
617 ;; Include scheduling descriptions.
619 (include "5400.md")
620 (include "5500.md")
621 (include "sr71k.md")
625 ;;  ....................
627 ;;      CONDITIONAL TRAPS
629 ;;  ....................
632 (define_insn "trap"
633   [(trap_if (const_int 1) (const_int 0))]
634   ""
635   "*
637   if (ISA_HAS_COND_TRAP)
638     return \"teq\\t$0,$0\";
639   else if (TARGET_MIPS16)
640     return \"break 0\";
641   else
642     return \"break\";
645 (define_expand "conditional_trap"
646   [(trap_if (match_operator 0 "cmp_op"
647                             [(match_dup 2) (match_dup 3)])
648             (match_operand 1 "const_int_operand" ""))]
649   "ISA_HAS_COND_TRAP"
650   "
652   mips_gen_conditional_trap (operands);
653   DONE;
656 ;; Match a TRAP_IF with 2nd arg of 0.  The div_trap_* insns match a
657 ;; 2nd arg of any CONST_INT, so this insn must appear first.
658 ;; gen_div_trap always generates TRAP_IF with 2nd arg of 6 or 7.
660 (define_insn ""
661   [(trap_if (match_operator 0 "trap_cmp_op"
662                             [(match_operand:SI 1 "reg_or_0_operand" "d")
663                              (match_operand:SI 2 "nonmemory_operand" "dI")])
664             (const_int 0))]
665   "ISA_HAS_COND_TRAP"
666   "t%C0\\t%z1,%z2")
669 ;;  ....................
671 ;;      ADDITION
673 ;;  ....................
676 (define_insn "adddf3"
677   [(set (match_operand:DF 0 "register_operand" "=f")
678         (plus:DF (match_operand:DF 1 "register_operand" "f")
679                  (match_operand:DF 2 "register_operand" "f")))]
680   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
681   "add.d\\t%0,%1,%2"
682   [(set_attr "type"     "fadd")
683    (set_attr "mode"     "DF")])
685 (define_insn "addsf3"
686   [(set (match_operand:SF 0 "register_operand" "=f")
687         (plus:SF (match_operand:SF 1 "register_operand" "f")
688                  (match_operand:SF 2 "register_operand" "f")))]
689   "TARGET_HARD_FLOAT"
690   "add.s\\t%0,%1,%2"
691   [(set_attr "type"     "fadd")
692    (set_attr "mode"     "SF")])
694 (define_expand "addsi3"
695   [(set (match_operand:SI 0 "register_operand" "")
696         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
697                  (match_operand:SI 2 "arith_operand" "")))]
698   ""
699   "
701   /* The mips16 assembler handles -32768 correctly, and so does gas,
702      but some other MIPS assemblers think that -32768 needs to be
703      loaded into a register before it can be added in.  */
704   if (! TARGET_MIPS16
705       && ! TARGET_GAS
706       && GET_CODE (operands[2]) == CONST_INT
707       && INTVAL (operands[2]) == -32768)
708     operands[2] = force_reg (SImode, operands[2]);
710   /* If a large stack adjustment was forced into a register, we may be
711      asked to generate rtx such as:
713         (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
715      but no such instruction is available in mips16.  Handle it by
716      using a temporary.  */
717   if (TARGET_MIPS16
718       && REGNO (operands[0]) == STACK_POINTER_REGNUM
719       && ((GET_CODE (operands[1]) == REG
720            && REGNO (operands[1]) != STACK_POINTER_REGNUM)
721           || GET_CODE (operands[2]) != CONST_INT))
722     {
723       rtx tmp = gen_reg_rtx (SImode);
725       emit_move_insn (tmp, operands[1]);
726       emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
727       emit_move_insn (operands[0], tmp);
728       DONE;
729     }
732 (define_insn "addsi3_internal"
733   [(set (match_operand:SI 0 "register_operand" "=d,d")
734         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
735                  (match_operand:SI 2 "arith_operand" "d,Q")))]
736   "! TARGET_MIPS16
737    && (TARGET_GAS
738        || GET_CODE (operands[2]) != CONST_INT
739        || INTVAL (operands[2]) != -32768)"
740   "@
741     addu\\t%0,%z1,%2
742     addiu\\t%0,%z1,%2"
743   [(set_attr "type"     "arith")
744    (set_attr "mode"     "SI")])
746 ;; For the mips16, we need to recognize stack pointer additions
747 ;; explicitly, since we don't have a constraint for $sp.  These insns
748 ;; will be generated by the save_restore_insns functions.
750 (define_insn ""
751   [(set (reg:SI 29)
752         (plus:SI (reg:SI 29)
753                  (match_operand:SI 0 "small_int" "I")))]
754   "TARGET_MIPS16"
755   "addu\\t%$,%$,%0"
756   [(set_attr "type"     "arith")
757    (set_attr "mode"     "SI")
758    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
759                                       (const_int 4)
760                                       (const_int 8)))])
762 (define_insn ""
763   [(set (match_operand:SI 0 "register_operand" "=d")
764         (plus:SI (reg:SI 29)
765                  (match_operand:SI 1 "small_int" "I")))]
766   "TARGET_MIPS16"
767   "addu\\t%0,%$,%1"
768   [(set_attr "type"     "arith")
769    (set_attr "mode"     "SI")
770    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
771                                       (const_int 4)
772                                       (const_int 8)))])
774 (define_insn ""
775   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
776         (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
777                  (match_operand:SI 2 "arith_operand" "Q,O,d")))]
778   "TARGET_MIPS16
779    && (GET_CODE (operands[1]) != REG
780        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
781        || M16_REG_P (REGNO (operands[1]))
782        || REGNO (operands[1]) == ARG_POINTER_REGNUM
783        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
784        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
785    && (GET_CODE (operands[2]) != REG
786        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
787        || M16_REG_P (REGNO (operands[2]))
788        || REGNO (operands[2]) == ARG_POINTER_REGNUM
789        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
790        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
791   "*
793   if (REGNO (operands[0]) == REGNO (operands[1]))
794     return \"addu\\t%0,%2\";
795   return \"addu\\t%0,%1,%2\";
797   [(set_attr "type"     "arith")
798    (set_attr "mode"     "SI")
799    (set_attr_alternative "length"
800                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
801                                (const_int 4)
802                                (const_int 8))
803                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
804                                (const_int 4)
805                                (const_int 8))
806                  (const_int 4)])])
809 ;; On the mips16, we can sometimes split an add of a constant which is
810 ;; a 4 byte instruction into two adds which are both 2 byte
811 ;; instructions.  There are two cases: one where we are adding a
812 ;; constant plus a register to another register, and one where we are
813 ;; simply adding a constant to a register.
815 (define_split
816   [(set (match_operand:SI 0 "register_operand" "")
817         (plus:SI (match_dup 0)
818                  (match_operand:SI 1 "const_int_operand" "")))]
819   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
820    && GET_CODE (operands[0]) == REG
821    && M16_REG_P (REGNO (operands[0]))
822    && GET_CODE (operands[1]) == CONST_INT
823    && ((INTVAL (operands[1]) > 0x7f
824         && INTVAL (operands[1]) <= 0x7f + 0x7f)
825        || (INTVAL (operands[1]) < - 0x80
826            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
827   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
828    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
829   "
831   HOST_WIDE_INT val = INTVAL (operands[1]);
833   if (val >= 0)
834     {
835       operands[1] = GEN_INT (0x7f);
836       operands[2] = GEN_INT (val - 0x7f);
837     }
838   else
839     {
840       operands[1] = GEN_INT (- 0x80);
841       operands[2] = GEN_INT (val + 0x80);
842     }
845 (define_split
846   [(set (match_operand:SI 0 "register_operand" "")
847         (plus:SI (match_operand:SI 1 "register_operand" "")
848                  (match_operand:SI 2 "const_int_operand" "")))]
849   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
850    && GET_CODE (operands[0]) == REG
851    && M16_REG_P (REGNO (operands[0]))
852    && GET_CODE (operands[1]) == REG
853    && M16_REG_P (REGNO (operands[1]))
854    && REGNO (operands[0]) != REGNO (operands[1])
855    && GET_CODE (operands[2]) == CONST_INT
856    && ((INTVAL (operands[2]) > 0x7
857         && INTVAL (operands[2]) <= 0x7 + 0x7f)
858        || (INTVAL (operands[2]) < - 0x8
859            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
860   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
861    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
862   "
864   HOST_WIDE_INT val = INTVAL (operands[2]);
866   if (val >= 0)
867     {
868       operands[2] = GEN_INT (0x7);
869       operands[3] = GEN_INT (val - 0x7);
870     }
871   else
872     {
873       operands[2] = GEN_INT (- 0x8);
874       operands[3] = GEN_INT (val + 0x8);
875     }
878 (define_expand "adddi3"
879   [(parallel [(set (match_operand:DI 0 "register_operand" "")
880                    (plus:DI (match_operand:DI 1 "register_operand" "")
881                             (match_operand:DI 2 "arith_operand" "")))
882               (clobber (match_dup 3))])]
883   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
884   "
886   /* The mips16 assembler handles -32768 correctly, and so does gas,
887      but some other MIPS assemblers think that -32768 needs to be
888      loaded into a register before it can be added in.  */
889   if (! TARGET_MIPS16
890       && ! TARGET_GAS
891       && GET_CODE (operands[2]) == CONST_INT
892       && INTVAL (operands[2]) == -32768)
893     operands[2] = force_reg (DImode, operands[2]);
895   /* If a large stack adjustment was forced into a register, we may be
896      asked to generate rtx such as:
898         (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
900      but no such instruction is available in mips16.  Handle it by
901      using a temporary.  */
902   if (TARGET_MIPS16
903       && REGNO (operands[0]) == STACK_POINTER_REGNUM
904       && ((GET_CODE (operands[1]) == REG
905            && REGNO (operands[1]) != STACK_POINTER_REGNUM)
906           || GET_CODE (operands[2]) != CONST_INT))
907     {
908       rtx tmp = gen_reg_rtx (DImode);
910       emit_move_insn (tmp, operands[1]);
911       emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
912       emit_move_insn (operands[0], tmp);
913       DONE;
914     }
916   if (TARGET_64BIT)
917     {
918       emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
919                                         operands[2]));
920       DONE;
921     }
923   operands[3] = gen_reg_rtx (SImode);
926 (define_insn "adddi3_internal_1"
927   [(set (match_operand:DI 0 "register_operand" "=d,&d")
928         (plus:DI (match_operand:DI 1 "register_operand" "0,d")
929                  (match_operand:DI 2 "register_operand" "d,d")))
930    (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
931   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
932   "*
934   return (REGNO (operands[0]) == REGNO (operands[1])
935           && REGNO (operands[0]) == REGNO (operands[2]))
936     ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
937     : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
939   [(set_attr "type"     "darith")
940    (set_attr "mode"     "DI")
941    (set_attr "length"   "16")])
943 (define_split
944   [(set (match_operand:DI 0 "register_operand" "")
945         (plus:DI (match_operand:DI 1 "register_operand" "")
946                  (match_operand:DI 2 "register_operand" "")))
947    (clobber (match_operand:SI 3 "register_operand" ""))]
948   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
949    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
950    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
951    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
952    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
953    && (REGNO (operands[0]) != REGNO (operands[1])
954        || REGNO (operands[0]) != REGNO (operands[2]))"
956   [(set (subreg:SI (match_dup 0) 0)
957         (plus:SI (subreg:SI (match_dup 1) 0)
958                  (subreg:SI (match_dup 2) 0)))
960    (set (match_dup 3)
961         (ltu:SI (subreg:SI (match_dup 0) 0)
962                 (subreg:SI (match_dup 2) 0)))
964    (set (subreg:SI (match_dup 0) 4)
965         (plus:SI (subreg:SI (match_dup 1) 4)
966                  (subreg:SI (match_dup 2) 4)))
968    (set (subreg:SI (match_dup 0) 4)
969         (plus:SI (subreg:SI (match_dup 0) 4)
970                  (match_dup 3)))]
971   "")
973 (define_split
974   [(set (match_operand:DI 0 "register_operand" "")
975         (plus:DI (match_operand:DI 1 "register_operand" "")
976                  (match_operand:DI 2 "register_operand" "")))
977    (clobber (match_operand:SI 3 "register_operand" ""))]
978   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
979    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
980    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
981    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
982    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
983    && (REGNO (operands[0]) != REGNO (operands[1])
984        || REGNO (operands[0]) != REGNO (operands[2]))"
986   [(set (subreg:SI (match_dup 0) 4)
987         (plus:SI (subreg:SI (match_dup 1) 4)
988                  (subreg:SI (match_dup 2) 4)))
990    (set (match_dup 3)
991         (ltu:SI (subreg:SI (match_dup 0) 4)
992                 (subreg:SI (match_dup 2) 4)))
994    (set (subreg:SI (match_dup 0) 0)
995         (plus:SI (subreg:SI (match_dup 1) 0)
996                  (subreg:SI (match_dup 2) 0)))
998    (set (subreg:SI (match_dup 0) 0)
999         (plus:SI (subreg:SI (match_dup 0) 0)
1000                  (match_dup 3)))]
1001   "")
1003 (define_insn "adddi3_internal_2"
1004   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1005         (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
1006                  (match_operand:DI 2 "small_int" "P,J,N")))
1007    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1008   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1009    && (TARGET_GAS
1010        || GET_CODE (operands[2]) != CONST_INT
1011        || INTVAL (operands[2]) != -32768)"
1012   "@
1013    addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
1014    move\\t%L0,%L1\;move\\t%M0,%M1
1015    subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
1016   [(set_attr "type"     "darith")
1017    (set_attr "mode"     "DI")
1018    (set_attr "length"   "12,8,16")])
1020 (define_split
1021   [(set (match_operand:DI 0 "register_operand" "")
1022         (plus:DI (match_operand:DI 1 "register_operand" "")
1023                  (match_operand:DI 2 "small_int" "")))
1024    (clobber (match_operand:SI 3 "register_operand" ""))]
1025   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1026    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1027    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1028    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1029    && INTVAL (operands[2]) > 0"
1031   [(set (subreg:SI (match_dup 0) 0)
1032         (plus:SI (subreg:SI (match_dup 1) 0)
1033                  (match_dup 2)))
1035    (set (match_dup 3)
1036         (ltu:SI (subreg:SI (match_dup 0) 0)
1037                 (match_dup 2)))
1039    (set (subreg:SI (match_dup 0) 4)
1040         (plus:SI (subreg:SI (match_dup 1) 4)
1041                  (match_dup 3)))]
1042   "")
1044 (define_split
1045   [(set (match_operand:DI 0 "register_operand" "")
1046         (plus:DI (match_operand:DI 1 "register_operand" "")
1047                  (match_operand:DI 2 "small_int" "")))
1048    (clobber (match_operand:SI 3 "register_operand" ""))]
1049   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1050    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1051    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1052    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1053    && INTVAL (operands[2]) > 0"
1055   [(set (subreg:SI (match_dup 0) 4)
1056         (plus:SI (subreg:SI (match_dup 1) 4)
1057                  (match_dup 2)))
1059    (set (match_dup 3)
1060         (ltu:SI (subreg:SI (match_dup 0) 4)
1061                 (match_dup 2)))
1063    (set (subreg:SI (match_dup 0) 0)
1064         (plus:SI (subreg:SI (match_dup 1) 0)
1065                  (match_dup 3)))]
1066   "")
1068 (define_insn "adddi3_internal_3"
1069   [(set (match_operand:DI 0 "register_operand" "=d,d")
1070         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")
1071                  (match_operand:DI 2 "arith_operand" "d,Q")))]
1072   "TARGET_64BIT
1073    && !TARGET_MIPS16
1074    && (TARGET_GAS
1075        || GET_CODE (operands[2]) != CONST_INT
1076        || INTVAL (operands[2]) != -32768)"
1077   "@
1078     daddu\\t%0,%z1,%2
1079     daddiu\\t%0,%z1,%2"
1080   [(set_attr "type"     "darith")
1081    (set_attr "mode"     "DI")])
1083 ;; For the mips16, we need to recognize stack pointer additions
1084 ;; explicitly, since we don't have a constraint for $sp.  These insns
1085 ;; will be generated by the save_restore_insns functions.
1087 (define_insn ""
1088   [(set (reg:DI 29)
1089         (plus:DI (reg:DI 29)
1090                  (match_operand:DI 0 "small_int" "I")))]
1091   "TARGET_MIPS16 && TARGET_64BIT"
1092   "daddu\\t%$,%$,%0"
1093   [(set_attr "type"     "arith")
1094    (set_attr "mode"     "DI")
1095    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
1096                                       (const_int 4)
1097                                       (const_int 8)))])
1099 (define_insn ""
1100   [(set (match_operand:DI 0 "register_operand" "=d")
1101         (plus:DI (reg:DI 29)
1102                  (match_operand:DI 1 "small_int" "I")))]
1103   "TARGET_MIPS16 && TARGET_64BIT"
1104   "daddu\\t%0,%$,%1"
1105   [(set_attr "type"     "arith")
1106    (set_attr "mode"     "DI")
1107    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
1108                                       (const_int 4)
1109                                       (const_int 8)))])
1111 (define_insn ""
1112   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1113         (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1114                  (match_operand:DI 2 "arith_operand" "Q,O,d")))]
1115   "TARGET_MIPS16 && TARGET_64BIT
1116    && (GET_CODE (operands[1]) != REG
1117        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
1118        || M16_REG_P (REGNO (operands[1]))
1119        || REGNO (operands[1]) == ARG_POINTER_REGNUM
1120        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
1121        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
1122    && (GET_CODE (operands[2]) != REG
1123        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
1124        || M16_REG_P (REGNO (operands[2]))
1125        || REGNO (operands[2]) == ARG_POINTER_REGNUM
1126        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
1127        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
1128   "*
1130   if (REGNO (operands[0]) == REGNO (operands[1]))
1131     return \"daddu\\t%0,%2\";
1132   return \"daddu\\t%0,%1,%2\";
1134   [(set_attr "type"     "arith")
1135    (set_attr "mode"     "DI")
1136    (set_attr_alternative "length"
1137                 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
1138                                (const_int 4)
1139                                (const_int 8))
1140                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1141                                (const_int 4)
1142                                (const_int 8))
1143                  (const_int 4)])])
1146 ;; On the mips16, we can sometimes split an add of a constant which is
1147 ;; a 4 byte instruction into two adds which are both 2 byte
1148 ;; instructions.  There are two cases: one where we are adding a
1149 ;; constant plus a register to another register, and one where we are
1150 ;; simply adding a constant to a register.
1152 (define_split
1153   [(set (match_operand:DI 0 "register_operand" "")
1154         (plus:DI (match_dup 0)
1155                  (match_operand:DI 1 "const_int_operand" "")))]
1156   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1157    && GET_CODE (operands[0]) == REG
1158    && M16_REG_P (REGNO (operands[0]))
1159    && GET_CODE (operands[1]) == CONST_INT
1160    && ((INTVAL (operands[1]) > 0xf
1161         && INTVAL (operands[1]) <= 0xf + 0xf)
1162        || (INTVAL (operands[1]) < - 0x10
1163            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1164   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1165    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1166   "
1168   HOST_WIDE_INT val = INTVAL (operands[1]);
1170   if (val >= 0)
1171     {
1172       operands[1] = GEN_INT (0xf);
1173       operands[2] = GEN_INT (val - 0xf);
1174     }
1175   else
1176     {
1177       operands[1] = GEN_INT (- 0x10);
1178       operands[2] = GEN_INT (val + 0x10);
1179     }
1182 (define_split
1183   [(set (match_operand:DI 0 "register_operand" "")
1184         (plus:DI (match_operand:DI 1 "register_operand" "")
1185                  (match_operand:DI 2 "const_int_operand" "")))]
1186   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1187    && GET_CODE (operands[0]) == REG
1188    && M16_REG_P (REGNO (operands[0]))
1189    && GET_CODE (operands[1]) == REG
1190    && M16_REG_P (REGNO (operands[1]))
1191    && REGNO (operands[0]) != REGNO (operands[1])
1192    && GET_CODE (operands[2]) == CONST_INT
1193    && ((INTVAL (operands[2]) > 0x7
1194         && INTVAL (operands[2]) <= 0x7 + 0xf)
1195        || (INTVAL (operands[2]) < - 0x8
1196            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1197   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1198    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1199   "
1201   HOST_WIDE_INT val = INTVAL (operands[2]);
1203   if (val >= 0)
1204     {
1205       operands[2] = GEN_INT (0x7);
1206       operands[3] = GEN_INT (val - 0x7);
1207     }
1208   else
1209     {
1210       operands[2] = GEN_INT (- 0x8);
1211       operands[3] = GEN_INT (val + 0x8);
1212     }
1215 (define_insn "addsi3_internal_2"
1216   [(set (match_operand:DI 0 "register_operand" "=d,d")
1217         (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
1218                                  (match_operand:SI 2 "arith_operand" "d,Q"))))]
1219   "TARGET_64BIT
1220    && !TARGET_MIPS16
1221    && (TARGET_GAS
1222        || GET_CODE (operands[2]) != CONST_INT
1223        || INTVAL (operands[2]) != -32768)"
1224   "@
1225     addu\\t%0,%z1,%2
1226     addiu\\t%0,%z1,%2"
1227   [(set_attr "type"     "arith")
1228    (set_attr "mode"     "SI")])
1230 (define_insn ""
1231   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1232         (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1233                                  (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
1234   "TARGET_MIPS16 && TARGET_64BIT"
1235   "*
1237   if (REGNO (operands[0]) == REGNO (operands[1]))
1238     return \"addu\\t%0,%2\";
1239   return \"addu\\t%0,%1,%2\";
1241   [(set_attr "type"     "arith")
1242    (set_attr "mode"     "SI")
1243    (set_attr_alternative "length"
1244                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1245                                (const_int 4)
1246                                (const_int 8))
1247                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1248                                (const_int 4)
1249                                (const_int 8))
1250                  (const_int 4)])])
1254 ;;  ....................
1256 ;;      SUBTRACTION
1258 ;;  ....................
1261 (define_insn "subdf3"
1262   [(set (match_operand:DF 0 "register_operand" "=f")
1263         (minus:DF (match_operand:DF 1 "register_operand" "f")
1264                   (match_operand:DF 2 "register_operand" "f")))]
1265   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1266   "sub.d\\t%0,%1,%2"
1267   [(set_attr "type"     "fadd")
1268    (set_attr "mode"     "DF")])
1270 (define_insn "subsf3"
1271   [(set (match_operand:SF 0 "register_operand" "=f")
1272         (minus:SF (match_operand:SF 1 "register_operand" "f")
1273                   (match_operand:SF 2 "register_operand" "f")))]
1274   "TARGET_HARD_FLOAT"
1275   "sub.s\\t%0,%1,%2"
1276   [(set_attr "type"     "fadd")
1277    (set_attr "mode"     "SF")])
1279 (define_expand "subsi3"
1280   [(set (match_operand:SI 0 "register_operand" "=d")
1281         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1282                   (match_operand:SI 2 "arith_operand" "dI")))]
1283   ""
1284   "
1286   if (GET_CODE (operands[2]) == CONST_INT
1287       && (INTVAL (operands[2]) == -32768
1288           || (TARGET_MIPS16
1289               && INTVAL (operands[2]) == -0x4000)))
1290     operands[2] = force_reg (SImode, operands[2]);
1293 (define_insn "subsi3_internal"
1294   [(set (match_operand:SI 0 "register_operand" "=d")
1295         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1296                   (match_operand:SI 2 "arith_operand" "dI")))]
1297   "!TARGET_MIPS16
1298    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1299   "subu\\t%0,%z1,%2"
1300   [(set_attr "type"     "arith")
1301    (set_attr "mode"     "SI")])
1303 ;; For the mips16, we need to recognize stack pointer subtractions
1304 ;; explicitly, since we don't have a constraint for $sp.  These insns
1305 ;; will be generated by the save_restore_insns functions.
1307 (define_insn ""
1308   [(set (reg:SI 29)
1309         (minus:SI (reg:SI 29)
1310                   (match_operand:SI 0 "small_int" "I")))]
1311   "TARGET_MIPS16
1312    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1313   "addu\\t%$,%$,%n0"
1314   [(set_attr "type"     "arith")
1315    (set_attr "mode"     "SI")
1316    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1317                                       (const_int 4)
1318                                       (const_int 8)))])
1320 (define_insn ""
1321   [(set (match_operand:SI 0 "register_operand" "=d")
1322         (minus:SI (reg:SI 29)
1323                   (match_operand:SI 1 "small_int" "I")))]
1324   "TARGET_MIPS16
1325    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1326   "addu\\t%0,%$,%n1"
1327   [(set_attr "type"     "arith")
1328    (set_attr "mode"     "SI")
1329    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
1330                                       (const_int 4)
1331                                       (const_int 8)))])
1334 (define_insn ""
1335   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1336         (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1337                   (match_operand:SI 2 "arith_operand" "I,O,d")))]
1338   "TARGET_MIPS16
1339    && (GET_CODE (operands[2]) != CONST_INT
1340        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1341   "*
1343   if (REGNO (operands[0]) == REGNO (operands[1]))
1344     return \"subu\\t%0,%2\";
1345   return \"subu\\t%0,%1,%2\";
1347   [(set_attr "type"     "arith")
1348    (set_attr "mode"     "SI")
1349    (set_attr_alternative "length"
1350                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1351                                (const_int 4)
1352                                (const_int 8))
1353                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1354                                (const_int 4)
1355                                (const_int 8))
1356                  (const_int 4)])])
1358 ;; On the mips16, we can sometimes split a subtract of a constant
1359 ;; which is a 4 byte instruction into two adds which are both 2 byte
1360 ;; instructions.  There are two cases: one where we are setting a
1361 ;; register to a register minus a constant, and one where we are
1362 ;; simply subtracting a constant from a register.
1364 (define_split
1365   [(set (match_operand:SI 0 "register_operand" "")
1366         (minus:SI (match_dup 0)
1367                   (match_operand:SI 1 "const_int_operand" "")))]
1368   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1369    && GET_CODE (operands[0]) == REG
1370    && M16_REG_P (REGNO (operands[0]))
1371    && GET_CODE (operands[1]) == CONST_INT
1372    && ((INTVAL (operands[1]) > 0x80
1373         && INTVAL (operands[1]) <= 0x80 + 0x80)
1374        || (INTVAL (operands[1]) < - 0x7f
1375            && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1376   [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1377    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1378   "
1380   HOST_WIDE_INT val = INTVAL (operands[1]);
1382   if (val >= 0)
1383     {
1384       operands[1] = GEN_INT (0x80);
1385       operands[2] = GEN_INT (val - 0x80);
1386     }
1387   else
1388     {
1389       operands[1] = GEN_INT (- 0x7f);
1390       operands[2] = GEN_INT (val + 0x7f);
1391     }
1394 (define_split
1395   [(set (match_operand:SI 0 "register_operand" "")
1396         (minus:SI (match_operand:SI 1 "register_operand" "")
1397                   (match_operand:SI 2 "const_int_operand" "")))]
1398   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1399    && GET_CODE (operands[0]) == REG
1400    && M16_REG_P (REGNO (operands[0]))
1401    && GET_CODE (operands[1]) == REG
1402    && M16_REG_P (REGNO (operands[1]))
1403    && REGNO (operands[0]) != REGNO (operands[1])
1404    && GET_CODE (operands[2]) == CONST_INT
1405    && ((INTVAL (operands[2]) > 0x8
1406         && INTVAL (operands[2]) <= 0x8 + 0x80)
1407        || (INTVAL (operands[2]) < - 0x7
1408            && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1409   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1410    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1411   "
1413   HOST_WIDE_INT val = INTVAL (operands[2]);
1415   if (val >= 0)
1416     {
1417       operands[2] = GEN_INT (0x8);
1418       operands[3] = GEN_INT (val - 0x8);
1419     }
1420   else
1421     {
1422       operands[2] = GEN_INT (- 0x7);
1423       operands[3] = GEN_INT (val + 0x7);
1424     }
1427 (define_expand "subdi3"
1428   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1429                    (minus:DI (match_operand:DI 1 "register_operand" "d")
1430                              (match_operand:DI 2 "register_operand" "d")))
1431               (clobber (match_dup 3))])]
1432   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1433   "
1435   if (TARGET_64BIT)
1436     {
1437       emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1438                                         operands[2]));
1439       DONE;
1440     }
1442   operands[3] = gen_reg_rtx (SImode);
1445 (define_insn "subdi3_internal"
1446   [(set (match_operand:DI 0 "register_operand" "=d")
1447         (minus:DI (match_operand:DI 1 "register_operand" "d")
1448                   (match_operand:DI 2 "register_operand" "d")))
1449    (clobber (match_operand:SI 3 "register_operand" "=d"))]
1450   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1451   "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1452   [(set_attr "type"     "darith")
1453    (set_attr "mode"     "DI")
1454    (set_attr "length"   "16")])
1456 (define_split
1457   [(set (match_operand:DI 0 "register_operand" "")
1458         (minus:DI (match_operand:DI 1 "register_operand" "")
1459                   (match_operand:DI 2 "register_operand" "")))
1460    (clobber (match_operand:SI 3 "register_operand" ""))]
1461   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1462    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1463    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1464    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1465    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1467   [(set (match_dup 3)
1468         (ltu:SI (subreg:SI (match_dup 1) 0)
1469                 (subreg:SI (match_dup 2) 0)))
1471    (set (subreg:SI (match_dup 0) 0)
1472         (minus:SI (subreg:SI (match_dup 1) 0)
1473                   (subreg:SI (match_dup 2) 0)))
1475    (set (subreg:SI (match_dup 0) 4)
1476         (minus:SI (subreg:SI (match_dup 1) 4)
1477                   (subreg:SI (match_dup 2) 4)))
1479    (set (subreg:SI (match_dup 0) 4)
1480         (minus:SI (subreg:SI (match_dup 0) 4)
1481                   (match_dup 3)))]
1482   "")
1484 (define_split
1485   [(set (match_operand:DI 0 "register_operand" "")
1486         (minus:DI (match_operand:DI 1 "register_operand" "")
1487                   (match_operand:DI 2 "register_operand" "")))
1488    (clobber (match_operand:SI 3 "register_operand" ""))]
1489   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1490    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1491    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1492    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1493    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1495   [(set (match_dup 3)
1496         (ltu:SI (subreg:SI (match_dup 1) 4)
1497                 (subreg:SI (match_dup 2) 4)))
1499    (set (subreg:SI (match_dup 0) 4)
1500         (minus:SI (subreg:SI (match_dup 1) 4)
1501                   (subreg:SI (match_dup 2) 4)))
1503    (set (subreg:SI (match_dup 0) 0)
1504         (minus:SI (subreg:SI (match_dup 1) 0)
1505                   (subreg:SI (match_dup 2) 0)))
1507    (set (subreg:SI (match_dup 0) 0)
1508         (minus:SI (subreg:SI (match_dup 0) 0)
1509                   (match_dup 3)))]
1510   "")
1512 (define_insn "subdi3_internal_2"
1513   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1514         (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1515                   (match_operand:DI 2 "small_int" "P,J,N")))
1516    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1517   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1518    && INTVAL (operands[2]) != -32768"
1519   "@
1520    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1521    move\\t%L0,%L1\;move\\t%M0,%M1
1522    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1523   [(set_attr "type"     "darith")
1524    (set_attr "mode"     "DI")
1525    (set_attr "length"   "12,8,16")])
1527 (define_split
1528   [(set (match_operand:DI 0 "register_operand" "")
1529         (minus:DI (match_operand:DI 1 "register_operand" "")
1530                   (match_operand:DI 2 "small_int" "")))
1531    (clobber (match_operand:SI 3 "register_operand" ""))]
1532   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1533    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1534    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1535    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1536    && INTVAL (operands[2]) > 0"
1538   [(set (match_dup 3)
1539         (ltu:SI (subreg:SI (match_dup 1) 0)
1540                 (match_dup 2)))
1542    (set (subreg:SI (match_dup 0) 0)
1543         (minus:SI (subreg:SI (match_dup 1) 0)
1544                   (match_dup 2)))
1546    (set (subreg:SI (match_dup 0) 4)
1547         (minus:SI (subreg:SI (match_dup 1) 4)
1548                   (match_dup 3)))]
1549   "")
1551 (define_split
1552   [(set (match_operand:DI 0 "register_operand" "")
1553         (minus:DI (match_operand:DI 1 "register_operand" "")
1554                   (match_operand:DI 2 "small_int" "")))
1555    (clobber (match_operand:SI 3 "register_operand" ""))]
1556   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1557    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1558    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1559    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1560    && INTVAL (operands[2]) > 0"
1562   [(set (match_dup 3)
1563         (ltu:SI (subreg:SI (match_dup 1) 4)
1564                 (match_dup 2)))
1566    (set (subreg:SI (match_dup 0) 4)
1567         (minus:SI (subreg:SI (match_dup 1) 4)
1568                   (match_dup 2)))
1570    (set (subreg:SI (match_dup 0) 0)
1571         (minus:SI (subreg:SI (match_dup 1) 0)
1572                   (match_dup 3)))]
1573   "")
1575 (define_insn "subdi3_internal_3"
1576   [(set (match_operand:DI 0 "register_operand" "=d")
1577         (minus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ")
1578                   (match_operand:DI 2 "arith_operand" "dI")))]
1579   "TARGET_64BIT && !TARGET_MIPS16
1580    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1581   "*
1583   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1584     ? \"daddu\\t%0,%z1,%n2\"
1585     : \"dsubu\\t%0,%z1,%2\";
1587   [(set_attr "type"     "darith")
1588    (set_attr "mode"     "DI")])
1590 ;; For the mips16, we need to recognize stack pointer subtractions
1591 ;; explicitly, since we don't have a constraint for $sp.  These insns
1592 ;; will be generated by the save_restore_insns functions.
1594 (define_insn ""
1595   [(set (reg:DI 29)
1596         (minus:DI (reg:DI 29)
1597                   (match_operand:DI 0 "small_int" "I")))]
1598   "TARGET_MIPS16
1599    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1600   "daddu\\t%$,%$,%n0"
1601   [(set_attr "type"     "arith")
1602    (set_attr "mode"     "DI")
1603    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1604                                       (const_int 4)
1605                                       (const_int 8)))])
1607 (define_insn ""
1608   [(set (match_operand:DI 0 "register_operand" "=d")
1609         (minus:DI (reg:DI 29)
1610                   (match_operand:DI 1 "small_int" "I")))]
1611   "TARGET_MIPS16
1612    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1613   "daddu\\t%0,%$,%n1"
1614   [(set_attr "type"     "arith")
1615    (set_attr "mode"     "DI")
1616    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
1617                                       (const_int 4)
1618                                       (const_int 8)))])
1620 (define_insn ""
1621   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1622         (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1623                   (match_operand:DI 2 "arith_operand" "I,O,d")))]
1624   "TARGET_MIPS16
1625    && (GET_CODE (operands[2]) != CONST_INT
1626        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1627   "*
1629   if (REGNO (operands[0]) == REGNO (operands[1]))
1630     return \"dsubu\\t%0,%2\";
1631   return \"dsubu\\t%0,%1,%2\";
1633   [(set_attr "type"     "arith")
1634    (set_attr "mode"     "DI")
1635    (set_attr_alternative "length"
1636                 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
1637                                (const_int 4)
1638                                (const_int 8))
1639                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1640                                (const_int 4)
1641                                (const_int 8))
1642                  (const_int 4)])])
1644 ;; On the mips16, we can sometimes split an add of a constant which is
1645 ;; a 4 byte instruction into two adds which are both 2 byte
1646 ;; instructions.  There are two cases: one where we are adding a
1647 ;; constant plus a register to another register, and one where we are
1648 ;; simply adding a constant to a register.
1650 (define_split
1651   [(set (match_operand:DI 0 "register_operand" "")
1652         (minus:DI (match_dup 0)
1653                   (match_operand:DI 1 "const_int_operand" "")))]
1654   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1655    && GET_CODE (operands[0]) == REG
1656    && M16_REG_P (REGNO (operands[0]))
1657    && GET_CODE (operands[1]) == CONST_INT
1658    && ((INTVAL (operands[1]) > 0x10
1659         && INTVAL (operands[1]) <= 0x10 + 0x10)
1660        || (INTVAL (operands[1]) < - 0xf
1661            && INTVAL (operands[1]) >= - 0xf - 0xf))"
1662   [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1663    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1664   "
1666   HOST_WIDE_INT val = INTVAL (operands[1]);
1668   if (val >= 0)
1669     {
1670       operands[1] = GEN_INT (0xf);
1671       operands[2] = GEN_INT (val - 0xf);
1672     }
1673   else
1674     {
1675       operands[1] = GEN_INT (- 0x10);
1676       operands[2] = GEN_INT (val + 0x10);
1677     }
1680 (define_split
1681   [(set (match_operand:DI 0 "register_operand" "")
1682         (minus:DI (match_operand:DI 1 "register_operand" "")
1683                   (match_operand:DI 2 "const_int_operand" "")))]
1684   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1685    && GET_CODE (operands[0]) == REG
1686    && M16_REG_P (REGNO (operands[0]))
1687    && GET_CODE (operands[1]) == REG
1688    && M16_REG_P (REGNO (operands[1]))
1689    && REGNO (operands[0]) != REGNO (operands[1])
1690    && GET_CODE (operands[2]) == CONST_INT
1691    && ((INTVAL (operands[2]) > 0x8
1692         && INTVAL (operands[2]) <= 0x8 + 0x10)
1693        || (INTVAL (operands[2]) < - 0x7
1694            && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1695   [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1696    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1697   "
1699   HOST_WIDE_INT val = INTVAL (operands[2]);
1701   if (val >= 0)
1702     {
1703       operands[2] = GEN_INT (0x8);
1704       operands[3] = GEN_INT (val - 0x8);
1705     }
1706   else
1707     {
1708       operands[2] = GEN_INT (- 0x7);
1709       operands[3] = GEN_INT (val + 0x7);
1710     }
1713 (define_insn "subsi3_internal_2"
1714   [(set (match_operand:DI 0 "register_operand" "=d")
1715         (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1716                                   (match_operand:SI 2 "arith_operand" "dI"))))]
1717   "TARGET_64BIT && !TARGET_MIPS16
1718    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1719   "*
1721   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1722     ? \"addu\\t%0,%z1,%n2\"
1723     : \"subu\\t%0,%z1,%2\";
1725   [(set_attr "type"     "arith")
1726    (set_attr "mode"     "DI")])
1728 (define_insn ""
1729   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1730         (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1731                                   (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1732   "TARGET_64BIT && TARGET_MIPS16
1733    && (GET_CODE (operands[2]) != CONST_INT
1734        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1735   "*
1737   if (REGNO (operands[0]) == REGNO (operands[1]))
1738     return \"subu\\t%0,%2\";
1739   return \"subu\\t%0,%1,%2\";
1741   [(set_attr "type"     "arith")
1742    (set_attr "mode"     "SI")
1743    (set_attr_alternative "length"
1744                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1745                                (const_int 4)
1746                                (const_int 8))
1747                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1748                                (const_int 4)
1749                                (const_int 8))
1750                  (const_int 4)])])
1755 ;;  ....................
1757 ;;      MULTIPLICATION
1759 ;;  ....................
1762 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1763 ;; operands may corrupt immediately following multiplies. This is a
1764 ;; simple fix to insert NOPs.
1766 (define_expand "muldf3"
1767   [(set (match_operand:DF 0 "register_operand" "=f")
1768         (mult:DF (match_operand:DF 1 "register_operand" "f")
1769                  (match_operand:DF 2 "register_operand" "f")))]
1770   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1771   "
1773   if (!TARGET_MIPS4300)
1774     emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1775   else
1776     emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1777   DONE;
1780 (define_insn "muldf3_internal"
1781   [(set (match_operand:DF 0 "register_operand" "=f")
1782         (mult:DF (match_operand:DF 1 "register_operand" "f")
1783                  (match_operand:DF 2 "register_operand" "f")))]
1784   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_MIPS4300"
1785   "mul.d\\t%0,%1,%2"
1786   [(set_attr "type"     "fmul")
1787    (set_attr "mode"     "DF")])
1789 (define_insn "muldf3_r4300"
1790   [(set (match_operand:DF 0 "register_operand" "=f")
1791         (mult:DF (match_operand:DF 1 "register_operand" "f")
1792                  (match_operand:DF 2 "register_operand" "f")))]
1793   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_MIPS4300"
1794   "*
1796   output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1797   if (TARGET_4300_MUL_FIX)
1798     output_asm_insn (\"nop\", operands);
1799   return \"\";
1801   [(set_attr "type"     "fmul")
1802    (set_attr "mode"     "DF")
1803    (set_attr "length"   "8")])  ;; mul.d + nop
1805 (define_expand "mulsf3"
1806   [(set (match_operand:SF 0 "register_operand" "=f")
1807         (mult:SF (match_operand:SF 1 "register_operand" "f")
1808                  (match_operand:SF 2 "register_operand" "f")))]
1809   "TARGET_HARD_FLOAT"
1810   "
1812   if (!TARGET_MIPS4300)
1813     emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1814   else
1815     emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1816   DONE;
1819 (define_insn "mulsf3_internal"
1820   [(set (match_operand:SF 0 "register_operand" "=f")
1821         (mult:SF (match_operand:SF 1 "register_operand" "f")
1822                  (match_operand:SF 2 "register_operand" "f")))]
1823   "TARGET_HARD_FLOAT && !TARGET_MIPS4300"
1824   "mul.s\\t%0,%1,%2"
1825   [(set_attr "type"     "fmul")
1826    (set_attr "mode"     "SF")])
1828 (define_insn "mulsf3_r4300"
1829   [(set (match_operand:SF 0 "register_operand" "=f")
1830         (mult:SF (match_operand:SF 1 "register_operand" "f")
1831                  (match_operand:SF 2 "register_operand" "f")))]
1832   "TARGET_HARD_FLOAT && TARGET_MIPS4300"
1833   "*
1835   output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1836   if (TARGET_4300_MUL_FIX)
1837     output_asm_insn (\"nop\", operands);
1838   return \"\";
1840   [(set_attr "type"     "fmul")
1841    (set_attr "mode"     "SF")
1842    (set_attr "length"   "8")])  ;; mul.s + nop
1845 ;; ??? The R4000 (only) has a cpu bug.  If a double-word shift executes while
1846 ;; a multiply is in progress, it may give an incorrect result.  Avoid
1847 ;; this by keeping the mflo with the mult on the R4000.
1849 (define_expand "mulsi3"
1850   [(set (match_operand:SI 0 "register_operand" "=l")
1851         (mult:SI (match_operand:SI 1 "register_operand" "d")
1852                  (match_operand:SI 2 "register_operand" "d")))
1853    (clobber (match_scratch:SI 3 "=h"))
1854    (clobber (match_scratch:SI 4 "=a"))]
1855   ""
1856   "
1858   if (GENERATE_MULT3_SI || TARGET_MAD)
1859     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1860   else if (!TARGET_MIPS4000 || TARGET_MIPS16)
1861     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1862   else
1863     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1864   DONE;
1867 (define_insn "mulsi3_mult3"
1868   [(set (match_operand:SI 0 "register_operand" "=d,l")
1869         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1870                  (match_operand:SI 2 "register_operand" "d,d")))
1871    (clobber (match_scratch:SI 3 "=h,h"))
1872    (clobber (match_scratch:SI 4 "=l,X"))
1873    (clobber (match_scratch:SI 5 "=a,a"))]
1874   "GENERATE_MULT3_SI
1875    || TARGET_MAD"
1876   "*
1878   if (which_alternative == 1)
1879     return \"mult\\t%1,%2\";
1880   if (TARGET_MAD
1881       || TARGET_MIPS5400
1882       || TARGET_MIPS5500
1883       || ISA_MIPS32
1884       || ISA_MIPS32R2
1885       || ISA_MIPS64)
1886     return \"mul\\t%0,%1,%2\";
1887   return \"mult\\t%0,%1,%2\";
1889   [(set_attr "type"     "imul")
1890    (set_attr "mode"     "SI")])
1892 ;; If a register gets allocated to LO, and we spill to memory, the reload
1893 ;; will include a move from LO to a GPR.  Merge it into the multiplication
1894 ;; if it can set the GPR directly.
1896 ;; Operand 0: LO
1897 ;; Operand 1: GPR (1st multiplication operand)
1898 ;; Operand 2: GPR (2nd multiplication operand)
1899 ;; Operand 3: HI
1900 ;; Operand 4: HILO
1901 ;; Operand 5: GPR (destination)
1902 (define_peephole2
1903   [(parallel
1904        [(set (match_operand:SI 0 "register_operand" "")
1905              (mult:SI (match_operand:SI 1 "register_operand" "")
1906                       (match_operand:SI 2 "register_operand" "")))
1907         (clobber (match_operand:SI 3 "register_operand" ""))
1908         (clobber (scratch:SI))
1909         (clobber (match_operand:SI 4 "register_operand" ""))])
1910    (set (match_operand:SI 5 "register_operand" "")
1911         (match_dup 0))]
1912   "GENERATE_MULT3_SI
1913    && true_regnum (operands[0]) == LO_REGNUM
1914    && GP_REG_P (true_regnum (operands[5]))
1915    && peep2_reg_dead_p (2, operands[0])"
1916   [(parallel
1917        [(set (match_dup 5)
1918              (mult:SI (match_dup 1)
1919                       (match_dup 2)))
1920         (clobber (match_dup 3))
1921         (clobber (match_dup 0))
1922         (clobber (match_dup 4))])])
1924 (define_insn "mulsi3_internal"
1925   [(set (match_operand:SI 0 "register_operand" "=l")
1926         (mult:SI (match_operand:SI 1 "register_operand" "d")
1927                  (match_operand:SI 2 "register_operand" "d")))
1928    (clobber (match_scratch:SI 3 "=h"))
1929    (clobber (match_scratch:SI 4 "=a"))]
1930   "!TARGET_MIPS4000 || TARGET_MIPS16"
1931   "mult\\t%1,%2"
1932   [(set_attr "type"     "imul")
1933    (set_attr "mode"     "SI")])
1935 (define_insn "mulsi3_r4000"
1936   [(set (match_operand:SI 0 "register_operand" "=d")
1937         (mult:SI (match_operand:SI 1 "register_operand" "d")
1938                  (match_operand:SI 2 "register_operand" "d")))
1939    (clobber (match_scratch:SI 3 "=h"))
1940    (clobber (match_scratch:SI 4 "=l"))
1941    (clobber (match_scratch:SI 5 "=a"))]
1942   "TARGET_MIPS4000 && !TARGET_MIPS16"
1943   "mult\t%1,%2\;mflo\t%0"
1944   [(set_attr "type"     "imul")
1945    (set_attr "mode"     "SI")
1946    (set_attr "length"   "8")])
1948 ;; Multiply-accumulate patterns
1950 ;; For processors that can copy the output to a general register:
1952 ;; The all-d alternative is needed because the combiner will find this
1953 ;; pattern and then register alloc/reload will move registers around to
1954 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1956 ;; The last alternative should be made slightly less desirable, but adding
1957 ;; "?" to the constraint is too strong, and causes values to be loaded into
1958 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1959 ;; trick.
1960 (define_insn "*mul_acc_si"
1961   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1962         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1963                           (match_operand:SI 2 "register_operand" "d,d,d"))
1964                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1965    (clobber (match_scratch:SI 4 "=h,h,h"))
1966    (clobber (match_scratch:SI 5 "=X,3,l"))
1967    (clobber (match_scratch:SI 6 "=a,a,a"))
1968    (clobber (match_scratch:SI 7 "=X,X,d"))]
1969   "(TARGET_MIPS3900
1970    || ISA_HAS_MADD_MSUB)
1971    && !TARGET_MIPS16"
1972   "*
1974   static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
1975   if (which_alternative == 2)
1976     return \"#\";
1977   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1978     return \"#\";
1979   return madd[which_alternative];
1981   [(set_attr "type"     "imadd,imadd,multi")
1982    (set_attr "mode"     "SI")
1983    (set_attr "length"   "4,4,8")])
1985 ;; Split the above insn if we failed to get LO allocated.
1986 (define_split
1987   [(set (match_operand:SI 0 "register_operand" "")
1988         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1989                           (match_operand:SI 2 "register_operand" ""))
1990                  (match_operand:SI 3 "register_operand" "")))
1991    (clobber (match_scratch:SI 4 ""))
1992    (clobber (match_scratch:SI 5 ""))
1993    (clobber (match_scratch:SI 6 ""))
1994    (clobber (match_scratch:SI 7 ""))]
1995   "reload_completed && !TARGET_DEBUG_D_MODE
1996    && GP_REG_P (true_regnum (operands[0]))
1997    && GP_REG_P (true_regnum (operands[3]))"
1998   [(parallel [(set (match_dup 7)
1999                    (mult:SI (match_dup 1) (match_dup 2)))
2000               (clobber (match_dup 4))
2001               (clobber (match_dup 5))
2002               (clobber (match_dup 6))])
2003    (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
2004   "")
2006 ;; Splitter to copy result of MADD to a general register
2007 (define_split
2008   [(set (match_operand:SI                   0 "register_operand" "")
2009         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
2010                           (match_operand:SI 2 "register_operand" ""))
2011                  (match_operand:SI          3 "register_operand" "")))
2012    (clobber (match_scratch:SI               4 ""))
2013    (clobber (match_scratch:SI               5 ""))
2014    (clobber (match_scratch:SI               6 ""))
2015    (clobber (match_scratch:SI               7 ""))]
2016   "reload_completed && !TARGET_DEBUG_D_MODE
2017    && GP_REG_P (true_regnum (operands[0]))
2018    && true_regnum (operands[3]) == LO_REGNUM"
2019   [(parallel [(set (match_dup 3)
2020                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
2021                             (match_dup 3)))
2022               (clobber (match_dup 4))
2023               (clobber (match_dup 5))
2024               (clobber (match_dup 6))
2025               (clobber (match_dup 7))])
2026    (set (match_dup 0) (match_dup 3))]
2027   "")
2029 (define_insn "*macc"
2030   [(set (match_operand:SI 0 "register_operand" "=l,d")
2031         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
2032                           (match_operand:SI 2 "register_operand" "d,d"))
2033                  (match_operand:SI 3 "register_operand" "0,l")))
2034    (clobber (match_scratch:SI 4 "=h,h"))
2035    (clobber (match_scratch:SI 5 "=X,3"))
2036    (clobber (match_scratch:SI 6 "=a,a"))]
2037   "ISA_HAS_MACC"
2038   "*
2040   if (which_alternative == 1)
2041     return \"macc\\t%0,%1,%2\";
2042   else if (TARGET_MIPS5500)
2043     return \"madd\\t%1,%2\";
2044   else
2045     return \"macc\\t%.,%1,%2\";
2047   [(set_attr "type" "imadd")
2048    (set_attr "mode" "SI")])
2050 ;; Pattern generated by define_peephole2 below
2051 (define_insn "*macc2"
2052   [(set (match_operand:SI 0 "register_operand" "=l")
2053         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2054                           (match_operand:SI 2 "register_operand" "d"))
2055                  (match_dup 0)))
2056    (set (match_operand:SI 3 "register_operand" "=d")
2057         (plus:SI (mult:SI (match_dup 1)
2058                           (match_dup 2))
2059                  (match_dup 0)))
2060    (clobber (match_scratch:SI 4 "=h"))
2061    (clobber (match_scratch:SI 5 "=a"))]
2062   "ISA_HAS_MACC && reload_completed"
2063   "macc\\t%3,%1,%2"
2064   [(set_attr "type"     "imadd")
2065    (set_attr "mode"     "SI")])
2067 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
2069 ;; Operand 0: LO
2070 ;; Operand 1: GPR (1st multiplication operand)
2071 ;; Operand 2: GPR (2nd multiplication operand)
2072 ;; Operand 3: HI
2073 ;; Operand 4: HILO
2074 ;; Operand 5: GPR (destination)
2075 (define_peephole2
2076   [(parallel
2077        [(set (match_operand:SI 0 "register_operand" "")
2078              (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
2079                                (match_operand:SI 2 "register_operand" ""))
2080                       (match_dup 0)))
2081         (clobber (match_operand:SI 3 "register_operand" ""))
2082         (clobber (scratch:SI))
2083         (clobber (match_operand:SI 4 "register_operand" ""))])
2084    (set (match_operand:SI 5 "register_operand" "")
2085         (match_dup 0))]
2086   "ISA_HAS_MACC
2087    && true_regnum (operands[0]) == LO_REGNUM
2088    && GP_REG_P (true_regnum (operands[5]))"
2089   [(parallel [(set (match_dup 0)
2090                    (plus:SI (mult:SI (match_dup 1)
2091                                      (match_dup 2))
2092                             (match_dup 0)))
2093               (set (match_dup 5)
2094                    (plus:SI (mult:SI (match_dup 1)
2095                                      (match_dup 2))
2096                             (match_dup 0)))
2097               (clobber (match_dup 3))
2098               (clobber (match_dup 4))])]
2099   "")
2101 ;; When we have a three-address multiplication instruction, it should
2102 ;; be faster to do a separate multiply and add, rather than moving
2103 ;; something into LO in order to use a macc instruction.
2105 ;; This peephole needs a scratch register to cater for the case when one
2106 ;; of the multiplication operands is the same as the destination.
2108 ;; Operand 0: GPR (scratch)
2109 ;; Operand 1: LO
2110 ;; Operand 2: GPR (addend)
2111 ;; Operand 3: GPR (destination)
2112 ;; Operand 4: GPR (1st multiplication operand)
2113 ;; Operand 5: GPR (2nd multiplication operand)
2114 ;; Operand 6: HI
2115 ;; Operand 7: HILO
2116 (define_peephole2
2117   [(match_scratch:SI 0 "d")
2118    (set (match_operand:SI 1 "register_operand" "")
2119         (match_operand:SI 2 "register_operand" ""))
2120    (match_dup 0)
2121    (parallel
2122        [(set (match_operand:SI 3 "register_operand" "")
2123              (plus:SI (mult:SI (match_operand:SI 4 "register_operand" "")
2124                                (match_operand:SI 5 "register_operand" ""))
2125                       (match_dup 1)))
2126         (clobber (match_operand:SI 6 "register_operand" ""))
2127         (clobber (match_dup 1))
2128         (clobber (match_operand:SI 7 "register_operand" ""))])]
2129   "ISA_HAS_MACC && GENERATE_MULT3_SI
2130    && true_regnum (operands[1]) == LO_REGNUM
2131    && peep2_reg_dead_p (2, operands[1])
2132    && GP_REG_P (true_regnum (operands[3]))"
2133   [(parallel [(set (match_dup 0)
2134                    (mult:SI (match_dup 4)
2135                             (match_dup 5)))
2136               (clobber (match_dup 6))
2137               (clobber (match_dup 1))
2138               (clobber (match_dup 7))])
2139    (set (match_dup 3)
2140         (plus:SI (match_dup 0)
2141                  (match_dup 2)))]
2142   "")
2144 ;; Same as above, except LO is the initial target of the macc.
2146 ;; Operand 0: GPR (scratch)
2147 ;; Operand 1: LO
2148 ;; Operand 2: GPR (addend)
2149 ;; Operand 3: GPR (1st multiplication operand)
2150 ;; Operand 4: GPR (2nd multiplication operand)
2151 ;; Operand 5: HI
2152 ;; Operand 6: HILO
2153 ;; Operand 7: GPR (destination)
2154 (define_peephole2
2155   [(match_scratch:SI 0 "d")
2156    (set (match_operand:SI 1 "register_operand" "")
2157         (match_operand:SI 2 "register_operand" ""))
2158    (match_dup 0)
2159    (parallel
2160        [(set (match_dup 1)
2161              (plus:SI (mult:SI (match_operand:SI 3 "register_operand" "")
2162                                (match_operand:SI 4 "register_operand" ""))
2163                       (match_dup 1)))
2164         (clobber (match_operand:SI 5 "register_operand" ""))
2165         (clobber (scratch:SI))
2166         (clobber (match_operand:SI 6 "register_operand" ""))])
2167    (match_dup 0)
2168    (set (match_operand:SI 7 "register_operand" "")
2169         (match_dup 1))]
2170   "ISA_HAS_MACC && GENERATE_MULT3_SI
2171    && true_regnum (operands[1]) == LO_REGNUM
2172    && peep2_reg_dead_p (3, operands[1])
2173    && GP_REG_P (true_regnum (operands[7]))"
2174   [(parallel [(set (match_dup 0)
2175                    (mult:SI (match_dup 3)
2176                             (match_dup 4)))
2177               (clobber (match_dup 5))
2178               (clobber (match_dup 1))
2179               (clobber (match_dup 6))])
2180    (set (match_dup 7)
2181         (plus:SI (match_dup 0)
2182                  (match_dup 2)))]
2183   "")
2185 (define_insn "*mul_sub_si"
2186   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
2187         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
2188                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
2189                            (match_operand:SI 3 "register_operand" "d,d,d"))))
2190    (clobber (match_scratch:SI 4 "=h,h,h"))
2191    (clobber (match_scratch:SI 5 "=X,1,l"))
2192    (clobber (match_scratch:SI 6 "=a,a,a"))
2193    (clobber (match_scratch:SI 7 "=X,X,d"))]
2194   "ISA_HAS_MADD_MSUB"
2195   "*
2197   if (which_alternative != 0)
2198     return \"#\";
2199   return \"msub\\t%2,%3\";
2201   [(set_attr "type"     "imadd,multi,multi")
2202    (set_attr "mode"     "SI")
2203    (set_attr "length"   "4,8,8")])
2205 ;; Split the above insn if we failed to get LO allocated.
2206 (define_split
2207   [(set (match_operand:SI 0 "register_operand" "")
2208         (minus:SI (match_operand:SI 1 "register_operand" "")
2209                   (mult:SI (match_operand:SI 2 "register_operand" "")
2210                            (match_operand:SI 3 "register_operand" ""))))
2211    (clobber (match_scratch:SI 4 ""))
2212    (clobber (match_scratch:SI 5 ""))
2213    (clobber (match_scratch:SI 6 ""))
2214    (clobber (match_scratch:SI 7 ""))]
2215   "reload_completed && !TARGET_DEBUG_D_MODE
2216    && GP_REG_P (true_regnum (operands[0]))
2217    && GP_REG_P (true_regnum (operands[1]))"
2218   [(parallel [(set (match_dup 7)
2219                    (mult:SI (match_dup 2) (match_dup 3)))
2220               (clobber (match_dup 4))
2221               (clobber (match_dup 5))
2222               (clobber (match_dup 6))])
2223    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
2224   "")
2226 ;; Splitter to copy result of MSUB to a general register
2227 (define_split
2228   [(set (match_operand:SI 0 "register_operand" "")
2229         (minus:SI (match_operand:SI 1 "register_operand" "")
2230                   (mult:SI (match_operand:SI 2 "register_operand" "")
2231                            (match_operand:SI 3 "register_operand" ""))))
2232    (clobber (match_scratch:SI 4 ""))
2233    (clobber (match_scratch:SI 5 ""))
2234    (clobber (match_scratch:SI 6 ""))
2235    (clobber (match_scratch:SI 7 ""))]
2236   "reload_completed && !TARGET_DEBUG_D_MODE
2237    && GP_REG_P (true_regnum (operands[0]))
2238    && true_regnum (operands[1]) == LO_REGNUM"
2239   [(parallel [(set (match_dup 1)
2240                    (minus:SI (match_dup 1)
2241                              (mult:SI (match_dup 2) (match_dup 3))))
2242               (clobber (match_dup 4))
2243               (clobber (match_dup 5))
2244               (clobber (match_dup 6))
2245               (clobber (match_dup 7))])
2246    (set (match_dup 0) (match_dup 1))]
2247   "")
2249 (define_insn "*muls"
2250   [(set (match_operand:SI                  0 "register_operand" "=l,d")
2251         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
2252                          (match_operand:SI 2 "register_operand" "d,d"))))
2253    (clobber (match_scratch:SI              3                    "=h,h"))
2254    (clobber (match_scratch:SI              4                    "=a,a"))
2255    (clobber (match_scratch:SI              5                    "=X,l"))]
2256   "ISA_HAS_MULS"
2257   "@
2258    muls\\t$0,%1,%2
2259    muls\\t%0,%1,%2"
2260   [(set_attr "type"     "imul")
2261    (set_attr "mode"     "SI")])
2263 (define_insn "*msac"
2264   [(set (match_operand:SI 0 "register_operand" "=l,d")
2265         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
2266                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
2267                            (match_operand:SI 3 "register_operand" "d,d"))))
2268    (clobber (match_scratch:SI 4 "=h,h"))
2269    (clobber (match_scratch:SI 5 "=X,1"))
2270    (clobber (match_scratch:SI 6 "=a,a"))]
2271   "ISA_HAS_MSAC"
2272   "*
2274   if (which_alternative == 1)
2275     return \"msac\\t%0,%2,%3\";
2276   else if (TARGET_MIPS5500)
2277     return \"msub\\t%2,%3\";
2278   else
2279     return \"msac\\t$0,%2,%3\";
2281   [(set_attr "type"     "imadd")
2282    (set_attr "mode"     "SI")])
2284 (define_expand "muldi3"
2285   [(set (match_operand:DI 0 "register_operand" "=l")
2286         (mult:DI (match_operand:DI 1 "register_operand" "d")
2287                  (match_operand:DI 2 "register_operand" "d")))
2288    (clobber (match_scratch:DI 3 "=h"))
2289    (clobber (match_scratch:DI 4 "=a"))]
2290   "TARGET_64BIT"
2292   "
2294   if (GENERATE_MULT3_DI || TARGET_MIPS4000)
2295     emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
2296   else
2297     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
2298   DONE;
2301 (define_insn "muldi3_internal"
2302   [(set (match_operand:DI 0 "register_operand" "=l")
2303         (mult:DI (match_operand:DI 1 "register_operand" "d")
2304                  (match_operand:DI 2 "register_operand" "d")))
2305    (clobber (match_scratch:DI 3 "=h"))
2306    (clobber (match_scratch:DI 4 "=a"))]
2307   "TARGET_64BIT && !TARGET_MIPS4000"
2308   "dmult\\t%1,%2"
2309   [(set_attr "type"     "imul")
2310    (set_attr "mode"     "DI")])
2312 (define_insn "muldi3_internal2"
2313   [(set (match_operand:DI 0 "register_operand" "=d")
2314         (mult:DI (match_operand:DI 1 "register_operand" "d")
2315                  (match_operand:DI 2 "register_operand" "d")))
2316    (clobber (match_scratch:DI 3 "=h"))
2317    (clobber (match_scratch:DI 4 "=l"))
2318    (clobber (match_scratch:DI 5 "=a"))]
2319   "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000)"
2320   {
2321     if (GENERATE_MULT3_DI)
2322       return "dmult\t%0,%1,%2";
2323     else
2324       return "dmult\t%1,%2\n\tmflo\t%0";
2325   }
2326   [(set_attr "type"     "imul")
2327    (set_attr "mode"     "DI")
2328    (set (attr "length")
2329         (if_then_else (ne (symbol_ref "GENERATE_MULT3_DI") (const_int 0))
2330                       (const_int 4)
2331                       (const_int 8)))])
2333 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
2335 (define_expand "mulsidi3"
2336   [(set (match_operand:DI 0 "register_operand" "=x")
2337         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2338                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2339   ""
2340   "
2342   if (TARGET_64BIT)
2343     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2]));
2344   else
2345     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2]));
2346   DONE;
2349 (define_insn "mulsidi3_internal"
2350   [(set (match_operand:DI 0 "register_operand" "=x")
2351         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2352                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2353    (clobber (match_scratch:SI 3 "=a"))]
2354   "!TARGET_64BIT"
2355   "mult\\t%1,%2"
2356   [(set_attr "type"     "imul")
2357    (set_attr "mode"     "SI")])
2359 (define_insn "mulsidi3_64bit"
2360   [(set (match_operand:DI 0 "register_operand" "=a")
2361         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2362                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2363    (clobber (match_scratch:DI 3 "=l"))
2364    (clobber (match_scratch:DI 4 "=h"))]
2365   "TARGET_64BIT"
2366   "mult\\t%1,%2"
2367   [(set_attr "type"     "imul")
2368    (set_attr "mode"     "SI")])
2370 (define_expand "umulsidi3"
2371   [(set (match_operand:DI 0 "register_operand" "=x")
2372         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2373                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2374   ""
2375   "
2377   if (TARGET_64BIT)
2378     emit_insn (gen_umulsidi3_64bit (operands[0], operands[1], operands[2]));
2379   else
2380     emit_insn (gen_umulsidi3_internal (operands[0], operands[1], operands[2]));
2382   DONE;
2386 (define_insn "umulsidi3_internal"
2387   [(set (match_operand:DI 0 "register_operand" "=x")
2388         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2389                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2390    (clobber (match_scratch:SI 3 "=a"))]
2391   "!TARGET_64BIT"
2392   "multu\\t%1,%2"
2393   [(set_attr "type"     "imul")
2394    (set_attr "mode"     "SI")])
2396 (define_insn "umulsidi3_64bit"
2397   [(set (match_operand:DI 0 "register_operand" "=a")
2398         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2399                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2400    (clobber (match_scratch:DI 3 "=l"))
2401    (clobber (match_scratch:DI 4 "=h"))]
2402   "TARGET_64BIT"
2403   "multu\\t%1,%2"
2404   [(set_attr "type"     "imul")
2405    (set_attr "mode"     "SI")])
2407 ;; Widening multiply with negation.  It isn't worth using this pattern
2408 ;; for 64-bit code since the reload sequence for HILO_REGNUM is so long.
2409 (define_insn "*muls_di"
2410   [(set (match_operand:DI 0 "register_operand" "=x")
2411         (neg:DI
2412          (mult:DI
2413           (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2414           (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))
2415    (clobber (match_scratch:SI 3 "=a"))]
2416   "!TARGET_64BIT && ISA_HAS_MULS"
2417   "muls\\t$0,%1,%2"
2418   [(set_attr "type"     "imul")
2419    (set_attr "length"   "4")
2420    (set_attr "mode"     "SI")])
2422 (define_insn "*umuls_di"
2423   [(set (match_operand:DI 0 "register_operand" "=x")
2424         (neg:DI
2425          (mult:DI
2426           (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2427           (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))
2428    (clobber (match_scratch:SI 3 "=a"))]
2429   "!TARGET_64BIT && ISA_HAS_MULS"
2430   "mulsu\\t$0,%1,%2"
2431   [(set_attr "type"     "imul")
2432    (set_attr "length"   "4")
2433    (set_attr "mode"     "SI")])
2435 ;; Not used for 64-bit code: see comment for *muls_di.
2436 (define_insn "*smsac_di"
2437   [(set (match_operand:DI 0 "register_operand" "=x")
2438         (minus:DI (match_operand:DI 3 "register_operand" "0")
2439                   (mult:DI
2440                    (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2441                    (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))
2442    (clobber (match_scratch:SI 4 "=a"))]
2443   "!TARGET_64BIT && ISA_HAS_MSAC"
2444   "*
2446   if (TARGET_MIPS5500)
2447     return \"msub\\t%1,%2\";
2448   else
2449     return \"msac\\t$0,%1,%2\";
2451   [(set_attr "type"     "imadd")
2452    (set_attr "length"   "4")
2453    (set_attr "mode"     "SI")])
2455 (define_insn "*umsac_di"
2456   [(set (match_operand:DI 0 "register_operand" "=x")
2457         (minus:DI (match_operand:DI 3 "register_operand" "0")
2458                   (mult:DI
2459                    (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2460                    (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))
2461    (clobber (match_scratch:SI 4 "=a"))]
2462   "!TARGET_64BIT && ISA_HAS_MSAC"
2463   "*
2465   if (TARGET_MIPS5500)
2466     return \"msubu\\t%1,%2\";
2467   else
2468     return \"msacu\\t$0,%1,%2\";
2470   [(set_attr "type"     "imadd")
2471    (set_attr "length"   "4")
2472    (set_attr "mode"     "SI")])
2474 ;; _highpart patterns
2475 (define_expand "umulsi3_highpart"
2476   [(set (match_operand:SI 0 "register_operand" "=h")
2477         (truncate:SI
2478          (lshiftrt:DI
2479           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2480                    (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2481           (const_int 32))))]
2482   ""
2483   "
2485   if (ISA_HAS_MULHI)
2486     emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1],
2487                                                     operands[2]));
2488   else
2489     emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1],
2490                                               operands[2]));
2491   DONE;
2494 (define_insn "umulsi3_highpart_internal"
2495   [(set (match_operand:SI 0 "register_operand" "=h")
2496         (truncate:SI
2497          (lshiftrt:DI
2498           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2499                    (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2500           (const_int 32))))
2501    (clobber (match_scratch:SI 3 "=l"))
2502    (clobber (match_scratch:SI 4 "=a"))]
2503   "!ISA_HAS_MULHI"
2504   "multu\\t%1,%2"
2505   [(set_attr "type"   "imul")
2506    (set_attr "mode"   "SI")
2507    (set_attr "length" "4")])
2509 (define_insn "umulsi3_highpart_mulhi_internal"
2510   [(set (match_operand:SI 0 "register_operand" "=h,d")
2511         (truncate:SI
2512          (lshiftrt:DI
2513           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2514                    (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
2515           (const_int 32))))
2516    (clobber (match_scratch:SI 3 "=l,l"))
2517    (clobber (match_scratch:SI 4 "=a,a"))
2518    (clobber (match_scratch:SI 5 "=X,h"))]
2519   "ISA_HAS_MULHI"
2520   "@
2521    multu\\t%1,%2
2522    mulhiu\\t%0,%1,%2"
2523   [(set_attr "type"   "imul")
2524    (set_attr "mode"   "SI")
2525    (set_attr "length" "4")])
2527 (define_insn "umulsi3_highpart_neg_mulhi_internal"
2528   [(set (match_operand:SI 0 "register_operand" "=h,d")
2529         (truncate:SI
2530          (lshiftrt:DI
2531           (neg:DI
2532            (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2533                     (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
2534           (const_int 32))))
2535    (clobber (match_scratch:SI 3 "=l,l"))
2536    (clobber (match_scratch:SI 4 "=a,a"))
2537    (clobber (match_scratch:SI 5 "=X,h"))]
2538   "ISA_HAS_MULHI"
2539   "@
2540    mulshiu\\t%.,%1,%2
2541    mulshiu\\t%0,%1,%2"
2542   [(set_attr "type"   "imul")
2543    (set_attr "mode"   "SI")
2544    (set_attr "length" "4")])
2546 (define_expand "smulsi3_highpart"
2547   [(set (match_operand:SI 0 "register_operand" "=h")
2548         (truncate:SI
2549          (lshiftrt:DI
2550           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2551                    (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2552          (const_int 32))))]
2553   ""
2554   "
2556   if (ISA_HAS_MULHI)
2557     emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1],
2558                                                     operands[2]));
2559   else
2560     emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1],
2561                                               operands[2]));
2562   DONE;
2565 (define_insn "smulsi3_highpart_internal"
2566   [(set (match_operand:SI 0 "register_operand" "=h")
2567         (truncate:SI
2568          (lshiftrt:DI
2569           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2570                    (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2571           (const_int 32))))
2572    (clobber (match_scratch:SI 3 "=l"))
2573    (clobber (match_scratch:SI 4 "=a"))]
2574   "!ISA_HAS_MULHI"
2575   "mult\\t%1,%2"
2576   [(set_attr "type"     "imul")
2577    (set_attr "mode"     "SI")
2578    (set_attr "length"   "4")])
2580 (define_insn "smulsi3_highpart_mulhi_internal"
2581   [(set (match_operand:SI 0 "register_operand" "=h,d")
2582         (truncate:SI
2583          (lshiftrt:DI
2584           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2585                    (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
2586           (const_int 32))))
2587    (clobber (match_scratch:SI 3 "=l,l"))
2588    (clobber (match_scratch:SI 4 "=a,a"))
2589    (clobber (match_scratch:SI 5 "=X,h"))]
2590   "ISA_HAS_MULHI"
2591   "@
2592    mult\\t%1,%2
2593    mulhi\\t%0,%1,%2"
2594   [(set_attr "type"   "imul")
2595    (set_attr "mode"   "SI")
2596    (set_attr "length" "4")])
2598 (define_insn "smulsi3_highpart_neg_mulhi_internal"
2599   [(set (match_operand:SI 0 "register_operand" "=h,d")
2600         (truncate:SI
2601          (lshiftrt:DI
2602           (neg:DI
2603            (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2604                     (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
2605           (const_int 32))))
2606    (clobber (match_scratch:SI 3 "=l,l"))
2607    (clobber (match_scratch:SI 4 "=a,a"))
2608    (clobber (match_scratch:SI 5 "=X,h"))]
2609   "ISA_HAS_MULHI"
2610   "@
2611    mulshi\\t%.,%1,%2
2612    mulshi\\t%0,%1,%2"
2613   [(set_attr "type"   "imul")
2614    (set_attr "mode"   "SI")])
2616 (define_insn "smuldi3_highpart"
2617   [(set (match_operand:DI 0 "register_operand" "=h")
2618         (truncate:DI
2619          (lshiftrt:TI
2620           (mult:TI
2621            (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
2622            (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
2623          (const_int 64))))
2624    (clobber (match_scratch:DI 3 "=l"))
2625    (clobber (match_scratch:DI 4 "=a"))]
2626   "TARGET_64BIT"
2627   "dmult\\t%1,%2"
2628   [(set_attr "type"     "imul")
2629    (set_attr "mode"     "DI")])
2631 (define_insn "umuldi3_highpart"
2632   [(set (match_operand:DI 0 "register_operand" "=h")
2633         (truncate:DI
2634          (lshiftrt:TI
2635           (mult:TI
2636            (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
2637            (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
2638           (const_int 64))))
2639    (clobber (match_scratch:DI 3 "=l"))
2640    (clobber (match_scratch:DI 4 "=a"))]
2641   "TARGET_64BIT"
2642   "dmultu\\t%1,%2"
2643   [(set_attr "type"     "imul")
2644    (set_attr "mode"     "DI")])
2647 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2648 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
2650 (define_insn "madsi"
2651   [(set (match_operand:SI 0 "register_operand" "+l")
2652         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2653                           (match_operand:SI 2 "register_operand" "d"))
2654                  (match_dup 0)))
2655    (clobber (match_scratch:SI 3 "=h"))
2656    (clobber (match_scratch:SI 4 "=a"))]
2657   "TARGET_MAD"
2658   "mad\\t%1,%2"
2659   [(set_attr "type"     "imadd")
2660    (set_attr "mode"     "SI")])
2662 ;; Only use this pattern in 32-bit code: see *muls_di.
2663 (define_insn "*umul_acc_di"
2664   [(set (match_operand:DI 0 "register_operand" "=x")
2665         (plus:DI
2666          (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2667                   (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2668          (match_operand:DI 3 "register_operand" "0")))
2669    (clobber (match_scratch:SI 4 "=a"))]
2670   "(TARGET_MAD || ISA_HAS_MACC)
2671    && !TARGET_64BIT"
2672   "*
2674   if (TARGET_MAD)
2675     return \"madu\\t%1,%2\";
2676   else if (TARGET_MIPS5500)
2677     return \"maddu\\t%1,%2\";
2678   else
2679     return \"maccu\\t%.,%1,%2\";
2681   [(set_attr "type"   "imadd")
2682    (set_attr "mode"   "SI")])
2685 (define_insn "*smul_acc_di"
2686   [(set (match_operand:DI 0 "register_operand" "=x")
2687         (plus:DI
2688          (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2689                   (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2690          (match_operand:DI 3 "register_operand" "0")))
2691    (clobber (match_scratch:SI 4 "=a"))]
2692   "(TARGET_MAD || ISA_HAS_MACC)
2693    && !TARGET_64BIT"
2694   "*
2696   if (TARGET_MAD)
2697     return \"mad\\t%1,%2\";
2698   else if (TARGET_MIPS5500)
2699     return \"madd\\t%1,%2\";
2700   else
2701     return \"macc\\t%.,%1,%2\";
2703   [(set_attr "type"   "imadd")
2704    (set_attr "mode"   "SI")])
2706 ;; Floating point multiply accumulate instructions.
2708 (define_insn ""
2709   [(set (match_operand:DF 0 "register_operand" "=f")
2710         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2711                           (match_operand:DF 2 "register_operand" "f"))
2712                  (match_operand:DF 3 "register_operand" "f")))]
2713   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2714   "madd.d\\t%0,%3,%1,%2"
2715   [(set_attr "type"     "fmadd")
2716    (set_attr "mode"     "DF")])
2718 (define_insn ""
2719   [(set (match_operand:SF 0 "register_operand" "=f")
2720         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2721                           (match_operand:SF 2 "register_operand" "f"))
2722                  (match_operand:SF 3 "register_operand" "f")))]
2723   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2724   "madd.s\\t%0,%3,%1,%2"
2725   [(set_attr "type"     "fmadd")
2726    (set_attr "mode"     "SF")])
2728 (define_insn ""
2729   [(set (match_operand:DF 0 "register_operand" "=f")
2730         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2731                            (match_operand:DF 2 "register_operand" "f"))
2732                   (match_operand:DF 3 "register_operand" "f")))]
2733   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2734   "msub.d\\t%0,%3,%1,%2"
2735   [(set_attr "type"     "fmadd")
2736    (set_attr "mode"     "DF")])
2738 (define_insn ""
2739   [(set (match_operand:SF 0 "register_operand" "=f")
2740         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2741                            (match_operand:SF 2 "register_operand" "f"))
2742                   (match_operand:SF 3 "register_operand" "f")))]
2744   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2745   "msub.s\\t%0,%3,%1,%2"
2746   [(set_attr "type"     "fmadd")
2747    (set_attr "mode"     "SF")])
2749 (define_insn ""
2750   [(set (match_operand:DF 0 "register_operand" "=f")
2751         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2752                                   (match_operand:DF 2 "register_operand" "f"))
2753                          (match_operand:DF 3 "register_operand" "f"))))]
2754   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2755   "nmadd.d\\t%0,%3,%1,%2"
2756   [(set_attr "type"     "fmadd")
2757    (set_attr "mode"     "DF")])
2759 (define_insn ""
2760   [(set (match_operand:SF 0 "register_operand" "=f")
2761         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2762                                   (match_operand:SF 2 "register_operand" "f"))
2763                          (match_operand:SF 3 "register_operand" "f"))))]
2764   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2765   "nmadd.s\\t%0,%3,%1,%2"
2766   [(set_attr "type"     "fmadd")
2767    (set_attr "mode"     "SF")])
2769 (define_insn ""
2770   [(set (match_operand:DF 0 "register_operand" "=f")
2771         (minus:DF (match_operand:DF 1 "register_operand" "f")
2772                   (mult:DF (match_operand:DF 2 "register_operand" "f")
2773                            (match_operand:DF 3 "register_operand" "f"))))]
2774   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2775   "nmsub.d\\t%0,%1,%2,%3"
2776   [(set_attr "type"     "fmadd")
2777    (set_attr "mode"     "DF")])
2779 (define_insn ""
2780   [(set (match_operand:SF 0 "register_operand" "=f")
2781         (minus:SF (match_operand:SF 1 "register_operand" "f")
2782                   (mult:SF (match_operand:SF 2 "register_operand" "f")
2783                            (match_operand:SF 3 "register_operand" "f"))))]
2784   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2785   "nmsub.s\\t%0,%1,%2,%3"
2786   [(set_attr "type"     "fmadd")
2787    (set_attr "mode"     "SF")])
2790 ;;  ....................
2792 ;;      DIVISION and REMAINDER
2794 ;;  ....................
2797 (define_insn "divdf3"
2798   [(set (match_operand:DF 0 "register_operand" "=f")
2799         (div:DF (match_operand:DF 1 "register_operand" "f")
2800                 (match_operand:DF 2 "register_operand" "f")))]
2801   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2802   "div.d\\t%0,%1,%2"
2803   [(set_attr "type"     "fdiv")
2804    (set_attr "mode"     "DF")])
2806 (define_insn "divsf3"
2807   [(set (match_operand:SF 0 "register_operand" "=f")
2808         (div:SF (match_operand:SF 1 "register_operand" "f")
2809                 (match_operand:SF 2 "register_operand" "f")))]
2810   "TARGET_HARD_FLOAT"
2811   "div.s\\t%0,%1,%2"
2812   [(set_attr "type"     "fdiv")
2813    (set_attr "mode"     "SF")])
2815 (define_insn ""
2816   [(set (match_operand:DF 0 "register_operand" "=f")
2817         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2818                 (match_operand:DF 2 "register_operand" "f")))]
2819   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2820   "recip.d\\t%0,%2"
2821   [(set_attr "type"     "fdiv")
2822    (set_attr "mode"     "DF")])
2824 (define_insn ""
2825   [(set (match_operand:SF 0 "register_operand" "=f")
2826         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2827                 (match_operand:SF 2 "register_operand" "f")))]
2828   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2829   "recip.s\\t%0,%2"
2830   [(set_attr "type"     "fdiv")
2831    (set_attr "mode"     "SF")])
2833 ;; If optimizing, prefer the divmod functions over separate div and
2834 ;; mod functions, since this will allow using one instruction for both
2835 ;; the quotient and remainder.  At present, the divmod is not moved out
2836 ;; of loops if it is constant within the loop, so allow -mdebugc to
2837 ;; use the old method of doing things.
2839 ;; 64 is the multiply/divide hi register
2840 ;; 65 is the multiply/divide lo register
2842 ;; ??? We can't accept constants here, because the MIPS assembler will replace
2843 ;; a divide by power of 2 with a shift, and then the remainder is no longer
2844 ;; available.
2846 (define_expand "divmodsi4"
2847   [(set (match_operand:SI 0 "register_operand" "=d")
2848         (div:SI (match_operand:SI 1 "register_operand" "d")
2849                 (match_operand:SI 2 "register_operand" "d")))
2850    (set (match_operand:SI 3 "register_operand" "=d")
2851         (mod:SI (match_dup 1)
2852                 (match_dup 2)))
2853    (clobber (match_scratch:SI 4 "=l"))
2854    (clobber (match_scratch:SI 5 "=h"))
2855    (clobber (match_scratch:SI 6 "=a"))]
2856   "optimize"
2857   "
2859   emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
2860              operands[3]));
2861   if (!TARGET_NO_CHECK_ZERO_DIV)
2862     {
2863       emit_insn (gen_div_trap (operands[2],
2864                                GEN_INT (0),
2865                                GEN_INT (0x7)));
2866     }
2867   if (TARGET_CHECK_RANGE_DIV)
2868     {
2869       emit_insn (gen_div_trap (operands[2],
2870                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2871                                GEN_INT (0x6)));
2872       emit_insn (gen_div_trap (operands[2],
2873                                copy_to_mode_reg (SImode,
2874                                                  GEN_INT
2875                                                  (trunc_int_for_mode
2876                                                   (BITMASK_HIGH, SImode))),
2877                                GEN_INT (0x6)));
2878     }
2880   DONE;
2883 (define_insn "divmodsi4_internal"
2884   [(set (match_operand:SI 0 "register_operand" "=l")
2885         (div:SI (match_operand:SI 1 "register_operand" "d")
2886                 (match_operand:SI 2 "register_operand" "d")))
2887    (set (match_operand:SI 3 "register_operand" "=h")
2888         (mod:SI (match_dup 1)
2889                 (match_dup 2)))
2890    (clobber (match_scratch:SI 4 "=a"))]
2891   "optimize"
2892   "div\\t$0,%1,%2"
2893   [(set_attr "type"     "idiv")
2894    (set_attr "mode"     "SI")])
2896 (define_expand "divmoddi4"
2897   [(set (match_operand:DI 0 "register_operand" "=d")
2898         (div:DI (match_operand:DI 1 "register_operand" "d")
2899                 (match_operand:DI 2 "register_operand" "d")))
2900    (set (match_operand:DI 3 "register_operand" "=d")
2901         (mod:DI (match_dup 1)
2902                 (match_dup 2)))
2903    (clobber (match_scratch:DI 4 "=l"))
2904    (clobber (match_scratch:DI 5 "=h"))
2905    (clobber (match_scratch:DI 6 "=a"))]
2906   "TARGET_64BIT && optimize"
2907   "
2909   emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
2910              operands[3]));
2911   if (!TARGET_NO_CHECK_ZERO_DIV)
2912     {
2913       emit_insn (gen_div_trap (operands[2],
2914                                GEN_INT (0),
2915                                GEN_INT (0x7)));
2916     }
2917   if (TARGET_CHECK_RANGE_DIV)
2918     {
2919       emit_insn (gen_div_trap (operands[2],
2920                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2921                                GEN_INT (0x6)));
2922       emit_insn (gen_div_trap (operands[2],
2923                                copy_to_mode_reg (DImode,
2924                                                  GEN_INT (BITMASK_HIGH)),
2925                                GEN_INT (0x6)));
2926     }
2928   DONE;
2931 (define_insn "divmoddi4_internal"
2932   [(set (match_operand:DI 0 "register_operand" "=l")
2933         (div:DI (match_operand:DI 1 "register_operand" "d")
2934                 (match_operand:DI 2 "register_operand" "d")))
2935    (set (match_operand:DI 3 "register_operand" "=h")
2936         (mod:DI (match_dup 1)
2937                 (match_dup 2)))
2938    (clobber (match_scratch:DI 4 "=a"))]
2939   "TARGET_64BIT && optimize"
2940   "ddiv\\t$0,%1,%2"
2941   [(set_attr "type"     "idiv")
2942    (set_attr "mode"     "SI")])
2944 (define_expand "udivmodsi4"
2945   [(set (match_operand:SI 0 "register_operand" "=d")
2946         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2947                  (match_operand:SI 2 "register_operand" "d")))
2948    (set (match_operand:SI 3 "register_operand" "=d")
2949         (umod:SI (match_dup 1)
2950                  (match_dup 2)))
2951    (clobber (match_scratch:SI 4 "=l"))
2952    (clobber (match_scratch:SI 5 "=h"))
2953    (clobber (match_scratch:SI 6 "=a"))]
2954   "optimize"
2955   "
2957   emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
2958                                       operands[3]));
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     }
2966   DONE;
2969 (define_insn "udivmodsi4_internal"
2970   [(set (match_operand:SI 0 "register_operand" "=l")
2971         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2972                  (match_operand:SI 2 "register_operand" "d")))
2973    (set (match_operand:SI 3 "register_operand" "=h")
2974         (umod:SI (match_dup 1)
2975                  (match_dup 2)))
2976    (clobber (match_scratch:SI 4 "=a"))]
2977   "optimize"
2978   "divu\\t$0,%1,%2"
2979   [(set_attr "type"     "idiv")
2980    (set_attr "mode"     "SI")])
2982 (define_expand "udivmoddi4"
2983   [(set (match_operand:DI 0 "register_operand" "=d")
2984         (udiv:DI (match_operand:DI 1 "register_operand" "d")
2985                  (match_operand:DI 2 "register_operand" "d")))
2986    (set (match_operand:DI 3 "register_operand" "=d")
2987         (umod:DI (match_dup 1)
2988                  (match_dup 2)))
2989    (clobber (match_scratch:DI 4 "=l"))
2990    (clobber (match_scratch:DI 5 "=h"))
2991    (clobber (match_scratch:DI 6 "=a"))]
2992   "TARGET_64BIT && optimize"
2993   "
2995   emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
2996                                       operands[3]));
2997   if (!TARGET_NO_CHECK_ZERO_DIV)
2998     {
2999       emit_insn (gen_div_trap (operands[2],
3000                                GEN_INT (0),
3001                                GEN_INT (0x7)));
3002     }
3004   DONE;
3007 (define_insn "udivmoddi4_internal"
3008   [(set (match_operand:DI 0 "register_operand" "=l")
3009         (udiv:DI (match_operand:DI 1 "register_operand" "d")
3010                  (match_operand:DI 2 "register_operand" "d")))
3011    (set (match_operand:DI 3 "register_operand" "=h")
3012         (umod:DI (match_dup 1)
3013                  (match_dup 2)))
3014    (clobber (match_scratch:DI 4 "=a"))]
3015   "TARGET_64BIT && optimize"
3016   "ddivu\\t$0,%1,%2"
3017   [(set_attr "type"     "idiv")
3018    (set_attr "mode"     "SI")])
3020 ;; Division trap
3022 (define_expand "div_trap"
3023   [(trap_if (eq (match_operand 0 "register_operand" "d")
3024                 (match_operand 1 "true_reg_or_0_operand" "dJ"))
3025             (match_operand 2 "immediate_operand" ""))]
3026   ""
3027   "
3029   if (TARGET_MIPS16)
3030     emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
3031   else
3032     emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
3033   DONE;
3036 (define_insn "div_trap_normal"
3037   [(trap_if (eq (match_operand 0 "register_operand" "d,d")
3038                 (match_operand 1 "true_reg_or_0_operand" "d,J"))
3039             (match_operand 2 "immediate_operand" ""))]
3040   "!TARGET_MIPS16"
3041   "*
3043   rtx link;
3044   int have_dep_anti = 0;
3046   /* For divmod if one division is not needed then we don't need an extra
3047      divide by zero trap, which is anti dependent on previous trap */
3048   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
3050     if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
3051         && GET_CODE (XEXP (link, 0)) == INSN
3052         && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
3053         && which_alternative == 1)
3054       have_dep_anti = 1;
3055   if (! have_dep_anti)
3056     {
3057       if (GENERATE_BRANCHLIKELY)
3058         {
3059           if (which_alternative == 1)
3060             return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
3061           else
3062             return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
3063         }
3064       else
3065         {
3066           if (which_alternative == 1)
3067             return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
3068           else
3069             return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
3070         }
3071     }
3072   return \"\";
3074   [(set_attr "type" "unknown")
3075    (set_attr "length" "12")])
3078 ;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
3080 (define_insn "div_trap_mips16"
3081   [(trap_if (eq (match_operand 0 "register_operand" "d,d")
3082                 (match_operand 1 "true_reg_or_0_operand" "d,J"))
3083             (match_operand 2 "immediate_operand" ""))
3084    (clobber (reg:SI 24))]
3085   "TARGET_MIPS16"
3086   "*
3088   rtx link;
3089   int have_dep_anti = 0;
3091   /* For divmod if one division is not needed then we don't need an extra
3092      divide by zero trap, which is anti dependent on previous trap */
3093   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
3095     if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
3096         && GET_CODE (XEXP (link, 0)) == INSN
3097         && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
3098         && which_alternative == 1)
3099       have_dep_anti = 1;
3100   if (! have_dep_anti)
3101     {
3102       /* No branch delay slots on mips16.  */
3103       if (which_alternative == 1)
3104         return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
3105       else
3106         return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
3107     }
3108   return \"\";
3110   [(set_attr "type" "unknown")
3111    (set_attr "length" "12")])
3113 (define_expand "divsi3"
3114   [(set (match_operand:SI 0 "register_operand" "=l")
3115         (div:SI (match_operand:SI 1 "register_operand" "d")
3116                 (match_operand:SI 2 "register_operand" "d")))
3117    (clobber (match_scratch:SI 3 "=h"))
3118    (clobber (match_scratch:SI 4 "=a"))]
3119   "!optimize"
3120   "
3122   emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
3124   if (!TARGET_NO_CHECK_ZERO_DIV)
3125     {
3126       emit_insn (gen_div_trap (operands[2],
3127                                GEN_INT (0),
3128                                GEN_INT (0x7)));
3129     }
3130   if (TARGET_CHECK_RANGE_DIV)
3131     {
3132       emit_insn (gen_div_trap (operands[2],
3133                                copy_to_mode_reg (SImode, GEN_INT (-1)),
3134                                GEN_INT (0x6)));
3135       emit_insn (gen_div_trap (operands[2],
3136                                copy_to_mode_reg (SImode,
3137                                                  GEN_INT
3138                                                  (trunc_int_for_mode
3139                                                   (BITMASK_HIGH, SImode))),
3140                                GEN_INT (0x6)));
3141     }
3143   DONE;
3146 (define_insn "divsi3_internal"
3147   [(set (match_operand:SI 0 "register_operand" "=l")
3148         (div:SI (match_operand:SI 1 "register_operand" "d")
3149                 (match_operand:SI 2 "nonmemory_operand" "di")))
3150    (clobber (match_scratch:SI 3 "=h"))
3151    (clobber (match_scratch:SI 4 "=a"))]
3152   "!optimize"
3153   "div\\t$0,%1,%2"
3154   [(set_attr "type"     "idiv")
3155    (set_attr "mode"     "SI")])
3157 (define_expand "divdi3"
3158   [(set (match_operand:DI 0 "register_operand" "=l")
3159         (div:DI (match_operand:DI 1 "register_operand" "d")
3160                 (match_operand:DI 2 "register_operand" "d")))
3161    (clobber (match_scratch:DI 3 "=h"))
3162    (clobber (match_scratch:DI 4 "=a"))]
3163   "TARGET_64BIT && !optimize"
3164   "
3166   emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
3167   if (!TARGET_NO_CHECK_ZERO_DIV)
3168     {
3169       emit_insn (gen_div_trap (operands[2],
3170                                GEN_INT (0),
3171                                GEN_INT (0x7)));
3172     }
3173   if (TARGET_CHECK_RANGE_DIV)
3174     {
3175       emit_insn (gen_div_trap (operands[2],
3176                                copy_to_mode_reg (DImode, GEN_INT (-1)),
3177                                GEN_INT (0x6)));
3178       emit_insn (gen_div_trap (operands[2],
3179                                copy_to_mode_reg (DImode,
3180                                                  GEN_INT (BITMASK_HIGH)),
3181                                GEN_INT (0x6)));
3182     }
3184   DONE;
3187 (define_insn "divdi3_internal"
3188   [(set (match_operand:DI 0 "register_operand" "=l")
3189         (div:DI (match_operand:DI 1 "register_operand" "d")
3190                 (match_operand:DI 2 "nonmemory_operand" "di")))
3191    (clobber (match_scratch:SI 3 "=h"))
3192    (clobber (match_scratch:SI 4 "=a"))]
3193   "TARGET_64BIT && !optimize"
3194   "ddiv\\t$0,%1,%2"
3195   [(set_attr "type"     "idiv")
3196    (set_attr "mode"     "DI")])
3198 (define_expand "modsi3"
3199   [(set (match_operand:SI 0 "register_operand" "=h")
3200         (mod:SI (match_operand:SI 1 "register_operand" "d")
3201                 (match_operand:SI 2 "register_operand" "d")))
3202    (clobber (match_scratch:SI 3 "=l"))
3203    (clobber (match_scratch:SI 4 "=a"))]
3204   "!optimize"
3205   "
3207   emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
3208   if (!TARGET_NO_CHECK_ZERO_DIV)
3209     {
3210       emit_insn (gen_div_trap (operands[2],
3211                                GEN_INT (0),
3212                                GEN_INT (0x7)));
3213     }
3214   if (TARGET_CHECK_RANGE_DIV)
3215     {
3216       emit_insn (gen_div_trap (operands[2],
3217                                copy_to_mode_reg (SImode, GEN_INT (-1)),
3218                                GEN_INT (0x6)));
3219       emit_insn (gen_div_trap (operands[2],
3220                                copy_to_mode_reg (SImode,
3221                                                  GEN_INT
3222                                                  (trunc_int_for_mode
3223                                                   (BITMASK_HIGH, SImode))),
3224                                GEN_INT (0x6)));
3225     }
3227   DONE;
3230 (define_insn "modsi3_internal"
3231   [(set (match_operand:SI 0 "register_operand" "=h")
3232         (mod:SI (match_operand:SI 1 "register_operand" "d")
3233                 (match_operand:SI 2 "nonmemory_operand" "di")))
3234    (clobber (match_scratch:SI 3 "=l"))
3235    (clobber (match_scratch:SI 4 "=a"))]
3236   "!optimize"
3237   "div\\t$0,%1,%2"
3238   [(set_attr "type"     "idiv")
3239    (set_attr "mode"     "SI")])
3241 (define_expand "moddi3"
3242   [(set (match_operand:DI 0 "register_operand" "=h")
3243         (mod:DI (match_operand:DI 1 "register_operand" "d")
3244                 (match_operand:DI 2 "register_operand" "d")))
3245    (clobber (match_scratch:DI 3 "=l"))
3246    (clobber (match_scratch:DI 4 "=a"))]
3247   "TARGET_64BIT && !optimize"
3248   "
3250   emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
3251   if (!TARGET_NO_CHECK_ZERO_DIV)
3252     {
3253       emit_insn (gen_div_trap (operands[2],
3254                                GEN_INT (0),
3255                                GEN_INT (0x7)));
3256     }
3257   if (TARGET_CHECK_RANGE_DIV)
3258     {
3259       emit_insn (gen_div_trap (operands[2],
3260                                copy_to_mode_reg (DImode, GEN_INT (-1)),
3261                                GEN_INT (0x6)));
3262       emit_insn (gen_div_trap (operands[2],
3263                                copy_to_mode_reg (DImode,
3264                                                  GEN_INT (BITMASK_HIGH)),
3265                                GEN_INT (0x6)));
3266     }
3268   DONE;
3271 (define_insn "moddi3_internal"
3272   [(set (match_operand:DI 0 "register_operand" "=h")
3273         (mod:DI (match_operand:DI 1 "register_operand" "d")
3274                 (match_operand:DI 2 "nonmemory_operand" "di")))
3275    (clobber (match_scratch:SI 3 "=l"))
3276    (clobber (match_scratch:SI 4 "=a"))]
3277   "TARGET_64BIT && !optimize"
3278   "ddiv\\t$0,%1,%2"
3279   [(set_attr "type"     "idiv")
3280    (set_attr "mode"     "DI")])
3282 (define_expand "udivsi3"
3283   [(set (match_operand:SI 0 "register_operand" "=l")
3284         (udiv:SI (match_operand:SI 1 "register_operand" "d")
3285                  (match_operand:SI 2 "register_operand" "d")))
3286    (clobber (match_scratch:SI 3 "=h"))
3287    (clobber (match_scratch:SI 4 "=a"))]
3288   "!optimize"
3289   "
3291   emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
3292   if (!TARGET_NO_CHECK_ZERO_DIV)
3293     {
3294       emit_insn (gen_div_trap (operands[2],
3295                                GEN_INT (0),
3296                                GEN_INT (0x7)));
3297     }
3299   DONE;
3302 (define_insn "udivsi3_internal"
3303   [(set (match_operand:SI 0 "register_operand" "=l")
3304         (udiv:SI (match_operand:SI 1 "register_operand" "d")
3305                  (match_operand:SI 2 "nonmemory_operand" "di")))
3306    (clobber (match_scratch:SI 3 "=h"))
3307    (clobber (match_scratch:SI 4 "=a"))]
3308   "!optimize"
3309   "divu\\t$0,%1,%2"
3310   [(set_attr "type"     "idiv")
3311    (set_attr "mode"     "SI")])
3313 (define_expand "udivdi3"
3314   [(set (match_operand:DI 0 "register_operand" "=l")
3315         (udiv:DI (match_operand:DI 1 "register_operand" "d")
3316                  (match_operand:DI 2 "register_operand" "di")))
3317    (clobber (match_scratch:DI 3 "=h"))
3318    (clobber (match_scratch:DI 4 "=a"))]
3319   "TARGET_64BIT && !optimize"
3320   "
3322   emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
3323   if (!TARGET_NO_CHECK_ZERO_DIV)
3324     {
3325       emit_insn (gen_div_trap (operands[2],
3326                                GEN_INT (0),
3327                                GEN_INT (0x7)));
3328     }
3330   DONE;
3333 (define_insn "udivdi3_internal"
3334   [(set (match_operand:DI 0 "register_operand" "=l")
3335         (udiv:DI (match_operand:DI 1 "register_operand" "d")
3336                  (match_operand:DI 2 "nonmemory_operand" "di")))
3337    (clobber (match_scratch:SI 3 "=h"))
3338    (clobber (match_scratch:SI 4 "=a"))]
3339   "TARGET_64BIT && !optimize"
3340   "ddivu\\t$0,%1,%2"
3341   [(set_attr "type"     "idiv")
3342    (set_attr "mode"     "DI")])
3344 (define_expand "umodsi3"
3345   [(set (match_operand:SI 0 "register_operand" "=h")
3346         (umod:SI (match_operand:SI 1 "register_operand" "d")
3347                  (match_operand:SI 2 "register_operand" "d")))
3348    (clobber (match_scratch:SI 3 "=l"))
3349    (clobber (match_scratch:SI 4 "=a"))]
3350   "!optimize"
3351   "
3353   emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
3354   if (!TARGET_NO_CHECK_ZERO_DIV)
3355     {
3356       emit_insn (gen_div_trap (operands[2],
3357                                GEN_INT (0),
3358                                GEN_INT (0x7)));
3359     }
3361   DONE;
3364 (define_insn "umodsi3_internal"
3365   [(set (match_operand:SI 0 "register_operand" "=h")
3366         (umod:SI (match_operand:SI 1 "register_operand" "d")
3367                  (match_operand:SI 2 "nonmemory_operand" "di")))
3368    (clobber (match_scratch:SI 3 "=l"))
3369    (clobber (match_scratch:SI 4 "=a"))]
3370   "!optimize"
3371   "divu\\t$0,%1,%2"
3372   [(set_attr "type"     "idiv")
3373    (set_attr "mode"     "SI")])
3375 (define_expand "umoddi3"
3376   [(set (match_operand:DI 0 "register_operand" "=h")
3377         (umod:DI (match_operand:DI 1 "register_operand" "d")
3378                  (match_operand:DI 2 "register_operand" "di")))
3379    (clobber (match_scratch:DI 3 "=l"))
3380    (clobber (match_scratch:DI 4 "=a"))]
3381   "TARGET_64BIT && !optimize"
3382   "
3384   emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
3385   if (!TARGET_NO_CHECK_ZERO_DIV)
3386     {
3387       emit_insn (gen_div_trap (operands[2],
3388                                GEN_INT (0),
3389                                GEN_INT (0x7)));
3390     }
3392   DONE;
3395 (define_insn "umoddi3_internal"
3396   [(set (match_operand:DI 0 "register_operand" "=h")
3397         (umod:DI (match_operand:DI 1 "register_operand" "d")
3398                  (match_operand:DI 2 "nonmemory_operand" "di")))
3399    (clobber (match_scratch:SI 3 "=l"))
3400    (clobber (match_scratch:SI 4 "=a"))]
3401   "TARGET_64BIT && !optimize"
3402   "ddivu\\t$0,%1,%2"
3403   [(set_attr "type"     "idiv")
3404    (set_attr "mode"     "DI")])
3407 ;;  ....................
3409 ;;      SQUARE ROOT
3411 ;;  ....................
3413 (define_insn "sqrtdf2"
3414   [(set (match_operand:DF 0 "register_operand" "=f")
3415         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
3416   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
3417   "sqrt.d\\t%0,%1"
3418   [(set_attr "type"     "fsqrt")
3419    (set_attr "mode"     "DF")])
3421 (define_insn "sqrtsf2"
3422   [(set (match_operand:SF 0 "register_operand" "=f")
3423         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
3424   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
3425   "sqrt.s\\t%0,%1"
3426   [(set_attr "type"     "fsqrt")
3427    (set_attr "mode"     "SF")])
3429 (define_insn ""
3430   [(set (match_operand:DF 0 "register_operand" "=f")
3431         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
3432                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
3433   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
3434   "rsqrt.d\\t%0,%2"
3435   [(set_attr "type"     "frsqrt")
3436    (set_attr "mode"     "DF")])
3438 (define_insn ""
3439   [(set (match_operand:SF 0 "register_operand" "=f")
3440         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
3441                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
3442   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
3443   "rsqrt.s\\t%0,%2"
3444   [(set_attr "type"     "frsqrt")
3445    (set_attr "mode"     "SF")])
3449 ;;  ....................
3451 ;;      ABSOLUTE VALUE
3453 ;;  ....................
3455 ;; Do not use the integer abs macro instruction, since that signals an
3456 ;; exception on -2147483648 (sigh).
3458 (define_insn "abssi2"
3459   [(set (match_operand:SI 0 "register_operand" "=d")
3460         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
3461   "!TARGET_MIPS16"
3462   "*
3464   operands[2] = const0_rtx;
3466   if (REGNO (operands[0]) == REGNO (operands[1]))
3467     {
3468       if (GENERATE_BRANCHLIKELY)
3469         return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
3470       else
3471         return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
3472     }
3473   else
3474     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
3476   [(set_attr "type"     "multi")
3477    (set_attr "mode"     "SI")
3478    (set_attr "length"   "12")])
3480 (define_insn "absdi2"
3481   [(set (match_operand:DI 0 "register_operand" "=d")
3482         (abs:DI (match_operand:DI 1 "register_operand" "d")))]
3483   "TARGET_64BIT && !TARGET_MIPS16"
3484   "*
3486   unsigned int regno1;
3487   operands[2] = const0_rtx;
3489   if (GET_CODE (operands[1]) == REG)
3490     regno1 = REGNO (operands[1]);
3491   else
3492     regno1 = REGNO (XEXP (operands[1], 0));
3494   if (REGNO (operands[0]) == regno1)
3495     return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3496   else
3497     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3499   [(set_attr "type"     "multi")
3500    (set_attr "mode"     "DI")
3501    (set_attr "length"   "12")])
3503 (define_insn "absdf2"
3504   [(set (match_operand:DF 0 "register_operand" "=f")
3505         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
3506   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3507   "abs.d\\t%0,%1"
3508   [(set_attr "type"     "fabs")
3509    (set_attr "mode"     "DF")])
3511 (define_insn "abssf2"
3512   [(set (match_operand:SF 0 "register_operand" "=f")
3513         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
3514   "TARGET_HARD_FLOAT"
3515   "abs.s\\t%0,%1"
3516   [(set_attr "type"     "fabs")
3517    (set_attr "mode"     "SF")])
3521 ;;  ....................
3523 ;;      FIND FIRST BIT INSTRUCTION
3525 ;;  ....................
3528 (define_insn "ffssi2"
3529   [(set (match_operand:SI 0 "register_operand" "=&d")
3530         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
3531    (clobber (match_scratch:SI 2 "=&d"))
3532    (clobber (match_scratch:SI 3 "=&d"))]
3533   "!TARGET_MIPS16"
3534   "*
3536   operands[4] = const0_rtx;
3538   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3539     return \"%(\\
3540 move\\t%0,%z4\\n\\
3541 \\tbeq\\t%1,%z4,2f\\n\\
3542 %~1:\\tand\\t%2,%1,0x0001\\n\\
3543 \\taddu\\t%0,%0,1\\n\\
3544 \\tbeq\\t%2,%z4,1b\\n\\
3545 \\tsrl\\t%1,%1,1\\n\\
3546 %~2:%)\";
3548   return \"%(\\
3549 move\\t%0,%z4\\n\\
3550 \\tmove\\t%3,%1\\n\\
3551 \\tbeq\\t%3,%z4,2f\\n\\
3552 %~1:\\tand\\t%2,%3,0x0001\\n\\
3553 \\taddu\\t%0,%0,1\\n\\
3554 \\tbeq\\t%2,%z4,1b\\n\\
3555 \\tsrl\\t%3,%3,1\\n\\
3556 %~2:%)\";
3558   [(set_attr "type"     "multi")
3559    (set_attr "mode"     "SI")
3560    (set_attr "length"   "12")])
3562 (define_insn "ffsdi2"
3563   [(set (match_operand:DI 0 "register_operand" "=&d")
3564         (ffs:DI (match_operand:DI 1 "register_operand" "d")))
3565    (clobber (match_scratch:DI 2 "=&d"))
3566    (clobber (match_scratch:DI 3 "=&d"))]
3567   "TARGET_64BIT && !TARGET_MIPS16"
3568   "*
3570   operands[4] = const0_rtx;
3572   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3573     return \"%(\\
3574 move\\t%0,%z4\\n\\
3575 \\tbeq\\t%1,%z4,2f\\n\\
3576 %~1:\\tand\\t%2,%1,0x0001\\n\\
3577 \\tdaddu\\t%0,%0,1\\n\\
3578 \\tbeq\\t%2,%z4,1b\\n\\
3579 \\tdsrl\\t%1,%1,1\\n\\
3580 %~2:%)\";
3582   return \"%(\\
3583 move\\t%0,%z4\\n\\
3584 \\tmove\\t%3,%1\\n\\
3585 \\tbeq\\t%3,%z4,2f\\n\\
3586 %~1:\\tand\\t%2,%3,0x0001\\n\\
3587 \\tdaddu\\t%0,%0,1\\n\\
3588 \\tbeq\\t%2,%z4,1b\\n\\
3589 \\tdsrl\\t%3,%3,1\\n\\
3590 %~2:%)\";
3592   [(set_attr "type"     "multi")
3593    (set_attr "mode"     "DI")
3594    (set_attr "length"   "24")])
3599 ;;  ...................
3601 ;;  Count leading zeroes.
3603 ;;  ...................
3606 (define_insn "clzsi2"
3607   [(set (match_operand:SI 0 "register_operand" "=d")
3608         (clz:SI (match_operand:SI 1 "register_operand" "d")))]
3609   "ISA_HAS_CLZ_CLO"
3610   "clz\\t%0,%1"
3611   [(set_attr "type" "arith")
3612    (set_attr "mode" "SI")])
3614 (define_insn "clzdi2"
3615   [(set (match_operand:DI 0 "register_operand" "=d")
3616         (clz:DI (match_operand:DI 1 "register_operand" "d")))]
3617   "ISA_HAS_DCLZ_DCLO"
3618   "dclz\\t%0,%1"
3619   [(set_attr "type" "arith")
3620    (set_attr "mode" "DI")])
3623 ;;  ....................
3625 ;;      NEGATION and ONE'S COMPLEMENT
3627 ;;  ....................
3629 (define_insn "negsi2"
3630   [(set (match_operand:SI 0 "register_operand" "=d")
3631         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
3632   ""
3633   "*
3635   if (TARGET_MIPS16)
3636     return \"neg\\t%0,%1\";
3637   operands[2] = const0_rtx;
3638   return \"subu\\t%0,%z2,%1\";
3640   [(set_attr "type"     "arith")
3641    (set_attr "mode"     "SI")])
3643 (define_expand "negdi2"
3644   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
3645                    (neg:DI (match_operand:DI 1 "register_operand" "d")))
3646               (clobber (match_dup 2))])]
3647   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3648   "
3650   if (TARGET_64BIT)
3651     {
3652       emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
3653       DONE;
3654     }
3656   operands[2] = gen_reg_rtx (SImode);
3659 (define_insn "negdi2_internal"
3660   [(set (match_operand:DI 0 "register_operand" "=d")
3661         (neg:DI (match_operand:DI 1 "register_operand" "d")))
3662    (clobber (match_operand:SI 2 "register_operand" "=d"))]
3663   "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
3664   "*
3666   operands[3] = const0_rtx;
3667   return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
3669   [(set_attr "type"     "darith")
3670    (set_attr "mode"     "DI")
3671    (set_attr "length"   "16")])
3673 (define_insn "negdi2_internal_2"
3674   [(set (match_operand:DI 0 "register_operand" "=d")
3675         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
3676   "TARGET_64BIT && !TARGET_MIPS16"
3677   "*
3679   operands[2] = const0_rtx;
3680   return \"dsubu\\t%0,%z2,%1\";
3682   [(set_attr "type"     "arith")
3683    (set_attr "mode"     "DI")])
3685 (define_insn "negdf2"
3686   [(set (match_operand:DF 0 "register_operand" "=f")
3687         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3688   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3689   "neg.d\\t%0,%1"
3690   [(set_attr "type"     "fneg")
3691    (set_attr "mode"     "DF")])
3693 (define_insn "negsf2"
3694   [(set (match_operand:SF 0 "register_operand" "=f")
3695         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3696   "TARGET_HARD_FLOAT"
3697   "neg.s\\t%0,%1"
3698   [(set_attr "type"     "fneg")
3699    (set_attr "mode"     "SF")])
3701 (define_insn "one_cmplsi2"
3702   [(set (match_operand:SI 0 "register_operand" "=d")
3703         (not:SI (match_operand:SI 1 "register_operand" "d")))]
3704   ""
3705   "*
3707   if (TARGET_MIPS16)
3708     return \"not\\t%0,%1\";
3709   operands[2] = const0_rtx;
3710   return \"nor\\t%0,%z2,%1\";
3712   [(set_attr "type"     "arith")
3713    (set_attr "mode"     "SI")])
3715 (define_insn "one_cmpldi2"
3716   [(set (match_operand:DI 0 "register_operand" "=d")
3717         (not:DI (match_operand:DI 1 "register_operand" "d")))]
3718   "TARGET_64BIT"
3719   "*
3721   if (TARGET_MIPS16)
3722     return \"not\\t%0,%1\";
3723   return \"nor\\t%0,%.,%1\";
3725   [(set_attr "type"     "darith")
3726    (set_attr "mode"     "DI")])
3729 ;;  ....................
3731 ;;      LOGICAL
3733 ;;  ....................
3736 ;; Many of these instructions uses trivial define_expands, because we
3737 ;; want to use a different set of constraints when TARGET_MIPS16.
3739 (define_expand "andsi3"
3740   [(set (match_operand:SI 0 "register_operand" "=d,d")
3741         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3742                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3743   ""
3744   "
3746   if (TARGET_MIPS16)
3747     {
3748       operands[1] = force_reg (SImode, operands[1]);
3749       operands[2] = force_reg (SImode, operands[2]);
3750     }
3753 (define_insn ""
3754   [(set (match_operand:SI 0 "register_operand" "=d,d")
3755         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3756                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3757   "!TARGET_MIPS16"
3758   "@
3759    and\\t%0,%1,%2
3760    andi\\t%0,%1,%x2"
3761   [(set_attr "type"     "arith")
3762    (set_attr "mode"     "SI")])
3764 (define_insn ""
3765   [(set (match_operand:SI 0 "register_operand" "=d")
3766         (and:SI (match_operand:SI 1 "register_operand" "%0")
3767                 (match_operand:SI 2 "register_operand" "d")))]
3768   "TARGET_MIPS16"
3769   "and\\t%0,%2"
3770   [(set_attr "type"     "arith")
3771    (set_attr "mode"     "SI")])
3773 (define_expand "anddi3"
3774   [(set (match_operand:DI 0 "register_operand" "")
3775         (and:DI (match_operand:DI 1 "register_operand" "")
3776                 (match_operand:DI 2 "uns_arith_operand" "")))]
3777   "TARGET_64BIT"
3778   "
3780   if (TARGET_MIPS16)
3781     {
3782       operands[1] = force_reg (DImode, operands[1]);
3783       operands[2] = force_reg (DImode, operands[2]);
3784     }
3787 (define_insn ""
3788   [(set (match_operand:DI 0 "register_operand" "=d,d")
3789         (and:DI (match_operand:DI 1 "register_operand" "d,d")
3790                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
3791   "TARGET_64BIT && !TARGET_MIPS16"
3792   "@
3793    and\\t%0,%1,%2
3794    andi\\t%0,%1,%x2"
3795   [(set_attr "type"     "darith")
3796    (set_attr "mode"     "DI")])
3798 (define_insn ""
3799   [(set (match_operand:DI 0 "register_operand" "=d")
3800         (and:DI (match_operand:DI 1 "register_operand" "0")
3801                 (match_operand:DI 2 "register_operand" "d")))]
3802   "TARGET_64BIT && TARGET_MIPS16"
3803   "and\\t%0,%2"
3804   [(set_attr "type"     "darith")
3805    (set_attr "mode"     "DI")])
3807 (define_expand "iorsi3"
3808   [(set (match_operand:SI 0 "register_operand" "=d,d")
3809         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3810                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3811   ""
3812   "
3814   if (TARGET_MIPS16)
3815     {
3816       operands[1] = force_reg (SImode, operands[1]);
3817       operands[2] = force_reg (SImode, operands[2]);
3818     }
3821 (define_insn ""
3822   [(set (match_operand:SI 0 "register_operand" "=d,d")
3823         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3824                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3825   "!TARGET_MIPS16"
3826   "@
3827    or\\t%0,%1,%2
3828    ori\\t%0,%1,%x2"
3829   [(set_attr "type"     "arith")
3830    (set_attr "mode"     "SI")])
3832 (define_insn ""
3833   [(set (match_operand:SI 0 "register_operand" "=d")
3834         (ior:SI (match_operand:SI 1 "register_operand" "%0")
3835                 (match_operand:SI 2 "register_operand" "d")))]
3836   "TARGET_MIPS16"
3837   "or\\t%0,%2"
3838   [(set_attr "type"     "arith")
3839    (set_attr "mode"     "SI")])
3841 (define_expand "iordi3"
3842   [(set (match_operand:DI 0 "register_operand" "")
3843         (ior:DI (match_operand:DI 1 "register_operand" "")
3844                 (match_operand:DI 2 "uns_arith_operand" "")))]
3845   "TARGET_64BIT"
3846   "
3848   if (TARGET_MIPS16)
3849     {
3850       operands[1] = force_reg (DImode, operands[1]);
3851       operands[2] = force_reg (DImode, operands[2]);
3852     }
3855 (define_insn ""
3856   [(set (match_operand:DI 0 "register_operand" "=d,d")
3857         (ior:DI (match_operand:DI 1 "register_operand" "d,d")
3858                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
3859   "TARGET_64BIT && !TARGET_MIPS16"
3860   "@
3861    or\t%0,%1,%2
3862    ori\t%0,%1,%x2"
3863   [(set_attr "type"     "darith")
3864    (set_attr "mode"     "DI")])
3866 (define_insn ""
3867   [(set (match_operand:DI 0 "register_operand" "=d")
3868         (ior:DI (match_operand:DI 1 "register_operand" "0")
3869                 (match_operand:DI 2 "register_operand" "d")))]
3870   "TARGET_64BIT && TARGET_MIPS16"
3871   "or\t%0,%2"
3872   [(set_attr "type"     "darith")
3873    (set_attr "mode"     "DI")])
3875 (define_expand "xorsi3"
3876   [(set (match_operand:SI 0 "register_operand" "=d,d")
3877         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3878                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3879   ""
3880   "")
3882 (define_insn ""
3883   [(set (match_operand:SI 0 "register_operand" "=d,d")
3884         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3885                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3886   "!TARGET_MIPS16"
3887   "@
3888    xor\\t%0,%1,%2
3889    xori\\t%0,%1,%x2"
3890   [(set_attr "type"     "arith")
3891    (set_attr "mode"     "SI")])
3893 (define_insn ""
3894   [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3895         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3896                 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3897   "TARGET_MIPS16"
3898   "@
3899    xor\\t%0,%2
3900    cmpi\\t%1,%2
3901    cmp\\t%1,%2"
3902   [(set_attr "type"     "arith")
3903    (set_attr "mode"     "SI")
3904    (set_attr_alternative "length"
3905                 [(const_int 4)
3906                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3907                                (const_int 4)
3908                                (const_int 8))
3909                  (const_int 4)])])
3911 (define_expand "xordi3"
3912   [(set (match_operand:DI 0 "register_operand" "")
3913         (xor:DI (match_operand:DI 1 "register_operand" "")
3914                 (match_operand:DI 2 "uns_arith_operand" "")))]
3915   "TARGET_64BIT"
3916   "
3918   if (TARGET_MIPS16)
3919     {
3920       operands[1] = force_reg (DImode, operands[1]);
3921       operands[2] = force_reg (DImode, operands[2]);
3922     }
3925 (define_insn ""
3926   [(set (match_operand:DI 0 "register_operand" "=d,d")
3927         (xor:DI (match_operand:DI 1 "register_operand" "d,d")
3928                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
3929   "TARGET_64BIT && !TARGET_MIPS16"
3930   "@
3931    xor\t%0,%1,%2
3932    xori\t%0,%1,%x2"
3933   [(set_attr "type"     "darith")
3934    (set_attr "mode"     "DI")])
3936 (define_insn ""
3937   [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3938         (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
3939                 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
3940   "TARGET_64BIT && TARGET_MIPS16"
3941   "@
3942    xor\\t%0,%2
3943    cmpi\\t%1,%2
3944    cmp\\t%1,%2"
3945   [(set_attr "type"     "arith")
3946    (set_attr "mode"     "DI")
3947    (set_attr_alternative "length"
3948                 [(const_int 4)
3949                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3950                                (const_int 4)
3951                                (const_int 8))
3952                  (const_int 4)])])
3954 (define_insn "*norsi3"
3955   [(set (match_operand:SI 0 "register_operand" "=d")
3956         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3957                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3958   "!TARGET_MIPS16"
3959   "nor\\t%0,%z1,%z2"
3960   [(set_attr "type"     "arith")
3961    (set_attr "mode"     "SI")])
3963 (define_insn "*nordi3"
3964   [(set (match_operand:DI 0 "register_operand" "=d")
3965         (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
3966                 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
3967   "TARGET_64BIT && !TARGET_MIPS16"
3968   "nor\\t%0,%z1,%z2"
3969   [(set_attr "type"     "darith")
3970    (set_attr "mode"     "DI")])
3973 ;;  ....................
3975 ;;      TRUNCATION
3977 ;;  ....................
3981 (define_insn "truncdfsf2"
3982   [(set (match_operand:SF 0 "register_operand" "=f")
3983         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3984   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3985   "cvt.s.d\\t%0,%1"
3986   [(set_attr "type"     "fcvt")
3987    (set_attr "mode"     "SF")])
3989 ;; Integer truncation patterns.  Truncating SImode values to smaller
3990 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
3991 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
3992 ;; need to make sure that the lower 32 bits are properly sign-extended
3993 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
3994 ;; smaller than SImode is equivalent to two separate truncations:
3996 ;;                        A       B
3997 ;;    DI ---> HI  ==  DI ---> SI ---> HI
3998 ;;    DI ---> QI  ==  DI ---> SI ---> QI
4000 ;; Step A needs a real instruction but step B does not.
4002 (define_insn "truncdisi2"
4003   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4004         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
4005   "TARGET_64BIT"
4006   "@
4007     sll\t%0,%1,0
4008     sw\t%1,%0"
4009   [(set_attr "type" "darith")
4010    (set_attr "mode" "SI")
4011    (set_attr "extended_mips16" "yes,*")])
4013 (define_insn "truncdihi2"
4014   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
4015         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
4016   "TARGET_64BIT"
4017   "@
4018     sll\t%0,%1,0
4019     sh\t%1,%0"
4020   [(set_attr "type" "darith")
4021    (set_attr "mode" "SI")
4022    (set_attr "extended_mips16" "yes,*")])
4024 (define_insn "truncdiqi2"
4025   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
4026         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
4027   "TARGET_64BIT"
4028   "@
4029     sll\t%0,%1,0
4030     sb\t%1,%0"
4031   [(set_attr "type" "darith")
4032    (set_attr "mode" "SI")
4033    (set_attr "extended_mips16" "yes,*")])
4035 ;; Combiner patterns to optimize shift/truncate combinations.
4037 (define_insn ""
4038   [(set (match_operand:SI 0 "register_operand" "=d")
4039         (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4040                                   (match_operand:DI 2 "small_int" "I"))))]
4041   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
4042   "dsra\\t%0,%1,%2"
4043   [(set_attr "type" "darith")
4044    (set_attr "mode" "SI")])
4046 (define_insn ""
4047   [(set (match_operand:SI 0 "register_operand" "=d")
4048         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4049                                   (const_int 32))))]
4050   "TARGET_64BIT && !TARGET_MIPS16"
4051   "dsra\\t%0,%1,32"
4052   [(set_attr "type" "darith")
4053    (set_attr "mode" "SI")])
4056 ;; Combiner patterns for truncate/sign_extend combinations.  They use
4057 ;; the shift/truncate patterns above.
4059 (define_insn_and_split ""
4060   [(set (match_operand:SI 0 "register_operand" "=d")
4061         (sign_extend:SI
4062             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
4063   "TARGET_64BIT && !TARGET_MIPS16"
4064   "#"
4065   "&& reload_completed"
4066   [(set (match_dup 2)
4067         (ashift:DI (match_dup 1)
4068                    (const_int 48)))
4069    (set (match_dup 0)
4070         (truncate:SI (ashiftrt:DI (match_dup 2)
4071                                   (const_int 48))))]
4072   { operands[2] = gen_lowpart (DImode, operands[0]); })
4074 (define_insn_and_split ""
4075   [(set (match_operand:SI 0 "register_operand" "=d")
4076         (sign_extend:SI
4077             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
4078   "TARGET_64BIT && !TARGET_MIPS16"
4079   "#"
4080   "&& reload_completed"
4081   [(set (match_dup 2)
4082         (ashift:DI (match_dup 1)
4083                    (const_int 56)))
4084    (set (match_dup 0)
4085         (truncate:SI (ashiftrt:DI (match_dup 2)
4086                                   (const_int 56))))]
4087   { operands[2] = gen_lowpart (DImode, operands[0]); })
4090 ;; Combiner patterns to optimize truncate/zero_extend combinations.
4092 (define_insn ""
4093   [(set (match_operand:SI 0 "register_operand" "=d")
4094         (zero_extend:SI (truncate:HI
4095                          (match_operand:DI 1 "register_operand" "d"))))]
4096   "TARGET_64BIT && !TARGET_MIPS16"
4097   "andi\\t%0,%1,0xffff"
4098   [(set_attr "type"     "darith")
4099    (set_attr "mode"     "SI")])
4101 (define_insn ""
4102   [(set (match_operand:SI 0 "register_operand" "=d")
4103         (zero_extend:SI (truncate:QI
4104                          (match_operand:DI 1 "register_operand" "d"))))]
4105   "TARGET_64BIT && !TARGET_MIPS16"
4106   "andi\\t%0,%1,0xff"
4107   [(set_attr "type"     "darith")
4108    (set_attr "mode"     "SI")])
4110 (define_insn ""
4111   [(set (match_operand:HI 0 "register_operand" "=d")
4112         (zero_extend:HI (truncate:QI
4113                          (match_operand:DI 1 "register_operand" "d"))))]
4114   "TARGET_64BIT && !TARGET_MIPS16"
4115   "andi\\t%0,%1,0xff"
4116   [(set_attr "type"     "darith")
4117    (set_attr "mode"     "HI")])
4121 ;;  ....................
4123 ;;      ZERO EXTENSION
4125 ;;  ....................
4127 ;; Extension insns.
4128 ;; Those for integer source operand are ordered widest source type first.
4130 (define_insn_and_split "zero_extendsidi2"
4131   [(set (match_operand:DI 0 "register_operand" "=d")
4132         (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
4133   "TARGET_64BIT"
4134   "#"
4135   "&& reload_completed"
4136   [(set (match_dup 0)
4137         (ashift:DI (match_dup 1) (const_int 32)))
4138    (set (match_dup 0)
4139         (lshiftrt:DI (match_dup 0) (const_int 32)))]
4140   "operands[1] = gen_lowpart (DImode, operands[1]);"
4141   [(set_attr "type" "arith")
4142    (set_attr "mode" "DI")])
4144 (define_insn "*zero_extendsidi2_mem"
4145   [(set (match_operand:DI 0 "register_operand" "=d")
4146         (zero_extend:DI (match_operand:SI 1 "memory_operand" "m")))]
4147   "TARGET_64BIT && !TARGET_MIPS16"
4148   "lwu\t%0,%1"
4149   [(set_attr "type"     "load")
4150    (set_attr "mode"     "DI")])
4152 (define_expand "zero_extendhisi2"
4153   [(set (match_operand:SI 0 "register_operand" "")
4154         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4155   ""
4156   "
4158   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4159     {
4160       rtx op = gen_lowpart (SImode, operands[1]);
4161       rtx temp = force_reg (SImode, GEN_INT (0xffff));
4163       emit_insn (gen_andsi3 (operands[0], op, temp));
4164       DONE;
4165     }
4168 (define_insn ""
4169   [(set (match_operand:SI 0 "register_operand" "=d,d")
4170         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
4171   "!TARGET_MIPS16"
4172   "@
4173    andi\t%0,%1,0xffff
4174    lhu\t%0,%1"
4175   [(set_attr "type"     "arith,load")
4176    (set_attr "mode"     "SI")
4177    (set_attr "length"   "4,*")])
4179 (define_insn ""
4180   [(set (match_operand:SI 0 "register_operand" "=d")
4181         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4182   "TARGET_MIPS16"
4183   "lhu\t%0,%1"
4184   [(set_attr "type"     "load")
4185    (set_attr "mode"     "SI")])
4187 (define_expand "zero_extendhidi2"
4188   [(set (match_operand:DI 0 "register_operand" "")
4189         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
4190   "TARGET_64BIT"
4191   "
4193   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4194     {
4195       rtx op = gen_lowpart (DImode, operands[1]);
4196       rtx temp = force_reg (DImode, GEN_INT (0xffff));
4198       emit_insn (gen_anddi3 (operands[0], op, temp));
4199       DONE;
4200     }
4203 (define_insn ""
4204   [(set (match_operand:DI 0 "register_operand" "=d,d")
4205         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
4206   "TARGET_64BIT && !TARGET_MIPS16"
4207   "@
4208    andi\t%0,%1,0xffff
4209    lhu\t%0,%1"
4210   [(set_attr "type"     "arith,load")
4211    (set_attr "mode"     "DI")
4212    (set_attr "length"   "4,*")])
4214 (define_insn ""
4215   [(set (match_operand:DI 0 "register_operand" "=d")
4216         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4217   "TARGET_64BIT && TARGET_MIPS16"
4218   "lhu\t%0,%1"
4219   [(set_attr "type"     "load")
4220    (set_attr "mode"     "DI")])
4222 (define_expand "zero_extendqihi2"
4223   [(set (match_operand:HI 0 "register_operand" "")
4224         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
4225   ""
4226   "
4228   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4229     {
4230       rtx op0 = gen_lowpart (SImode, operands[0]);
4231       rtx op1 = gen_lowpart (SImode, operands[1]);
4232       rtx temp = force_reg (SImode, GEN_INT (0xff));
4234       emit_insn (gen_andsi3 (op0, op1, temp));
4235       DONE;
4236     }
4239 (define_insn ""
4240   [(set (match_operand:HI 0 "register_operand" "=d,d")
4241         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
4242   "!TARGET_MIPS16"
4243   "@
4244    andi\t%0,%1,0x00ff
4245    lbu\t%0,%1"
4246   [(set_attr "type"     "arith,load")
4247    (set_attr "mode"     "HI")
4248    (set_attr "length"   "4,*")])
4250 (define_insn ""
4251   [(set (match_operand:HI 0 "register_operand" "=d")
4252         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4253   "TARGET_MIPS16"
4254   "lbu\t%0,%1"
4255   [(set_attr "type"     "load")
4256    (set_attr "mode"     "HI")])
4258 (define_expand "zero_extendqisi2"
4259   [(set (match_operand:SI 0 "register_operand" "")
4260         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4261   ""
4262   "
4264   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4265     {
4266       rtx op = gen_lowpart (SImode, operands[1]);
4267       rtx temp = force_reg (SImode, GEN_INT (0xff));
4269       emit_insn (gen_andsi3 (operands[0], op, temp));
4270       DONE;
4271     }
4274 (define_insn ""
4275   [(set (match_operand:SI 0 "register_operand" "=d,d")
4276         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
4277   "!TARGET_MIPS16"
4278   "@
4279    andi\t%0,%1,0x00ff
4280    lbu\t%0,%1"
4281   [(set_attr "type"     "arith,load")
4282    (set_attr "mode"     "SI")
4283    (set_attr "length"   "4,*")])
4285 (define_insn ""
4286   [(set (match_operand:SI 0 "register_operand" "=d")
4287         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4288   "TARGET_MIPS16"
4289   "lbu\t%0,%1"
4290   [(set_attr "type"     "load")
4291    (set_attr "mode"     "SI")])
4293 (define_expand "zero_extendqidi2"
4294   [(set (match_operand:DI 0 "register_operand" "")
4295         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4296   "TARGET_64BIT"
4297   "
4299   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4300     {
4301       rtx op = gen_lowpart (DImode, operands[1]);
4302       rtx temp = force_reg (DImode, GEN_INT (0xff));
4304       emit_insn (gen_anddi3 (operands[0], op, temp));
4305       DONE;
4306     }
4309 (define_insn ""
4310   [(set (match_operand:DI 0 "register_operand" "=d,d")
4311         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
4312   "TARGET_64BIT && !TARGET_MIPS16"
4313   "@
4314    andi\t%0,%1,0x00ff
4315    lbu\t%0,%1"
4316   [(set_attr "type"     "arith,load")
4317    (set_attr "mode"     "DI")
4318    (set_attr "length"   "4,*")])
4320 (define_insn ""
4321   [(set (match_operand:DI 0 "register_operand" "=d")
4322         (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4323   "TARGET_64BIT && TARGET_MIPS16"
4324   "lbu\t%0,%1"
4325   [(set_attr "type"     "load")
4326    (set_attr "mode"     "DI")])
4329 ;;  ....................
4331 ;;      SIGN EXTENSION
4333 ;;  ....................
4335 ;; Extension insns.
4336 ;; Those for integer source operand are ordered widest source type first.
4338 (define_expand "extendsidi2"
4339   [(set (match_operand:DI 0 "register_operand" "")
4340         (sign_extend:DI (match_operand:SI 1 "move_operand" "")))]
4341   "TARGET_64BIT"
4342   "
4344  if (symbolic_operand (operands[1], SImode))
4345    {
4346       emit_move_insn (operands[0], convert_memory_address (DImode, operands[1]));
4347       DONE;
4348    }
4352 (define_insn "*extendsidi2"
4353   [(set (match_operand:DI 0 "register_operand" "=d,d")
4354         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
4355   "TARGET_64BIT"
4356   "@
4357    sll\t%0,%1,0
4358    lw\t%0,%1"
4359   [(set_attr "type" "arith,load")
4360    (set_attr "mode" "DI")
4361    (set_attr "extended_mips16" "yes,*")])
4363 ;; These patterns originally accepted general_operands, however, slightly
4364 ;; better code is generated by only accepting register_operands, and then
4365 ;; letting combine generate the lh and lb insns.
4367 ;; These expanders originally put values in registers first. We split
4368 ;; all non-mem patterns after reload.
4370 (define_expand "extendhidi2"
4371   [(set (match_operand:DI 0 "register_operand" "")
4372         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
4373   "TARGET_64BIT"
4374   "")
4376 (define_insn "*extendhidi2"
4377   [(set (match_operand:DI 0 "register_operand" "=d")
4378         (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
4379   "TARGET_64BIT"
4380   "#")
4382 (define_split
4383   [(set (match_operand:DI 0 "register_operand" "")
4384         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4385   "TARGET_64BIT && reload_completed"
4386   [(set (match_dup 0)
4387         (ashift:DI (match_dup 1) (const_int 48)))
4388    (set (match_dup 0)
4389         (ashiftrt:DI (match_dup 0) (const_int 48)))]
4390   "operands[1] = gen_lowpart (DImode, operands[1]);")
4392 (define_insn "*extendhidi2_mem"
4393   [(set (match_operand:DI 0 "register_operand" "=d")
4394         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4395   "TARGET_64BIT"
4396   "lh\t%0,%1"
4397   [(set_attr "type"     "load")
4398    (set_attr "mode"     "DI")])
4400 (define_expand "extendhisi2"
4401   [(set (match_operand:SI 0 "register_operand" "")
4402         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4403   ""
4404   "
4405    if (ISA_HAS_SEB_SEH)
4406      {
4407         emit_insn (gen_extendhisi2_hw (operands[0],
4408                                        force_reg (HImode, operands[1])));
4409         DONE;
4410      }
4413 (define_insn "*extendhisi2"
4414   [(set (match_operand:SI 0 "register_operand" "=d")
4415         (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
4416   ""
4417   "#")
4419 (define_split
4420   [(set (match_operand:SI 0 "register_operand" "")
4421         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4422   "reload_completed"
4423   [(set (match_dup 0)
4424         (ashift:SI (match_dup 1) (const_int 16)))
4425    (set (match_dup 0)
4426         (ashiftrt:SI (match_dup 0) (const_int 16)))]
4427   "operands[1] = gen_lowpart (SImode, operands[1]);")
4429 (define_insn "extendhisi2_mem"
4430   [(set (match_operand:SI 0 "register_operand" "=d")
4431         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4432   ""
4433   "lh\t%0,%1"
4434   [(set_attr "type"     "load")
4435    (set_attr "mode"     "SI")])
4437 (define_insn "extendhisi2_hw"
4438   [(set (match_operand:SI 0 "register_operand" "=r")
4439         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
4440   "ISA_HAS_SEB_SEH"
4441   "seh\\t%0,%1"
4442   [(set_attr "type" "arith")
4443    (set_attr "mode" "SI")])
4445 (define_expand "extendqihi2"
4446   [(set (match_operand:HI 0 "register_operand" "")
4447         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
4448   ""
4449   "")
4451 (define_insn "*extendqihi2"
4452   [(set (match_operand:HI 0 "register_operand" "=d")
4453         (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
4454   ""
4455   "#")
4457 (define_split
4458   [(set (match_operand:HI 0 "register_operand" "")
4459         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4460   "reload_completed"
4461   [(set (match_dup 0)
4462         (ashift:SI (match_dup 1) (const_int 24)))
4463    (set (match_dup 0)
4464         (ashiftrt:SI (match_dup 0) (const_int 24)))]
4465   "operands[0] = gen_lowpart (SImode, operands[0]);
4466    operands[1] = gen_lowpart (SImode, operands[1]);")
4468 (define_insn "*extendqihi2_internal_mem"
4469   [(set (match_operand:HI 0 "register_operand" "=d")
4470         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4471   ""
4472   "lb\t%0,%1"
4473   [(set_attr "type"     "load")
4474    (set_attr "mode"     "SI")])
4477 (define_expand "extendqisi2"
4478   [(set (match_operand:SI 0 "register_operand" "")
4479         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4480   ""
4481   "
4482    if (ISA_HAS_SEB_SEH)
4483      {
4484        emit_insn (gen_extendqisi2_hw (operands[0],
4485                                       force_reg (QImode, operands[1])));
4486        DONE;
4487      }
4490 (define_insn "*extendqisi2"
4491   [(set (match_operand:SI 0 "register_operand" "=d")
4492         (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
4493   ""
4494   "#")
4496 (define_split
4497   [(set (match_operand:SI 0 "register_operand" "")
4498         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4499   "reload_completed"
4500   [(set (match_dup 0)
4501         (ashift:SI (match_dup 1) (const_int 24)))
4502    (set (match_dup 0)
4503         (ashiftrt:SI (match_dup 0) (const_int 24)))]
4504   "operands[1] = gen_lowpart (SImode, operands[1]);")
4506 (define_insn "*extendqisi2_mem"
4507   [(set (match_operand:SI 0 "register_operand" "=d")
4508         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4509   ""
4510   "lb\t%0,%1"
4511   [(set_attr "type"     "load")
4512    (set_attr "mode"     "SI")])
4514 (define_insn "extendqisi2_hw"
4515   [(set (match_operand:SI 0 "register_operand" "=r")
4516         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
4517   "ISA_HAS_SEB_SEH"
4518   "seb\\t%0,%1"
4519   [(set_attr "type" "arith")
4520    (set_attr "mode" "SI")])
4522 (define_expand "extendqidi2"
4523   [(set (match_operand:DI 0 "register_operand" "")
4524         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4525   "TARGET_64BIT"
4526   "")
4528 (define_insn "*extendqidi2"
4529   [(set (match_operand:DI 0 "register_operand" "=d")
4530         (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
4531   "TARGET_64BIT"
4532   "#")
4534 (define_split
4535   [(set (match_operand:DI 0 "register_operand" "")
4536         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4537   "TARGET_64BIT && reload_completed"
4538   [(set (match_dup 0)
4539         (ashift:DI (match_dup 1) (const_int 56)))
4540    (set (match_dup 0)
4541         (ashiftrt:DI (match_dup 0) (const_int 56)))]
4542   "operands[1] = gen_lowpart (DImode, operands[1]);")
4544 (define_insn "*extendqidi2_mem"
4545   [(set (match_operand:DI 0 "register_operand" "=d")
4546         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4547   "TARGET_64BIT"
4548   "lb\t%0,%1"
4549   [(set_attr "type"     "load")
4550    (set_attr "mode"     "DI")])
4552 (define_insn "extendsfdf2"
4553   [(set (match_operand:DF 0 "register_operand" "=f")
4554         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
4555   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4556   "cvt.d.s\\t%0,%1"
4557   [(set_attr "type"     "fcvt")
4558    (set_attr "mode"     "DF")])
4563 ;;  ....................
4565 ;;      CONVERSIONS
4567 ;;  ....................
4569 (define_expand "fix_truncdfsi2"
4570   [(set (match_operand:SI 0 "register_operand" "=f")
4571         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
4572   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4574   if (!ISA_HAS_TRUNC_W)
4575     {
4576       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
4577       DONE;
4578     }
4581 (define_insn "fix_truncdfsi2_insn"
4582   [(set (match_operand:SI 0 "register_operand" "=f")
4583         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
4584   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
4585   "trunc.w.d %0,%1"
4586   [(set_attr "type"     "fcvt")
4587    (set_attr "mode"     "DF")
4588    (set_attr "length"   "4")])
4590 (define_insn "fix_truncdfsi2_macro"
4591   [(set (match_operand:SI 0 "register_operand" "=f")
4592         (fix:SI (match_operand:DF 1 "register_operand" "f")))
4593    (clobber (match_scratch:DF 2 "=d"))]
4594   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
4595   "trunc.w.d %0,%1,%2"
4596   [(set_attr "type"     "fcvt")
4597    (set_attr "mode"     "DF")
4598    (set_attr "length"   "36")])
4600 (define_expand "fix_truncsfsi2"
4601   [(set (match_operand:SI 0 "register_operand" "=f")
4602         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
4603   "TARGET_HARD_FLOAT"
4605   if (!ISA_HAS_TRUNC_W)
4606     {
4607       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
4608       DONE;
4609     }
4612 (define_insn "fix_truncsfsi2_insn"
4613   [(set (match_operand:SI 0 "register_operand" "=f")
4614         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
4615   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
4616   "trunc.w.s %0,%1"
4617   [(set_attr "type"     "fcvt")
4618    (set_attr "mode"     "DF")
4619    (set_attr "length"   "4")])
4621 (define_insn "fix_truncsfsi2_macro"
4622   [(set (match_operand:SI 0 "register_operand" "=f")
4623         (fix:SI (match_operand:SF 1 "register_operand" "f")))
4624    (clobber (match_scratch:SF 2 "=d"))]
4625   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
4626   "trunc.w.s %0,%1,%2"
4627   [(set_attr "type"     "fcvt")
4628    (set_attr "mode"     "DF")
4629    (set_attr "length"   "36")])
4631 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
4632 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
4633 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
4635 ;;; Deleting this means that we now need two libgcc2.a libraries.  One for
4636 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
4638 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
4640 (define_insn "fix_truncdfdi2"
4641   [(set (match_operand:DI 0 "register_operand" "=f")
4642         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
4643   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4644   "trunc.l.d %0,%1"
4645   [(set_attr "type"     "fcvt")
4646    (set_attr "mode"     "DF")
4647    (set_attr "length"   "4")])
4650 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
4651 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
4652 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
4653 (define_insn "fix_truncsfdi2"
4654   [(set (match_operand:DI 0 "register_operand" "=f")
4655         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
4656   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4657   "trunc.l.s %0,%1"
4658   [(set_attr "type"     "fcvt")
4659    (set_attr "mode"     "SF")
4660    (set_attr "length"   "4")])
4663 (define_insn "floatsidf2"
4664   [(set (match_operand:DF 0 "register_operand" "=f")
4665         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4666   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4667   "cvt.d.w\\t%0,%1"
4668   [(set_attr "type"     "fcvt")
4669    (set_attr "mode"     "DF")
4670    (set_attr "length"   "4")])
4673 (define_insn "floatdidf2"
4674   [(set (match_operand:DF 0 "register_operand" "=f")
4675         (float:DF (match_operand:DI 1 "register_operand" "f")))]
4676   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4677   "cvt.d.l\\t%0,%1"
4678   [(set_attr "type"     "fcvt")
4679    (set_attr "mode"     "DF")
4680    (set_attr "length"   "4")])
4683 (define_insn "floatsisf2"
4684   [(set (match_operand:SF 0 "register_operand" "=f")
4685         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4686   "TARGET_HARD_FLOAT"
4687   "cvt.s.w\\t%0,%1"
4688   [(set_attr "type"     "fcvt")
4689    (set_attr "mode"     "SF")
4690    (set_attr "length"   "4")])
4693 (define_insn "floatdisf2"
4694   [(set (match_operand:SF 0 "register_operand" "=f")
4695         (float:SF (match_operand:DI 1 "register_operand" "f")))]
4696   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4697   "cvt.s.l\\t%0,%1"
4698   [(set_attr "type"     "fcvt")
4699    (set_attr "mode"     "SF")
4700    (set_attr "length"   "4")])
4703 (define_expand "fixuns_truncdfsi2"
4704   [(set (match_operand:SI 0 "register_operand" "")
4705         (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
4706   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4707   "
4709   rtx reg1 = gen_reg_rtx (DFmode);
4710   rtx reg2 = gen_reg_rtx (DFmode);
4711   rtx reg3 = gen_reg_rtx (SImode);
4712   rtx label1 = gen_label_rtx ();
4713   rtx label2 = gen_label_rtx ();
4714   REAL_VALUE_TYPE offset;
4716   real_2expN (&offset, 31);
4718   if (reg1)                     /* turn off complaints about unreached code */
4719     {
4720       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
4721       do_pending_stack_adjust ();
4723       emit_insn (gen_cmpdf (operands[1], reg1));
4724       emit_jump_insn (gen_bge (label1));
4726       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
4727       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4728                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4729       emit_barrier ();
4731       emit_label (label1);
4732       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4733       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4734                                      (BITMASK_HIGH, SImode)));
4736       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4737       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4739       emit_label (label2);
4741       /* allow REG_NOTES to be set on last insn (labels don't have enough
4742          fields, and can't be used for REG_NOTES anyway).  */
4743       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4744       DONE;
4745     }
4749 (define_expand "fixuns_truncdfdi2"
4750   [(set (match_operand:DI 0 "register_operand" "")
4751         (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
4752   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4753   "
4755   rtx reg1 = gen_reg_rtx (DFmode);
4756   rtx reg2 = gen_reg_rtx (DFmode);
4757   rtx reg3 = gen_reg_rtx (DImode);
4758   rtx label1 = gen_label_rtx ();
4759   rtx label2 = gen_label_rtx ();
4760   REAL_VALUE_TYPE offset;
4762   real_2expN (&offset, 63);
4764   if (reg1)                     /* turn off complaints about unreached code */
4765     {
4766       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
4767       do_pending_stack_adjust ();
4769       emit_insn (gen_cmpdf (operands[1], reg1));
4770       emit_jump_insn (gen_bge (label1));
4772       emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
4773       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4774                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4775       emit_barrier ();
4777       emit_label (label1);
4778       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4779       emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4780       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4782       emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4783       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4785       emit_label (label2);
4787       /* allow REG_NOTES to be set on last insn (labels don't have enough
4788          fields, and can't be used for REG_NOTES anyway).  */
4789       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4790       DONE;
4791     }
4795 (define_expand "fixuns_truncsfsi2"
4796   [(set (match_operand:SI 0 "register_operand" "")
4797         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4798   "TARGET_HARD_FLOAT"
4799   "
4801   rtx reg1 = gen_reg_rtx (SFmode);
4802   rtx reg2 = gen_reg_rtx (SFmode);
4803   rtx reg3 = gen_reg_rtx (SImode);
4804   rtx label1 = gen_label_rtx ();
4805   rtx label2 = gen_label_rtx ();
4806   REAL_VALUE_TYPE offset;
4808   real_2expN (&offset, 31);
4810   if (reg1)                     /* turn off complaints about unreached code */
4811     {
4812       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
4813       do_pending_stack_adjust ();
4815       emit_insn (gen_cmpsf (operands[1], reg1));
4816       emit_jump_insn (gen_bge (label1));
4818       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4819       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4820                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4821       emit_barrier ();
4823       emit_label (label1);
4824       emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4825       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4826                                      (BITMASK_HIGH, SImode)));
4828       emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4829       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4831       emit_label (label2);
4833       /* allow REG_NOTES to be set on last insn (labels don't have enough
4834          fields, and can't be used for REG_NOTES anyway).  */
4835       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4836       DONE;
4837     }
4841 (define_expand "fixuns_truncsfdi2"
4842   [(set (match_operand:DI 0 "register_operand" "")
4843         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4844   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4845   "
4847   rtx reg1 = gen_reg_rtx (SFmode);
4848   rtx reg2 = gen_reg_rtx (SFmode);
4849   rtx reg3 = gen_reg_rtx (DImode);
4850   rtx label1 = gen_label_rtx ();
4851   rtx label2 = gen_label_rtx ();
4852   REAL_VALUE_TYPE offset;
4854   real_2expN (&offset, 63);
4856   if (reg1)                     /* turn off complaints about unreached code */
4857     {
4858       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
4859       do_pending_stack_adjust ();
4861       emit_insn (gen_cmpsf (operands[1], reg1));
4862       emit_jump_insn (gen_bge (label1));
4864       emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4865       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4866                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
4867       emit_barrier ();
4869       emit_label (label1);
4870       emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4871       emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4872       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4874       emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4875       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4877       emit_label (label2);
4879       /* allow REG_NOTES to be set on last insn (labels don't have enough
4880          fields, and can't be used for REG_NOTES anyway).  */
4881       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4882       DONE;
4883     }
4888 ;;  ....................
4890 ;;      DATA MOVEMENT
4892 ;;  ....................
4894 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
4896 (define_expand "extv"
4897   [(set (match_operand 0 "register_operand" "")
4898         (sign_extract (match_operand:QI 1 "memory_operand" "")
4899                       (match_operand 2 "immediate_operand" "")
4900                       (match_operand 3 "immediate_operand" "")))]
4901   "!TARGET_MIPS16"
4902   {
4903     if (mips_expand_unaligned_load (operands[0], operands[1],
4904                                     INTVAL (operands[2]),
4905                                     INTVAL (operands[3])))
4906       DONE;
4907     else
4908       FAIL;
4909   })
4911 (define_expand "extzv"
4912   [(set (match_operand 0 "register_operand" "")
4913         (zero_extract (match_operand:QI 1 "memory_operand" "")
4914                       (match_operand 2 "immediate_operand" "")
4915                       (match_operand 3 "immediate_operand" "")))]
4916   "!TARGET_MIPS16"
4917   {
4918     if (mips_expand_unaligned_load (operands[0], operands[1],
4919                                     INTVAL (operands[2]),
4920                                     INTVAL (operands[3])))
4921       DONE;
4922     else
4923       FAIL;
4924   })
4926 (define_expand "insv"
4927   [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4928                       (match_operand 1 "immediate_operand" "")
4929                       (match_operand 2 "immediate_operand" ""))
4930         (match_operand 3 "reg_or_0_operand" ""))]
4931   "!TARGET_MIPS16"
4932   {
4933     if (mips_expand_unaligned_store (operands[0], operands[3],
4934                                      INTVAL (operands[1]),
4935                                      INTVAL (operands[2])))
4936       DONE;
4937     else
4938       FAIL;
4939   })
4941 ;; Unaligned word moves generated by the bit field patterns.
4943 ;; As far as the rtl is concerned, both the left-part and right-part
4944 ;; instructions can access the whole field.  However, the real operand
4945 ;; refers to just the first or the last byte (depending on endianness).
4946 ;; We therefore use two memory operands to each instruction, one to
4947 ;; describe the rtl effect and one to use in the assembly output.
4949 (define_insn "mov_lwl"
4950   [(set (match_operand:SI 0 "register_operand" "=d")
4951         (unspec:SI [(match_operand:BLK 1 "general_operand" "m")
4952                     (match_operand:QI 2 "general_operand" "m")]
4953                    UNSPEC_LWL))]
4954   "!TARGET_MIPS16"
4955   "lwl\t%0,%2"
4956   [(set_attr "type" "load")
4957    (set_attr "mode" "SI")])
4959 (define_insn "mov_lwr"
4960   [(set (match_operand:SI 0 "register_operand" "=d")
4961         (unspec:SI [(match_operand:BLK 1 "general_operand" "m")
4962                     (match_operand:QI 2 "general_operand" "m")
4963                     (match_operand:SI 3 "register_operand" "0")]
4964                    UNSPEC_LWR))]
4965   "!TARGET_MIPS16"
4966   "lwr\t%0,%2"
4967   [(set_attr "type" "load")
4968    (set_attr "mode" "SI")])
4971 (define_insn "mov_swl"
4972   [(set (match_operand:BLK 0 "memory_operand" "=m")
4973         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
4974                      (match_operand:QI 2 "general_operand" "m")]
4975                     UNSPEC_SWL))]
4976   "!TARGET_MIPS16"
4977   "swl\t%z1,%2"
4978   [(set_attr "type" "store")
4979    (set_attr "mode" "SI")])
4981 (define_insn "mov_swr"
4982   [(set (match_operand:BLK 0 "memory_operand" "+m")
4983         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
4984                      (match_operand:QI 2 "general_operand" "m")
4985                      (match_dup 0)]
4986                     UNSPEC_SWR))]
4987   "!TARGET_MIPS16"
4988   "swr\t%z1,%2"
4989   [(set_attr "type" "store")
4990    (set_attr "mode" "SI")])
4993 (define_insn "mov_ldl"
4994   [(set (match_operand:DI 0 "register_operand" "=d")
4995         (unspec:DI [(match_operand:BLK 1 "general_operand" "m")
4996                     (match_operand:QI 2 "general_operand" "m")]
4997                    UNSPEC_LDL))]
4998   "TARGET_64BIT && !TARGET_MIPS16"
4999   "ldl\t%0,%2"
5000   [(set_attr "type" "load")
5001    (set_attr "mode" "DI")])
5003 (define_insn "mov_ldr"
5004   [(set (match_operand:DI 0 "register_operand" "=d")
5005         (unspec:DI [(match_operand:BLK 1 "general_operand" "m")
5006                     (match_operand:QI 2 "general_operand" "m")
5007                     (match_operand:DI 3 "register_operand" "0")]
5008                    UNSPEC_LDR))]
5009   "TARGET_64BIT && !TARGET_MIPS16"
5010   "ldr\t%0,%2"
5011   [(set_attr "type" "load")
5012    (set_attr "mode" "DI")])
5015 (define_insn "mov_sdl"
5016   [(set (match_operand:BLK 0 "memory_operand" "=m")
5017         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
5018                      (match_operand:QI 2 "general_operand" "m")]
5019                     UNSPEC_SDL))]
5020   "TARGET_64BIT && !TARGET_MIPS16"
5021   "sdl\t%z1,%2"
5022   [(set_attr "type" "store")
5023    (set_attr "mode" "DI")])
5025 (define_insn "mov_sdr"
5026   [(set (match_operand:BLK 0 "memory_operand" "+m")
5027         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
5028                      (match_operand:QI 2 "general_operand" "m")
5029                      (match_dup 0)]
5030                     UNSPEC_SDR))]
5031   "TARGET_64BIT && !TARGET_MIPS16"
5032   "sdr\t%z1,%2"
5033   [(set_attr "type" "store")
5034    (set_attr "mode" "DI")])
5037 ;; Instructions for loading a relocation expression using "lui".
5039 (define_insn "luisi"
5040   [(set (match_operand:SI 0 "register_operand" "=r")
5041         (unspec:SI [(match_operand 1 "const_arith_operand" "")] UNSPEC_HIGH))]
5042   ""
5043   "lui\t%0,%1"
5044   [(set_attr "type" "arith")])
5046 (define_insn "luidi"
5047   [(set (match_operand:DI 0 "register_operand" "=r")
5048         (unspec:DI [(match_operand 1 "const_arith_operand" "")] UNSPEC_HIGH))]
5049   "TARGET_64BIT"
5050   "lui\t%0,%1"
5051   [(set_attr "type" "arith")])
5054 ;; Instructions for adding the low 16 bits of an address to a register.
5055 ;; Operand 2 is the address: print_operand works out which relocation
5056 ;; should be applied.
5058 (define_insn "lowsi"
5059   [(set (match_operand:SI 0 "register_operand" "=r")
5060         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
5061                    (match_operand:SI 2 "immediate_operand" "")))]
5062   "!TARGET_MIPS16"
5063   "addiu\\t%0,%1,%R2"
5064   [(set_attr "type"     "arith")
5065    (set_attr "mode"     "SI")])
5067 (define_insn "lowdi"
5068   [(set (match_operand:DI 0 "register_operand" "=r")
5069         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
5070                    (match_operand:DI 2 "immediate_operand" "")))]
5071   "!TARGET_MIPS16 && TARGET_64BIT"
5072   "daddiu\\t%0,%1,%R2"
5073   [(set_attr "type"     "arith")
5074    (set_attr "mode"     "DI")])
5076 ;; 64-bit integer moves
5078 ;; Unlike most other insns, the move insns can't be split with
5079 ;; different predicates, because register spilling and other parts of
5080 ;; the compiler, have memoized the insn number already.
5082 (define_expand "movdi"
5083   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5084         (match_operand:DI 1 "" ""))]
5085   ""
5086   "
5088   if (mips_legitimize_move (DImode, operands[0], operands[1]))
5089     DONE;
5091   /* If we are generating embedded PIC code, and we are referring to a
5092      symbol in the .text section, we must use an offset from the start
5093      of the function.  */
5094   if (TARGET_EMBEDDED_PIC
5095       && (GET_CODE (operands[1]) == LABEL_REF
5096           || (GET_CODE (operands[1]) == SYMBOL_REF
5097               && ! SYMBOL_REF_FLAG (operands[1]))))
5098     {
5099       rtx temp;
5101       temp = embedded_pic_offset (operands[1]);
5102       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
5103                            force_reg (DImode, temp));
5104       emit_move_insn (operands[0], force_reg (DImode, temp));
5105       DONE;
5106     }
5109 ;; For mips16, we need a special case to handle storing $31 into
5110 ;; memory, since we don't have a constraint to match $31.  This
5111 ;; instruction can be generated by save_restore_insns.
5113 (define_insn ""
5114   [(set (match_operand:DI 0 "memory_operand" "=m")
5115         (reg:DI 31))]
5116   "TARGET_MIPS16 && TARGET_64BIT"
5117   "sd\t$31,%0"
5118   [(set_attr "type"     "store")
5119    (set_attr "mode"     "DI")])
5121 (define_insn "movdi_internal"
5122   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
5123         (match_operand:DI 1 "general_operand" "d,iF,m,d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
5124   "!TARGET_64BIT && !TARGET_MIPS16
5125    && (register_operand (operands[0], DImode)
5126        || register_operand (operands[1], DImode)
5127        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5128        || operands[1] == CONST0_RTX (DImode))"
5129   { return mips_output_move (operands[0], operands[1]); }
5130   [(set_attr "type"     "move,arith,load,store,hilo,hilo,hilo,xfer,load,xfer,store")
5131    (set_attr "mode"     "DI")
5132    (set_attr "length"   "8,16,*,*,8,8,8,8,*,8,*")])
5134 (define_insn ""
5135   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
5136         (match_operand:DI 1 "general_operand" "d,d,y,K,N,m,d,*x"))]
5137   "!TARGET_64BIT && TARGET_MIPS16
5138    && (register_operand (operands[0], DImode)
5139        || register_operand (operands[1], DImode))"
5140   { return mips_output_move (operands[0], operands[1]); }
5141   [(set_attr "type"     "move,move,move,arith,arith,load,store,hilo")
5142    (set_attr "mode"     "DI")
5143    (set_attr "length"   "8,8,8,8,12,*,*,8")])
5145 (define_insn "movdi_internal2"
5146   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*a,*B*C*D,*B*C*D,*d,*m")
5147         (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*J,*d,*m,*B*C*D,*B*C*D"))]
5148   "TARGET_64BIT && !TARGET_MIPS16
5149    && (register_operand (operands[0], DImode)
5150        || register_operand (operands[1], DImode)
5151        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5152        || operands[1] == CONST0_RTX (DImode))"
5153   { return mips_output_move (operands[0], operands[1]); }
5154   [(set_attr "type"     "move,const,const,load,store,move,xfer,load,xfer,store,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
5155    (set_attr "mode"     "DI")
5156    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,8,8,*,8,*")])
5158 (define_insn "*movdi_internal2_mips16"
5159   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
5160         (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d,*x"))]
5161   "TARGET_64BIT && TARGET_MIPS16
5162    && (register_operand (operands[0], DImode)
5163        || register_operand (operands[1], DImode))"
5164   { return mips_output_move (operands[0], operands[1]); }
5165   [(set_attr "type"     "move,move,move,arith,arith,const,load,store,hilo")
5166    (set_attr "mode"     "DI")
5167    (set_attr_alternative "length"
5168                 [(const_int 4)
5169                  (const_int 4)
5170                  (const_int 4)
5171                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5172                                (const_int 4)
5173                                (const_int 8))
5174                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5175                                (const_int 8)
5176                                (const_int 12))
5177                  (const_string "*")
5178                  (const_string "*")
5179                  (const_string "*")
5180                  (const_int 4)])])
5183 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
5184 ;; when the original load is a 4 byte instruction but the add and the
5185 ;; load are 2 2 byte instructions.
5187 (define_split
5188   [(set (match_operand:DI 0 "register_operand" "")
5189         (mem:DI (plus:DI (match_dup 0)
5190                          (match_operand:DI 1 "const_int_operand" ""))))]
5191   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
5192    && !TARGET_DEBUG_D_MODE
5193    && GET_CODE (operands[0]) == REG
5194    && M16_REG_P (REGNO (operands[0]))
5195    && GET_CODE (operands[1]) == CONST_INT
5196    && ((INTVAL (operands[1]) < 0
5197         && INTVAL (operands[1]) >= -0x10)
5198        || (INTVAL (operands[1]) >= 32 * 8
5199            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
5200        || (INTVAL (operands[1]) >= 0
5201            && INTVAL (operands[1]) < 32 * 8
5202            && (INTVAL (operands[1]) & 7) != 0))"
5203   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
5204    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
5205   "
5207   HOST_WIDE_INT val = INTVAL (operands[1]);
5209   if (val < 0)
5210     operands[2] = GEN_INT (0);
5211   else if (val >= 32 * 8)
5212     {
5213       int off = val & 7;
5215       operands[1] = GEN_INT (0x8 + off);
5216       operands[2] = GEN_INT (val - off - 0x8);
5217     }
5218   else
5219     {
5220       int off = val & 7;
5222       operands[1] = GEN_INT (off);
5223       operands[2] = GEN_INT (val - off);
5224     }
5227 ;; Handle input reloads in DImode.
5228 ;; This is mainly to handle reloading HILO_REGNUM.  Note that we may
5229 ;; see it as the source or the destination, depending upon which way
5230 ;; reload handles the instruction.
5231 ;; Making the second operand TImode is a trick.  The compiler may
5232 ;; reuse the same register for operand 0 and operand 2.  Using TImode
5233 ;; gives us two registers, so we can always use the one which is not
5234 ;; used.
5236 (define_expand "reload_indi"
5237   [(set (match_operand:DI 0 "register_operand" "=b")
5238         (match_operand:DI 1 "" "b"))
5239    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5240   "TARGET_64BIT"
5241   "
5243   rtx scratch = gen_rtx_REG (DImode,
5244                              (REGNO (operands[0]) == REGNO (operands[2])
5245                               ? REGNO (operands[2]) + 1
5246                               : REGNO (operands[2])));
5248   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5249     {
5250       if (GET_CODE (operands[1]) == MEM)
5251         {
5252           rtx memword, offword, hi_word, lo_word;
5253           rtx addr = find_replacement (&XEXP (operands[1], 0));
5254           rtx op1 = replace_equiv_address (operands[1], addr);
5256           scratch = gen_rtx_REG (SImode, REGNO (scratch));
5257           memword = adjust_address (op1, SImode, 0);
5258           offword = adjust_address (op1, SImode, 4);
5260           if (BYTES_BIG_ENDIAN)
5261             {
5262               hi_word = memword;
5263               lo_word = offword;
5264             }
5265           else
5266             {
5267               hi_word = offword;
5268               lo_word = memword;
5269             }
5270           emit_move_insn (scratch, hi_word);
5271           emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
5272           emit_move_insn (scratch, lo_word);
5273           emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
5274           emit_insn (gen_hilo_delay (operands[0]));
5275         }
5276       else
5277         {
5278           emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5279           emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
5280           emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5281           emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5282           emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5283           emit_insn (gen_hilo_delay (operands[0]));
5284         }
5285       DONE;
5286     }
5287   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5288     {
5289       emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
5290       emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5291       emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5292       emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
5293       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5294       emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5295       emit_insn (gen_hilo_delay (operands[1]));
5296       DONE;
5297     }
5298   /* This handles moves between a float register and HI/LO.  */
5299   emit_move_insn (scratch, operands[1]);
5300   emit_move_insn (operands[0], scratch);
5301   DONE;
5304 ;; Handle output reloads in DImode.
5306 ;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5307 ;; use a TImode scratch reg.
5309 (define_expand "reload_outdi"
5310   [(set (match_operand:DI 0 "general_operand" "=b")
5311         (match_operand:DI 1 "register_operand" "b"))
5312    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5313   "TARGET_64BIT"
5314   "
5316   rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5318   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5319     {
5320       emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5321       emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5322       emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5323       emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5324       emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5325       emit_insn (gen_hilo_delay (operands[0]));
5326       DONE;
5327     }
5328   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5329     {
5330       if (GET_CODE (operands[0]) == MEM)
5331         {
5332           rtx scratch, memword, offword, hi_word, lo_word;
5333           rtx addr = find_replacement (&XEXP (operands[0], 0));
5334           rtx op0 = replace_equiv_address (operands[0], addr);
5336           scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
5337           memword = adjust_address (op0, SImode, 0);
5338           offword = adjust_address (op0, SImode, 4);
5340           if (BYTES_BIG_ENDIAN)
5341             {
5342               hi_word = memword;
5343               lo_word = offword;
5344             }
5345           else
5346             {
5347               hi_word = offword;
5348               lo_word = memword;
5349             }
5350           emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
5351           emit_move_insn (hi_word, scratch);
5352           emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
5353           emit_move_insn (lo_word, scratch);
5354           emit_insn (gen_hilo_delay (operands[1]));
5355         }
5356       else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
5357         {
5358           /* Handle the case where operand[0] is not a 'd' register,
5359              and hence we can not directly move from the HILO register
5360              into it.  */
5361           rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5362           emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5363           emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5364           emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5365           emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
5366           emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
5367           emit_insn (gen_iordi3 (scratch, scratch, scratch2));
5368           emit_insn (gen_movdi (operands[0], scratch));
5369           emit_insn (gen_hilo_delay (operands[1]));
5370         }
5371       else
5372         {
5373           emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5374           emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5375           emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5376           emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5377           emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5378           emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5379           emit_insn (gen_hilo_delay (operands[1]));
5380         }
5381       DONE;
5382     }
5383   /* This handles moves between a float register and HI/LO.  */
5384   emit_move_insn (scratch, operands[1]);
5385   emit_move_insn (operands[0], scratch);
5386   DONE;
5389 ;; 32-bit Integer moves
5391 ;; Unlike most other insns, the move insns can't be split with
5392 ;; different predicates, because register spilling and other parts of
5393 ;; the compiler, have memoized the insn number already.
5395 (define_expand "movsi"
5396   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5397         (match_operand:SI 1 "" ""))]
5398   ""
5399   "
5401   if (mips_legitimize_move (SImode, operands[0], operands[1]))
5402     DONE;
5404   /* If we are generating embedded PIC code, and we are referring to a
5405      symbol in the .text section, we must use an offset from the start
5406      of the function.  */
5407   if (TARGET_EMBEDDED_PIC
5408       && (GET_CODE (operands[1]) == LABEL_REF
5409           || (GET_CODE (operands[1]) == SYMBOL_REF
5410               && ! SYMBOL_REF_FLAG (operands[1]))))
5411     {
5412       rtx temp;
5414       temp = embedded_pic_offset (operands[1]);
5415       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
5416                            force_reg (SImode, temp));
5417       emit_move_insn (operands[0], force_reg (SImode, temp));
5418       DONE;
5419     }
5422 ;; We can only store $ra directly into a small sp offset.  Should the
5423 ;; offset be too wide, non-constant or not sp-based, leave it up to
5424 ;; reload to choose a scratch register.
5426 (define_insn ""
5427   [(set (mem:SI (plus:SI (reg:SI 29)
5428                          (match_operand:SI 0 "small_int" "n")))
5429         (reg:SI 31))]
5430   "TARGET_MIPS16"
5431   "sw\\t$31,%0($sp)"
5432   [(set_attr "type"     "store")
5433    (set_attr "mode"     "SI")
5434    (set_attr_alternative
5435     "length"
5436     [(if_then_else
5437       (lt (symbol_ref "(unsigned HOST_WIDE_INT) INTVAL (operands[0])")
5438           (const_int 1024))
5439       (const_int 4)
5440       (const_int 8))])])
5442 ;; The difference between these two is whether or not ints are allowed
5443 ;; in FP registers (off by default, use -mdebugh to enable).
5445 (define_insn "movsi_internal"
5446   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*d,*m")
5447         (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*a,*d,*m,*B*C*D,*B*C*D"))]
5448   "!TARGET_MIPS16
5449    && (register_operand (operands[0], SImode)
5450        || register_operand (operands[1], SImode)
5451        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5452   { return mips_output_move (operands[0], operands[1]); }
5453   [(set_attr "type"     "move,const,const,load,store,move,xfer,load,xfer,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
5454    (set_attr "mode"     "SI")
5455    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,4,4,*,4,*")])
5457 (define_insn ""
5458   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d,*d")
5459         (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d,*x,*a"))]
5460   "TARGET_MIPS16
5461    && (register_operand (operands[0], SImode)
5462        || register_operand (operands[1], SImode))"
5463   { return mips_output_move (operands[0], operands[1]); }
5464   [(set_attr "type"     "move,move,move,arith,arith,const,load,store,hilo,hilo")
5465    (set_attr "mode"     "SI")
5466    (set_attr_alternative "length"
5467                 [(const_int 4)
5468                  (const_int 4)
5469                  (const_int 4)
5470                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5471                                (const_int 4)
5472                                (const_int 8))
5473                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5474                                (const_int 8)
5475                                (const_int 12))
5476                  (const_string "*")
5477                  (const_string "*")
5478                  (const_string "*")
5479                  (const_int 4)
5480                  (const_int 4)])])
5482 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
5483 ;; when the original load is a 4 byte instruction but the add and the
5484 ;; load are 2 2 byte instructions.
5486 (define_split
5487   [(set (match_operand:SI 0 "register_operand" "")
5488         (mem:SI (plus:SI (match_dup 0)
5489                          (match_operand:SI 1 "const_int_operand" ""))))]
5490   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5491    && GET_CODE (operands[0]) == REG
5492    && M16_REG_P (REGNO (operands[0]))
5493    && GET_CODE (operands[1]) == CONST_INT
5494    && ((INTVAL (operands[1]) < 0
5495         && INTVAL (operands[1]) >= -0x80)
5496        || (INTVAL (operands[1]) >= 32 * 4
5497            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5498        || (INTVAL (operands[1]) >= 0
5499            && INTVAL (operands[1]) < 32 * 4
5500            && (INTVAL (operands[1]) & 3) != 0))"
5501   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5502    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
5503   "
5505   HOST_WIDE_INT val = INTVAL (operands[1]);
5507   if (val < 0)
5508     operands[2] = GEN_INT (0);
5509   else if (val >= 32 * 4)
5510     {
5511       int off = val & 3;
5513       operands[1] = GEN_INT (0x7c + off);
5514       operands[2] = GEN_INT (val - off - 0x7c);
5515     }
5516   else
5517     {
5518       int off = val & 3;
5520       operands[1] = GEN_INT (off);
5521       operands[2] = GEN_INT (val - off);
5522     }
5525 ;; On the mips16, we can split a load of certain constants into a load
5526 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
5527 ;; instructions.
5529 (define_split
5530   [(set (match_operand:SI 0 "register_operand" "")
5531         (match_operand:SI 1 "const_int_operand" ""))]
5532   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5533    && GET_CODE (operands[0]) == REG
5534    && M16_REG_P (REGNO (operands[0]))
5535    && GET_CODE (operands[1]) == CONST_INT
5536    && INTVAL (operands[1]) >= 0x100
5537    && INTVAL (operands[1]) <= 0xff + 0x7f"
5538   [(set (match_dup 0) (match_dup 1))
5539    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5540   "
5542   int val = INTVAL (operands[1]);
5544   operands[1] = GEN_INT (0xff);
5545   operands[2] = GEN_INT (val - 0xff);
5548 ;; On the mips16, we can split a load of a negative constant into a
5549 ;; load and a neg.  That's what mips_output_move will generate anyhow.
5551 (define_split
5552   [(set (match_operand:SI 0 "register_operand" "")
5553         (match_operand:SI 1 "const_int_operand" ""))]
5554   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5555    && GET_CODE (operands[0]) == REG
5556    && M16_REG_P (REGNO (operands[0]))
5557    && GET_CODE (operands[1]) == CONST_INT
5558    && INTVAL (operands[1]) < 0
5559    && INTVAL (operands[1]) > - 0x8000"
5560   [(set (match_dup 0) (match_dup 1))
5561    (set (match_dup 0) (neg:SI (match_dup 0)))]
5562   "
5564   operands[1] = GEN_INT (- INTVAL (operands[1]));
5567 ;; Reload HILO_REGNUM in SI mode.  This needs a scratch register in
5568 ;; order to set the sign bit correctly in the HI register.
5570 (define_expand "reload_outsi"
5571   [(set (match_operand:SI 0 "general_operand" "=b")
5572         (match_operand:SI 1 "register_operand" "b"))
5573    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5574   "TARGET_64BIT || TARGET_MIPS16"
5575   "
5577   if (TARGET_64BIT
5578       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5579     {
5580       emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
5581       emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5582       emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
5583       emit_insn (gen_hilo_delay (operands[0]));
5584       DONE;
5585     }
5586   /* Use a mult to reload LO on mips16.  ??? This is hideous.  */
5587   if (TARGET_MIPS16
5588       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5589     {
5590       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5591       /* This is gen_mulsi3_internal, but we need to fill in the
5592          scratch registers.  */
5593       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5594                           gen_rtvec (3,
5595                                      gen_rtx (SET, VOIDmode,
5596                                               operands[0],
5597                                               gen_rtx (MULT, SImode,
5598                                                        operands[1],
5599                                                        operands[2])),
5600                                      gen_rtx (CLOBBER, VOIDmode,
5601                                               gen_rtx (REG, SImode, 64)),
5602                                      gen_rtx (CLOBBER, VOIDmode,
5603                                               gen_rtx (REG, SImode, 66)))));
5604       DONE;
5605     }
5606   /* FIXME: I don't know how to get a value into the HI register.  */
5607   if (GET_CODE (operands[0]) == REG
5608       && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5609           : GP_REG_P (REGNO (operands[0]))))
5610     {
5611       emit_move_insn (operands[0], operands[1]);
5612       DONE;
5613     }
5614   /* This handles moves between a float register and HI/LO.  */
5615   emit_move_insn (operands[2], operands[1]);
5616   emit_move_insn (operands[0], operands[2]);
5617   DONE;
5620 ;; Reload a value into HI or LO.  There is no mthi or mtlo on mips16,
5621 ;; so we use a mult.  ??? This is hideous, and we ought to figure out
5622 ;; something better.
5624 ;; We use no predicate for operand1, because it may be a PLUS, and there
5625 ;; is no convenient predicate for that.
5627 (define_expand "reload_insi"
5628   [(set (match_operand:SI 0 "register_operand" "=b")
5629         (match_operand:SI 1 "" "b"))
5630    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5631   "TARGET_MIPS16"
5632   "
5634   if (TARGET_MIPS16
5635       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5636     {
5637       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5638       /* This is gen_mulsi3_internal, but we need to fill in the
5639          scratch registers.  */
5640       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5641                           gen_rtvec (3,
5642                                      gen_rtx (SET, VOIDmode,
5643                                               operands[0],
5644                                               gen_rtx (MULT, SImode,
5645                                                        operands[1],
5646                                                        operands[2])),
5647                                      gen_rtx (CLOBBER, VOIDmode,
5648                                               gen_rtx (REG, SImode, 64)),
5649                                      gen_rtx (CLOBBER, VOIDmode,
5650                                               gen_rtx (REG, SImode, 66)))));
5651       DONE;
5652     }
5654   /* If this is a plus, then this must be an add of the stack pointer against
5655      either a hard register or a pseudo.  */
5656   if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5657     {
5658       rtx plus_op;
5660       if (XEXP (operands[1], 0) == stack_pointer_rtx)
5661         plus_op = XEXP (operands[1], 1);
5662       else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5663         plus_op = XEXP (operands[1], 0);
5664       else
5665         abort ();
5667       /* We should have a register now.  */
5668       if (GET_CODE (plus_op) != REG)
5669         abort ();
5671       if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5672         {
5673           /* We have to have at least one temporary register which is not
5674              overlapping plus_op.  */
5675           if (! rtx_equal_p (plus_op, operands[0]))
5676             {
5677               emit_move_insn (operands[0], stack_pointer_rtx);
5678               emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5679             }
5680           else if (! rtx_equal_p (plus_op, operands[2]))
5681             {
5682               emit_move_insn (operands[2], stack_pointer_rtx);
5683               emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5684             }
5685           else
5686             abort ();
5687         }
5688       else
5689         {
5690           /* We need two registers in this case.  */
5691           if (! rtx_equal_p (operands[0], operands[2]))
5692             {
5693               emit_move_insn (operands[0], stack_pointer_rtx);
5694               emit_move_insn (operands[2], plus_op);
5695               emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5696             }
5697           else
5698             abort ();
5699         }
5700       DONE;
5701     }
5703   /* FIXME: I don't know how to get a value into the HI register.  */
5704   emit_move_insn (operands[0], operands[1]);
5705   DONE;
5708 ;; This insn is for the unspec delay for HILO.
5710 (define_insn "hilo_delay"
5711   [(unspec [(match_operand 0 "register_operand" "=b")] UNSPEC_HILO_DELAY)]
5712   ""
5713   ""
5714   [(set_attr "type" "nop")
5715    (set_attr "mode" "none")
5716    (set_attr "can_delay" "no")])
5718 ;; This insn handles moving CCmode values.  It's really just a
5719 ;; slightly simplified copy of movsi_internal2, with additional cases
5720 ;; to move a condition register to a general register and to move
5721 ;; between the general registers and the floating point registers.
5723 (define_insn "movcc"
5724   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
5725         (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
5726   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5727   { return mips_output_move (operands[0], operands[1]); }
5728   [(set_attr "type"     "move,move,load,store,xfer,xfer,move,load,store")
5729    (set_attr "mode"     "SI")
5730    (set_attr "length"   "8,4,*,*,4,4,4,*,*")])
5732 ;; Reload condition code registers.  reload_incc and reload_outcc
5733 ;; both handle moves from arbitrary operands into condition code
5734 ;; registers.  reload_incc handles the more common case in which
5735 ;; a source operand is constrained to be in a condition-code
5736 ;; register, but has not been allocated to one.
5738 ;; Sometimes, such as in movcc, we have a CCmode destination whose
5739 ;; constraints do not include 'z'.  reload_outcc handles the case
5740 ;; when such an operand is allocated to a condition-code register.
5742 ;; Note that reloads from a condition code register to some
5743 ;; other location can be done using ordinary moves.  Moving
5744 ;; into a GPR takes a single movcc, moving elsewhere takes
5745 ;; two.  We can leave these cases to the generic reload code.
5746 (define_expand "reload_incc"
5747   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
5748         (match_operand:CC 1 "general_operand" ""))
5749    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5750   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5751   "
5753   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
5754   DONE;
5757 (define_expand "reload_outcc"
5758   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
5759         (match_operand:CC 1 "register_operand" ""))
5760    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5761   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5762   "
5764   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
5765   DONE;
5768 ;; MIPS4 supports loading and storing a floating point register from
5769 ;; the sum of two general registers.  We use two versions for each of
5770 ;; these four instructions: one where the two general registers are
5771 ;; SImode, and one where they are DImode.  This is because general
5772 ;; registers will be in SImode when they hold 32 bit values, but,
5773 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5774 ;; instructions will still work correctly.
5776 ;; ??? Perhaps it would be better to support these instructions by
5777 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
5778 ;; these instructions can only be used to load and store floating
5779 ;; point registers, that would probably cause trouble in reload.
5781 (define_insn ""
5782   [(set (match_operand:SF 0 "register_operand" "=f")
5783         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5784                          (match_operand:SI 2 "register_operand" "d"))))]
5785   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5786   "lwxc1\\t%0,%1(%2)"
5787   [(set_attr "type"     "load")
5788    (set_attr "mode"     "SF")
5789    (set_attr "length"   "4")])
5791 (define_insn ""
5792   [(set (match_operand:SF 0 "register_operand" "=f")
5793         (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
5794                          (match_operand:DI 2 "register_operand" "d"))))]
5795   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5796   "lwxc1\\t%0,%1(%2)"
5797   [(set_attr "type"     "load")
5798    (set_attr "mode"     "SF")
5799    (set_attr "length"   "4")])
5801 (define_insn ""
5802   [(set (match_operand:DF 0 "register_operand" "=f")
5803         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5804                          (match_operand:SI 2 "register_operand" "d"))))]
5805   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5806   "ldxc1\\t%0,%1(%2)"
5807   [(set_attr "type"     "load")
5808    (set_attr "mode"     "DF")
5809    (set_attr "length"   "4")])
5811 (define_insn ""
5812   [(set (match_operand:DF 0 "register_operand" "=f")
5813         (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
5814                          (match_operand:DI 2 "register_operand" "d"))))]
5815   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5816   "ldxc1\\t%0,%1(%2)"
5817   [(set_attr "type"     "load")
5818    (set_attr "mode"     "DF")
5819    (set_attr "length"   "4")])
5821 (define_insn ""
5822   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5823                          (match_operand:SI 2 "register_operand" "d")))
5824         (match_operand:SF 0 "register_operand" "f"))]
5825   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5826   "swxc1\\t%0,%1(%2)"
5827   [(set_attr "type"     "store")
5828    (set_attr "mode"     "SF")
5829    (set_attr "length"   "4")])
5831 (define_insn ""
5832   [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
5833                          (match_operand:DI 2 "register_operand" "d")))
5834         (match_operand:SF 0 "register_operand" "f"))]
5835   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5836   "swxc1\\t%0,%1(%2)"
5837   [(set_attr "type"     "store")
5838    (set_attr "mode"     "SF")
5839    (set_attr "length"   "4")])
5841 (define_insn ""
5842   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5843                          (match_operand:SI 2 "register_operand" "d")))
5844         (match_operand:DF 0 "register_operand" "f"))]
5845   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5846   "sdxc1\\t%0,%1(%2)"
5847   [(set_attr "type"     "store")
5848    (set_attr "mode"     "DF")
5849    (set_attr "length"   "4")])
5851 (define_insn ""
5852   [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
5853                          (match_operand:DI 2 "register_operand" "d")))
5854         (match_operand:DF 0 "register_operand" "f"))]
5855   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5856   "sdxc1\\t%0,%1(%2)"
5857   [(set_attr "type"     "store")
5858    (set_attr "mode"     "DF")
5859    (set_attr "length"   "4")])
5861 ;; 16-bit Integer moves
5863 ;; Unlike most other insns, the move insns can't be split with
5864 ;; different predicates, because register spilling and other parts of
5865 ;; the compiler, have memoized the insn number already.
5866 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5868 (define_expand "movhi"
5869   [(set (match_operand:HI 0 "nonimmediate_operand" "")
5870         (match_operand:HI 1 "general_operand" ""))]
5871   ""
5872   "
5874   if ((reload_in_progress | reload_completed) == 0
5875       && !register_operand (operands[0], HImode)
5876       && !register_operand (operands[1], HImode)
5877       && (TARGET_MIPS16
5878           || (GET_CODE (operands[1]) != CONST_INT
5879           || INTVAL (operands[1]) != 0)))
5880     {
5881       rtx temp = force_reg (HImode, operands[1]);
5882       emit_move_insn (operands[0], temp);
5883       DONE;
5884     }
5887 ;; The difference between these two is whether or not ints are allowed
5888 ;; in FP registers (off by default, use -mdebugh to enable).
5890 (define_insn "movhi_internal"
5891   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x,*d")
5892         (match_operand:HI 1 "general_operand"       "d,IK,m,dJ,*f,*d,*f,*d,*x"))]
5893   "!TARGET_MIPS16
5894    && (register_operand (operands[0], HImode)
5895        || register_operand (operands[1], HImode)
5896        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5897   "@
5898     move\t%0,%1
5899     li\t%0,%1
5900     lhu\t%0,%1
5901     sh\t%z1,%0
5902     mfc1\t%0,%1
5903     mtc1\t%1,%0
5904     mov.s\t%0,%1
5905     mt%0\t%1
5906     mf%1\t%0"
5907   [(set_attr "type"     "move,arith,load,store,xfer,xfer,move,hilo,hilo")
5908    (set_attr "mode"     "HI")
5909    (set_attr "length"   "4,4,*,*,4,4,4,4,4")])
5911 (define_insn ""
5912   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
5913         (match_operand:HI 1 "general_operand"      "d,d,y,K,N,m,d,*x"))]
5914   "TARGET_MIPS16
5915    && (register_operand (operands[0], HImode)
5916        || register_operand (operands[1], HImode))"
5917   "@
5918     move\t%0,%1
5919     move\t%0,%1
5920     move\t%0,%1
5921     li\t%0,%1
5922     li\t%0,%n1\;neg\t%0
5923     lhu\t%0,%1
5924     sh\t%1,%0
5925     mf%1\t%0"
5926   [(set_attr "type"     "move,move,move,arith,arith,load,store,hilo")
5927    (set_attr "mode"     "HI")
5928    (set_attr_alternative "length"
5929                 [(const_int 4)
5930                  (const_int 4)
5931                  (const_int 4)
5932                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5933                                (const_int 4)
5934                                (const_int 8))
5935                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5936                                (const_int 8)
5937                                (const_int 12))
5938                  (const_string "*")
5939                  (const_string "*")
5940                  (const_int 4)])])
5943 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
5944 ;; when the original load is a 4 byte instruction but the add and the
5945 ;; load are 2 2 byte instructions.
5947 (define_split
5948   [(set (match_operand:HI 0 "register_operand" "")
5949         (mem:HI (plus:SI (match_dup 0)
5950                          (match_operand:SI 1 "const_int_operand" ""))))]
5951   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5952    && GET_CODE (operands[0]) == REG
5953    && M16_REG_P (REGNO (operands[0]))
5954    && GET_CODE (operands[1]) == CONST_INT
5955    && ((INTVAL (operands[1]) < 0
5956         && INTVAL (operands[1]) >= -0x80)
5957        || (INTVAL (operands[1]) >= 32 * 2
5958            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
5959        || (INTVAL (operands[1]) >= 0
5960            && INTVAL (operands[1]) < 32 * 2
5961            && (INTVAL (operands[1]) & 1) != 0))"
5962   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5963    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
5964   "
5966   HOST_WIDE_INT val = INTVAL (operands[1]);
5968   if (val < 0)
5969     operands[2] = GEN_INT (0);
5970   else if (val >= 32 * 2)
5971     {
5972       int off = val & 1;
5974       operands[1] = GEN_INT (0x7e + off);
5975       operands[2] = GEN_INT (val - off - 0x7e);
5976     }
5977   else
5978     {
5979       int off = val & 1;
5981       operands[1] = GEN_INT (off);
5982       operands[2] = GEN_INT (val - off);
5983     }
5986 ;; 8-bit Integer moves
5988 ;; Unlike most other insns, the move insns can't be split with
5989 ;; different predicates, because register spilling and other parts of
5990 ;; the compiler, have memoized the insn number already.
5991 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5993 (define_expand "movqi"
5994   [(set (match_operand:QI 0 "nonimmediate_operand" "")
5995         (match_operand:QI 1 "general_operand" ""))]
5996   ""
5997   "
5999   if ((reload_in_progress | reload_completed) == 0
6000       && !register_operand (operands[0], QImode)
6001       && !register_operand (operands[1], QImode)
6002       && (TARGET_MIPS16
6003           || (GET_CODE (operands[1]) != CONST_INT
6004           || INTVAL (operands[1]) != 0)))
6005     {
6006       rtx temp = force_reg (QImode, operands[1]);
6007       emit_move_insn (operands[0], temp);
6008       DONE;
6009     }
6012 ;; The difference between these two is whether or not ints are allowed
6013 ;; in FP registers (off by default, use -mdebugh to enable).
6015 (define_insn "movqi_internal"
6016   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x,*d")
6017         (match_operand:QI 1 "general_operand"       "d,IK,m,dJ,*f,*d,*f,*d,*x"))]
6018   "!TARGET_MIPS16
6019    && (register_operand (operands[0], QImode)
6020        || register_operand (operands[1], QImode)
6021        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6022   "@
6023     move\t%0,%1
6024     li\t%0,%1
6025     lbu\t%0,%1
6026     sb\t%z1,%0
6027     mfc1\t%0,%1
6028     mtc1\t%1,%0
6029     mov.s\t%0,%1
6030     mt%0\t%1
6031     mf%1\t%0"
6032   [(set_attr "type"     "move,arith,load,store,xfer,xfer,move,hilo,hilo")
6033    (set_attr "mode"     "QI")
6034    (set_attr "length"   "4,4,*,*,4,4,4,4,4")])
6036 (define_insn ""
6037   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
6038         (match_operand:QI 1 "general_operand"      "d,d,y,K,N,m,d,*x"))]
6039   "TARGET_MIPS16
6040    && (register_operand (operands[0], QImode)
6041        || register_operand (operands[1], QImode))"
6042   "@
6043     move\t%0,%1
6044     move\t%0,%1
6045     move\t%0,%1
6046     li\t%0,%1
6047     li\t%0,%n1\;neg\t%0
6048     lbu\t%0,%1
6049     sb\t%1,%0
6050     mf%1\t%0"
6051   [(set_attr "type"     "move,move,move,arith,arith,load,store,hilo")
6052    (set_attr "mode"     "QI")
6053    (set_attr "length"   "4,4,4,4,8,*,*,4")])
6055 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
6056 ;; when the original load is a 4 byte instruction but the add and the
6057 ;; load are 2 2 byte instructions.
6059 (define_split
6060   [(set (match_operand:QI 0 "register_operand" "")
6061         (mem:QI (plus:SI (match_dup 0)
6062                          (match_operand:SI 1 "const_int_operand" ""))))]
6063   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6064    && GET_CODE (operands[0]) == REG
6065    && M16_REG_P (REGNO (operands[0]))
6066    && GET_CODE (operands[1]) == CONST_INT
6067    && ((INTVAL (operands[1]) < 0
6068         && INTVAL (operands[1]) >= -0x80)
6069        || (INTVAL (operands[1]) >= 32
6070            && INTVAL (operands[1]) <= 31 + 0x7f))"
6071   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6072    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
6073   "
6075   HOST_WIDE_INT val = INTVAL (operands[1]);
6077   if (val < 0)
6078     operands[2] = GEN_INT (0);
6079   else
6080     {
6081       operands[1] = GEN_INT (0x7f);
6082       operands[2] = GEN_INT (val - 0x7f);
6083     }
6086 ;; 32-bit floating point moves
6088 (define_expand "movsf"
6089   [(set (match_operand:SF 0 "nonimmediate_operand" "")
6090         (match_operand:SF 1 "general_operand" ""))]
6091   ""
6092   "
6094   if ((reload_in_progress | reload_completed) == 0
6095       && !register_operand (operands[0], SFmode)
6096       && !nonmemory_operand (operands[1], SFmode))
6097     operands[1] = force_reg (SFmode, operands[1]);
6100 (define_insn "movsf_internal1"
6101   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
6102         (match_operand:SF 1 "general_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
6103   "TARGET_HARD_FLOAT
6104    && (register_operand (operands[0], SFmode)
6105        || nonmemory_operand (operands[1], SFmode))"
6106   { return mips_output_move (operands[0], operands[1]); }
6107   [(set_attr "type"     "move,xfer,load,store,xfer,xfer,move,load,store")
6108    (set_attr "mode"     "SF")
6109    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
6111 (define_insn "movsf_internal2"
6112   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
6113         (match_operand:SF 1 "general_operand" "      Gd,m,d"))]
6114   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
6115    && (register_operand (operands[0], SFmode)
6116        || nonmemory_operand (operands[1], SFmode))"
6117   { return mips_output_move (operands[0], operands[1]); }
6118   [(set_attr "type"     "move,load,store")
6119    (set_attr "mode"     "SF")
6120    (set_attr "length"   "4,*,*")])
6122 (define_insn ""
6123   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
6124         (match_operand:SF 1 "nonimmediate_operand" "d,d,y,m,d"))]
6125   "TARGET_MIPS16
6126    && (register_operand (operands[0], SFmode)
6127        || register_operand (operands[1], SFmode))"
6128   { return mips_output_move (operands[0], operands[1]); }
6129   [(set_attr "type"     "move,move,move,load,store")
6130    (set_attr "mode"     "SF")
6131    (set_attr "length"   "4,4,4,*,*")])
6134 ;; 64-bit floating point moves
6136 (define_expand "movdf"
6137   [(set (match_operand:DF 0 "nonimmediate_operand" "")
6138         (match_operand:DF 1 "general_operand" ""))]
6139   ""
6140   "
6142   if ((reload_in_progress | reload_completed) == 0
6143       && !register_operand (operands[0], DFmode)
6144       && !nonmemory_operand (operands[1], DFmode))
6145     operands[1] = force_reg (DFmode, operands[1]);
6148 (define_insn "movdf_internal1a"
6149   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
6150         (match_operand:DF 1 "general_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
6151   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
6152    && (register_operand (operands[0], DFmode)
6153        || nonmemory_operand (operands[1], DFmode))"
6154   { return mips_output_move (operands[0], operands[1]); }
6155   [(set_attr "type"     "move,xfer,load,store,xfer,xfer,move,load,store")
6156    (set_attr "mode"     "DF")
6157    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
6159 (define_insn "movdf_internal1b"
6160   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
6161         (match_operand:DF 1 "general_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
6162   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
6163    && (register_operand (operands[0], DFmode)
6164        || nonmemory_operand (operands[1], DFmode))"
6165   { return mips_output_move (operands[0], operands[1]); }
6166   [(set_attr "type"     "move,xfer,load,store,xfer,xfer,move,load,store")
6167    (set_attr "mode"     "DF")
6168    (set_attr "length"   "4,8,*,*,8,8,8,*,*")])
6170 (define_insn "movdf_internal2"
6171   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
6172         (match_operand:DF 1 "general_operand" "dG,m,dG,f,d,f"))]
6173   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
6174    && (register_operand (operands[0], DFmode)
6175        || nonmemory_operand (operands[1], DFmode))"
6176   { return mips_output_move (operands[0], operands[1]); }
6177   [(set_attr "type"     "move,load,store,xfer,xfer,move")
6178    (set_attr "mode"     "DF")
6179    (set_attr "length"   "8,*,*,4,4,4")])
6181 (define_insn ""
6182   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
6183         (match_operand:DF 1 "nonimmediate_operand" "d,d,y,m,d"))]
6184   "TARGET_MIPS16
6185    && (register_operand (operands[0], DFmode)
6186        || register_operand (operands[1], DFmode))"
6187   { return mips_output_move (operands[0], operands[1]); }
6188   [(set_attr "type"     "move,move,move,load,store")
6189    (set_attr "mode"     "DF")
6190    (set_attr "length"   "8,8,8,*,*")])
6192 (define_split
6193   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6194         (match_operand:DI 1 "general_operand" ""))]
6195   "reload_completed && !TARGET_64BIT
6196    && mips_split_64bit_move_p (operands[0], operands[1])"
6197   [(const_int 0)]
6198   {
6199     mips_split_64bit_move (operands[0], operands[1]);
6200     DONE;
6201   })
6203 (define_split
6204   [(set (match_operand:DF 0 "nonimmediate_operand" "")
6205         (match_operand:DF 1 "general_operand" ""))]
6206   "reload_completed && !TARGET_64BIT
6207    && mips_split_64bit_move_p (operands[0], operands[1])"
6208   [(const_int 0)]
6209   {
6210     mips_split_64bit_move (operands[0], operands[1]);
6211     DONE;
6212   })
6214 ;; Patterns for loading or storing part of a paired floating point
6215 ;; register.  We need them because odd-numbered floating-point registers
6216 ;; are not fully independent: see mips_split_64bit_move.
6218 ;; Load the low word of operand 0 with operand 1.
6219 (define_insn "load_df_low"
6220   [(set (match_operand:DF 0 "register_operand" "=f,f")
6221         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
6222                    UNSPEC_LOAD_DF_LOW))]
6223   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
6224   {
6225     operands[0] = mips_subword (operands[0], 0);
6226     return mips_output_move (operands[0], operands[1]);
6227   }
6228   [(set_attr "type"     "xfer,load")
6229    (set_attr "mode"     "SF")
6230    (set_attr "length"   "4")])
6232 ;; Load the high word of operand 0 from operand 1, preserving the value
6233 ;; in the low word.
6234 (define_insn "load_df_high"
6235   [(set (match_operand:DF 0 "register_operand" "=f,f")
6236         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
6237                     (match_operand:DF 2 "register_operand" "0,0")]
6238                    UNSPEC_LOAD_DF_HIGH))]
6239   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
6240   {
6241     operands[0] = mips_subword (operands[0], 1);
6242     return mips_output_move (operands[0], operands[1]);
6243   }
6244   [(set_attr "type"     "xfer,load")
6245    (set_attr "mode"     "SF")
6246    (set_attr "length"   "4")])
6248 ;; Store the high word of operand 1 in operand 0.  The corresponding
6249 ;; low-word move is done in the normal way.
6250 (define_insn "store_df_high"
6251   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
6252         (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
6253                    UNSPEC_STORE_DF_HIGH))]
6254   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
6255   {
6256     operands[1] = mips_subword (operands[1], 1);
6257     return mips_output_move (operands[0], operands[1]);
6258   }
6259   [(set_attr "type"     "xfer,store")
6260    (set_attr "mode"     "SF")
6261    (set_attr "length"   "4")])
6263 ;; Instructions to load the global pointer register.
6264 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
6265 ;; uses in front of it.  All symbol_refs implicitly use the gp reg.
6267 (define_insn "loadgp"
6268   [(set (reg:DI 28)
6269         (unspec_volatile:DI [(match_operand 0 "immediate_operand" "")
6270                              (match_operand:DI 1 "register_operand" "")]
6271                             UNSPEC_LOADGP))
6272    (clobber (reg:DI 1))]
6273   ""
6274   "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%0)))\\n\\tdaddu\\t$gp,$1,%1%]"
6275   [(set_attr "type"     "move")
6276    (set_attr "mode"     "DI")
6277    (set_attr "length"   "12")])
6279 ;; Block moves, see mips.c for more details.
6280 ;; Argument 0 is the destination
6281 ;; Argument 1 is the source
6282 ;; Argument 2 is the length
6283 ;; Argument 3 is the alignment
6285 (define_expand "movstrsi"
6286   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6287                    (match_operand:BLK 1 "general_operand" ""))
6288               (use (match_operand:SI 2 "arith32_operand" ""))
6289               (use (match_operand:SI 3 "immediate_operand" ""))])]
6290   "!TARGET_MIPS16"
6291   "
6293   if (operands[0])              /* avoid unused code messages */
6294     {
6295       expand_block_move (operands);
6296       DONE;
6297     }
6300 ;; Insn generated by block moves
6302 (define_insn "movstrsi_internal"
6303   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6304         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6305    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6306    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6307    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6308    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6309    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6310    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6311    (use (const_int 0))]                                 ;; normal block move
6312   ""
6313   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6314   [(set_attr "type"     "store")
6315    (set_attr "mode"     "none")
6316    (set_attr "length"   "80")])
6318 ;; We need mips16 versions, because an offset from the stack pointer
6319 ;; is not offsettable, since the stack pointer can only handle 4 and 8
6320 ;; byte loads.
6322 (define_insn ""
6323   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6324         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6325    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6326    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6327    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6328    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6329    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6330    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6331    (use (const_int 0))]                                 ;; normal block move
6332   "TARGET_MIPS16"
6333   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6334   [(set_attr "type"     "multi")
6335    (set_attr "mode"     "none")
6336    (set_attr "length"   "80")])
6338 ;; Split a block move into 2 parts, the first part is everything
6339 ;; except for the last move, and the second part is just the last
6340 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
6341 ;; fill a delay slot.  This also prevents a bug in delayed branches
6342 ;; from showing up, which reuses one of the registers in our clobbers.
6344 ;; ??? Disabled because it doesn't preserve alias information for
6345 ;; operands 0 and 1.  Also, the rtl for the second insn doesn't mention
6346 ;; that it uses the registers clobbered by the first.
6348 ;; It would probably be better to split the block into individual
6349 ;; instructions instead.
6350 (define_split
6351   [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6352         (mem:BLK (match_operand:SI 1 "register_operand" "")))
6353    (clobber (match_operand:SI 4 "register_operand" ""))
6354    (clobber (match_operand:SI 5 "register_operand" ""))
6355    (clobber (match_operand:SI 6 "register_operand" ""))
6356    (clobber (match_operand:SI 7 "register_operand" ""))
6357    (use (match_operand:SI 2 "small_int" ""))
6358    (use (match_operand:SI 3 "small_int" ""))
6359    (use (const_int 0))]
6361   "reload_completed && 0 && INTVAL (operands[2]) > 0"
6363   ;; All but the last move
6364   [(parallel [(set (mem:BLK (match_dup 0))
6365                    (mem:BLK (match_dup 1)))
6366               (clobber (match_dup 4))
6367               (clobber (match_dup 5))
6368               (clobber (match_dup 6))
6369               (clobber (match_dup 7))
6370               (use (match_dup 2))
6371               (use (match_dup 3))
6372               (use (const_int 1))])
6374    ;; The last store, so it can fill a delay slot
6375    (parallel [(set (mem:BLK (match_dup 0))
6376                    (mem:BLK (match_dup 1)))
6377               (clobber (match_dup 4))
6378               (clobber (match_dup 5))
6379               (clobber (match_dup 6))
6380               (clobber (match_dup 7))
6381               (use (match_dup 2))
6382               (use (match_dup 3))
6383               (use (const_int 2))])]
6385   "")
6387 (define_insn "movstrsi_internal2"
6388   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6389         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6390    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6391    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6392    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6393    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6394    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6395    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6396    (use (const_int 1))]                                 ;; all but last store
6397   ""
6398   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6399   [(set_attr "type"     "store")
6400    (set_attr "mode"     "none")
6401    (set_attr "length"   "80")])
6403 (define_insn ""
6404   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6405         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6406    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6407    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6408    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6409    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6410    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6411    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6412    (use (const_int 1))]                                 ;; all but last store
6413   "TARGET_MIPS16"
6414   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6415   [(set_attr "type"     "multi")
6416    (set_attr "mode"     "none")
6417    (set_attr "length"   "80")])
6419 (define_insn "movstrsi_internal3"
6420   [(set (match_operand:BLK 0 "memory_operand" "=m")     ;; destination
6421         (match_operand:BLK 1 "memory_operand" "m"))     ;; source
6422    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6423    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6424    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6425    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6426    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6427    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6428    (use (const_int 2))]                                 ;; just last store of block move
6429   ""
6430   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6431   [(set_attr "type"     "store")
6432    (set_attr "mode"     "none")])
6435 ;;  ....................
6437 ;;      SHIFTS
6439 ;;  ....................
6441 ;; Many of these instructions uses trivial define_expands, because we
6442 ;; want to use a different set of constraints when TARGET_MIPS16.
6444 (define_expand "ashlsi3"
6445   [(set (match_operand:SI 0 "register_operand" "=d")
6446         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6447                    (match_operand:SI 2 "arith_operand" "dI")))]
6448   ""
6449   "
6451   /* On the mips16, a shift of more than 8 is a four byte instruction,
6452      so, for a shift between 8 and 16, it is just as fast to do two
6453      shifts of 8 or less.  If there is a lot of shifting going on, we
6454      may win in CSE.  Otherwise combine will put the shifts back
6455      together again.  This can be called by function_arg, so we must
6456      be careful not to allocate a new register if we've reached the
6457      reload pass.  */
6458   if (TARGET_MIPS16
6459       && optimize
6460       && GET_CODE (operands[2]) == CONST_INT
6461       && INTVAL (operands[2]) > 8
6462       && INTVAL (operands[2]) <= 16
6463       && ! reload_in_progress
6464       && ! reload_completed)
6465     {
6466       rtx temp = gen_reg_rtx (SImode);
6468       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6469       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6470                                         GEN_INT (INTVAL (operands[2]) - 8)));
6471       DONE;
6472     }
6475 (define_insn "ashlsi3_internal1"
6476   [(set (match_operand:SI 0 "register_operand" "=d")
6477         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6478                    (match_operand:SI 2 "arith_operand" "dI")))]
6479   "!TARGET_MIPS16"
6480   "*
6482   if (GET_CODE (operands[2]) == CONST_INT)
6483     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6485   return \"sll\\t%0,%1,%2\";
6487   [(set_attr "type"     "arith")
6488    (set_attr "mode"     "SI")])
6490 (define_insn "ashlsi3_internal1_extend"
6491   [(set (match_operand:DI 0 "register_operand" "=d")
6492        (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
6493                                   (match_operand:SI 2 "arith_operand" "dI"))))]
6494   "TARGET_64BIT && !TARGET_MIPS16"
6495   "*
6497   if (GET_CODE (operands[2]) == CONST_INT)
6498     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6500   return \"sll\\t%0,%1,%2\";
6502   [(set_attr "type"    "arith")
6503    (set_attr "mode"    "DI")])
6506 (define_insn "ashlsi3_internal2"
6507   [(set (match_operand:SI 0 "register_operand" "=d,d")
6508         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6509                    (match_operand:SI 2 "arith_operand" "d,I")))]
6510   "TARGET_MIPS16"
6511   "*
6513   if (which_alternative == 0)
6514     return \"sll\\t%0,%2\";
6516   if (GET_CODE (operands[2]) == CONST_INT)
6517     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6519   return \"sll\\t%0,%1,%2\";
6521   [(set_attr "type"     "arith")
6522    (set_attr "mode"     "SI")
6523    (set_attr_alternative "length"
6524                 [(const_int 4)
6525                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6526                                (const_int 4)
6527                                (const_int 8))])])
6529 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6531 (define_split
6532   [(set (match_operand:SI 0 "register_operand" "")
6533         (ashift:SI (match_operand:SI 1 "register_operand" "")
6534                    (match_operand:SI 2 "const_int_operand" "")))]
6535   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6536    && GET_CODE (operands[2]) == CONST_INT
6537    && INTVAL (operands[2]) > 8
6538    && INTVAL (operands[2]) <= 16"
6539   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6540    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6543   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6546 (define_expand "ashldi3"
6547   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6548                    (ashift:DI (match_operand:DI 1 "register_operand" "")
6549                               (match_operand:SI 2 "arith_operand" "")))
6550               (clobber (match_dup  3))])]
6551   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6552   "
6554   if (TARGET_64BIT)
6555     {
6556       /* On the mips16, a shift of more than 8 is a four byte
6557          instruction, so, for a shift between 8 and 16, it is just as
6558          fast to do two shifts of 8 or less.  If there is a lot of
6559          shifting going on, we may win in CSE.  Otherwise combine will
6560          put the shifts back together again.  This can be called by
6561          function_arg, so we must be careful not to allocate a new
6562          register if we've reached the reload pass.  */
6563       if (TARGET_MIPS16
6564           && optimize
6565           && GET_CODE (operands[2]) == CONST_INT
6566           && INTVAL (operands[2]) > 8
6567           && INTVAL (operands[2]) <= 16
6568           && ! reload_in_progress
6569           && ! reload_completed)
6570         {
6571           rtx temp = gen_reg_rtx (DImode);
6573           emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6574           emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6575                                             GEN_INT (INTVAL (operands[2]) - 8)));
6576           DONE;
6577         }
6579       emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6580                                         operands[2]));
6581       DONE;
6582     }
6584   operands[3] = gen_reg_rtx (SImode);
6588 (define_insn "ashldi3_internal"
6589   [(set (match_operand:DI 0 "register_operand" "=&d")
6590         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6591                    (match_operand:SI 2 "register_operand" "d")))
6592    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6593   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6594   "*
6596   operands[4] = const0_rtx;
6598   return \"sll\\t%3,%2,26\\n\\
6599 \\tbgez\\t%3,1f\\n\\
6600 \\tsll\\t%M0,%L1,%2\\n\\
6601 \\t%(b\\t3f\\n\\
6602 \\tmove\\t%L0,%z4%)\\n\\
6603 \\n\\
6604 %~1:\\n\\
6605 \\t%(beq\\t%3,%z4,2f\\n\\
6606 \\tsll\\t%M0,%M1,%2%)\\n\\
6607 \\n\\
6608 \\tsubu\\t%3,%z4,%2\\n\\
6609 \\tsrl\\t%3,%L1,%3\\n\\
6610 \\tor\\t%M0,%M0,%3\\n\\
6611 %~2:\\n\\
6612 \\tsll\\t%L0,%L1,%2\\n\\
6613 %~3:\";
6615   [(set_attr "type"     "darith")
6616    (set_attr "mode"     "SI")
6617    (set_attr "length"   "48")])
6620 (define_insn "ashldi3_internal2"
6621   [(set (match_operand:DI 0 "register_operand" "=d")
6622         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6623                    (match_operand:SI 2 "small_int" "IJK")))
6624    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6625   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6626    && (INTVAL (operands[2]) & 32) != 0"
6627   "*
6629   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6630   operands[4] = const0_rtx;
6631   return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6633   [(set_attr "type"     "darith")
6634    (set_attr "mode"     "DI")
6635    (set_attr "length"   "8")])
6638 (define_split
6639   [(set (match_operand:DI 0 "register_operand" "")
6640         (ashift:DI (match_operand:DI 1 "register_operand" "")
6641                    (match_operand:SI 2 "small_int" "")))
6642    (clobber (match_operand:SI 3 "register_operand" ""))]
6643   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6644    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6645    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6646    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6647    && (INTVAL (operands[2]) & 32) != 0"
6649   [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6650    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6652   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6655 (define_split
6656   [(set (match_operand:DI 0 "register_operand" "")
6657         (ashift:DI (match_operand:DI 1 "register_operand" "")
6658                    (match_operand:SI 2 "small_int" "")))
6659    (clobber (match_operand:SI 3 "register_operand" ""))]
6660   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6661    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6662    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6663    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6664    && (INTVAL (operands[2]) & 32) != 0"
6666   [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6667    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
6669   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6672 (define_insn "ashldi3_internal3"
6673   [(set (match_operand:DI 0 "register_operand" "=d")
6674         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6675                    (match_operand:SI 2 "small_int" "IJK")))
6676    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6677   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6678    && (INTVAL (operands[2]) & 63) < 32
6679    && (INTVAL (operands[2]) & 63) != 0"
6680   "*
6682   int amount = INTVAL (operands[2]);
6684   operands[2] = GEN_INT (amount & 31);
6685   operands[4] = const0_rtx;
6686   operands[5] = GEN_INT ((-amount) & 31);
6688   return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6690   [(set_attr "type"     "darith")
6691    (set_attr "mode"     "DI")
6692    (set_attr "length"   "16")])
6695 (define_split
6696   [(set (match_operand:DI 0 "register_operand" "")
6697         (ashift:DI (match_operand:DI 1 "register_operand" "")
6698                    (match_operand:SI 2 "small_int" "")))
6699    (clobber (match_operand:SI 3 "register_operand" ""))]
6700   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6701    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6702    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6703    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6704    && (INTVAL (operands[2]) & 63) < 32
6705    && (INTVAL (operands[2]) & 63) != 0"
6707   [(set (subreg:SI (match_dup 0) 4)
6708         (ashift:SI (subreg:SI (match_dup 1) 4)
6709                    (match_dup 2)))
6711    (set (match_dup 3)
6712         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6713                      (match_dup 4)))
6715    (set (subreg:SI (match_dup 0) 4)
6716         (ior:SI (subreg:SI (match_dup 0) 4)
6717                 (match_dup 3)))
6719    (set (subreg:SI (match_dup 0) 0)
6720         (ashift:SI (subreg:SI (match_dup 1) 0)
6721                    (match_dup 2)))]
6722   "
6724   int amount = INTVAL (operands[2]);
6725   operands[2] = GEN_INT (amount & 31);
6726   operands[4] = GEN_INT ((-amount) & 31);
6730 (define_split
6731   [(set (match_operand:DI 0 "register_operand" "")
6732         (ashift:DI (match_operand:DI 1 "register_operand" "")
6733                    (match_operand:SI 2 "small_int" "")))
6734    (clobber (match_operand:SI 3 "register_operand" ""))]
6735   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6736    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6737    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6738    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6739    && (INTVAL (operands[2]) & 63) < 32
6740    && (INTVAL (operands[2]) & 63) != 0"
6742   [(set (subreg:SI (match_dup 0) 0)
6743         (ashift:SI (subreg:SI (match_dup 1) 0)
6744                    (match_dup 2)))
6746    (set (match_dup 3)
6747         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6748                      (match_dup 4)))
6750    (set (subreg:SI (match_dup 0) 0)
6751         (ior:SI (subreg:SI (match_dup 0) 0)
6752                 (match_dup 3)))
6754    (set (subreg:SI (match_dup 0) 4)
6755         (ashift:SI (subreg:SI (match_dup 1) 4)
6756                    (match_dup 2)))]
6757   "
6759   int amount = INTVAL (operands[2]);
6760   operands[2] = GEN_INT (amount & 31);
6761   operands[4] = GEN_INT ((-amount) & 31);
6765 (define_insn "ashldi3_internal4"
6766   [(set (match_operand:DI 0 "register_operand" "=d")
6767         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6768                    (match_operand:SI 2 "arith_operand" "dI")))]
6769   "TARGET_64BIT && !TARGET_MIPS16"
6770   "*
6772   if (GET_CODE (operands[2]) == CONST_INT)
6773     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6775   return \"dsll\\t%0,%1,%2\";
6777   [(set_attr "type"     "arith")
6778    (set_attr "mode"     "DI")])
6780 (define_insn ""
6781   [(set (match_operand:DI 0 "register_operand" "=d,d")
6782         (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
6783                    (match_operand:SI 2 "arith_operand" "d,I")))]
6784   "TARGET_64BIT && TARGET_MIPS16"
6785   "*
6787   if (which_alternative == 0)
6788     return \"dsll\\t%0,%2\";
6790   if (GET_CODE (operands[2]) == CONST_INT)
6791     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6793   return \"dsll\\t%0,%1,%2\";
6795   [(set_attr "type"     "arith")
6796    (set_attr "mode"     "DI")
6797    (set_attr_alternative "length"
6798                 [(const_int 4)
6799                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6800                                (const_int 4)
6801                                (const_int 8))])])
6804 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6806 (define_split
6807   [(set (match_operand:DI 0 "register_operand" "")
6808         (ashift:DI (match_operand:DI 1 "register_operand" "")
6809                    (match_operand:SI 2 "const_int_operand" "")))]
6810   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
6811    && reload_completed
6812    && GET_CODE (operands[2]) == CONST_INT
6813    && INTVAL (operands[2]) > 8
6814    && INTVAL (operands[2]) <= 16"
6815   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6816    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6819   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6822 (define_expand "ashrsi3"
6823   [(set (match_operand:SI 0 "register_operand" "=d")
6824         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6825                      (match_operand:SI 2 "arith_operand" "dI")))]
6826   ""
6827   "
6829   /* On the mips16, a shift of more than 8 is a four byte instruction,
6830      so, for a shift between 8 and 16, it is just as fast to do two
6831      shifts of 8 or less.  If there is a lot of shifting going on, we
6832      may win in CSE.  Otherwise combine will put the shifts back
6833      together again.  */
6834   if (TARGET_MIPS16
6835       && optimize
6836       && GET_CODE (operands[2]) == CONST_INT
6837       && INTVAL (operands[2]) > 8
6838       && INTVAL (operands[2]) <= 16)
6839     {
6840       rtx temp = gen_reg_rtx (SImode);
6842       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6843       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6844                                         GEN_INT (INTVAL (operands[2]) - 8)));
6845       DONE;
6846     }
6849 (define_insn "ashrsi3_internal1"
6850   [(set (match_operand:SI 0 "register_operand" "=d")
6851         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6852                      (match_operand:SI 2 "arith_operand" "dI")))]
6853   "!TARGET_MIPS16"
6854   "*
6856   if (GET_CODE (operands[2]) == CONST_INT)
6857     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6859   return \"sra\\t%0,%1,%2\";
6861   [(set_attr "type"     "arith")
6862    (set_attr "mode"     "SI")])
6864 (define_insn "ashrsi3_internal2"
6865   [(set (match_operand:SI 0 "register_operand" "=d,d")
6866         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6867                      (match_operand:SI 2 "arith_operand" "d,I")))]
6868   "TARGET_MIPS16"
6869   "*
6871   if (which_alternative == 0)
6872     return \"sra\\t%0,%2\";
6874   if (GET_CODE (operands[2]) == CONST_INT)
6875     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6877   return \"sra\\t%0,%1,%2\";
6879   [(set_attr "type"     "arith")
6880    (set_attr "mode"     "SI")
6881    (set_attr_alternative "length"
6882                 [(const_int 4)
6883                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6884                                (const_int 4)
6885                                (const_int 8))])])
6888 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6890 (define_split
6891   [(set (match_operand:SI 0 "register_operand" "")
6892         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6893                      (match_operand:SI 2 "const_int_operand" "")))]
6894   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6895    && GET_CODE (operands[2]) == CONST_INT
6896    && INTVAL (operands[2]) > 8
6897    && INTVAL (operands[2]) <= 16"
6898   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
6899    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
6902   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6905 (define_expand "ashrdi3"
6906   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6907                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6908                                 (match_operand:SI 2 "arith_operand" "")))
6909               (clobber (match_dup  3))])]
6910   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6911   "
6913   if (TARGET_64BIT)
6914     {
6915       /* On the mips16, a shift of more than 8 is a four byte
6916          instruction, so, for a shift between 8 and 16, it is just as
6917          fast to do two shifts of 8 or less.  If there is a lot of
6918          shifting going on, we may win in CSE.  Otherwise combine will
6919          put the shifts back together again.  */
6920       if (TARGET_MIPS16
6921           && optimize
6922           && GET_CODE (operands[2]) == CONST_INT
6923           && INTVAL (operands[2]) > 8
6924           && INTVAL (operands[2]) <= 16)
6925         {
6926           rtx temp = gen_reg_rtx (DImode);
6928           emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
6929           emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
6930                                             GEN_INT (INTVAL (operands[2]) - 8)));
6931           DONE;
6932         }
6934       emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
6935                                         operands[2]));
6936       DONE;
6937     }
6939   operands[3] = gen_reg_rtx (SImode);
6943 (define_insn "ashrdi3_internal"
6944   [(set (match_operand:DI 0 "register_operand" "=&d")
6945         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6946                      (match_operand:SI 2 "register_operand" "d")))
6947    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6948   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6949   "*
6951   operands[4] = const0_rtx;
6953   return \"sll\\t%3,%2,26\\n\\
6954 \\tbgez\\t%3,1f\\n\\
6955 \\tsra\\t%L0,%M1,%2\\n\\
6956 \\t%(b\\t3f\\n\\
6957 \\tsra\\t%M0,%M1,31%)\\n\\
6958 \\n\\
6959 %~1:\\n\\
6960 \\t%(beq\\t%3,%z4,2f\\n\\
6961 \\tsrl\\t%L0,%L1,%2%)\\n\\
6962 \\n\\
6963 \\tsubu\\t%3,%z4,%2\\n\\
6964 \\tsll\\t%3,%M1,%3\\n\\
6965 \\tor\\t%L0,%L0,%3\\n\\
6966 %~2:\\n\\
6967 \\tsra\\t%M0,%M1,%2\\n\\
6968 %~3:\";
6970   [(set_attr "type"     "darith")
6971    (set_attr "mode"     "DI")
6972    (set_attr "length"   "48")])
6975 (define_insn "ashrdi3_internal2"
6976   [(set (match_operand:DI 0 "register_operand" "=d")
6977         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6978                      (match_operand:SI 2 "small_int" "IJK")))
6979    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6980   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
6981   "*
6983   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6984   return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
6986   [(set_attr "type"     "darith")
6987    (set_attr "mode"     "DI")
6988    (set_attr "length"   "8")])
6991 (define_split
6992   [(set (match_operand:DI 0 "register_operand" "")
6993         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6994                      (match_operand:SI 2 "small_int" "")))
6995    (clobber (match_operand:SI 3 "register_operand" ""))]
6996   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6997    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6998    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6999    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7000    && (INTVAL (operands[2]) & 32) != 0"
7002   [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7003    (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
7005   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7008 (define_split
7009   [(set (match_operand:DI 0 "register_operand" "")
7010         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7011                      (match_operand:SI 2 "small_int" "")))
7012    (clobber (match_operand:SI 3 "register_operand" ""))]
7013   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7014    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7015    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7016    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7017    && (INTVAL (operands[2]) & 32) != 0"
7019   [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7020    (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
7022   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7025 (define_insn "ashrdi3_internal3"
7026   [(set (match_operand:DI 0 "register_operand" "=d")
7027         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7028                      (match_operand:SI 2 "small_int" "IJK")))
7029    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7030   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7031    && (INTVAL (operands[2]) & 63) < 32
7032    && (INTVAL (operands[2]) & 63) != 0"
7033   "*
7035   int amount = INTVAL (operands[2]);
7037   operands[2] = GEN_INT (amount & 31);
7038   operands[4] = GEN_INT ((-amount) & 31);
7040   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
7042   [(set_attr "type"     "darith")
7043    (set_attr "mode"     "DI")
7044    (set_attr "length"   "16")])
7047 (define_split
7048   [(set (match_operand:DI 0 "register_operand" "")
7049         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7050                      (match_operand:SI 2 "small_int" "")))
7051    (clobber (match_operand:SI 3 "register_operand" ""))]
7052   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7053    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7054    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7055    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7056    && (INTVAL (operands[2]) & 63) < 32
7057    && (INTVAL (operands[2]) & 63) != 0"
7059   [(set (subreg:SI (match_dup 0) 0)
7060         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7061                      (match_dup 2)))
7063    (set (match_dup 3)
7064         (ashift:SI (subreg:SI (match_dup 1) 4)
7065                    (match_dup 4)))
7067    (set (subreg:SI (match_dup 0) 0)
7068         (ior:SI (subreg:SI (match_dup 0) 0)
7069                 (match_dup 3)))
7071    (set (subreg:SI (match_dup 0) 4)
7072         (ashiftrt:SI (subreg:SI (match_dup 1) 4)
7073                      (match_dup 2)))]
7074   "
7076   int amount = INTVAL (operands[2]);
7077   operands[2] = GEN_INT (amount & 31);
7078   operands[4] = GEN_INT ((-amount) & 31);
7082 (define_split
7083   [(set (match_operand:DI 0 "register_operand" "")
7084         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7085                      (match_operand:SI 2 "small_int" "")))
7086    (clobber (match_operand:SI 3 "register_operand" ""))]
7087   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7088    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7089    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7090    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7091    && (INTVAL (operands[2]) & 63) < 32
7092    && (INTVAL (operands[2]) & 63) != 0"
7094   [(set (subreg:SI (match_dup 0) 4)
7095         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7096                      (match_dup 2)))
7098    (set (match_dup 3)
7099         (ashift:SI (subreg:SI (match_dup 1) 0)
7100                    (match_dup 4)))
7102    (set (subreg:SI (match_dup 0) 4)
7103         (ior:SI (subreg:SI (match_dup 0) 4)
7104                 (match_dup 3)))
7106    (set (subreg:SI (match_dup 0) 0)
7107         (ashiftrt:SI (subreg:SI (match_dup 1) 0)
7108                      (match_dup 2)))]
7109   "
7111   int amount = INTVAL (operands[2]);
7112   operands[2] = GEN_INT (amount & 31);
7113   operands[4] = GEN_INT ((-amount) & 31);
7117 (define_insn "ashrdi3_internal4"
7118   [(set (match_operand:DI 0 "register_operand" "=d")
7119         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7120                      (match_operand:SI 2 "arith_operand" "dI")))]
7121   "TARGET_64BIT && !TARGET_MIPS16"
7122   "*
7124   if (GET_CODE (operands[2]) == CONST_INT)
7125     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7127   return \"dsra\\t%0,%1,%2\";
7129   [(set_attr "type"     "arith")
7130    (set_attr "mode"     "DI")])
7132 (define_insn ""
7133   [(set (match_operand:DI 0 "register_operand" "=d,d")
7134         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
7135                      (match_operand:SI 2 "arith_operand" "d,I")))]
7136   "TARGET_64BIT && TARGET_MIPS16"
7137   "*
7139   if (GET_CODE (operands[2]) == CONST_INT)
7140     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7142   return \"dsra\\t%0,%2\";
7144   [(set_attr "type"     "arith")
7145    (set_attr "mode"     "DI")
7146    (set_attr_alternative "length"
7147                 [(const_int 4)
7148                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7149                                (const_int 4)
7150                                (const_int 8))])])
7152 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7154 (define_split
7155   [(set (match_operand:DI 0 "register_operand" "")
7156         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7157                      (match_operand:SI 2 "const_int_operand" "")))]
7158   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
7159    && reload_completed
7160    && GET_CODE (operands[2]) == CONST_INT
7161    && INTVAL (operands[2]) > 8
7162    && INTVAL (operands[2]) <= 16"
7163   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7164    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7167   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7170 (define_expand "lshrsi3"
7171   [(set (match_operand:SI 0 "register_operand" "=d")
7172         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7173                      (match_operand:SI 2 "arith_operand" "dI")))]
7174   ""
7175   "
7177   /* On the mips16, a shift of more than 8 is a four byte instruction,
7178      so, for a shift between 8 and 16, it is just as fast to do two
7179      shifts of 8 or less.  If there is a lot of shifting going on, we
7180      may win in CSE.  Otherwise combine will put the shifts back
7181      together again.  */
7182   if (TARGET_MIPS16
7183       && optimize
7184       && GET_CODE (operands[2]) == CONST_INT
7185       && INTVAL (operands[2]) > 8
7186       && INTVAL (operands[2]) <= 16)
7187     {
7188       rtx temp = gen_reg_rtx (SImode);
7190       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7191       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7192                                         GEN_INT (INTVAL (operands[2]) - 8)));
7193       DONE;
7194     }
7197 (define_insn "lshrsi3_internal1"
7198   [(set (match_operand:SI 0 "register_operand" "=d")
7199         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7200                      (match_operand:SI 2 "arith_operand" "dI")))]
7201   "!TARGET_MIPS16"
7202   "*
7204   if (GET_CODE (operands[2]) == CONST_INT)
7205     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7207   return \"srl\\t%0,%1,%2\";
7209   [(set_attr "type"     "arith")
7210    (set_attr "mode"     "SI")])
7212 (define_insn "lshrsi3_internal2"
7213   [(set (match_operand:SI 0 "register_operand" "=d,d")
7214         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7215                      (match_operand:SI 2 "arith_operand" "d,I")))]
7216   "TARGET_MIPS16"
7217   "*
7219   if (which_alternative == 0)
7220     return \"srl\\t%0,%2\";
7222   if (GET_CODE (operands[2]) == CONST_INT)
7223     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7225   return \"srl\\t%0,%1,%2\";
7227   [(set_attr "type"     "arith")
7228    (set_attr "mode"     "SI")
7229    (set_attr_alternative "length"
7230                 [(const_int 4)
7231                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7232                                (const_int 4)
7233                                (const_int 8))])])
7236 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7238 (define_split
7239   [(set (match_operand:SI 0 "register_operand" "")
7240         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7241                      (match_operand:SI 2 "const_int_operand" "")))]
7242   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7243    && GET_CODE (operands[2]) == CONST_INT
7244    && INTVAL (operands[2]) > 8
7245    && INTVAL (operands[2]) <= 16"
7246   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7247    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7250   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7253 ;; If we load a byte on the mips16 as a bitfield, the resulting
7254 ;; sequence of instructions is too complicated for combine, because it
7255 ;; involves four instructions: a load, a shift, a constant load into a
7256 ;; register, and an and (the key problem here is that the mips16 does
7257 ;; not have and immediate).  We recognize a shift of a load in order
7258 ;; to make it simple enough for combine to understand.
7260 ;; ??? FIXME: turn into a define_insn_and_split
7261 (define_insn ""
7262   [(set (match_operand:SI 0 "register_operand" "=d")
7263         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
7264                      (match_operand:SI 2 "immediate_operand" "I")))]
7265   "0 && TARGET_MIPS16"
7266   "lw\\t%0,%1\;srl\\t%0,%2"
7267   [(set_attr "type"     "load")
7268    (set_attr "mode"     "SI")
7269    (set_attr_alternative "length"
7270                 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7271                                (const_int 12)
7272                                (const_int 16))])])
7274 (define_split
7275   [(set (match_operand:SI 0 "register_operand" "")
7276         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7277                      (match_operand:SI 2 "immediate_operand" "")))]
7278   "TARGET_MIPS16 && !TARGET_DEBUG_D_MODE"
7279   [(set (match_dup 0) (match_dup 1))
7280    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7281   "")
7283 (define_expand "lshrdi3"
7284   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7285                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7286                                 (match_operand:SI 2 "arith_operand" "")))
7287               (clobber (match_dup  3))])]
7288   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7289   "
7291   if (TARGET_64BIT)
7292     {
7293       /* On the mips16, a shift of more than 8 is a four byte
7294          instruction, so, for a shift between 8 and 16, it is just as
7295          fast to do two shifts of 8 or less.  If there is a lot of
7296          shifting going on, we may win in CSE.  Otherwise combine will
7297          put the shifts back together again.  */
7298       if (TARGET_MIPS16
7299           && optimize
7300           && GET_CODE (operands[2]) == CONST_INT
7301           && INTVAL (operands[2]) > 8
7302           && INTVAL (operands[2]) <= 16)
7303         {
7304           rtx temp = gen_reg_rtx (DImode);
7306           emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7307           emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7308                                             GEN_INT (INTVAL (operands[2]) - 8)));
7309           DONE;
7310         }
7312       emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7313                                         operands[2]));
7314       DONE;
7315     }
7317   operands[3] = gen_reg_rtx (SImode);
7321 (define_insn "lshrdi3_internal"
7322   [(set (match_operand:DI 0 "register_operand" "=&d")
7323         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7324                      (match_operand:SI 2 "register_operand" "d")))
7325    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7326   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7327   "*
7329   operands[4] = const0_rtx;
7331   return \"sll\\t%3,%2,26\\n\\
7332 \\tbgez\\t%3,1f\\n\\
7333 \\tsrl\\t%L0,%M1,%2\\n\\
7334 \\t%(b\\t3f\\n\\
7335 \\tmove\\t%M0,%z4%)\\n\\
7336 \\n\\
7337 %~1:\\n\\
7338 \\t%(beq\\t%3,%z4,2f\\n\\
7339 \\tsrl\\t%L0,%L1,%2%)\\n\\
7340 \\n\\
7341 \\tsubu\\t%3,%z4,%2\\n\\
7342 \\tsll\\t%3,%M1,%3\\n\\
7343 \\tor\\t%L0,%L0,%3\\n\\
7344 %~2:\\n\\
7345 \\tsrl\\t%M0,%M1,%2\\n\\
7346 %~3:\";
7348   [(set_attr "type"     "darith")
7349    (set_attr "mode"     "DI")
7350    (set_attr "length"   "48")])
7353 (define_insn "lshrdi3_internal2"
7354   [(set (match_operand:DI 0 "register_operand" "=d")
7355         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7356                      (match_operand:SI 2 "small_int" "IJK")))
7357    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7358   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7359    && (INTVAL (operands[2]) & 32) != 0"
7360   "*
7362   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7363   operands[4] = const0_rtx;
7364   return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7366   [(set_attr "type"     "darith")
7367    (set_attr "mode"     "DI")
7368    (set_attr "length"   "8")])
7371 (define_split
7372   [(set (match_operand:DI 0 "register_operand" "")
7373         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7374                      (match_operand:SI 2 "small_int" "")))
7375    (clobber (match_operand:SI 3 "register_operand" ""))]
7376   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7377    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7378    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7379    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7380    && (INTVAL (operands[2]) & 32) != 0"
7382   [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7383    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
7385   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7388 (define_split
7389   [(set (match_operand:DI 0 "register_operand" "")
7390         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7391                      (match_operand:SI 2 "small_int" "")))
7392    (clobber (match_operand:SI 3 "register_operand" ""))]
7393   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7394    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7395    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7396    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7397    && (INTVAL (operands[2]) & 32) != 0"
7399   [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7400    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7402   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7405 (define_insn "lshrdi3_internal3"
7406   [(set (match_operand:DI 0 "register_operand" "=d")
7407         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7408                    (match_operand:SI 2 "small_int" "IJK")))
7409    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7410   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7411    && (INTVAL (operands[2]) & 63) < 32
7412    && (INTVAL (operands[2]) & 63) != 0"
7413   "*
7415   int amount = INTVAL (operands[2]);
7417   operands[2] = GEN_INT (amount & 31);
7418   operands[4] = GEN_INT ((-amount) & 31);
7420   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7422   [(set_attr "type"     "darith")
7423    (set_attr "mode"     "DI")
7424    (set_attr "length"   "16")])
7427 (define_split
7428   [(set (match_operand:DI 0 "register_operand" "")
7429         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7430                      (match_operand:SI 2 "small_int" "")))
7431    (clobber (match_operand:SI 3 "register_operand" ""))]
7432   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7433    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7434    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7435    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7436    && (INTVAL (operands[2]) & 63) < 32
7437    && (INTVAL (operands[2]) & 63) != 0"
7439   [(set (subreg:SI (match_dup 0) 0)
7440         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7441                      (match_dup 2)))
7443    (set (match_dup 3)
7444         (ashift:SI (subreg:SI (match_dup 1) 4)
7445                    (match_dup 4)))
7447    (set (subreg:SI (match_dup 0) 0)
7448         (ior:SI (subreg:SI (match_dup 0) 0)
7449                 (match_dup 3)))
7451    (set (subreg:SI (match_dup 0) 4)
7452         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7453                      (match_dup 2)))]
7454   "
7456   int amount = INTVAL (operands[2]);
7457   operands[2] = GEN_INT (amount & 31);
7458   operands[4] = GEN_INT ((-amount) & 31);
7462 (define_split
7463   [(set (match_operand:DI 0 "register_operand" "")
7464         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7465                      (match_operand:SI 2 "small_int" "")))
7466    (clobber (match_operand:SI 3 "register_operand" ""))]
7467   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7468    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7469    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7470    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7471    && (INTVAL (operands[2]) & 63) < 32
7472    && (INTVAL (operands[2]) & 63) != 0"
7474   [(set (subreg:SI (match_dup 0) 4)
7475         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7476                      (match_dup 2)))
7478    (set (match_dup 3)
7479         (ashift:SI (subreg:SI (match_dup 1) 0)
7480                    (match_dup 4)))
7482    (set (subreg:SI (match_dup 0) 4)
7483         (ior:SI (subreg:SI (match_dup 0) 4)
7484                 (match_dup 3)))
7486    (set (subreg:SI (match_dup 0) 0)
7487         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7488                      (match_dup 2)))]
7489   "
7491   int amount = INTVAL (operands[2]);
7492   operands[2] = GEN_INT (amount & 31);
7493   operands[4] = GEN_INT ((-amount) & 31);
7497 (define_insn "lshrdi3_internal4"
7498   [(set (match_operand:DI 0 "register_operand" "=d")
7499         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7500                      (match_operand:SI 2 "arith_operand" "dI")))]
7501   "TARGET_64BIT && !TARGET_MIPS16"
7502   "*
7504   if (GET_CODE (operands[2]) == CONST_INT)
7505     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7507   return \"dsrl\\t%0,%1,%2\";
7509   [(set_attr "type"     "arith")
7510    (set_attr "mode"     "DI")])
7512 (define_insn ""
7513   [(set (match_operand:DI 0 "register_operand" "=d,d")
7514         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
7515                      (match_operand:SI 2 "arith_operand" "d,I")))]
7516   "TARGET_64BIT && TARGET_MIPS16"
7517   "*
7519   if (GET_CODE (operands[2]) == CONST_INT)
7520     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7522   return \"dsrl\\t%0,%2\";
7524   [(set_attr "type"     "arith")
7525    (set_attr "mode"     "DI")
7526    (set_attr_alternative "length"
7527                 [(const_int 4)
7528                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7529                                (const_int 4)
7530                                (const_int 8))])])
7532 (define_insn "rotrsi3"
7533   [(set (match_operand:SI              0 "register_operand" "=d")
7534         (rotatert:SI (match_operand:SI 1 "register_operand" "d")
7535                      (match_operand:SI 2 "arith_operand"    "dn")))]
7536   "ISA_HAS_ROTR_SI"
7537   "*
7539   if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
7540     return \"rorv\\t%0,%1,%2\";
7542   if ((GET_CODE (operands[2]) == CONST_INT)
7543       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
7544     abort ();
7546   return \"ror\\t%0,%1,%2\";
7548   [(set_attr "type"     "arith")
7549    (set_attr "mode"     "SI")])
7551 (define_insn "rotrdi3"
7552   [(set (match_operand:DI              0 "register_operand" "=d")
7553         (rotatert:DI (match_operand:DI 1 "register_operand" "d")
7554                      (match_operand:DI 2 "arith_operand"    "dn")))]
7555   "ISA_HAS_ROTR_DI"
7556   "*
7558    if (TARGET_SR71K)
7559     {
7560       if (GET_CODE (operands[2]) != CONST_INT)
7561         return \"drorv\\t%0,%1,%2\";
7563       if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
7564         return \"dror32\\t%0,%1,%2\";
7565     }
7567   if ((GET_CODE (operands[2]) == CONST_INT)
7568       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
7569     abort ();
7571   return \"dror\\t%0,%1,%2\";
7573   [(set_attr "type"     "arith")
7574    (set_attr "mode"     "DI")])
7577 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7579 (define_split
7580   [(set (match_operand:DI 0 "register_operand" "")
7581         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7582                      (match_operand:SI 2 "const_int_operand" "")))]
7583   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7584    && GET_CODE (operands[2]) == CONST_INT
7585    && INTVAL (operands[2]) > 8
7586    && INTVAL (operands[2]) <= 16"
7587   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7588    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7591   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7596 ;;  ....................
7598 ;;      COMPARISONS
7600 ;;  ....................
7602 ;; Flow here is rather complex:
7604 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the
7605 ;;      arguments into the branch_cmp array, and the type into
7606 ;;      branch_type.  No RTL is generated.
7608 ;;  2)  The appropriate branch define_expand is called, which then
7609 ;;      creates the appropriate RTL for the comparison and branch.
7610 ;;      Different CC modes are used, based on what type of branch is
7611 ;;      done, so that we can constrain things appropriately.  There
7612 ;;      are assumptions in the rest of GCC that break if we fold the
7613 ;;      operands into the branchs for integer operations, and use cc0
7614 ;;      for floating point, so we use the fp status register instead.
7615 ;;      If needed, an appropriate temporary is created to hold the
7616 ;;      of the integer compare.
7618 (define_expand "cmpsi"
7619   [(set (cc0)
7620         (compare:CC (match_operand:SI 0 "register_operand" "")
7621                     (match_operand:SI 1 "arith_operand" "")))]
7622   ""
7623   "
7625   if (operands[0])              /* avoid unused code message */
7626     {
7627       branch_cmp[0] = operands[0];
7628       branch_cmp[1] = operands[1];
7629       branch_type = CMP_SI;
7630       DONE;
7631     }
7634 (define_expand "tstsi"
7635   [(set (cc0)
7636         (match_operand:SI 0 "register_operand" ""))]
7637   ""
7638   "
7640   if (operands[0])              /* avoid unused code message */
7641     {
7642       branch_cmp[0] = operands[0];
7643       branch_cmp[1] = const0_rtx;
7644       branch_type = CMP_SI;
7645       DONE;
7646     }
7649 (define_expand "cmpdi"
7650   [(set (cc0)
7651         (compare:CC (match_operand:DI 0 "register_operand" "")
7652                     (match_operand:DI 1 "arith_operand" "")))]
7653   "TARGET_64BIT"
7654   "
7656   if (operands[0])              /* avoid unused code message */
7657     {
7658       branch_cmp[0] = operands[0];
7659       branch_cmp[1] = operands[1];
7660       branch_type = CMP_DI;
7661       DONE;
7662     }
7665 (define_expand "tstdi"
7666   [(set (cc0)
7667         (match_operand:DI 0 "register_operand" ""))]
7668   "TARGET_64BIT"
7669   "
7671   if (operands[0])              /* avoid unused code message */
7672     {
7673       branch_cmp[0] = operands[0];
7674       branch_cmp[1] = const0_rtx;
7675       branch_type = CMP_DI;
7676       DONE;
7677     }
7680 (define_expand "cmpdf"
7681   [(set (cc0)
7682         (compare:CC (match_operand:DF 0 "register_operand" "")
7683                     (match_operand:DF 1 "register_operand" "")))]
7684   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7685   "
7687   if (operands[0])              /* avoid unused code message */
7688     {
7689       branch_cmp[0] = operands[0];
7690       branch_cmp[1] = operands[1];
7691       branch_type = CMP_DF;
7692       DONE;
7693     }
7696 (define_expand "cmpsf"
7697   [(set (cc0)
7698         (compare:CC (match_operand:SF 0 "register_operand" "")
7699                     (match_operand:SF 1 "register_operand" "")))]
7700   "TARGET_HARD_FLOAT"
7701   "
7703   if (operands[0])              /* avoid unused code message */
7704     {
7705       branch_cmp[0] = operands[0];
7706       branch_cmp[1] = operands[1];
7707       branch_type = CMP_SF;
7708       DONE;
7709     }
7714 ;;  ....................
7716 ;;      CONDITIONAL BRANCHES
7718 ;;  ....................
7720 ;; Conditional branches on floating-point equality tests.
7722 (define_insn "branch_fp"
7723   [(set (pc)
7724         (if_then_else
7725          (match_operator:CC 0 "cmp_op"
7726                             [(match_operand:CC 2 "register_operand" "z")
7727                              (const_int 0)])
7728          (label_ref (match_operand 1 "" ""))
7729          (pc)))]
7730   "TARGET_HARD_FLOAT"
7731   "*
7733   return mips_output_conditional_branch (insn,
7734                                          operands,
7735                                          /*two_operands_p=*/0,
7736                                          /*float_p=*/1,
7737                                          /*inverted_p=*/0,
7738                                          get_attr_length (insn));
7740   [(set_attr "type"     "branch")
7741    (set_attr "mode"     "none")])
7743 (define_insn "branch_fp_inverted"
7744   [(set (pc)
7745         (if_then_else
7746          (match_operator:CC 0 "cmp_op"
7747                             [(match_operand:CC 2 "register_operand" "z")
7748                              (const_int 0)])
7749          (pc)
7750          (label_ref (match_operand 1 "" ""))))]
7751   "TARGET_HARD_FLOAT"
7752   "*
7754   return mips_output_conditional_branch (insn,
7755                                          operands,
7756                                          /*two_operands_p=*/0,
7757                                          /*float_p=*/1,
7758                                          /*inverted_p=*/1,
7759                                          get_attr_length (insn));
7761   [(set_attr "type"     "branch")
7762    (set_attr "mode"     "none")])
7764 ;; Conditional branches on comparisons with zero.
7766 (define_insn "branch_zero"
7767   [(set (pc)
7768         (if_then_else
7769          (match_operator:SI 0 "cmp_op"
7770                             [(match_operand:SI 2 "register_operand" "d")
7771                              (const_int 0)])
7772         (label_ref (match_operand 1 "" ""))
7773         (pc)))]
7774   "!TARGET_MIPS16"
7775   "*
7777   return mips_output_conditional_branch (insn,
7778                                          operands,
7779                                          /*two_operands_p=*/0,
7780                                          /*float_p=*/0,
7781                                          /*inverted_p=*/0,
7782                                          get_attr_length (insn));
7784   [(set_attr "type"     "branch")
7785    (set_attr "mode"     "none")])
7787 (define_insn "branch_zero_inverted"
7788   [(set (pc)
7789         (if_then_else
7790          (match_operator:SI 0 "cmp_op"
7791                             [(match_operand:SI 2 "register_operand" "d")
7792                              (const_int 0)])
7793         (pc)
7794         (label_ref (match_operand 1 "" ""))))]
7795   "!TARGET_MIPS16"
7796   "*
7798   return mips_output_conditional_branch (insn,
7799                                          operands,
7800                                          /*two_operands_p=*/0,
7801                                          /*float_p=*/0,
7802                                          /*inverted_p=*/1,
7803                                          get_attr_length (insn));
7805   [(set_attr "type"     "branch")
7806    (set_attr "mode"     "none")])
7808 (define_insn "branch_zero_di"
7809   [(set (pc)
7810         (if_then_else
7811          (match_operator:DI 0 "cmp_op"
7812                             [(match_operand:DI 2 "register_operand" "d")
7813                              (const_int 0)])
7814         (label_ref (match_operand 1 "" ""))
7815         (pc)))]
7816   "!TARGET_MIPS16"
7817   "*
7819   return mips_output_conditional_branch (insn,
7820                                          operands,
7821                                          /*two_operands_p=*/0,
7822                                          /*float_p=*/0,
7823                                          /*inverted_p=*/0,
7824                                          get_attr_length (insn));
7826   [(set_attr "type"     "branch")
7827    (set_attr "mode"     "none")])
7829 (define_insn "branch_zero_di_inverted"
7830   [(set (pc)
7831         (if_then_else
7832          (match_operator:DI 0 "cmp_op"
7833                             [(match_operand:DI 2 "register_operand" "d")
7834                              (const_int 0)])
7835         (pc)
7836         (label_ref (match_operand 1 "" ""))))]
7837   "!TARGET_MIPS16"
7838   "*
7840   return mips_output_conditional_branch (insn,
7841                                          operands,
7842                                          /*two_operands_p=*/0,
7843                                          /*float_p=*/0,
7844                                          /*inverted_p=*/1,
7845                                          get_attr_length (insn));
7847   [(set_attr "type"     "branch")
7848    (set_attr "mode"     "none")])
7850 ;; Conditional branch on equality comparision.
7852 (define_insn "branch_equality"
7853   [(set (pc)
7854         (if_then_else
7855          (match_operator:SI 0 "equality_op"
7856                             [(match_operand:SI 2 "register_operand" "d")
7857                              (match_operand:SI 3 "register_operand" "d")])
7858          (label_ref (match_operand 1 "" ""))
7859          (pc)))]
7860   "!TARGET_MIPS16"
7861   "*
7863   return mips_output_conditional_branch (insn,
7864                                          operands,
7865                                          /*two_operands_p=*/1,
7866                                          /*float_p=*/0,
7867                                          /*inverted_p=*/0,
7868                                          get_attr_length (insn));
7870   [(set_attr "type"     "branch")
7871    (set_attr "mode"     "none")])
7873 (define_insn "branch_equality_di"
7874   [(set (pc)
7875         (if_then_else
7876          (match_operator:DI 0 "equality_op"
7877                             [(match_operand:DI 2 "register_operand" "d")
7878                              (match_operand:DI 3 "register_operand" "d")])
7879         (label_ref (match_operand 1 "" ""))
7880         (pc)))]
7881   "!TARGET_MIPS16"
7882   "*
7884   return mips_output_conditional_branch (insn,
7885                                          operands,
7886                                          /*two_operands_p=*/1,
7887                                          /*float_p=*/0,
7888                                          /*inverted_p=*/0,
7889                                          get_attr_length (insn));
7891   [(set_attr "type"     "branch")
7892    (set_attr "mode"     "none")])
7894 (define_insn "branch_equality_inverted"
7895   [(set (pc)
7896         (if_then_else
7897          (match_operator:SI 0 "equality_op"
7898                             [(match_operand:SI 2 "register_operand" "d")
7899                              (match_operand:SI 3 "register_operand" "d")])
7900          (pc)
7901          (label_ref (match_operand 1 "" ""))))]
7902   "!TARGET_MIPS16"
7903   "*
7905   return mips_output_conditional_branch (insn,
7906                                          operands,
7907                                          /*two_operands_p=*/1,
7908                                          /*float_p=*/0,
7909                                          /*inverted_p=*/1,
7910                                          get_attr_length (insn));
7912   [(set_attr "type"     "branch")
7913    (set_attr "mode"     "none")])
7915 (define_insn "branch_equality_di_inverted"
7916   [(set (pc)
7917         (if_then_else
7918          (match_operator:DI 0 "equality_op"
7919                             [(match_operand:DI 2 "register_operand" "d")
7920                              (match_operand:DI 3 "register_operand" "d")])
7921         (pc)
7922         (label_ref (match_operand 1 "" ""))))]
7923   "!TARGET_MIPS16"
7924   "*
7926   return mips_output_conditional_branch (insn,
7927                                          operands,
7928                                          /*two_operands_p=*/1,
7929                                          /*float_p=*/0,
7930                                          /*inverted_p=*/1,
7931                                          get_attr_length (insn));
7933   [(set_attr "type"     "branch")
7934    (set_attr "mode"     "none")])
7936 ;; MIPS16 branches
7938 (define_insn ""
7939   [(set (pc)
7940         (if_then_else (match_operator:SI 0 "equality_op"
7941                                          [(match_operand:SI 1 "register_operand" "d,t")
7942                                           (const_int 0)])
7943         (match_operand 2 "pc_or_label_operand" "")
7944         (match_operand 3 "pc_or_label_operand" "")))]
7945   "TARGET_MIPS16"
7946   "*
7948   if (operands[2] != pc_rtx)
7949     {
7950       if (which_alternative == 0)
7951         return \"%*b%C0z\\t%1,%2\";
7952       else
7953         return \"%*bt%C0z\\t%2\";
7954     }
7955   else
7956     {
7957       if (which_alternative == 0)
7958         return \"%*b%N0z\\t%1,%3\";
7959       else
7960         return \"%*bt%N0z\\t%3\";
7961     }
7963   [(set_attr "type"     "branch")
7964    (set_attr "mode"     "none")
7965    (set_attr "length"   "8")])
7967 (define_insn ""
7968   [(set (pc)
7969         (if_then_else (match_operator:DI 0 "equality_op"
7970                                          [(match_operand:DI 1 "register_operand" "d,t")
7971                                           (const_int 0)])
7972         (match_operand 2 "pc_or_label_operand" "")
7973         (match_operand 3 "pc_or_label_operand" "")))]
7974   "TARGET_MIPS16"
7975   "*
7977   if (operands[2] != pc_rtx)
7978     {
7979       if (which_alternative == 0)
7980         return \"%*b%C0z\\t%1,%2\";
7981       else
7982         return \"%*bt%C0z\\t%2\";
7983     }
7984   else
7985     {
7986       if (which_alternative == 0)
7987         return \"%*b%N0z\\t%1,%3\";
7988       else
7989         return \"%*bt%N0z\\t%3\";
7990     }
7992   [(set_attr "type"     "branch")
7993    (set_attr "mode"     "none")
7994    (set_attr "length"   "8")])
7996 (define_expand "bunordered"
7997   [(set (pc)
7998         (if_then_else (unordered:CC (cc0)
7999                                     (const_int 0))
8000                       (label_ref (match_operand 0 "" ""))
8001                       (pc)))]
8002   ""
8003   "
8005   if (operands[0])              /* avoid unused code warning */
8006     {
8007       gen_conditional_branch (operands, UNORDERED);
8008       DONE;
8009     }
8012 (define_expand "bordered"
8013   [(set (pc)
8014         (if_then_else (ordered:CC (cc0)
8015                                   (const_int 0))
8016                       (label_ref (match_operand 0 "" ""))
8017                       (pc)))]
8018   ""
8019   "
8021   if (operands[0])              /* avoid unused code warning */
8022      {
8023         gen_conditional_branch (operands, ORDERED);
8024         DONE;
8025      }
8028 (define_expand "bunlt"
8029   [(set (pc)
8030         (if_then_else (unlt:CC (cc0)
8031                                (const_int 0))
8032                       (label_ref (match_operand 0 "" ""))
8033                       (pc)))]
8034   ""
8035   "
8037   if (operands[0])              /* avoid unused code warning */
8038      {
8039         gen_conditional_branch (operands, UNLT);
8040         DONE;
8041      }
8044 (define_expand "bunge"
8045   [(set (pc)
8046         (if_then_else (unge:CC (cc0)
8047                                (const_int 0))
8048                       (label_ref (match_operand 0 "" ""))
8049                       (pc)))]
8050   ""
8051   "
8053   gen_conditional_branch (operands, UNGE);
8054   DONE;
8057 (define_expand "buneq"
8058   [(set (pc)
8059         (if_then_else (uneq:CC (cc0)
8060                                (const_int 0))
8061                       (label_ref (match_operand 0 "" ""))
8062                       (pc)))]
8063   ""
8064   "
8066   if (operands[0])              /* avoid unused code warning */
8067      {
8068         gen_conditional_branch (operands, UNEQ);
8069         DONE;
8070      }
8073 (define_expand "bltgt"
8074   [(set (pc)
8075         (if_then_else (ltgt:CC (cc0)
8076                                (const_int 0))
8077                       (label_ref (match_operand 0 "" ""))
8078                       (pc)))]
8079   ""
8080   "
8082   gen_conditional_branch (operands, LTGT);
8083   DONE;
8086 (define_expand "bunle"
8087   [(set (pc)
8088         (if_then_else (unle:CC (cc0)
8089                                (const_int 0))
8090                       (label_ref (match_operand 0 "" ""))
8091                       (pc)))]
8092   ""
8093   "
8095   if (operands[0])              /* avoid unused code warning */
8096      {
8097         gen_conditional_branch (operands, UNLE);
8098         DONE;
8099      }
8102 (define_expand "bungt"
8103   [(set (pc)
8104         (if_then_else (ungt:CC (cc0)
8105                                (const_int 0))
8106                       (label_ref (match_operand 0 "" ""))
8107                       (pc)))]
8108   ""
8109   "
8111   gen_conditional_branch (operands, UNGT);
8112   DONE;
8115 (define_expand "beq"
8116   [(set (pc)
8117         (if_then_else (eq:CC (cc0)
8118                              (const_int 0))
8119                       (label_ref (match_operand 0 "" ""))
8120                       (pc)))]
8121   ""
8122   "
8124   if (operands[0])              /* avoid unused code warning */
8125     {
8126       gen_conditional_branch (operands, EQ);
8127       DONE;
8128     }
8131 (define_expand "bne"
8132   [(set (pc)
8133         (if_then_else (ne:CC (cc0)
8134                              (const_int 0))
8135                       (label_ref (match_operand 0 "" ""))
8136                       (pc)))]
8137   ""
8138   "
8140   if (operands[0])              /* avoid unused code warning */
8141     {
8142       gen_conditional_branch (operands, NE);
8143       DONE;
8144     }
8147 (define_expand "bgt"
8148   [(set (pc)
8149         (if_then_else (gt:CC (cc0)
8150                              (const_int 0))
8151                       (label_ref (match_operand 0 "" ""))
8152                       (pc)))]
8153   ""
8154   "
8156   if (operands[0])              /* avoid unused code warning */
8157     {
8158       gen_conditional_branch (operands, GT);
8159       DONE;
8160     }
8163 (define_expand "bge"
8164   [(set (pc)
8165         (if_then_else (ge:CC (cc0)
8166                              (const_int 0))
8167                       (label_ref (match_operand 0 "" ""))
8168                       (pc)))]
8169   ""
8170   "
8172   if (operands[0])              /* avoid unused code warning */
8173     {
8174       gen_conditional_branch (operands, GE);
8175       DONE;
8176     }
8179 (define_expand "blt"
8180   [(set (pc)
8181         (if_then_else (lt:CC (cc0)
8182                              (const_int 0))
8183                       (label_ref (match_operand 0 "" ""))
8184                       (pc)))]
8185   ""
8186   "
8188   if (operands[0])              /* avoid unused code warning */
8189     {
8190       gen_conditional_branch (operands, LT);
8191       DONE;
8192     }
8195 (define_expand "ble"
8196   [(set (pc)
8197         (if_then_else (le:CC (cc0)
8198                              (const_int 0))
8199                       (label_ref (match_operand 0 "" ""))
8200                       (pc)))]
8201   ""
8202   "
8204   if (operands[0])              /* avoid unused code warning */
8205     {
8206       gen_conditional_branch (operands, LE);
8207       DONE;
8208     }
8211 (define_expand "bgtu"
8212   [(set (pc)
8213         (if_then_else (gtu:CC (cc0)
8214                               (const_int 0))
8215                       (label_ref (match_operand 0 "" ""))
8216                       (pc)))]
8217   ""
8218   "
8220   if (operands[0])              /* avoid unused code warning */
8221     {
8222       gen_conditional_branch (operands, GTU);
8223       DONE;
8224     }
8227 (define_expand "bgeu"
8228   [(set (pc)
8229         (if_then_else (geu:CC (cc0)
8230                               (const_int 0))
8231                       (label_ref (match_operand 0 "" ""))
8232                       (pc)))]
8233   ""
8234   "
8236   if (operands[0])              /* avoid unused code warning */
8237     {
8238       gen_conditional_branch (operands, GEU);
8239       DONE;
8240     }
8244 (define_expand "bltu"
8245   [(set (pc)
8246         (if_then_else (ltu:CC (cc0)
8247                               (const_int 0))
8248                       (label_ref (match_operand 0 "" ""))
8249                       (pc)))]
8250   ""
8251   "
8253   if (operands[0])              /* avoid unused code warning */
8254     {
8255       gen_conditional_branch (operands, LTU);
8256       DONE;
8257     }
8260 (define_expand "bleu"
8261   [(set (pc)
8262         (if_then_else (leu:CC (cc0)
8263                               (const_int 0))
8264                       (label_ref (match_operand 0 "" ""))
8265                       (pc)))]
8266   ""
8267   "
8269   if (operands[0])              /* avoid unused code warning */
8270     {
8271       gen_conditional_branch (operands, LEU);
8272       DONE;
8273     }
8278 ;;  ....................
8280 ;;      SETTING A REGISTER FROM A COMPARISON
8282 ;;  ....................
8284 (define_expand "seq"
8285   [(set (match_operand:SI 0 "register_operand" "=d")
8286         (eq:SI (match_dup 1)
8287                (match_dup 2)))]
8288   ""
8289   "
8291   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8292     FAIL;
8294   /* set up operands from compare.  */
8295   operands[1] = branch_cmp[0];
8296   operands[2] = branch_cmp[1];
8298   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8299     {
8300       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8301       DONE;
8302     }
8304   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8305     operands[2] = force_reg (SImode, operands[2]);
8307   /* fall through and generate default code */
8311 (define_insn "seq_si_zero"
8312   [(set (match_operand:SI 0 "register_operand" "=d")
8313         (eq:SI (match_operand:SI 1 "register_operand" "d")
8314                (const_int 0)))]
8315   "!TARGET_MIPS16"
8316   "sltu\\t%0,%1,1"
8317   [(set_attr "type"     "arith")
8318    (set_attr "mode"     "SI")])
8320 (define_insn ""
8321   [(set (match_operand:SI 0 "register_operand" "=t")
8322         (eq:SI (match_operand:SI 1 "register_operand" "d")
8323                (const_int 0)))]
8324   "TARGET_MIPS16"
8325   "sltu\\t%1,1"
8326   [(set_attr "type"     "arith")
8327    (set_attr "mode"     "SI")])
8329 (define_insn "seq_di_zero"
8330   [(set (match_operand:DI 0 "register_operand" "=d")
8331         (eq:DI (match_operand:DI 1 "register_operand" "d")
8332                (const_int 0)))]
8333   "TARGET_64BIT && !TARGET_MIPS16"
8334   "sltu\\t%0,%1,1"
8335   [(set_attr "type"     "arith")
8336    (set_attr "mode"     "DI")])
8338 (define_insn ""
8339   [(set (match_operand:DI 0 "register_operand" "=t")
8340         (eq:DI (match_operand:DI 1 "register_operand" "d")
8341                (const_int 0)))]
8342   "TARGET_64BIT && TARGET_MIPS16"
8343   "sltu\\t%1,1"
8344   [(set_attr "type"     "arith")
8345    (set_attr "mode"     "DI")])
8347 (define_insn "seq_si"
8348   [(set (match_operand:SI 0 "register_operand" "=d,d")
8349         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8350                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8351   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8352   "@
8353    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8354    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8355   [(set_attr "type"     "arith")
8356    (set_attr "mode"     "SI")
8357    (set_attr "length"   "8")])
8359 (define_split
8360   [(set (match_operand:SI 0 "register_operand" "")
8361         (eq:SI (match_operand:SI 1 "register_operand" "")
8362                (match_operand:SI 2 "uns_arith_operand" "")))]
8363   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8364     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8365   [(set (match_dup 0)
8366         (xor:SI (match_dup 1)
8367                 (match_dup 2)))
8368    (set (match_dup 0)
8369         (ltu:SI (match_dup 0)
8370                 (const_int 1)))]
8371   "")
8373 (define_insn "seq_di"
8374   [(set (match_operand:DI 0 "register_operand" "=d,d")
8375         (eq:DI (match_operand:DI 1 "register_operand" "%d,d")
8376                (match_operand:DI 2 "uns_arith_operand" "d,K")))]
8377   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8378   "@
8379    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8380    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8381   [(set_attr "type"     "arith")
8382    (set_attr "mode"     "DI")
8383    (set_attr "length"   "8")])
8385 (define_split
8386   [(set (match_operand:DI 0 "register_operand" "")
8387         (eq:DI (match_operand:DI 1 "register_operand" "")
8388                (match_operand:DI 2 "uns_arith_operand" "")))]
8389   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8390     && !TARGET_MIPS16
8391     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8392   [(set (match_dup 0)
8393         (xor:DI (match_dup 1)
8394                 (match_dup 2)))
8395    (set (match_dup 0)
8396         (ltu:DI (match_dup 0)
8397                 (const_int 1)))]
8398   "")
8400 ;; On the mips16 the default code is better than using sltu.
8402 (define_expand "sne"
8403   [(set (match_operand:SI 0 "register_operand" "=d")
8404         (ne:SI (match_dup 1)
8405                (match_dup 2)))]
8406   "!TARGET_MIPS16"
8407   "
8409   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8410     FAIL;
8412   /* set up operands from compare.  */
8413   operands[1] = branch_cmp[0];
8414   operands[2] = branch_cmp[1];
8416   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
8417     {
8418       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8419       DONE;
8420     }
8422   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8423     operands[2] = force_reg (SImode, operands[2]);
8425   /* fall through and generate default code */
8428 (define_insn "sne_si_zero"
8429   [(set (match_operand:SI 0 "register_operand" "=d")
8430         (ne:SI (match_operand:SI 1 "register_operand" "d")
8431                (const_int 0)))]
8432   "!TARGET_MIPS16"
8433   "sltu\\t%0,%.,%1"
8434   [(set_attr "type"     "arith")
8435    (set_attr "mode"     "SI")])
8437 (define_insn "sne_di_zero"
8438   [(set (match_operand:DI 0 "register_operand" "=d")
8439         (ne:DI (match_operand:DI 1 "register_operand" "d")
8440                (const_int 0)))]
8441   "TARGET_64BIT && !TARGET_MIPS16"
8442   "sltu\\t%0,%.,%1"
8443   [(set_attr "type"     "arith")
8444    (set_attr "mode"     "DI")])
8446 (define_insn "sne_si"
8447   [(set (match_operand:SI 0 "register_operand" "=d,d")
8448         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8449                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8450   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8451   "@
8452     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8453     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8454   [(set_attr "type"     "arith")
8455    (set_attr "mode"     "SI")
8456    (set_attr "length"   "8")])
8458 (define_split
8459   [(set (match_operand:SI 0 "register_operand" "")
8460         (ne:SI (match_operand:SI 1 "register_operand" "")
8461                (match_operand:SI 2 "uns_arith_operand" "")))]
8462   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8463     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8464   [(set (match_dup 0)
8465         (xor:SI (match_dup 1)
8466                 (match_dup 2)))
8467    (set (match_dup 0)
8468         (gtu:SI (match_dup 0)
8469                 (const_int 0)))]
8470   "")
8472 (define_insn "sne_di"
8473   [(set (match_operand:DI 0 "register_operand" "=d,d")
8474         (ne:DI (match_operand:DI 1 "register_operand" "%d,d")
8475                (match_operand:DI 2 "uns_arith_operand" "d,K")))]
8476   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8477   "@
8478     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8479     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8480   [(set_attr "type"     "arith")
8481    (set_attr "mode"     "DI")
8482    (set_attr "length"   "8")])
8484 (define_split
8485   [(set (match_operand:DI 0 "register_operand" "")
8486         (ne:DI (match_operand:DI 1 "register_operand" "")
8487                (match_operand:DI 2 "uns_arith_operand" "")))]
8488   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8489     && !TARGET_MIPS16
8490     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8491   [(set (match_dup 0)
8492         (xor:DI (match_dup 1)
8493                 (match_dup 2)))
8494    (set (match_dup 0)
8495         (gtu:DI (match_dup 0)
8496                 (const_int 0)))]
8497   "")
8499 (define_expand "sgt"
8500   [(set (match_operand:SI 0 "register_operand" "=d")
8501         (gt:SI (match_dup 1)
8502                (match_dup 2)))]
8503   ""
8504   "
8506   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8507     FAIL;
8509   /* set up operands from compare.  */
8510   operands[1] = branch_cmp[0];
8511   operands[2] = branch_cmp[1];
8513   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8514     {
8515       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8516       DONE;
8517     }
8519   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8520     operands[2] = force_reg (SImode, operands[2]);
8522   /* fall through and generate default code */
8525 (define_insn "sgt_si"
8526   [(set (match_operand:SI 0 "register_operand" "=d")
8527         (gt:SI (match_operand:SI 1 "register_operand" "d")
8528                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8529   "!TARGET_MIPS16"
8530   "slt\\t%0,%z2,%1"
8531   [(set_attr "type"     "arith")
8532    (set_attr "mode"     "SI")])
8534 (define_insn ""
8535   [(set (match_operand:SI 0 "register_operand" "=t")
8536         (gt:SI (match_operand:SI 1 "register_operand" "d")
8537                (match_operand:SI 2 "register_operand" "d")))]
8538   "TARGET_MIPS16"
8539   "slt\\t%2,%1"
8540   [(set_attr "type"     "arith")
8541    (set_attr "mode"     "SI")])
8543 (define_insn "sgt_di"
8544   [(set (match_operand:DI 0 "register_operand" "=d")
8545         (gt:DI (match_operand:DI 1 "register_operand" "d")
8546                (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
8547   "TARGET_64BIT && !TARGET_MIPS16"
8548   "slt\\t%0,%z2,%1"
8549   [(set_attr "type"     "arith")
8550    (set_attr "mode"     "DI")])
8552 (define_insn ""
8553   [(set (match_operand:DI 0 "register_operand" "=d")
8554         (gt:DI (match_operand:DI 1 "register_operand" "d")
8555                (match_operand:DI 2 "register_operand" "d")))]
8556   "TARGET_64BIT && TARGET_MIPS16"
8557   "slt\\t%2,%1"
8558   [(set_attr "type"     "arith")
8559    (set_attr "mode"     "DI")])
8561 (define_expand "sge"
8562   [(set (match_operand:SI 0 "register_operand" "=d")
8563         (ge:SI (match_dup 1)
8564                (match_dup 2)))]
8565   ""
8566   "
8568   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8569     FAIL;
8571   /* set up operands from compare.  */
8572   operands[1] = branch_cmp[0];
8573   operands[2] = branch_cmp[1];
8575   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8576     {
8577       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8578       DONE;
8579     }
8581   /* fall through and generate default code */
8584 (define_insn "sge_si"
8585   [(set (match_operand:SI 0 "register_operand" "=d")
8586         (ge:SI (match_operand:SI 1 "register_operand" "d")
8587                (match_operand:SI 2 "arith_operand" "dI")))]
8588   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8589   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8590   [(set_attr "type"     "arith")
8591    (set_attr "mode"     "SI")
8592    (set_attr "length"   "8")])
8594 (define_split
8595   [(set (match_operand:SI 0 "register_operand" "")
8596         (ge:SI (match_operand:SI 1 "register_operand" "")
8597                (match_operand:SI 2 "arith_operand" "")))]
8598   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8599   [(set (match_dup 0)
8600         (lt:SI (match_dup 1)
8601                (match_dup 2)))
8602    (set (match_dup 0)
8603         (xor:SI (match_dup 0)
8604                 (const_int 1)))]
8605   "")
8607 (define_insn "sge_di"
8608   [(set (match_operand:DI 0 "register_operand" "=d")
8609         (ge:DI (match_operand:DI 1 "register_operand" "d")
8610                (match_operand:DI 2 "arith_operand" "dI")))]
8611   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8612   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8613   [(set_attr "type"     "arith")
8614    (set_attr "mode"     "DI")
8615    (set_attr "length"   "8")])
8617 (define_split
8618   [(set (match_operand:DI 0 "register_operand" "")
8619         (ge:DI (match_operand:DI 1 "register_operand" "")
8620                (match_operand:DI 2 "arith_operand" "")))]
8621   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8622    && !TARGET_MIPS16"
8623   [(set (match_dup 0)
8624         (lt:DI (match_dup 1)
8625                (match_dup 2)))
8626    (set (match_dup 0)
8627         (xor:DI (match_dup 0)
8628                 (const_int 1)))]
8629   "")
8631 (define_expand "slt"
8632   [(set (match_operand:SI 0 "register_operand" "=d")
8633         (lt:SI (match_dup 1)
8634                (match_dup 2)))]
8635   ""
8636   "
8638   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8639     FAIL;
8641   /* set up operands from compare.  */
8642   operands[1] = branch_cmp[0];
8643   operands[2] = branch_cmp[1];
8645   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8646     {
8647       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8648       DONE;
8649     }
8651   /* fall through and generate default code */
8654 (define_insn "slt_si"
8655   [(set (match_operand:SI 0 "register_operand" "=d")
8656         (lt:SI (match_operand:SI 1 "register_operand" "d")
8657                (match_operand:SI 2 "arith_operand" "dI")))]
8658   "!TARGET_MIPS16"
8659   "slt\\t%0,%1,%2"
8660   [(set_attr "type"     "arith")
8661    (set_attr "mode"     "SI")])
8663 (define_insn ""
8664   [(set (match_operand:SI 0 "register_operand" "=t,t")
8665         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8666                (match_operand:SI 2 "arith_operand" "d,I")))]
8667   "TARGET_MIPS16"
8668   "slt\\t%1,%2"
8669   [(set_attr "type"     "arith")
8670    (set_attr "mode"     "SI")
8671    (set_attr_alternative "length"
8672                 [(const_int 4)
8673                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8674                                (const_int 4)
8675                                (const_int 8))])])
8677 (define_insn "slt_di"
8678   [(set (match_operand:DI 0 "register_operand" "=d")
8679         (lt:DI (match_operand:DI 1 "register_operand" "d")
8680                (match_operand:DI 2 "arith_operand" "dI")))]
8681   "TARGET_64BIT && !TARGET_MIPS16"
8682   "slt\\t%0,%1,%2"
8683   [(set_attr "type"     "arith")
8684    (set_attr "mode"     "DI")])
8686 (define_insn ""
8687   [(set (match_operand:DI 0 "register_operand" "=t,t")
8688         (lt:DI (match_operand:DI 1 "register_operand" "d,d")
8689                (match_operand:DI 2 "arith_operand" "d,I")))]
8690   "TARGET_64BIT && TARGET_MIPS16"
8691   "slt\\t%1,%2"
8692   [(set_attr "type"     "arith")
8693    (set_attr "mode"     "DI")
8694    (set_attr_alternative "length"
8695                 [(const_int 4)
8696                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8697                                (const_int 4)
8698                                (const_int 8))])])
8700 (define_expand "sle"
8701   [(set (match_operand:SI 0 "register_operand" "=d")
8702         (le: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 (LE, operands[0], operands[1], operands[2], (int *)0);
8717       DONE;
8718     }
8720   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8721     operands[2] = force_reg (SImode, operands[2]);
8723   /* fall through and generate default code */
8726 (define_insn "sle_si_const"
8727   [(set (match_operand:SI 0 "register_operand" "=d")
8728         (le:SI (match_operand:SI 1 "register_operand" "d")
8729                (match_operand:SI 2 "small_int" "I")))]
8730   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8731   "*
8733   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8734   return \"slt\\t%0,%1,%2\";
8736   [(set_attr "type"     "arith")
8737    (set_attr "mode"     "SI")])
8739 (define_insn ""
8740   [(set (match_operand:SI 0 "register_operand" "=t")
8741         (le:SI (match_operand:SI 1 "register_operand" "d")
8742                (match_operand:SI 2 "small_int" "I")))]
8743   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8744   "*
8746   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8747   return \"slt\\t%1,%2\";
8749   [(set_attr "type"     "arith")
8750    (set_attr "mode"     "SI")
8751    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8752                                       (const_int 4)
8753                                       (const_int 8)))])
8755 (define_insn "sle_di_const"
8756   [(set (match_operand:DI 0 "register_operand" "=d")
8757         (le:DI (match_operand:DI 1 "register_operand" "d")
8758                (match_operand:DI 2 "small_int" "I")))]
8759   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8760   "*
8762   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8763   return \"slt\\t%0,%1,%2\";
8765   [(set_attr "type"     "arith")
8766    (set_attr "mode"     "DI")])
8768 (define_insn ""
8769   [(set (match_operand:DI 0 "register_operand" "=t")
8770         (le:DI (match_operand:DI 1 "register_operand" "d")
8771                (match_operand:DI 2 "small_int" "I")))]
8772   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8773   "*
8775   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8776   return \"slt\\t%1,%2\";
8778   [(set_attr "type"     "arith")
8779    (set_attr "mode"     "DI")
8780    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8781                                       (const_int 4)
8782                                       (const_int 8)))])
8784 (define_insn "sle_si_reg"
8785   [(set (match_operand:SI 0 "register_operand" "=d")
8786         (le:SI (match_operand:SI 1 "register_operand" "d")
8787                (match_operand:SI 2 "register_operand" "d")))]
8788   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8789   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8790   [(set_attr "type"     "arith")
8791    (set_attr "mode"     "SI")
8792    (set_attr "length"   "8")])
8794 (define_split
8795   [(set (match_operand:SI 0 "register_operand" "")
8796         (le:SI (match_operand:SI 1 "register_operand" "")
8797                (match_operand:SI 2 "register_operand" "")))]
8798   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8799   [(set (match_dup 0)
8800         (lt:SI (match_dup 2)
8801                (match_dup 1)))
8802    (set (match_dup 0)
8803         (xor:SI (match_dup 0)
8804                 (const_int 1)))]
8805   "")
8807 (define_insn "sle_di_reg"
8808   [(set (match_operand:DI 0 "register_operand" "=d")
8809         (le:DI (match_operand:DI 1 "register_operand" "d")
8810                (match_operand:DI 2 "register_operand" "d")))]
8811   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8812   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8813   [(set_attr "type"     "arith")
8814    (set_attr "mode"     "DI")
8815    (set_attr "length"   "8")])
8817 (define_split
8818   [(set (match_operand:DI 0 "register_operand" "")
8819         (le:DI (match_operand:DI 1 "register_operand" "")
8820                (match_operand:DI 2 "register_operand" "")))]
8821   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8822    && !TARGET_MIPS16"
8823   [(set (match_dup 0)
8824         (lt:DI (match_dup 2)
8825                (match_dup 1)))
8826    (set (match_dup 0)
8827         (xor:DI (match_dup 0)
8828                 (const_int 1)))]
8829   "")
8831 (define_expand "sgtu"
8832   [(set (match_operand:SI 0 "register_operand" "=d")
8833         (gtu:SI (match_dup 1)
8834                 (match_dup 2)))]
8835   ""
8836   "
8838   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8839     FAIL;
8841   /* set up operands from compare.  */
8842   operands[1] = branch_cmp[0];
8843   operands[2] = branch_cmp[1];
8845   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8846     {
8847       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8848       DONE;
8849     }
8851   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8852     operands[2] = force_reg (SImode, operands[2]);
8854   /* fall through and generate default code */
8857 (define_insn "sgtu_si"
8858   [(set (match_operand:SI 0 "register_operand" "=d")
8859         (gtu:SI (match_operand:SI 1 "register_operand" "d")
8860                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8861   "!TARGET_MIPS16"
8862   "sltu\\t%0,%z2,%1"
8863   [(set_attr "type"     "arith")
8864    (set_attr "mode"     "SI")])
8866 (define_insn ""
8867   [(set (match_operand:SI 0 "register_operand" "=t")
8868         (gtu:SI (match_operand:SI 1 "register_operand" "d")
8869                 (match_operand:SI 2 "register_operand" "d")))]
8870   "TARGET_MIPS16"
8871   "sltu\\t%2,%1"
8872   [(set_attr "type"     "arith")
8873    (set_attr "mode"     "SI")])
8875 (define_insn "sgtu_di"
8876   [(set (match_operand:DI 0 "register_operand" "=d")
8877         (gtu:DI (match_operand:DI 1 "register_operand" "d")
8878                 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
8879   "TARGET_64BIT && !TARGET_MIPS16"
8880   "sltu\\t%0,%z2,%1"
8881   [(set_attr "type"     "arith")
8882    (set_attr "mode"     "DI")])
8884 (define_insn ""
8885   [(set (match_operand:DI 0 "register_operand" "=t")
8886         (gtu:DI (match_operand:DI 1 "register_operand" "d")
8887                 (match_operand:DI 2 "register_operand" "d")))]
8888   "TARGET_64BIT && TARGET_MIPS16"
8889   "sltu\\t%2,%1"
8890   [(set_attr "type"     "arith")
8891    (set_attr "mode"     "DI")])
8893 (define_expand "sgeu"
8894   [(set (match_operand:SI 0 "register_operand" "=d")
8895         (geu:SI (match_dup 1)
8896                 (match_dup 2)))]
8897   ""
8898   "
8900   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8901     FAIL;
8903   /* set up operands from compare.  */
8904   operands[1] = branch_cmp[0];
8905   operands[2] = branch_cmp[1];
8907   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8908     {
8909       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8910       DONE;
8911     }
8913   /* fall through and generate default code */
8916 (define_insn "sgeu_si"
8917   [(set (match_operand:SI 0 "register_operand" "=d")
8918         (geu:SI (match_operand:SI 1 "register_operand" "d")
8919                 (match_operand:SI 2 "arith_operand" "dI")))]
8920   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8921   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8922   [(set_attr "type"     "arith")
8923    (set_attr "mode"     "SI")
8924    (set_attr "length"   "8")])
8926 (define_split
8927   [(set (match_operand:SI 0 "register_operand" "")
8928         (geu:SI (match_operand:SI 1 "register_operand" "")
8929                 (match_operand:SI 2 "arith_operand" "")))]
8930   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8931   [(set (match_dup 0)
8932         (ltu:SI (match_dup 1)
8933                 (match_dup 2)))
8934    (set (match_dup 0)
8935         (xor:SI (match_dup 0)
8936                 (const_int 1)))]
8937   "")
8939 (define_insn "sgeu_di"
8940   [(set (match_operand:DI 0 "register_operand" "=d")
8941         (geu:DI (match_operand:DI 1 "register_operand" "d")
8942                 (match_operand:DI 2 "arith_operand" "dI")))]
8943   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8944   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8945   [(set_attr "type"     "arith")
8946    (set_attr "mode"     "DI")
8947    (set_attr "length"   "8")])
8949 (define_split
8950   [(set (match_operand:DI 0 "register_operand" "")
8951         (geu:DI (match_operand:DI 1 "register_operand" "")
8952                 (match_operand:DI 2 "arith_operand" "")))]
8953   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8954    && !TARGET_MIPS16"
8955   [(set (match_dup 0)
8956         (ltu:DI (match_dup 1)
8957                 (match_dup 2)))
8958    (set (match_dup 0)
8959         (xor:DI (match_dup 0)
8960                 (const_int 1)))]
8961   "")
8963 (define_expand "sltu"
8964   [(set (match_operand:SI 0 "register_operand" "=d")
8965         (ltu:SI (match_dup 1)
8966                 (match_dup 2)))]
8967   ""
8968   "
8970   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8971     FAIL;
8973   /* set up operands from compare.  */
8974   operands[1] = branch_cmp[0];
8975   operands[2] = branch_cmp[1];
8977   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8978     {
8979       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8980       DONE;
8981     }
8983   /* fall through and generate default code */
8986 (define_insn "sltu_si"
8987   [(set (match_operand:SI 0 "register_operand" "=d")
8988         (ltu:SI (match_operand:SI 1 "register_operand" "d")
8989                 (match_operand:SI 2 "arith_operand" "dI")))]
8990   "!TARGET_MIPS16"
8991   "sltu\\t%0,%1,%2"
8992   [(set_attr "type"     "arith")
8993    (set_attr "mode"     "SI")])
8995 (define_insn ""
8996   [(set (match_operand:SI 0 "register_operand" "=t,t")
8997         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8998                 (match_operand:SI 2 "arith_operand" "d,I")))]
8999   "TARGET_MIPS16"
9000   "sltu\\t%1,%2"
9001   [(set_attr "type"     "arith")
9002    (set_attr "mode"     "SI")
9003    (set_attr_alternative "length"
9004                 [(const_int 4)
9005                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
9006                                (const_int 4)
9007                                (const_int 8))])])
9009 (define_insn "sltu_di"
9010   [(set (match_operand:DI 0 "register_operand" "=d")
9011         (ltu:DI (match_operand:DI 1 "register_operand" "d")
9012                 (match_operand:DI 2 "arith_operand" "dI")))]
9013   "TARGET_64BIT && !TARGET_MIPS16"
9014   "sltu\\t%0,%1,%2"
9015   [(set_attr "type"     "arith")
9016    (set_attr "mode"     "DI")])
9018 (define_insn ""
9019   [(set (match_operand:DI 0 "register_operand" "=t,t")
9020         (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
9021                 (match_operand:DI 2 "arith_operand" "d,I")))]
9022   "TARGET_64BIT && TARGET_MIPS16"
9023   "sltu\\t%1,%2"
9024   [(set_attr "type"     "arith")
9025    (set_attr "mode"     "DI")
9026    (set_attr_alternative "length"
9027                 [(const_int 4)
9028                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
9029                                (const_int 4)
9030                                (const_int 8))])])
9032 (define_expand "sleu"
9033   [(set (match_operand:SI 0 "register_operand" "=d")
9034         (leu: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 (LEU, operands[0], operands[1], operands[2], (int *)0);
9049       DONE;
9050     }
9052   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
9053     operands[2] = force_reg (SImode, operands[2]);
9055   /* fall through and generate default code */
9058 (define_insn "sleu_si_const"
9059   [(set (match_operand:SI 0 "register_operand" "=d")
9060         (leu:SI (match_operand:SI 1 "register_operand" "d")
9061                 (match_operand:SI 2 "small_int" "I")))]
9062   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9063   "*
9065   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9066   return \"sltu\\t%0,%1,%2\";
9068   [(set_attr "type"     "arith")
9069    (set_attr "mode"     "SI")])
9071 (define_insn ""
9072   [(set (match_operand:SI 0 "register_operand" "=t")
9073         (leu:SI (match_operand:SI 1 "register_operand" "d")
9074                 (match_operand:SI 2 "small_int" "I")))]
9075   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9076   "*
9078   operands[2] = GEN_INT (INTVAL (operands[2])+1);
9079   return \"sltu\\t%1,%2\";
9081   [(set_attr "type"     "arith")
9082    (set_attr "mode"     "SI")
9083    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9084                                       (const_int 4)
9085                                       (const_int 8)))])
9087 (define_insn "sleu_di_const"
9088   [(set (match_operand:DI 0 "register_operand" "=d")
9089         (leu:DI (match_operand:DI 1 "register_operand" "d")
9090                 (match_operand:DI 2 "small_int" "I")))]
9091   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9092   "*
9094   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9095   return \"sltu\\t%0,%1,%2\";
9097   [(set_attr "type"     "arith")
9098    (set_attr "mode"     "DI")])
9100 (define_insn ""
9101   [(set (match_operand:DI 0 "register_operand" "=t")
9102         (leu:DI (match_operand:DI 1 "register_operand" "d")
9103                 (match_operand:DI 2 "small_int" "I")))]
9104   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9105   "*
9107   operands[2] = GEN_INT (INTVAL (operands[2])+1);
9108   return \"sltu\\t%1,%2\";
9110   [(set_attr "type"     "arith")
9111    (set_attr "mode"     "DI")
9112    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9113                                       (const_int 4)
9114                                       (const_int 8)))])
9116 (define_insn "sleu_si_reg"
9117   [(set (match_operand:SI 0 "register_operand" "=d")
9118         (leu:SI (match_operand:SI 1 "register_operand" "d")
9119                 (match_operand:SI 2 "register_operand" "d")))]
9120   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9121   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9122   [(set_attr "type"     "arith")
9123    (set_attr "mode"     "SI")
9124    (set_attr "length"   "8")])
9126 (define_split
9127   [(set (match_operand:SI 0 "register_operand" "")
9128         (leu:SI (match_operand:SI 1 "register_operand" "")
9129                 (match_operand:SI 2 "register_operand" "")))]
9130   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
9131   [(set (match_dup 0)
9132         (ltu:SI (match_dup 2)
9133                 (match_dup 1)))
9134    (set (match_dup 0)
9135         (xor:SI (match_dup 0)
9136                 (const_int 1)))]
9137   "")
9139 (define_insn "sleu_di_reg"
9140   [(set (match_operand:DI 0 "register_operand" "=d")
9141         (leu:DI (match_operand:DI 1 "register_operand" "d")
9142                 (match_operand:DI 2 "register_operand" "d")))]
9143   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9144   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9145   [(set_attr "type"     "arith")
9146    (set_attr "mode"     "DI")
9147    (set_attr "length"   "8")])
9149 (define_split
9150   [(set (match_operand:DI 0 "register_operand" "")
9151         (leu:DI (match_operand:DI 1 "register_operand" "")
9152                 (match_operand:DI 2 "register_operand" "")))]
9153   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9154    && !TARGET_MIPS16"
9155   [(set (match_dup 0)
9156         (ltu:DI (match_dup 2)
9157                 (match_dup 1)))
9158    (set (match_dup 0)
9159         (xor:DI (match_dup 0)
9160                 (const_int 1)))]
9161   "")
9165 ;;  ....................
9167 ;;      FLOATING POINT COMPARISONS
9169 ;;  ....................
9171 (define_insn "sunordered_df"
9172   [(set (match_operand:CC 0 "register_operand" "=z")
9173         (unordered:CC (match_operand:DF 1 "register_operand" "f")
9174                       (match_operand:DF 2 "register_operand" "f")))]
9175   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9176   "c.un.d\t%Z0%1,%2"
9177   [(set_attr "type" "fcmp")
9178    (set_attr "mode" "FPSW")])
9180 (define_insn "sunlt_df"
9181   [(set (match_operand:CC 0 "register_operand" "=z")
9182         (unlt:CC (match_operand:DF 1 "register_operand" "f")
9183                  (match_operand:DF 2 "register_operand" "f")))]
9184   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9185   "c.ult.d\t%Z0%1,%2"
9186   [(set_attr "type" "fcmp")
9187    (set_attr "mode" "FPSW")])
9189 (define_insn "suneq_df"
9190   [(set (match_operand:CC 0 "register_operand" "=z")
9191         (uneq:CC (match_operand:DF 1 "register_operand" "f")
9192                  (match_operand:DF 2 "register_operand" "f")))]
9193   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9194   "c.ueq.d\t%Z0%1,%2"
9195   [(set_attr "type" "fcmp")
9196    (set_attr "mode" "FPSW")])
9198 (define_insn "sunle_df"
9199   [(set (match_operand:CC 0 "register_operand" "=z")
9200         (unle:CC (match_operand:DF 1 "register_operand" "f")
9201                  (match_operand:DF 2 "register_operand" "f")))]
9202   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9203   "c.ule.d\t%Z0%1,%2"
9204   [(set_attr "type" "fcmp")
9205    (set_attr "mode" "FPSW")])
9207 (define_insn "seq_df"
9208   [(set (match_operand:CC 0 "register_operand" "=z")
9209         (eq:CC (match_operand:DF 1 "register_operand" "f")
9210                (match_operand:DF 2 "register_operand" "f")))]
9211   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9212   "c.eq.d\t%Z0%1,%2"
9213   [(set_attr "type" "fcmp")
9214    (set_attr "mode" "FPSW")])
9216 (define_insn "slt_df"
9217   [(set (match_operand:CC 0 "register_operand" "=z")
9218         (lt:CC (match_operand:DF 1 "register_operand" "f")
9219                (match_operand:DF 2 "register_operand" "f")))]
9220   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9221   "c.lt.d\t%Z0%1,%2"
9222   [(set_attr "type" "fcmp")
9223    (set_attr "mode" "FPSW")])
9225 (define_insn "sle_df"
9226   [(set (match_operand:CC 0 "register_operand" "=z")
9227         (le:CC (match_operand:DF 1 "register_operand" "f")
9228                (match_operand:DF 2 "register_operand" "f")))]
9229   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9230   "c.le.d\t%Z0%1,%2"
9231   [(set_attr "type" "fcmp")
9232    (set_attr "mode" "FPSW")])
9234 (define_insn "sgt_df"
9235   [(set (match_operand:CC 0 "register_operand" "=z")
9236         (gt:CC (match_operand:DF 1 "register_operand" "f")
9237                (match_operand:DF 2 "register_operand" "f")))]
9238   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9239   "c.lt.d\t%Z0%2,%1"
9240   [(set_attr "type" "fcmp")
9241    (set_attr "mode" "FPSW")])
9243 (define_insn "sge_df"
9244   [(set (match_operand:CC 0 "register_operand" "=z")
9245         (ge:CC (match_operand:DF 1 "register_operand" "f")
9246                (match_operand:DF 2 "register_operand" "f")))]
9247   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9248   "c.le.d\t%Z0%2,%1"
9249   [(set_attr "type" "fcmp")
9250    (set_attr "mode" "FPSW")])
9252 (define_insn "sunordered_sf"
9253   [(set (match_operand:CC 0 "register_operand" "=z")
9254         (unordered:CC (match_operand:SF 1 "register_operand" "f")
9255                       (match_operand:SF 2 "register_operand" "f")))]
9256   "TARGET_HARD_FLOAT"
9257   "c.un.s\t%Z0%1,%2"
9258   [(set_attr "type" "fcmp")
9259    (set_attr "mode" "FPSW")])
9261 (define_insn "sunlt_sf"
9262   [(set (match_operand:CC 0 "register_operand" "=z")
9263         (unlt:CC (match_operand:SF 1 "register_operand" "f")
9264                  (match_operand:SF 2 "register_operand" "f")))]
9265   "TARGET_HARD_FLOAT"
9266   "c.ult.s\t%Z0%1,%2"
9267   [(set_attr "type" "fcmp")
9268    (set_attr "mode" "FPSW")])
9270 (define_insn "suneq_sf"
9271   [(set (match_operand:CC 0 "register_operand" "=z")
9272         (uneq:CC (match_operand:SF 1 "register_operand" "f")
9273                  (match_operand:SF 2 "register_operand" "f")))]
9274   "TARGET_HARD_FLOAT"
9275   "c.ueq.s\t%Z0%1,%2"
9276   [(set_attr "type" "fcmp")
9277    (set_attr "mode" "FPSW")])
9279 (define_insn "sunle_sf"
9280   [(set (match_operand:CC 0 "register_operand" "=z")
9281         (unle:CC (match_operand:SF 1 "register_operand" "f")
9282                  (match_operand:SF 2 "register_operand" "f")))]
9283   "TARGET_HARD_FLOAT"
9284   "c.ule.s\t%Z0%1,%2"
9285   [(set_attr "type" "fcmp")
9286    (set_attr "mode" "FPSW")])
9288 (define_insn "seq_sf"
9289   [(set (match_operand:CC 0 "register_operand" "=z")
9290         (eq:CC (match_operand:SF 1 "register_operand" "f")
9291                (match_operand:SF 2 "register_operand" "f")))]
9292   "TARGET_HARD_FLOAT"
9293   "c.eq.s\t%Z0%1,%2"
9294   [(set_attr "type" "fcmp")
9295    (set_attr "mode" "FPSW")])
9297 (define_insn "slt_sf"
9298   [(set (match_operand:CC 0 "register_operand" "=z")
9299         (lt:CC (match_operand:SF 1 "register_operand" "f")
9300                (match_operand:SF 2 "register_operand" "f")))]
9301   "TARGET_HARD_FLOAT"
9302   "c.lt.s\t%Z0%1,%2"
9303   [(set_attr "type" "fcmp")
9304    (set_attr "mode" "FPSW")])
9306 (define_insn "sle_sf"
9307   [(set (match_operand:CC 0 "register_operand" "=z")
9308         (le:CC (match_operand:SF 1 "register_operand" "f")
9309                (match_operand:SF 2 "register_operand" "f")))]
9310   "TARGET_HARD_FLOAT"
9311   "c.le.s\t%Z0%1,%2"
9312   [(set_attr "type" "fcmp")
9313    (set_attr "mode" "FPSW")])
9315 (define_insn "sgt_sf"
9316   [(set (match_operand:CC 0 "register_operand" "=z")
9317         (gt:CC (match_operand:SF 1 "register_operand" "f")
9318                (match_operand:SF 2 "register_operand" "f")))]
9319   "TARGET_HARD_FLOAT"
9320   "c.lt.s\t%Z0%2,%1"
9321   [(set_attr "type" "fcmp")
9322    (set_attr "mode" "FPSW")])
9324 (define_insn "sge_sf"
9325   [(set (match_operand:CC 0 "register_operand" "=z")
9326         (ge:CC (match_operand:SF 1 "register_operand" "f")
9327                (match_operand:SF 2 "register_operand" "f")))]
9328   "TARGET_HARD_FLOAT"
9329   "c.le.s\t%Z0%2,%1"
9330   [(set_attr "type" "fcmp")
9331    (set_attr "mode" "FPSW")])
9335 ;;  ....................
9337 ;;      UNCONDITIONAL BRANCHES
9339 ;;  ....................
9341 ;; Unconditional branches.
9343 (define_insn "jump"
9344   [(set (pc)
9345         (label_ref (match_operand 0 "" "")))]
9346   "!TARGET_MIPS16"
9347   "*
9349   if (flag_pic && ! TARGET_EMBEDDED_PIC)
9350     {
9351       if (get_attr_length (insn) <= 8)
9352         return \"%*b\\t%l0\";
9353       else if (Pmode == DImode)
9354         return \"%[dla\\t%@,%l0\;%*jr\\t%@%]\";
9355       else
9356         return \"%[la\\t%@,%l0\;%*jr\\t%@%]\";
9357     }
9358   else
9359     return \"%*j\\t%l0\";
9361   [(set_attr "type"     "jump")
9362    (set_attr "mode"     "none")
9363    (set (attr "length")
9364         ;; we can't use `j' when emitting non-embedded PIC, so we emit
9365         ;; branch, if it's in range, or load the address of the branch
9366         ;; target into $at in a PIC-compatible way and then jump to it.
9367         (if_then_else
9368          (ior (eq (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
9369                   (const_int 0))
9370               (lt (abs (minus (match_dup 0)
9371                               (plus (pc) (const_int 4))))
9372                   (const_int 131072)))
9373          (const_int 4) (const_int 16)))])
9375 ;; We need a different insn for the mips16, because a mips16 branch
9376 ;; does not have a delay slot.
9378 (define_insn ""
9379   [(set (pc)
9380         (label_ref (match_operand 0 "" "")))]
9381   "TARGET_MIPS16"
9382   "b\\t%l0"
9383   [(set_attr "type"     "branch")
9384    (set_attr "mode"     "none")
9385    (set_attr "length"   "8")])
9387 (define_expand "indirect_jump"
9388   [(set (pc) (match_operand 0 "register_operand" "d"))]
9389   ""
9390   "
9392   rtx dest;
9394   if (operands[0])              /* eliminate unused code warnings */
9395     {
9396       dest = operands[0];
9397       if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9398         operands[0] = copy_to_mode_reg (Pmode, dest);
9400       if (!(Pmode == DImode))
9401         emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9402       else
9403         emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9405       DONE;
9406     }
9409 (define_insn "indirect_jump_internal1"
9410   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
9411   "!(Pmode == DImode)"
9412   "%*j\\t%0"
9413   [(set_attr "type"     "jump")
9414    (set_attr "mode"     "none")])
9416 (define_insn "indirect_jump_internal2"
9417   [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
9418   "Pmode == DImode"
9419   "%*j\\t%0"
9420   [(set_attr "type"     "jump")
9421    (set_attr "mode"     "none")])
9423 (define_expand "tablejump"
9424   [(set (pc)
9425         (match_operand 0 "register_operand" "d"))
9426    (use (label_ref (match_operand 1 "" "")))]
9427   ""
9428   "
9430   if (operands[0])              /* eliminate unused code warnings */
9431     {
9432       if (TARGET_MIPS16)
9433         {
9434           if (GET_MODE (operands[0]) != HImode)
9435             abort ();
9436           if (!(Pmode == DImode))
9437             emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
9438           else
9439             emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
9440           DONE;
9441         }
9443       if (GET_MODE (operands[0]) != ptr_mode)
9444         abort ();
9446       if (TARGET_GPWORD)
9447         operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
9448                                     pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
9450       if (Pmode == SImode)
9451         emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9452       else
9453         emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
9454       DONE;
9455     }
9458 (define_insn "tablejump_internal1"
9459   [(set (pc)
9460         (match_operand:SI 0 "register_operand" "d"))
9461    (use (label_ref (match_operand 1 "" "")))]
9462   ""
9463   "%*j\\t%0"
9464   [(set_attr "type"     "jump")
9465    (set_attr "mode"     "none")])
9467 (define_insn "tablejump_internal2"
9468   [(set (pc)
9469         (match_operand:DI 0 "register_operand" "d"))
9470    (use (label_ref (match_operand 1 "" "")))]
9471   "TARGET_64BIT"
9472   "%*j\\t%0"
9473   [(set_attr "type"     "jump")
9474    (set_attr "mode"     "none")])
9476 (define_expand "tablejump_mips161"
9477   [(set (pc) (plus:SI (sign_extend:SI
9478                        (match_operand:HI 0 "register_operand" "d"))
9479                       (label_ref:SI (match_operand 1 "" ""))))]
9480   "TARGET_MIPS16 && !(Pmode == DImode)"
9481   "
9483   if (operands[0])      /* eliminate unused code warnings.  */
9484     {
9485       rtx t1, t2, t3;
9487       t1 = gen_reg_rtx (SImode);
9488       t2 = gen_reg_rtx (SImode);
9489       t3 = gen_reg_rtx (SImode);
9490       emit_insn (gen_extendhisi2 (t1, operands[0]));
9491       emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
9492       emit_insn (gen_addsi3 (t3, t1, t2));
9493       emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
9494       DONE;
9495     }
9498 (define_expand "tablejump_mips162"
9499   [(set (pc) (plus:DI (sign_extend:DI
9500                        (match_operand:HI 0 "register_operand" "d"))
9501                       (label_ref:DI (match_operand 1 "" ""))))]
9502   "TARGET_MIPS16 && Pmode == DImode"
9503   "
9505   if (operands[0])      /* eliminate unused code warnings.  */
9506     {
9507       rtx t1, t2, t3;
9509       t1 = gen_reg_rtx (DImode);
9510       t2 = gen_reg_rtx (DImode);
9511       t3 = gen_reg_rtx (DImode);
9512       emit_insn (gen_extendhidi2 (t1, operands[0]));
9513       emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
9514       emit_insn (gen_adddi3 (t3, t1, t2));
9515       emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
9516       DONE;
9517     }
9520 ;; Implement a switch statement when generating embedded PIC code.
9521 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
9523 (define_expand "casesi"
9524   [(set (match_dup 5)
9525         (minus:SI (match_operand:SI 0 "register_operand" "d")
9526                   (match_operand:SI 1 "arith_operand" "dI")))
9527    (set (cc0)
9528         (compare:CC (match_dup 5)
9529                     (match_operand:SI 2 "arith_operand" "")))
9530    (set (pc)
9531         (if_then_else (gtu (cc0)
9532                            (const_int 0))
9533                       (label_ref (match_operand 4 "" ""))
9534                       (pc)))
9535    (parallel
9536     [(set (pc)
9537           (mem:SI (plus:SI (mult:SI (match_dup 5)
9538                                     (const_int 4))
9539                            (label_ref (match_operand 3 "" "")))))
9540      (clobber (match_scratch:SI 6 ""))
9541      (clobber (reg:SI 31))])]
9542   "TARGET_EMBEDDED_PIC"
9543   "
9545   if (operands[0])
9546     {
9547       rtx reg = gen_reg_rtx (SImode);
9549       /* If the index is too large, go to the default label.  */
9550       emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9551       emit_insn (gen_cmpsi (reg, operands[2]));
9552       emit_insn (gen_bgtu (operands[4]));
9554       /* Do the PIC jump.  */
9555       if (Pmode != DImode)
9556         emit_jump_insn (gen_casesi_internal (reg, operands[3],
9557                                              gen_reg_rtx (SImode)));
9558       else
9559         emit_jump_insn (gen_casesi_internal_di (reg, operands[3],
9560                                                 gen_reg_rtx (DImode)));
9562       DONE;
9563     }
9566 ;; An embedded PIC switch statement looks like this:
9567 ;;      bal     $LS1
9568 ;;      sll     $reg,$index,2
9569 ;; $LS1:
9570 ;;      addu    $reg,$reg,$31
9571 ;;      lw      $reg,$L1-$LS1($reg)
9572 ;;      addu    $reg,$reg,$31
9573 ;;      j       $reg
9574 ;; $L1:
9575 ;;      .word   case1-$LS1
9576 ;;      .word   case2-$LS1
9577 ;;      ...
9579 (define_insn "casesi_internal"
9580   [(set (pc)
9581         (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9582                                   (const_int 4))
9583                          (label_ref (match_operand 1 "" "")))))
9584    (clobber (match_operand:SI 2 "register_operand" "=d"))
9585    (clobber (reg:SI 31))]
9586   "TARGET_EMBEDDED_PIC"
9587   "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9588 lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2"
9589   [(set_attr "type"     "jump")
9590    (set_attr "mode"     "none")
9591    (set_attr "length"   "24")])
9593 ;; This code assumes that the table index will never be >= 29 bits wide,
9594 ;; which allows the 'sign extend' from SI to DI be a no-op.
9595 (define_insn "casesi_internal_di"
9596   [(set (pc)
9597         (mem:DI (plus:DI (sign_extend:DI
9598                           (mult:SI (match_operand:SI 0 "register_operand" "d")
9599                                   (const_int 8)))
9600                          (label_ref (match_operand 1 "" "")))))
9601    (clobber (match_operand:DI 2 "register_operand" "=d"))
9602    (clobber (reg:DI 31))]
9603   "TARGET_EMBEDDED_PIC"
9604   "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
9605 ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
9606   [(set_attr "type"     "jump")
9607    (set_attr "mode"     "none")
9608    (set_attr "length"   "24")])
9610 ;; For o32/n32/n64, we save the gp in the jmp_buf as well.  While it is
9611 ;; possible to either pull it off the stack (in the o32 case) or recalculate
9612 ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9613 ;; this is easy.
9615 (define_expand "builtin_setjmp_setup"
9616   [(unspec [(match_operand 0 "register_operand" "r")] UNSPEC_SETJMP)]
9617   "TARGET_ABICALLS"
9618   "
9620   if (Pmode == DImode)
9621     emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9622   else
9623     emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9624   DONE;
9627 (define_expand "builtin_setjmp_setup_32"
9628   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9629                    (const_int 12)))
9630       (reg:SI 28))]
9631   "TARGET_ABICALLS && ! (Pmode == DImode)"
9632   "")
9634 (define_expand "builtin_setjmp_setup_64"
9635   [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9636                    (const_int 24)))
9637       (reg:DI 28))]
9638   "TARGET_ABICALLS && Pmode == DImode"
9639   "")
9641 ;; For o32/n32/n64, we need to arrange for longjmp to put the
9642 ;; target address in t9 so that we can use it for loading $gp.
9644 (define_expand "builtin_longjmp"
9645   [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPEC_LONGJMP)]
9646   "TARGET_ABICALLS"
9647   "
9649   /* The elements of the buffer are, in order:  */
9650   int W = (Pmode == DImode ? 8 : 4);
9651   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9652   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9653   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9654   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9655   rtx pv = gen_rtx_REG (Pmode, 25);
9656   rtx gp = gen_rtx_REG (Pmode, 28);
9658   /* This bit is the same as expand_builtin_longjmp.  */
9659   emit_move_insn (hard_frame_pointer_rtx, fp);
9660   emit_move_insn (pv, lab);
9661   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9662   emit_move_insn (gp, gpv);
9663   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9664   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9665   emit_insn (gen_rtx_USE (VOIDmode, gp));
9666   emit_indirect_jump (pv);
9667   DONE;
9671 ;;  ....................
9673 ;;      Function prologue/epilogue
9675 ;;  ....................
9678 (define_expand "prologue"
9679   [(const_int 1)]
9680   ""
9681   "
9683   if (mips_isa >= 0)            /* avoid unused code warnings */
9684     {
9685       mips_expand_prologue ();
9686       DONE;
9687     }
9690 ;; Block any insns from being moved before this point, since the
9691 ;; profiling call to mcount can use various registers that aren't
9692 ;; saved or used to pass arguments.
9694 (define_insn "blockage"
9695   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
9696   ""
9697   ""
9698   [(set_attr "type"     "unknown")
9699    (set_attr "mode"     "none")
9700    (set_attr "length"   "0")])
9702 (define_expand "epilogue"
9703   [(const_int 2)]
9704   ""
9706   mips_expand_epilogue (false);
9707   DONE;
9710 (define_expand "sibcall_epilogue"
9711   [(const_int 2)]
9712   ""
9714   mips_expand_epilogue (true);
9715   DONE;
9718 ;; Trivial return.  Make it look like a normal return insn as that
9719 ;; allows jump optimizations to work better .
9720 (define_insn "return"
9721   [(return)]
9722   "mips_can_use_return_insn ()"
9723   "%*j\\t$31"
9724   [(set_attr "type"     "jump")
9725    (set_attr "mode"     "none")])
9727 ;; Normal return.
9729 (define_insn "return_internal"
9730   [(use (match_operand 0 "pmode_register_operand" ""))
9731    (return)]
9732   ""
9733   "*
9735   return \"%*j\\t%0\";
9737   [(set_attr "type"     "jump")
9738    (set_attr "mode"     "none")])
9740 ;; When generating embedded PIC code we need to get the address of the
9741 ;; current function.  This specialized instruction does just that.
9743 (define_insn "get_fnaddr"
9744   [(set (match_operand 0 "register_operand" "=d")
9745         (unspec [(match_operand 1 "" "")] UNSPEC_GET_FNADDR))
9746    (clobber (reg:SI 31))]
9747   "TARGET_EMBEDDED_PIC
9748    && GET_CODE (operands[1]) == SYMBOL_REF"
9749   "%($LF%= = . + 8\;bal\\t$LF%=\;nop;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
9750   [(set_attr "type"     "call")
9751    (set_attr "mode"     "none")
9752    (set_attr "length"   "20")])
9754 ;; This is used in compiling the unwind routines.
9755 (define_expand "eh_return"
9756   [(use (match_operand 0 "general_operand" ""))]
9757   ""
9758   "
9760   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
9762   if (GET_MODE (operands[0]) != gpr_mode)
9763     operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
9764   if (TARGET_64BIT)
9765     emit_insn (gen_eh_set_lr_di (operands[0]));
9766   else
9767     emit_insn (gen_eh_set_lr_si (operands[0]));
9769   DONE;
9772 ;; Clobber the return address on the stack.  We can't expand this
9773 ;; until we know where it will be put in the stack frame.
9775 (define_insn "eh_set_lr_si"
9776   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
9777    (clobber (match_scratch:SI 1 "=&d"))]
9778   "! TARGET_64BIT"
9779   "#")
9781 (define_insn "eh_set_lr_di"
9782   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
9783    (clobber (match_scratch:DI 1 "=&d"))]
9784   "TARGET_64BIT"
9785   "#")
9787 (define_split
9788   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9789    (clobber (match_scratch 1 ""))]
9790   "reload_completed && !TARGET_DEBUG_D_MODE"
9791   [(const_int 0)]
9792   "
9794   mips_set_return_address (operands[0], operands[1]);
9795   DONE;
9798 (define_insn "exception_receiver"
9799   [(unspec_volatile [(const_int 0)] UNSPEC_EH_RECEIVER)]
9800   "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
9801   { return mips_restore_gp (operands); }
9802   [(set_attr "type"   "load")
9803    (set_attr "length" "8")])
9806 ;;  ....................
9808 ;;      FUNCTION CALLS
9810 ;;  ....................
9812 ;; Sibling calls.  All these patterns use direct jumps.
9814 ;; call_insn_operand will only accepts constant addresses if a direct
9815 ;; jump is acceptable.  Since the 'S' constraint is defined in terms of
9816 ;; call_insn_operand, the same is true of the contraints.
9818 ;; When we use an indirect jump, we need a register that will be
9819 ;; preserved by the epilogue.  Since TARGET_ABICALLS forces us to
9820 ;; use $25 for this purpose -- and $25 is never clobbered by the
9821 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
9823 (define_expand "sibcall"
9824   [(parallel [(call (match_operand 0 "" "")
9825                     (match_operand 1 "" ""))
9826               (use (match_operand 2 "" ""))     ;; next_arg_reg
9827               (use (match_operand 3 "" ""))])]  ;; struct_value_size_rtx
9828   "TARGET_SIBCALLS"
9830   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
9831   DONE;
9834 (define_insn "sibcall_internal"
9835   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
9836          (match_operand 1 "" ""))]
9837   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
9838   "@
9839     %*jr\\t%0
9840     %*j\\t%0"
9841   [(set_attr "type" "call")])
9843 (define_expand "sibcall_value"
9844   [(parallel [(set (match_operand 0 "" "")
9845                    (call (match_operand 1 "" "")
9846                          (match_operand 2 "" "")))
9847               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
9848   "TARGET_SIBCALLS"
9850   mips_expand_call (operands[0], XEXP (operands[1], 0),
9851                     operands[2], operands[3], true);
9852   DONE;
9855 (define_insn "sibcall_value_internal"
9856   [(set (match_operand 0 "register_operand" "=df,df")
9857         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
9858               (match_operand 2 "" "")))]
9859   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
9860   "@
9861     %*jr\\t%1
9862     %*j\\t%1"
9863   [(set_attr "type" "call")])
9865 (define_insn "sibcall_value_multiple_internal"
9866   [(set (match_operand 0 "register_operand" "=df,df")
9867         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
9868               (match_operand 2 "" "")))
9869    (set (match_operand 3 "register_operand" "=df,df")
9870         (call (mem:SI (match_dup 1))
9871               (match_dup 2)))]
9872   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
9873   "@
9874     %*jr\\t%1
9875     %*j\\t%1"
9876   [(set_attr "type" "call")])
9878 (define_expand "call"
9879   [(parallel [(call (match_operand 0 "" "")
9880                     (match_operand 1 "" ""))
9881               (use (match_operand 2 "" ""))     ;; next_arg_reg
9882               (use (match_operand 3 "" ""))])]  ;; struct_value_size_rtx
9883   ""
9885   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
9886   DONE;
9889 (define_insn_and_split "call_internal"
9890   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
9891          (match_operand 1 "" ""))
9892    (clobber (reg:SI 31))]
9893   ""
9894   "%*jal\\t%0"
9895   "reload_completed && TARGET_SPLIT_CALLS"
9896   [(const_int 0)]
9897   {
9898     emit_call_insn (gen_call_split (operands[0], operands[1]));
9899     emit_insn (gen_exception_receiver ());
9900     DONE;
9901   }
9902   [(set_attr "jal" "indirect,direct")
9903    (set_attr "extended_mips16" "no,yes")])
9905 (define_insn "call_split"
9906   [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
9907          (match_operand 1 "" ""))
9908    (clobber (reg:SI 31))
9909    (const_int 1)]
9910   "TARGET_SPLIT_CALLS"
9911   "%*jalr\\t%0"
9912   [(set_attr "type" "call")])
9914 (define_expand "call_value"
9915   [(parallel [(set (match_operand 0 "" "")
9916                    (call (match_operand 1 "" "")
9917                          (match_operand 2 "" "")))
9918               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
9919   ""
9921   mips_expand_call (operands[0], XEXP (operands[1], 0),
9922                     operands[2], operands[3], false);
9923   DONE;
9926 (define_insn_and_split "call_value_internal"
9927   [(set (match_operand 0 "register_operand" "=df,df")
9928         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
9929               (match_operand 2 "" "")))
9930    (clobber (reg:SI 31))]
9931   ""
9932   "%*jal\\t%1"
9933   "reload_completed && TARGET_SPLIT_CALLS"
9934   [(const_int 0)]
9935   {
9936     emit_call_insn (gen_call_value_split (operands[0], operands[1],
9937                                           operands[2]));
9938     emit_insn (gen_exception_receiver ());
9939     DONE;
9940   }
9941   [(set_attr "jal" "indirect,direct")
9942    (set_attr "extended_mips16" "no,yes")])
9944 (define_insn "call_value_split"
9945   [(set (match_operand 0 "register_operand" "=df")
9946         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
9947               (match_operand 2 "" "")))
9948    (clobber (reg:SI 31))
9949    (const_int 1)]
9950   "TARGET_SPLIT_CALLS"
9951   "%*jalr\\t%1"
9952   [(set_attr "type" "call")])
9954 (define_insn_and_split "call_value_multiple_internal"
9955   [(set (match_operand 0 "register_operand" "=df,df")
9956         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
9957               (match_operand 2 "" "")))
9958    (set (match_operand 3 "register_operand" "=df,df")
9959         (call (mem:SI (match_dup 1))
9960               (match_dup 2)))
9961    (clobber (reg:SI 31))]
9962   ""
9963   "%*jal\\t%1"
9964   "reload_completed && TARGET_SPLIT_CALLS"
9965   [(const_int 0)]
9966   {
9967     emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
9968                                                    operands[2], operands[3]));
9969     emit_insn (gen_exception_receiver ());
9970     DONE;
9971   }
9972   [(set_attr "jal" "indirect,direct")
9973    (set_attr "extended_mips16" "no,yes")])
9975 (define_insn "call_value_multiple_split"
9976   [(set (match_operand 0 "register_operand" "=df")
9977         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
9978               (match_operand 2 "" "")))
9979    (set (match_operand 3 "register_operand" "=df")
9980         (call (mem:SI (match_dup 1))
9981               (match_dup 2)))
9982    (clobber (reg:SI 31))
9983    (const_int 1)]
9984   "TARGET_SPLIT_CALLS"
9985   "%*jalr\\t%1"
9986   [(set_attr "type" "call")])
9988 ;; Call subroutine returning any type.
9990 (define_expand "untyped_call"
9991   [(parallel [(call (match_operand 0 "" "")
9992                     (const_int 0))
9993               (match_operand 1 "" "")
9994               (match_operand 2 "" "")])]
9995   ""
9996   "
9998   int i;
10000   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
10002   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10003     {
10004       rtx set = XVECEXP (operands[2], 0, i);
10005       emit_move_insn (SET_DEST (set), SET_SRC (set));
10006     }
10008   emit_insn (gen_blockage ());
10009   DONE;
10013 ;;  ....................
10015 ;;      MISC.
10017 ;;  ....................
10021 (define_expand "prefetch"
10022   [(prefetch (match_operand 0 "address_operand" "")
10023              (match_operand 1 "const_int_operand" "")
10024              (match_operand 2 "const_int_operand" ""))]
10025   "ISA_HAS_PREFETCH"
10027   if (symbolic_operand (operands[0], GET_MODE (operands[0])))
10028     operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
10031 (define_insn "prefetch_si_address"
10032   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
10033                       (match_operand:SI 3 "const_int_operand" "i"))
10034              (match_operand:SI 1 "const_int_operand" "n")
10035              (match_operand:SI 2 "const_int_operand" "n"))]
10036   "ISA_HAS_PREFETCH && Pmode == SImode"
10037   "* return mips_emit_prefetch (operands);"
10038   [(set_attr "type" "prefetch")])
10040 (define_insn "prefetch_si"
10041   [(prefetch (match_operand:SI 0 "register_operand" "r")
10042              (match_operand:SI 1 "const_int_operand" "n")
10043              (match_operand:SI 2 "const_int_operand" "n"))]
10044   "ISA_HAS_PREFETCH && Pmode == SImode"
10045   "* return mips_emit_prefetch (operands);"
10046   [(set_attr "type" "prefetch")])
10048 (define_insn "prefetch_di_address"
10049   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
10050                       (match_operand:DI 3 "const_int_operand" "i"))
10051              (match_operand:DI 1 "const_int_operand" "n")
10052              (match_operand:DI 2 "const_int_operand" "n"))]
10053   "ISA_HAS_PREFETCH && Pmode == DImode"
10054   "* return mips_emit_prefetch (operands);"
10055   [(set_attr "type" "prefetch")])
10057 (define_insn "prefetch_di"
10058   [(prefetch (match_operand:DI 0 "register_operand" "r")
10059              (match_operand:DI 1 "const_int_operand" "n")
10060              (match_operand:DI 2 "const_int_operand" "n"))]
10061   "ISA_HAS_PREFETCH && Pmode == DImode"
10062   "* return mips_emit_prefetch (operands);"
10063   [(set_attr "type" "prefetch")])
10065 (define_insn "nop"
10066   [(const_int 0)]
10067   ""
10068   "%(nop%)"
10069   [(set_attr "type"     "nop")
10070    (set_attr "mode"     "none")])
10072 ;; The MIPS chip does not seem to require stack probes.
10074 ;; (define_expand "probe"
10075 ;;   [(set (match_dup 0)
10076 ;;      (match_dup 1))]
10077 ;;   ""
10078 ;;   "
10079 ;; {
10080 ;;   operands[0] = gen_reg_rtx (SImode);
10081 ;;   operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
10082 ;;   MEM_VOLATILE_P (operands[1]) = TRUE;
10084 ;;   /* fall through and generate default code */
10085 ;; }")
10089 ;; MIPS4 Conditional move instructions.
10091 (define_insn ""
10092   [(set (match_operand:SI 0 "register_operand" "=d,d")
10093         (if_then_else:SI
10094          (match_operator 4 "equality_op"
10095                          [(match_operand:SI 1 "register_operand" "d,d")
10096                           (const_int 0)])
10097          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10098          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10099   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10100   "@
10101     mov%B4\\t%0,%z2,%1
10102     mov%b4\\t%0,%z3,%1"
10103   [(set_attr "type" "move")
10104    (set_attr "mode" "SI")])
10106 (define_insn ""
10107   [(set (match_operand:SI 0 "register_operand" "=d,d")
10108         (if_then_else:SI
10109          (match_operator 4 "equality_op"
10110                          [(match_operand:DI 1 "register_operand" "d,d")
10111                           (const_int 0)])
10112          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10113          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10114   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10115   "@
10116     mov%B4\\t%0,%z2,%1
10117     mov%b4\\t%0,%z3,%1"
10118   [(set_attr "type" "move")
10119    (set_attr "mode" "SI")])
10121 (define_insn ""
10122   [(set (match_operand:SI 0 "register_operand" "=d,d")
10123         (if_then_else:SI
10124          (match_operator 3 "equality_op" [(match_operand:CC 4
10125                                                             "register_operand"
10126                                                             "z,z")
10127                                           (const_int 0)])
10128          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
10129          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
10130   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10131   "@
10132     mov%T3\\t%0,%z1,%4
10133     mov%t3\\t%0,%z2,%4"
10134   [(set_attr "type" "move")
10135    (set_attr "mode" "SI")])
10137 (define_insn ""
10138   [(set (match_operand:DI 0 "register_operand" "=d,d")
10139         (if_then_else:DI
10140          (match_operator 4 "equality_op"
10141                          [(match_operand:SI 1 "register_operand" "d,d")
10142                           (const_int 0)])
10143          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
10144          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
10145   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10146   "@
10147     mov%B4\\t%0,%z2,%1
10148     mov%b4\\t%0,%z3,%1"
10149   [(set_attr "type" "move")
10150    (set_attr "mode" "DI")])
10152 (define_insn ""
10153   [(set (match_operand:DI 0 "register_operand" "=d,d")
10154         (if_then_else:DI
10155          (match_operator 4 "equality_op"
10156                          [(match_operand:DI 1 "register_operand" "d,d")
10157                           (const_int 0)])
10158          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
10159          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
10160   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10161   "@
10162     mov%B4\\t%0,%z2,%1
10163     mov%b4\\t%0,%z3,%1"
10164   [(set_attr "type" "move")
10165    (set_attr "mode" "DI")])
10167 (define_insn ""
10168   [(set (match_operand:DI 0 "register_operand" "=d,d")
10169         (if_then_else:DI
10170          (match_operator 3 "equality_op" [(match_operand:CC 4
10171                                                             "register_operand"
10172                                                             "z,z")
10173                                           (const_int 0)])
10174          (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
10175          (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
10176   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
10177   "@
10178     mov%T3\\t%0,%z1,%4
10179     mov%t3\\t%0,%z2,%4"
10180   [(set_attr "type" "move")
10181    (set_attr "mode" "DI")])
10183 (define_insn ""
10184   [(set (match_operand:SF 0 "register_operand" "=f,f")
10185         (if_then_else:SF
10186          (match_operator 4 "equality_op"
10187                          [(match_operand:SI 1 "register_operand" "d,d")
10188                           (const_int 0)])
10189          (match_operand:SF 2 "register_operand" "f,0")
10190          (match_operand:SF 3 "register_operand" "0,f")))]
10191   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10192   "@
10193     mov%B4.s\\t%0,%2,%1
10194     mov%b4.s\\t%0,%3,%1"
10195   [(set_attr "type" "move")
10196    (set_attr "mode" "SF")])
10198 (define_insn ""
10199   [(set (match_operand:SF 0 "register_operand" "=f,f")
10200         (if_then_else:SF
10201          (match_operator 4 "equality_op"
10202                          [(match_operand:DI 1 "register_operand" "d,d")
10203                           (const_int 0)])
10204          (match_operand:SF 2 "register_operand" "f,0")
10205          (match_operand:SF 3 "register_operand" "0,f")))]
10206   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10207   "@
10208     mov%B4.s\\t%0,%2,%1
10209     mov%b4.s\\t%0,%3,%1"
10210   [(set_attr "type" "move")
10211    (set_attr "mode" "SF")])
10213 (define_insn ""
10214   [(set (match_operand:SF 0 "register_operand" "=f,f")
10215         (if_then_else:SF
10216          (match_operator 3 "equality_op" [(match_operand:CC 4
10217                                                             "register_operand"
10218                                                             "z,z")
10219                                           (const_int 0)])
10220          (match_operand:SF 1 "register_operand" "f,0")
10221          (match_operand:SF 2 "register_operand" "0,f")))]
10222   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10223   "@
10224     mov%T3.s\\t%0,%1,%4
10225     mov%t3.s\\t%0,%2,%4"
10226   [(set_attr "type" "move")
10227    (set_attr "mode" "SF")])
10229 (define_insn ""
10230   [(set (match_operand:DF 0 "register_operand" "=f,f")
10231         (if_then_else:DF
10232          (match_operator 4 "equality_op"
10233                          [(match_operand:SI 1 "register_operand" "d,d")
10234                           (const_int 0)])
10235          (match_operand:DF 2 "register_operand" "f,0")
10236          (match_operand:DF 3 "register_operand" "0,f")))]
10237   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10238   "@
10239     mov%B4.d\\t%0,%2,%1
10240     mov%b4.d\\t%0,%3,%1"
10241   [(set_attr "type" "move")
10242    (set_attr "mode" "DF")])
10244 (define_insn ""
10245   [(set (match_operand:DF 0 "register_operand" "=f,f")
10246         (if_then_else:DF
10247          (match_operator 4 "equality_op"
10248                          [(match_operand:DI 1 "register_operand" "d,d")
10249                           (const_int 0)])
10250          (match_operand:DF 2 "register_operand" "f,0")
10251          (match_operand:DF 3 "register_operand" "0,f")))]
10252   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10253   "@
10254     mov%B4.d\\t%0,%2,%1
10255     mov%b4.d\\t%0,%3,%1"
10256   [(set_attr "type" "move")
10257    (set_attr "mode" "DF")])
10259 (define_insn ""
10260   [(set (match_operand:DF 0 "register_operand" "=f,f")
10261         (if_then_else:DF
10262          (match_operator 3 "equality_op" [(match_operand:CC 4
10263                                                             "register_operand"
10264                                                             "z,z")
10265                                           (const_int 0)])
10266          (match_operand:DF 1 "register_operand" "f,0")
10267          (match_operand:DF 2 "register_operand" "0,f")))]
10268   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10269   "@
10270     mov%T3.d\\t%0,%1,%4
10271     mov%t3.d\\t%0,%2,%4"
10272   [(set_attr "type" "move")
10273    (set_attr "mode" "DF")])
10275 ;; These are the main define_expand's used to make conditional moves.
10277 (define_expand "movsicc"
10278   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10279    (set (match_operand:SI 0 "register_operand" "")
10280         (if_then_else:SI (match_dup 5)
10281                          (match_operand:SI 2 "reg_or_0_operand" "")
10282                          (match_operand:SI 3 "reg_or_0_operand" "")))]
10283   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10284   "
10286   gen_conditional_move (operands);
10287   DONE;
10290 (define_expand "movdicc"
10291   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10292    (set (match_operand:DI 0 "register_operand" "")
10293         (if_then_else:DI (match_dup 5)
10294                          (match_operand:DI 2 "reg_or_0_operand" "")
10295                          (match_operand:DI 3 "reg_or_0_operand" "")))]
10296   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10297   "
10299   gen_conditional_move (operands);
10300   DONE;
10303 (define_expand "movsfcc"
10304   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10305    (set (match_operand:SF 0 "register_operand" "")
10306         (if_then_else:SF (match_dup 5)
10307                          (match_operand:SF 2 "register_operand" "")
10308                          (match_operand:SF 3 "register_operand" "")))]
10309   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10310   "
10312   gen_conditional_move (operands);
10313   DONE;
10316 (define_expand "movdfcc"
10317   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10318    (set (match_operand:DF 0 "register_operand" "")
10319         (if_then_else:DF (match_dup 5)
10320                          (match_operand:DF 2 "register_operand" "")
10321                          (match_operand:DF 3 "register_operand" "")))]
10322   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10323   "
10325   gen_conditional_move (operands);
10326   DONE;
10330 ;;  ....................
10332 ;;      mips16 inline constant tables
10334 ;;  ....................
10337 (define_insn "consttable_qi"
10338   [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")]
10339                     UNSPEC_CONSTTABLE_QI)]
10340   "TARGET_MIPS16"
10341   "*
10343   assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
10344   return \"\";
10346   [(set_attr "type"     "unknown")
10347    (set_attr "mode"     "QI")
10348    (set_attr "length"   "8")])
10350 (define_insn "consttable_hi"
10351   [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")]
10352                     UNSPEC_CONSTTABLE_HI)]
10353   "TARGET_MIPS16"
10354   "*
10356   assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10357   return \"\";
10359   [(set_attr "type"     "unknown")
10360    (set_attr "mode"     "HI")
10361    (set_attr "length"   "8")])
10363 (define_insn "consttable_si"
10364   [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")]
10365                     UNSPEC_CONSTTABLE_SI)]
10366   "TARGET_MIPS16"
10367   "*
10369   assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10370   return \"\";
10372   [(set_attr "type"     "unknown")
10373    (set_attr "mode"     "SI")
10374    (set_attr "length"   "8")])
10376 (define_insn "consttable_di"
10377   [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")]
10378                     UNSPEC_CONSTTABLE_DI)]
10379   "TARGET_MIPS16"
10380   "*
10382   assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10383   return \"\";
10385   [(set_attr "type"     "unknown")
10386    (set_attr "mode"     "DI")
10387    (set_attr "length"   "16")])
10389 (define_insn "consttable_sf"
10390   [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")]
10391                     UNSPEC_CONSTTABLE_SF)]
10392   "TARGET_MIPS16"
10393   "*
10395   REAL_VALUE_TYPE d;
10397   if (GET_CODE (operands[0]) != CONST_DOUBLE)
10398     abort ();
10399   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10400   assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10401   return \"\";
10403   [(set_attr "type"     "unknown")
10404    (set_attr "mode"     "SF")
10405    (set_attr "length"   "8")])
10407 (define_insn "consttable_df"
10408   [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")]
10409                     UNSPEC_CONSTTABLE_DF)]
10410   "TARGET_MIPS16"
10411   "*
10413   REAL_VALUE_TYPE d;
10415   if (GET_CODE (operands[0]) != CONST_DOUBLE)
10416     abort ();
10417   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10418   assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10419   return \"\";
10421   [(set_attr "type"     "unknown")
10422    (set_attr "mode"     "DF")
10423    (set_attr "length"   "16")])
10425 (define_insn "align_2"
10426   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_2)]
10427   "TARGET_MIPS16"
10428   ".align 1"
10429   [(set_attr "type"     "unknown")
10430    (set_attr "mode"     "HI")
10431    (set_attr "length"   "8")])
10433 (define_insn "align_4"
10434   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_4)]
10435   "TARGET_MIPS16"
10436   ".align 2"
10437   [(set_attr "type"     "unknown")
10438    (set_attr "mode"     "SI")
10439    (set_attr "length"   "8")])
10441 (define_insn "align_8"
10442   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_8)]
10443   "TARGET_MIPS16"
10444   ".align 3"
10445   [(set_attr "type"     "unknown")
10446    (set_attr "mode"     "DI")
10447    (set_attr "length"   "12")])
10450 ;;  ....................
10452 ;;      mips16 peepholes
10454 ;;  ....................
10457 ;; On the mips16, reload will sometimes decide that a pseudo register
10458 ;; should go into $24, and then later on have to reload that register.
10459 ;; When that happens, we get a load of a general register followed by
10460 ;; a move from the general register to $24 followed by a branch.
10461 ;; These peepholes catch the common case, and fix it to just use the
10462 ;; general register for the branch.
10464 (define_peephole
10465   [(set (match_operand:SI 0 "register_operand" "=t")
10466         (match_operand:SI 1 "register_operand" "d"))
10467    (set (pc)
10468         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10469                                                           (const_int 0)])
10470                       (match_operand 3 "pc_or_label_operand" "")
10471                       (match_operand 4 "pc_or_label_operand" "")))]
10472   "TARGET_MIPS16
10473    && GET_CODE (operands[0]) == REG
10474    && REGNO (operands[0]) == 24
10475    && dead_or_set_p (insn, operands[0])
10476    && GET_CODE (operands[1]) == REG
10477    && M16_REG_P (REGNO (operands[1]))"
10478   "*
10480   if (operands[3] != pc_rtx)
10481     return \"%*b%C2z\\t%1,%3\";
10482   else
10483     return \"%*b%N2z\\t%1,%4\";
10485   [(set_attr "type"     "branch")
10486    (set_attr "mode"     "none")
10487    (set_attr "length"   "8")])
10489 (define_peephole
10490   [(set (match_operand:DI 0 "register_operand" "=t")
10491         (match_operand:DI 1 "register_operand" "d"))
10492    (set (pc)
10493         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10494                                                           (const_int 0)])
10495                       (match_operand 3 "pc_or_label_operand" "")
10496                       (match_operand 4 "pc_or_label_operand" "")))]
10497   "TARGET_MIPS16 && TARGET_64BIT
10498    && GET_CODE (operands[0]) == REG
10499    && REGNO (operands[0]) == 24
10500    && dead_or_set_p (insn, operands[0])
10501    && GET_CODE (operands[1]) == REG
10502    && M16_REG_P (REGNO (operands[1]))"
10503   "*
10505   if (operands[3] != pc_rtx)
10506     return \"%*b%C2z\\t%1,%3\";
10507   else
10508     return \"%*b%N2z\\t%1,%4\";
10510   [(set_attr "type"     "branch")
10511    (set_attr "mode"     "none")
10512    (set_attr "length"   "8")])
10514 ;; We can also have the reverse reload: reload will spill $24 into
10515 ;; another register, and then do a branch on that register when it
10516 ;; could have just stuck with $24.
10518 (define_peephole
10519   [(set (match_operand:SI 0 "register_operand" "=d")
10520         (match_operand:SI 1 "register_operand" "t"))
10521    (set (pc)
10522         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10523                                                           (const_int 0)])
10524                       (match_operand 3 "pc_or_label_operand" "")
10525                       (match_operand 4 "pc_or_label_operand" "")))]
10526   "TARGET_MIPS16
10527    && GET_CODE (operands[1]) == REG
10528    && REGNO (operands[1]) == 24
10529    && GET_CODE (operands[0]) == REG
10530    && M16_REG_P (REGNO (operands[0]))
10531    && dead_or_set_p (insn, operands[0])"
10532   "*
10534   if (operands[3] != pc_rtx)
10535     return \"%*bt%C2z\\t%3\";
10536   else
10537     return \"%*bt%N2z\\t%4\";
10539   [(set_attr "type"     "branch")
10540    (set_attr "mode"     "none")
10541    (set_attr "length"   "8")])
10543 (define_peephole
10544   [(set (match_operand:DI 0 "register_operand" "=d")
10545         (match_operand:DI 1 "register_operand" "t"))
10546    (set (pc)
10547         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10548                                                           (const_int 0)])
10549                       (match_operand 3 "pc_or_label_operand" "")
10550                       (match_operand 4 "pc_or_label_operand" "")))]
10551   "TARGET_MIPS16 && TARGET_64BIT
10552    && GET_CODE (operands[1]) == REG
10553    && REGNO (operands[1]) == 24
10554    && GET_CODE (operands[0]) == REG
10555    && M16_REG_P (REGNO (operands[0]))
10556    && dead_or_set_p (insn, operands[0])"
10557   "*
10559   if (operands[3] != pc_rtx)
10560     return \"%*bt%C2z\\t%3\";
10561   else
10562     return \"%*bt%N2z\\t%4\";
10564   [(set_attr "type"     "branch")
10565    (set_attr "mode"     "none")
10566    (set_attr "length"   "8")])