re PR target/14599 (ieee/20000320-1.c fails for -mips16 using -O2 and above)
[official-gcc.git] / gcc / config / mips / mips.md
blob5b3c8465226f6bde2ccaf34e1fbd43815017257e
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, 2004 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 GCC.
11 ;; GCC 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 ;; GCC 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 GCC; 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            3)
34    (UNSPEC_BLOCKAGE              4)
35    (UNSPEC_CPRESTORE             5)
36    (UNSPEC_EH_RECEIVER           6)
37    (UNSPEC_EH_RETURN             7)
38    (UNSPEC_CONSTTABLE_QI         8)
39    (UNSPEC_CONSTTABLE_HI         9)
40    (UNSPEC_CONSTTABLE_SI        10)
41    (UNSPEC_CONSTTABLE_DI        11)
42    (UNSPEC_CONSTTABLE_SF        12)
43    (UNSPEC_CONSTTABLE_DF        13)
44    (UNSPEC_ALIGN_2              14)
45    (UNSPEC_ALIGN_4              15)
46    (UNSPEC_ALIGN_8              16)
47    (UNSPEC_HIGH                 17)
48    (UNSPEC_LWL                  18)
49    (UNSPEC_LWR                  19)
50    (UNSPEC_SWL                  20)
51    (UNSPEC_SWR                  21)
52    (UNSPEC_LDL                  22)
53    (UNSPEC_LDR                  23)
54    (UNSPEC_SDL                  24)
55    (UNSPEC_SDR                  25)
56    (UNSPEC_LOADGP               26)
57    (UNSPEC_LOAD_CALL            27)
58    (UNSPEC_LOAD_GOT             28)
59    (UNSPEC_GP                   29)
61    (UNSPEC_ADDRESS_FIRST        100)
63    (FAKE_CALL_REGNO             79)])
65 ;; ....................
67 ;;      Attributes
69 ;; ....................
71 (define_attr "got" "unset,xgot_high,load"
72   (const_string "unset"))
74 ;; For jal instructions, this attribute is DIRECT when the target address
75 ;; is symbolic and INDIRECT when it is a register.
76 (define_attr "jal" "unset,direct,indirect"
77   (const_string "unset"))
79 ;; This attribute is YES if the instruction is a jal macro (not a
80 ;; real jal instruction).
82 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
83 ;; restore $gp.  Direct jals are also macros in NewABI PIC since they
84 ;; load the target address into $25.
85 (define_attr "jal_macro" "no,yes"
86   (cond [(eq_attr "jal" "direct")
87          (symbol_ref "TARGET_ABICALLS != 0")
88          (eq_attr "jal" "indirect")
89          (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
90         (const_string "no")))
92 ;; Classification of each insn.
93 ;; branch       conditional branch
94 ;; jump         unconditional jump
95 ;; call         unconditional call
96 ;; load         load instruction(s)
97 ;; fpload       floating point load
98 ;; fpidxload    floating point indexed load
99 ;; store        store instruction(s)
100 ;; fpstore      floating point store
101 ;; fpidxstore   floating point indexed store
102 ;; prefetch     memory prefetch (register + offset)
103 ;; prefetchx    memory indexed prefetch (register + register)
104 ;; move         data movement within same register set
105 ;; condmove     conditional moves
106 ;; xfer         transfer to/from coprocessor
107 ;; hilo         transfer of hi/lo registers
108 ;; arith        integer arithmetic instruction
109 ;; darith       double precision integer arithmetic instructions
110 ;; const        load constant
111 ;; imul         integer multiply
112 ;; imadd        integer multiply-add
113 ;; idiv         integer divide
114 ;; icmp         integer compare
115 ;; fadd         floating point add/subtract
116 ;; fmul         floating point multiply
117 ;; fmadd        floating point multiply-add
118 ;; fdiv         floating point divide
119 ;; fabs         floating point absolute value
120 ;; fneg         floating point negation
121 ;; fcmp         floating point compare
122 ;; fcvt         floating point convert
123 ;; fsqrt        floating point square root
124 ;; frsqrt       floating point reciprocal square root
125 ;; multi        multiword sequence (or user asm statements)
126 ;; nop          no operation
127 (define_attr "type"
128   "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,move,condmove,xfer,hilo,const,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
129   (cond [(eq_attr "jal" "!unset") (const_string "call")
130          (eq_attr "got" "load") (const_string "load")]
131         (const_string "unknown")))
133 ;; Main data type used by the insn
134 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
135   (const_string "unknown"))
137 ;; Is this an extended instruction in mips16 mode?
138 (define_attr "extended_mips16" "no,yes"
139   (const_string "no"))
141 ;; Length of instruction in bytes.
142 (define_attr "length" ""
143    (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
144           ;; If a branch is outside this range, we have a choice of two
145           ;; sequences.  For PIC, an out-of-range branch like:
146           ;;
147           ;;    bne     r1,r2,target
148           ;;    dslot
149           ;;
150           ;; becomes the equivalent of:
151           ;;
152           ;;    beq     r1,r2,1f
153           ;;    dslot
154           ;;    la      $at,target
155           ;;    jr      $at
156           ;;    nop
157           ;; 1:
158           ;;
159           ;; where the load address can be up to three instructions long
160           ;; (lw, nop, addiu).
161           ;;
162           ;; The non-PIC case is similar except that we use a direct
163           ;; jump instead of an la/jr pair.  Since the target of this
164           ;; jump is an absolute 28-bit bit address (the other bits
165           ;; coming from the address of the delay slot) this form cannot
166           ;; cross a 256MB boundary.  We could provide the option of
167           ;; using la/jr in this case too, but we do not do so at
168           ;; present.
169           ;;
170           ;; Note that this value does not account for the delay slot
171           ;; instruction, whose length is added separately.  If the RTL
172           ;; pattern has no explicit delay slot, mips_adjust_insn_length
173           ;; will add the length of the implicit nop.
174           (eq_attr "type" "branch")
175           (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
176                      (const_int 131072))
177                  (const_int 4)
178                  (ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
179                      (const_int 0))
180                  (const_int 24)
181                  ] (const_int 12))
183           (eq_attr "got" "load")
184           (const_int 4)
185           (eq_attr "got" "xgot_high")
186           (const_int 8)
188           (eq_attr "type" "const")
189           (symbol_ref "mips_const_insns (operands[1]) * 4")
190           (eq_attr "type" "load,fpload,fpidxload")
191           (symbol_ref "mips_fetch_insns (operands[1]) * 4")
192           (eq_attr "type" "store,fpstore,fpidxstore")
193           (symbol_ref "mips_fetch_insns (operands[0]) * 4")
195           ;; In the worst case, a call macro will take 8 instructions:
196           ;;
197           ;;     lui $25,%call_hi(FOO)
198           ;;     addu $25,$25,$28
199           ;;     lw $25,%call_lo(FOO)($25)
200           ;;     nop
201           ;;     jalr $25
202           ;;     nop
203           ;;     lw $gp,X($sp)
204           ;;     nop
205           (eq_attr "jal_macro" "yes")
206           (const_int 32)
208           (and (eq_attr "extended_mips16" "yes")
209                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
210           (const_int 8)
212           (eq_attr "type" "idiv")
213           (symbol_ref "mips_idiv_insns () * 4")
214           ] (const_int 4)))
216 ;; Attribute describing the processor.  This attribute must match exactly
217 ;; with the processor_type enumeration in mips.h.
218 (define_attr "cpu"
219   "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
220   (const (symbol_ref "mips_tune")))
222 ;; The type of hardware hazard associated with this instruction.
223 ;; DELAY means that the next instruction cannot read the result
224 ;; of this one.  HILO means that the next two instructions cannot
225 ;; write to HI or LO.
226 (define_attr "hazard" "none,delay,hilo"
227   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
228               (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
229          (const_string "delay")
231          (and (eq_attr "type" "xfer")
232               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
233          (const_string "delay")
235          (and (eq_attr "type" "fcmp")
236               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
237          (const_string "delay")
239          ;; The r4000 multiplication patterns include an mflo instruction.
240          (and (eq_attr "type" "imul")
241               (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
242          (const_string "hilo")
244          (and (eq_attr "type" "hilo")
245               (and (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0))
246                    (match_operand 1 "hilo_operand" "")))
247          (const_string "hilo")]
248         (const_string "none")))
250 ;; Is it a single instruction?
251 (define_attr "single_insn" "no,yes"
252   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
254 ;; Can the instruction be put into a delay slot?
255 (define_attr "can_delay" "no,yes"
256   (if_then_else (and (eq_attr "type" "!branch,call,jump")
257                      (and (eq_attr "hazard" "none")
258                           (eq_attr "single_insn" "yes")))
259                 (const_string "yes")
260                 (const_string "no")))
262 ;; Attribute defining whether or not we can use the branch-likely instructions
263 (define_attr "branch_likely" "no,yes"
264   (const
265    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
266                  (const_string "yes")
267                  (const_string "no"))))
269 ;; Describe a user's asm statement.
270 (define_asm_attributes
271   [(set_attr "type" "multi")])
273 ;; .........................
275 ;;      Branch, call and jump delay slots
277 ;; .........................
279 (define_delay (and (eq_attr "type" "branch")
280                    (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
281   [(eq_attr "can_delay" "yes")
282    (nil)
283    (and (eq_attr "branch_likely" "yes")
284         (eq_attr "can_delay" "yes"))])
286 (define_delay (eq_attr "type" "jump")
287   [(eq_attr "can_delay" "yes")
288    (nil)
289    (nil)])
291 (define_delay (and (eq_attr "type" "call")
292                    (eq_attr "jal_macro" "no"))
293   [(eq_attr "can_delay" "yes")
294    (nil)
295    (nil)])
297 ;; .........................
299 ;;      Functional units
301 ;; .........................
303 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
304 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
306 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
308 (define_function_unit "memory" 1 0
309   (and (eq_attr "type" "load,fpload,fpidxload")
310        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
311   3 0)
313 (define_function_unit "memory" 1 0
314   (and (eq_attr "type" "load,fpload,fpidxload")
315        (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
316   2 0)
318 (define_function_unit "memory"   1 0
319   (eq_attr "type" "store,fpstore,fpidxstore")
320   1 0)
322 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
324 (define_function_unit "imuldiv"  1 0
325   (eq_attr "type" "hilo")
326   1 3)
328 (define_function_unit "imuldiv"  1 0
329   (and (eq_attr "type" "imul,imadd")
330        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
331   17 17)
333 ;; On them mips16, we want to stronly discourage a mult from appearing
334 ;; after an mflo, since that requires explicit nop instructions.  We
335 ;; do this by pretending that mflo ties up the function unit for long
336 ;; enough that the scheduler will ignore load stalls and the like when
337 ;; selecting instructions to between the two instructions.
339 (define_function_unit "imuldiv" 1 0
340   (and (eq_attr "type" "hilo") (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
341   1 5)
343 (define_function_unit "imuldiv"  1 0
344   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r3000,r3900"))
345   12 12)
347 (define_function_unit "imuldiv"  1 0
348   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4000,r4600"))
349   10 10)
351 (define_function_unit "imuldiv"  1 0
352   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4650"))
353   4 4)
355 (define_function_unit "imuldiv"  1 0
356   (and (eq_attr "type" "imul,imadd")
357        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
358   1 1)
360 (define_function_unit "imuldiv"  1 0
361   (and (eq_attr "type" "imul,imadd")
362        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
363   4 4)
365 (define_function_unit "imuldiv"  1 0
366   (and (eq_attr "type" "imul,imadd")
367        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
368   5 5)
370 (define_function_unit "imuldiv"  1 0
371   (and (eq_attr "type" "imul,imadd")
372        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
373   8 8)
375 (define_function_unit "imuldiv"  1 0
376   (and (eq_attr "type" "imul,imadd")
377        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
378   9 9)
380 (define_function_unit "imuldiv"  1 0
381   (and (eq_attr "type" "idiv")
382        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
383   38 38)
385 (define_function_unit "imuldiv"  1 0
386   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
387   35 35)
389 (define_function_unit "imuldiv"  1 0
390   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
391   42 42)
393 (define_function_unit "imuldiv"  1 0
394   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
395   36 36)
397 (define_function_unit "imuldiv"  1 0
398   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
399   69 69)
401 (define_function_unit "imuldiv" 1 0
402   (and (eq_attr "type" "idiv")
403        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
404   35 35)
406 (define_function_unit "imuldiv" 1 0
407   (and (eq_attr "type" "idiv")
408        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
409   67 67)
411 (define_function_unit "imuldiv" 1 0
412   (and (eq_attr "type" "idiv")
413        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
414   37 37)
416 (define_function_unit "imuldiv" 1 0
417   (and (eq_attr "type" "idiv")
418        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
419   69 69)
421 (define_function_unit "imuldiv" 1 0
422   (and (eq_attr "type" "idiv")
423        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
424   36 36)
426 (define_function_unit "imuldiv" 1 0
427   (and (eq_attr "type" "idiv")
428        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
429   68 68)
431 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
432 ;; the FP hardware is part of the normal ALU circuitry.  This means FP
433 ;; instructions affect the pipe-line, and no functional unit
434 ;; parallelism can occur on R4300 processors.  To force GCC into coding
435 ;; for only a single functional unit, we force the R4300 FP
436 ;; instructions to be processed in the "imuldiv" unit.
438 (define_function_unit "adder" 1 1
439   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
440   3 0)
442 (define_function_unit "adder" 1 1
443   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
444   2 0)
446 (define_function_unit "adder" 1 1
447   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
448   1 0)
450 (define_function_unit "adder" 1 1
451   (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
452   4 0)
454 (define_function_unit "adder" 1 1
455   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
456   2 0)
458 (define_function_unit "adder" 1 1
459   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
460   3 0)
462 (define_function_unit "adder" 1 1
463   (and (eq_attr "type" "fabs,fneg")
464        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
465   2 0)
467 (define_function_unit "adder" 1 1
468   (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
469   1 0)
471 (define_function_unit "mult" 1 1
472   (and (eq_attr "type" "fmul")
473        (and (eq_attr "mode" "SF")
474             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
475   7 0)
477 (define_function_unit "mult" 1 1
478   (and (eq_attr "type" "fmul")
479        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
480   4 0)
482 (define_function_unit "mult" 1 1
483   (and (eq_attr "type" "fmul")
484        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
485   5 0)
487 (define_function_unit "mult" 1 1
488   (and (eq_attr "type" "fmul")
489        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
490   8 0)
492 (define_function_unit "mult" 1 1
493   (and (eq_attr "type" "fmul")
494        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
495   8 0)
497 (define_function_unit "mult" 1 1
498   (and (eq_attr "type" "fmul")
499        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
500   5 0)
502 (define_function_unit "mult" 1 1
503   (and (eq_attr "type" "fmul")
504        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
505   6 0)
507 (define_function_unit "divide" 1 1
508   (and (eq_attr "type" "fdiv")
509        (and (eq_attr "mode" "SF")
510             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
511   23 0)
513 (define_function_unit "divide" 1 1
514   (and (eq_attr "type" "fdiv")
515        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
516   12 0)
518 (define_function_unit "divide" 1 1
519   (and (eq_attr "type" "fdiv")
520        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
521   15 0)
523 (define_function_unit "divide" 1 1
524   (and (eq_attr "type" "fdiv")
525        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
526   32 0)
528 (define_function_unit "divide" 1 1
529   (and (eq_attr "type" "fdiv")
530        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
531   21 0)
533 (define_function_unit "divide" 1 1
534   (and (eq_attr "type" "fdiv")
535        (and (eq_attr "mode" "DF")
536             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
537   36 0)
539 (define_function_unit "divide" 1 1
540   (and (eq_attr "type" "fdiv")
541        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
542   19 0)
544 (define_function_unit "divide" 1 1
545   (and (eq_attr "type" "fdiv")
546        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
547   16 0)
549 (define_function_unit "divide" 1 1
550   (and (eq_attr "type" "fdiv")
551        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
552   61 0)
554 ;;; ??? Is this number right?
555 (define_function_unit "divide" 1 1
556   (and (eq_attr "type" "fsqrt,frsqrt")
557        (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
558   54 0)
560 (define_function_unit "divide" 1 1
561   (and (eq_attr "type" "fsqrt,frsqrt")
562        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
563   31 0)
565 (define_function_unit "divide" 1 1
566   (and (eq_attr "type" "fsqrt,frsqrt")
567        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
568   21 0)
570 ;;; ??? Is this number right?
571 (define_function_unit "divide" 1 1
572   (and (eq_attr "type" "fsqrt,frsqrt")
573        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
574   112 0)
576 (define_function_unit "divide" 1 1
577   (and (eq_attr "type" "fsqrt,frsqrt")
578        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
579   60 0)
581 (define_function_unit "divide" 1 1
582   (and (eq_attr "type" "fsqrt,frsqrt")
583        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
584   36 0)
586 ;; R4300 FP instruction classes treated as part of the "imuldiv"
587 ;; functional unit:
589 (define_function_unit "imuldiv" 1 0
590   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
591   3 3)
593 (define_function_unit "imuldiv" 1 0
594   (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
595   1 1)
597 (define_function_unit "imuldiv" 1 0
598   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
599   5 5)
600 (define_function_unit "imuldiv" 1 0
601   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
602   8 8)
604 (define_function_unit "imuldiv" 1 0
605   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
606        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
607   29 29)
608 (define_function_unit "imuldiv" 1 0
609   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
610        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
611   58 58)
613 ;; Include scheduling descriptions.
615 (include "5400.md")
616 (include "5500.md")
617 (include "7000.md")
618 (include "9000.md")
619 (include "sr71k.md")
622 ;;  ....................
624 ;;      CONDITIONAL TRAPS
626 ;;  ....................
629 (define_insn "trap"
630   [(trap_if (const_int 1) (const_int 0))]
631   ""
633   if (ISA_HAS_COND_TRAP)
634     return "teq\t$0,$0";
635   /* The IRIX 6 O32 assembler requires the first break operand.  */
636   else if (TARGET_MIPS16 || !TARGET_GAS)
637     return "break 0";
638   else
639     return "break";
642 (define_expand "conditional_trap"
643   [(trap_if (match_operator 0 "cmp_op"
644                             [(match_dup 2) (match_dup 3)])
645             (match_operand 1 "const_int_operand" ""))]
646   "ISA_HAS_COND_TRAP"
648   if (operands[1] == const0_rtx)
649     {
650       mips_gen_conditional_trap (operands);
651       DONE;
652     }
653   else
654     FAIL;
657 (define_insn ""
658   [(trap_if (match_operator 0 "trap_cmp_op"
659                             [(match_operand:SI 1 "reg_or_0_operand" "dJ")
660                              (match_operand:SI 2 "arith_operand" "dI")])
661             (const_int 0))]
662   "ISA_HAS_COND_TRAP"
663   "t%C0\t%z1,%z2")
665 (define_insn ""
666   [(trap_if (match_operator 0 "trap_cmp_op"
667                             [(match_operand:DI 1 "reg_or_0_operand" "dJ")
668                              (match_operand:DI 2 "arith_operand" "dI")])
669             (const_int 0))]
670   "TARGET_64BIT && ISA_HAS_COND_TRAP"
671   "t%C0\t%z1,%z2")
674 ;;  ....................
676 ;;      ADDITION
678 ;;  ....................
681 (define_insn "adddf3"
682   [(set (match_operand:DF 0 "register_operand" "=f")
683         (plus:DF (match_operand:DF 1 "register_operand" "f")
684                  (match_operand:DF 2 "register_operand" "f")))]
685   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
686   "add.d\t%0,%1,%2"
687   [(set_attr "type"     "fadd")
688    (set_attr "mode"     "DF")])
690 (define_insn "addsf3"
691   [(set (match_operand:SF 0 "register_operand" "=f")
692         (plus:SF (match_operand:SF 1 "register_operand" "f")
693                  (match_operand:SF 2 "register_operand" "f")))]
694   "TARGET_HARD_FLOAT"
695   "add.s\t%0,%1,%2"
696   [(set_attr "type"     "fadd")
697    (set_attr "mode"     "SF")])
699 (define_expand "addsi3"
700   [(set (match_operand:SI 0 "register_operand" "")
701         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
702                  (match_operand:SI 2 "arith_operand" "")))]
703   ""
705   /* If a large stack adjustment was forced into a register, we may be
706      asked to generate rtx such as:
708         (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
710      but no such instruction is available in mips16.  Handle it by
711      using a temporary.  */
712   if (TARGET_MIPS16
713       && REGNO (operands[0]) == STACK_POINTER_REGNUM
714       && ((GET_CODE (operands[1]) == REG
715            && REGNO (operands[1]) != STACK_POINTER_REGNUM)
716           || GET_CODE (operands[2]) != CONST_INT))
717     {
718       rtx tmp = gen_reg_rtx (SImode);
720       emit_move_insn (tmp, operands[1]);
721       emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
722       emit_move_insn (operands[0], tmp);
723       DONE;
724     }
727 (define_insn "addsi3_internal"
728   [(set (match_operand:SI 0 "register_operand" "=d,d")
729         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
730                  (match_operand:SI 2 "arith_operand" "d,Q")))]
731   "!TARGET_MIPS16"
732   "@
733     addu\t%0,%z1,%2
734     addiu\t%0,%z1,%2"
735   [(set_attr "type"     "arith")
736    (set_attr "mode"     "SI")])
738 ;; For the mips16, we need to recognize stack pointer additions
739 ;; explicitly, since we don't have a constraint for $sp.  These insns
740 ;; will be generated by the save_restore_insns functions.
742 (define_insn ""
743   [(set (reg:SI 29)
744         (plus:SI (reg:SI 29)
745                  (match_operand:SI 0 "small_int" "I")))]
746   "TARGET_MIPS16"
747   "addu\t%$,%$,%0"
748   [(set_attr "type"     "arith")
749    (set_attr "mode"     "SI")
750    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
751                                       (const_int 4)
752                                       (const_int 8)))])
754 (define_insn ""
755   [(set (match_operand:SI 0 "register_operand" "=d")
756         (plus:SI (reg:SI 29)
757                  (match_operand:SI 1 "small_int" "I")))]
758   "TARGET_MIPS16"
759   "addu\t%0,%$,%1"
760   [(set_attr "type"     "arith")
761    (set_attr "mode"     "SI")
762    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
763                                       (const_int 4)
764                                       (const_int 8)))])
766 (define_insn ""
767   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
768         (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
769                  (match_operand:SI 2 "arith_operand" "Q,O,d")))]
770   "TARGET_MIPS16
771    && (GET_CODE (operands[1]) != REG
772        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
773        || M16_REG_P (REGNO (operands[1]))
774        || REGNO (operands[1]) == ARG_POINTER_REGNUM
775        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
776        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
777    && (GET_CODE (operands[2]) != REG
778        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
779        || M16_REG_P (REGNO (operands[2]))
780        || REGNO (operands[2]) == ARG_POINTER_REGNUM
781        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
782        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
784   if (REGNO (operands[0]) == REGNO (operands[1]))
785     return "addu\t%0,%2";
786   else
787     return "addu\t%0,%1,%2";
789   [(set_attr "type"     "arith")
790    (set_attr "mode"     "SI")
791    (set_attr_alternative "length"
792                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
793                                (const_int 4)
794                                (const_int 8))
795                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
796                                (const_int 4)
797                                (const_int 8))
798                  (const_int 4)])])
801 ;; On the mips16, we can sometimes split an add of a constant which is
802 ;; a 4 byte instruction into two adds which are both 2 byte
803 ;; instructions.  There are two cases: one where we are adding a
804 ;; constant plus a register to another register, and one where we are
805 ;; simply adding a constant to a register.
807 (define_split
808   [(set (match_operand:SI 0 "register_operand" "")
809         (plus:SI (match_dup 0)
810                  (match_operand:SI 1 "const_int_operand" "")))]
811   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
812    && GET_CODE (operands[0]) == REG
813    && M16_REG_P (REGNO (operands[0]))
814    && GET_CODE (operands[1]) == CONST_INT
815    && ((INTVAL (operands[1]) > 0x7f
816         && INTVAL (operands[1]) <= 0x7f + 0x7f)
817        || (INTVAL (operands[1]) < - 0x80
818            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
819   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
820    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
822   HOST_WIDE_INT val = INTVAL (operands[1]);
824   if (val >= 0)
825     {
826       operands[1] = GEN_INT (0x7f);
827       operands[2] = GEN_INT (val - 0x7f);
828     }
829   else
830     {
831       operands[1] = GEN_INT (- 0x80);
832       operands[2] = GEN_INT (val + 0x80);
833     }
836 (define_split
837   [(set (match_operand:SI 0 "register_operand" "")
838         (plus:SI (match_operand:SI 1 "register_operand" "")
839                  (match_operand:SI 2 "const_int_operand" "")))]
840   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
841    && GET_CODE (operands[0]) == REG
842    && M16_REG_P (REGNO (operands[0]))
843    && GET_CODE (operands[1]) == REG
844    && M16_REG_P (REGNO (operands[1]))
845    && REGNO (operands[0]) != REGNO (operands[1])
846    && GET_CODE (operands[2]) == CONST_INT
847    && ((INTVAL (operands[2]) > 0x7
848         && INTVAL (operands[2]) <= 0x7 + 0x7f)
849        || (INTVAL (operands[2]) < - 0x8
850            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
851   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
852    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
854   HOST_WIDE_INT val = INTVAL (operands[2]);
856   if (val >= 0)
857     {
858       operands[2] = GEN_INT (0x7);
859       operands[3] = GEN_INT (val - 0x7);
860     }
861   else
862     {
863       operands[2] = GEN_INT (- 0x8);
864       operands[3] = GEN_INT (val + 0x8);
865     }
868 (define_expand "adddi3"
869   [(parallel [(set (match_operand:DI 0 "register_operand" "")
870                    (plus:DI (match_operand:DI 1 "register_operand" "")
871                             (match_operand:DI 2 "arith_operand" "")))
872               (clobber (match_dup 3))])]
873   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
875   /* If a large stack adjustment was forced into a register, we may be
876      asked to generate rtx such as:
878         (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
880      but no such instruction is available in mips16.  Handle it by
881      using a temporary.  */
882   if (TARGET_MIPS16
883       && REGNO (operands[0]) == STACK_POINTER_REGNUM
884       && ((GET_CODE (operands[1]) == REG
885            && REGNO (operands[1]) != STACK_POINTER_REGNUM)
886           || GET_CODE (operands[2]) != CONST_INT))
887     {
888       rtx tmp = gen_reg_rtx (DImode);
890       emit_move_insn (tmp, operands[1]);
891       emit_insn (gen_adddi3 (tmp, tmp, operands[2]));
892       emit_move_insn (operands[0], tmp);
893       DONE;
894     }
896   if (TARGET_64BIT)
897     {
898       emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
899                                         operands[2]));
900       DONE;
901     }
903   operands[3] = gen_reg_rtx (SImode);
906 (define_insn "adddi3_internal_1"
907   [(set (match_operand:DI 0 "register_operand" "=d,&d")
908         (plus:DI (match_operand:DI 1 "register_operand" "0,d")
909                  (match_operand:DI 2 "register_operand" "d,d")))
910    (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
911   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
913   return (REGNO (operands[0]) == REGNO (operands[1])
914           && REGNO (operands[0]) == REGNO (operands[2]))
915     ? "srl\t%3,%L0,31\;sll\t%M0,%M0,1\;sll\t%L0,%L1,1\;addu\t%M0,%M0,%3"
916     : "addu\t%L0,%L1,%L2\;sltu\t%3,%L0,%L2\;addu\t%M0,%M1,%M2\;addu\t%M0,%M0,%3";
918   [(set_attr "type"     "darith")
919    (set_attr "mode"     "DI")
920    (set_attr "length"   "16")])
922 (define_split
923   [(set (match_operand:DI 0 "register_operand" "")
924         (plus:DI (match_operand:DI 1 "register_operand" "")
925                  (match_operand:DI 2 "register_operand" "")))
926    (clobber (match_operand:SI 3 "register_operand" ""))]
927   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
928    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
929    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
930    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
931    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
932    && (REGNO (operands[0]) != REGNO (operands[1])
933        || REGNO (operands[0]) != REGNO (operands[2]))"
935   [(set (subreg:SI (match_dup 0) 0)
936         (plus:SI (subreg:SI (match_dup 1) 0)
937                  (subreg:SI (match_dup 2) 0)))
939    (set (match_dup 3)
940         (ltu:SI (subreg:SI (match_dup 0) 0)
941                 (subreg:SI (match_dup 2) 0)))
943    (set (subreg:SI (match_dup 0) 4)
944         (plus:SI (subreg:SI (match_dup 1) 4)
945                  (subreg:SI (match_dup 2) 4)))
947    (set (subreg:SI (match_dup 0) 4)
948         (plus:SI (subreg:SI (match_dup 0) 4)
949                  (match_dup 3)))]
950   "")
952 (define_split
953   [(set (match_operand:DI 0 "register_operand" "")
954         (plus:DI (match_operand:DI 1 "register_operand" "")
955                  (match_operand:DI 2 "register_operand" "")))
956    (clobber (match_operand:SI 3 "register_operand" ""))]
957   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
958    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
959    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
960    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
961    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
962    && (REGNO (operands[0]) != REGNO (operands[1])
963        || REGNO (operands[0]) != REGNO (operands[2]))"
965   [(set (subreg:SI (match_dup 0) 4)
966         (plus:SI (subreg:SI (match_dup 1) 4)
967                  (subreg:SI (match_dup 2) 4)))
969    (set (match_dup 3)
970         (ltu:SI (subreg:SI (match_dup 0) 4)
971                 (subreg:SI (match_dup 2) 4)))
973    (set (subreg:SI (match_dup 0) 0)
974         (plus:SI (subreg:SI (match_dup 1) 0)
975                  (subreg:SI (match_dup 2) 0)))
977    (set (subreg:SI (match_dup 0) 0)
978         (plus:SI (subreg:SI (match_dup 0) 0)
979                  (match_dup 3)))]
980   "")
982 (define_insn "adddi3_internal_2"
983   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
984         (plus:DI (match_operand:DI 1 "register_operand" "%d,d,d")
985                  (match_operand:DI 2 "small_int" "P,J,N")))
986    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
987   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
988   "@
989    addu\t%L0,%L1,%2\;sltu\t%3,%L0,%2\;addu\t%M0,%M1,%3
990    move\t%L0,%L1\;move\t%M0,%M1
991    subu\t%L0,%L1,%n2\;sltu\t%3,%L0,%2\;subu\t%M0,%M1,1\;addu\t%M0,%M0,%3"
992   [(set_attr "type"     "darith")
993    (set_attr "mode"     "DI")
994    (set_attr "length"   "12,8,16")])
996 (define_split
997   [(set (match_operand:DI 0 "register_operand" "")
998         (plus:DI (match_operand:DI 1 "register_operand" "")
999                  (match_operand:DI 2 "small_int" "")))
1000    (clobber (match_operand:SI 3 "register_operand" ""))]
1001   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1002    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1003    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1004    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1005    && INTVAL (operands[2]) > 0"
1007   [(set (subreg:SI (match_dup 0) 0)
1008         (plus:SI (subreg:SI (match_dup 1) 0)
1009                  (match_dup 2)))
1011    (set (match_dup 3)
1012         (ltu:SI (subreg:SI (match_dup 0) 0)
1013                 (match_dup 2)))
1015    (set (subreg:SI (match_dup 0) 4)
1016         (plus:SI (subreg:SI (match_dup 1) 4)
1017                  (match_dup 3)))]
1018   "")
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) 4)
1032         (plus:SI (subreg:SI (match_dup 1) 4)
1033                  (match_dup 2)))
1035    (set (match_dup 3)
1036         (ltu:SI (subreg:SI (match_dup 0) 4)
1037                 (match_dup 2)))
1039    (set (subreg:SI (match_dup 0) 0)
1040         (plus:SI (subreg:SI (match_dup 1) 0)
1041                  (match_dup 3)))]
1042   "")
1044 (define_insn "adddi3_internal_3"
1045   [(set (match_operand:DI 0 "register_operand" "=d,d")
1046         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")
1047                  (match_operand:DI 2 "arith_operand" "d,Q")))]
1048   "TARGET_64BIT && !TARGET_MIPS16"
1049   "@
1050     daddu\t%0,%z1,%2
1051     daddiu\t%0,%z1,%2"
1052   [(set_attr "type"     "darith")
1053    (set_attr "mode"     "DI")])
1055 ;; For the mips16, we need to recognize stack pointer additions
1056 ;; explicitly, since we don't have a constraint for $sp.  These insns
1057 ;; will be generated by the save_restore_insns functions.
1059 (define_insn ""
1060   [(set (reg:DI 29)
1061         (plus:DI (reg:DI 29)
1062                  (match_operand:DI 0 "small_int" "I")))]
1063   "TARGET_MIPS16 && TARGET_64BIT"
1064   "daddu\t%$,%$,%0"
1065   [(set_attr "type"     "arith")
1066    (set_attr "mode"     "DI")
1067    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
1068                                       (const_int 4)
1069                                       (const_int 8)))])
1071 (define_insn ""
1072   [(set (match_operand:DI 0 "register_operand" "=d")
1073         (plus:DI (reg:DI 29)
1074                  (match_operand:DI 1 "small_int" "I")))]
1075   "TARGET_MIPS16 && TARGET_64BIT"
1076   "daddu\t%0,%$,%1"
1077   [(set_attr "type"     "arith")
1078    (set_attr "mode"     "DI")
1079    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
1080                                       (const_int 4)
1081                                       (const_int 8)))])
1083 (define_insn ""
1084   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1085         (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1086                  (match_operand:DI 2 "arith_operand" "Q,O,d")))]
1087   "TARGET_MIPS16 && TARGET_64BIT
1088    && (GET_CODE (operands[1]) != REG
1089        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
1090        || M16_REG_P (REGNO (operands[1]))
1091        || REGNO (operands[1]) == ARG_POINTER_REGNUM
1092        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
1093        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
1094    && (GET_CODE (operands[2]) != REG
1095        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
1096        || M16_REG_P (REGNO (operands[2]))
1097        || REGNO (operands[2]) == ARG_POINTER_REGNUM
1098        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
1099        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
1101   if (REGNO (operands[0]) == REGNO (operands[1]))
1102     return "daddu\t%0,%2";
1103   else
1104     return "daddu\t%0,%1,%2";
1106   [(set_attr "type"     "arith")
1107    (set_attr "mode"     "DI")
1108    (set_attr_alternative "length"
1109                 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
1110                                (const_int 4)
1111                                (const_int 8))
1112                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1113                                (const_int 4)
1114                                (const_int 8))
1115                  (const_int 4)])])
1118 ;; On the mips16, we can sometimes split an add of a constant which is
1119 ;; a 4 byte instruction into two adds which are both 2 byte
1120 ;; instructions.  There are two cases: one where we are adding a
1121 ;; constant plus a register to another register, and one where we are
1122 ;; simply adding a constant to a register.
1124 (define_split
1125   [(set (match_operand:DI 0 "register_operand" "")
1126         (plus:DI (match_dup 0)
1127                  (match_operand:DI 1 "const_int_operand" "")))]
1128   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1129    && GET_CODE (operands[0]) == REG
1130    && M16_REG_P (REGNO (operands[0]))
1131    && GET_CODE (operands[1]) == CONST_INT
1132    && ((INTVAL (operands[1]) > 0xf
1133         && INTVAL (operands[1]) <= 0xf + 0xf)
1134        || (INTVAL (operands[1]) < - 0x10
1135            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1136   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1137    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1139   HOST_WIDE_INT val = INTVAL (operands[1]);
1141   if (val >= 0)
1142     {
1143       operands[1] = GEN_INT (0xf);
1144       operands[2] = GEN_INT (val - 0xf);
1145     }
1146   else
1147     {
1148       operands[1] = GEN_INT (- 0x10);
1149       operands[2] = GEN_INT (val + 0x10);
1150     }
1153 (define_split
1154   [(set (match_operand:DI 0 "register_operand" "")
1155         (plus:DI (match_operand:DI 1 "register_operand" "")
1156                  (match_operand:DI 2 "const_int_operand" "")))]
1157   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1158    && GET_CODE (operands[0]) == REG
1159    && M16_REG_P (REGNO (operands[0]))
1160    && GET_CODE (operands[1]) == REG
1161    && M16_REG_P (REGNO (operands[1]))
1162    && REGNO (operands[0]) != REGNO (operands[1])
1163    && GET_CODE (operands[2]) == CONST_INT
1164    && ((INTVAL (operands[2]) > 0x7
1165         && INTVAL (operands[2]) <= 0x7 + 0xf)
1166        || (INTVAL (operands[2]) < - 0x8
1167            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1168   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1169    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1171   HOST_WIDE_INT val = INTVAL (operands[2]);
1173   if (val >= 0)
1174     {
1175       operands[2] = GEN_INT (0x7);
1176       operands[3] = GEN_INT (val - 0x7);
1177     }
1178   else
1179     {
1180       operands[2] = GEN_INT (- 0x8);
1181       operands[3] = GEN_INT (val + 0x8);
1182     }
1185 (define_insn "addsi3_internal_2"
1186   [(set (match_operand:DI 0 "register_operand" "=d,d")
1187         (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
1188                                  (match_operand:SI 2 "arith_operand" "d,Q"))))]
1189   "TARGET_64BIT && !TARGET_MIPS16"
1190   "@
1191     addu\t%0,%z1,%2
1192     addiu\t%0,%z1,%2"
1193   [(set_attr "type"     "arith")
1194    (set_attr "mode"     "SI")])
1196 (define_insn ""
1197   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1198         (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1199                                  (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
1200   "TARGET_MIPS16 && TARGET_64BIT"
1202   if (REGNO (operands[0]) == REGNO (operands[1]))
1203     return "addu\t%0,%2";
1204   else
1205     return "addu\t%0,%1,%2";
1207   [(set_attr "type"     "arith")
1208    (set_attr "mode"     "SI")
1209    (set_attr_alternative "length"
1210                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1211                                (const_int 4)
1212                                (const_int 8))
1213                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1214                                (const_int 4)
1215                                (const_int 8))
1216                  (const_int 4)])])
1219 ;;  ....................
1221 ;;      SUBTRACTION
1223 ;;  ....................
1226 (define_insn "subdf3"
1227   [(set (match_operand:DF 0 "register_operand" "=f")
1228         (minus:DF (match_operand:DF 1 "register_operand" "f")
1229                   (match_operand:DF 2 "register_operand" "f")))]
1230   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1231   "sub.d\t%0,%1,%2"
1232   [(set_attr "type"     "fadd")
1233    (set_attr "mode"     "DF")])
1235 (define_insn "subsf3"
1236   [(set (match_operand:SF 0 "register_operand" "=f")
1237         (minus:SF (match_operand:SF 1 "register_operand" "f")
1238                   (match_operand:SF 2 "register_operand" "f")))]
1239   "TARGET_HARD_FLOAT"
1240   "sub.s\t%0,%1,%2"
1241   [(set_attr "type"     "fadd")
1242    (set_attr "mode"     "SF")])
1244 (define_expand "subsi3"
1245   [(set (match_operand:SI 0 "register_operand" "")
1246         (minus:SI (match_operand:SI 1 "register_operand" "")
1247                   (match_operand:SI 2 "register_operand" "")))]
1248   ""
1249   "")
1251 (define_insn "subsi3_internal"
1252   [(set (match_operand:SI 0 "register_operand" "=d")
1253         (minus:SI (match_operand:SI 1 "register_operand" "d")
1254                   (match_operand:SI 2 "register_operand" "d")))]
1255   ""
1256   "subu\t%0,%z1,%2"
1257   [(set_attr "type"     "arith")
1258    (set_attr "mode"     "SI")])
1260 (define_expand "subdi3"
1261   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1262                    (minus:DI (match_operand:DI 1 "register_operand" "d")
1263                              (match_operand:DI 2 "register_operand" "d")))
1264               (clobber (match_dup 3))])]
1265   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1267   if (TARGET_64BIT)
1268     {
1269       emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1270                                         operands[2]));
1271       DONE;
1272     }
1274   operands[3] = gen_reg_rtx (SImode);
1277 (define_insn "subdi3_internal"
1278   [(set (match_operand:DI 0 "register_operand" "=d")
1279         (minus:DI (match_operand:DI 1 "register_operand" "d")
1280                   (match_operand:DI 2 "register_operand" "d")))
1281    (clobber (match_operand:SI 3 "register_operand" "=d"))]
1282   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1283   "sltu\t%3,%L1,%L2\;subu\t%L0,%L1,%L2\;subu\t%M0,%M1,%M2\;subu\t%M0,%M0,%3"
1284   [(set_attr "type"     "darith")
1285    (set_attr "mode"     "DI")
1286    (set_attr "length"   "16")])
1288 (define_split
1289   [(set (match_operand:DI 0 "register_operand" "")
1290         (minus:DI (match_operand:DI 1 "register_operand" "")
1291                   (match_operand:DI 2 "register_operand" "")))
1292    (clobber (match_operand:SI 3 "register_operand" ""))]
1293   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1294    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1295    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1296    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1297    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1299   [(set (match_dup 3)
1300         (ltu:SI (subreg:SI (match_dup 1) 0)
1301                 (subreg:SI (match_dup 2) 0)))
1303    (set (subreg:SI (match_dup 0) 0)
1304         (minus:SI (subreg:SI (match_dup 1) 0)
1305                   (subreg:SI (match_dup 2) 0)))
1307    (set (subreg:SI (match_dup 0) 4)
1308         (minus:SI (subreg:SI (match_dup 1) 4)
1309                   (subreg:SI (match_dup 2) 4)))
1311    (set (subreg:SI (match_dup 0) 4)
1312         (minus:SI (subreg:SI (match_dup 0) 4)
1313                   (match_dup 3)))]
1314   "")
1316 (define_split
1317   [(set (match_operand:DI 0 "register_operand" "")
1318         (minus:DI (match_operand:DI 1 "register_operand" "")
1319                   (match_operand:DI 2 "register_operand" "")))
1320    (clobber (match_operand:SI 3 "register_operand" ""))]
1321   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1322    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1323    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1324    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1325    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1327   [(set (match_dup 3)
1328         (ltu:SI (subreg:SI (match_dup 1) 4)
1329                 (subreg:SI (match_dup 2) 4)))
1331    (set (subreg:SI (match_dup 0) 4)
1332         (minus:SI (subreg:SI (match_dup 1) 4)
1333                   (subreg:SI (match_dup 2) 4)))
1335    (set (subreg:SI (match_dup 0) 0)
1336         (minus:SI (subreg:SI (match_dup 1) 0)
1337                   (subreg:SI (match_dup 2) 0)))
1339    (set (subreg:SI (match_dup 0) 0)
1340         (minus:SI (subreg:SI (match_dup 0) 0)
1341                   (match_dup 3)))]
1342   "")
1344 (define_insn "subdi3_internal_3"
1345   [(set (match_operand:DI 0 "register_operand" "=d")
1346         (minus:DI (match_operand:DI 1 "register_operand" "d")
1347                   (match_operand:DI 2 "register_operand" "d")))]
1348   "TARGET_64BIT"
1349   "dsubu\t%0,%1,%2"
1350   [(set_attr "type"     "darith")
1351    (set_attr "mode"     "DI")])
1353 (define_insn "subsi3_internal_2"
1354   [(set (match_operand:DI 0 "register_operand" "=d")
1355         (sign_extend:DI
1356             (minus:SI (match_operand:SI 1 "register_operand" "d")
1357                       (match_operand:SI 2 "register_operand" "d"))))]
1358   "TARGET_64BIT"
1359   "subu\t%0,%1,%2"
1360   [(set_attr "type"     "arith")
1361    (set_attr "mode"     "DI")])
1364 ;;  ....................
1366 ;;      MULTIPLICATION
1368 ;;  ....................
1371 (define_expand "muldf3"
1372   [(set (match_operand:DF 0 "register_operand" "=f")
1373         (mult:DF (match_operand:DF 1 "register_operand" "f")
1374                  (match_operand:DF 2 "register_operand" "f")))]
1375   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1376   "")
1378 (define_insn "muldf3_internal"
1379   [(set (match_operand:DF 0 "register_operand" "=f")
1380         (mult:DF (match_operand:DF 1 "register_operand" "f")
1381                  (match_operand:DF 2 "register_operand" "f")))]
1382   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
1383   "mul.d\t%0,%1,%2"
1384   [(set_attr "type"     "fmul")
1385    (set_attr "mode"     "DF")])
1387 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1388 ;; operands may corrupt immediately following multiplies. This is a
1389 ;; simple fix to insert NOPs.
1391 (define_insn "muldf3_r4300"
1392   [(set (match_operand:DF 0 "register_operand" "=f")
1393         (mult:DF (match_operand:DF 1 "register_operand" "f")
1394                  (match_operand:DF 2 "register_operand" "f")))]
1395   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
1396   "mul.d\t%0,%1,%2\;nop"
1397   [(set_attr "type"     "fmul")
1398    (set_attr "mode"     "DF")
1399    (set_attr "length"   "8")])
1401 (define_expand "mulsf3"
1402   [(set (match_operand:SF 0 "register_operand" "=f")
1403         (mult:SF (match_operand:SF 1 "register_operand" "f")
1404                  (match_operand:SF 2 "register_operand" "f")))]
1405   "TARGET_HARD_FLOAT"
1406   "")
1408 (define_insn "mulsf3_internal"
1409   [(set (match_operand:SF 0 "register_operand" "=f")
1410         (mult:SF (match_operand:SF 1 "register_operand" "f")
1411                  (match_operand:SF 2 "register_operand" "f")))]
1412   "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
1413   "mul.s\t%0,%1,%2"
1414   [(set_attr "type"     "fmul")
1415    (set_attr "mode"     "SF")])
1417 ;; See muldf3_r4300.
1419 (define_insn "mulsf3_r4300"
1420   [(set (match_operand:SF 0 "register_operand" "=f")
1421         (mult:SF (match_operand:SF 1 "register_operand" "f")
1422                  (match_operand:SF 2 "register_operand" "f")))]
1423   "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
1424   "mul.s\t%0,%1,%2\;nop"
1425   [(set_attr "type"     "fmul")
1426    (set_attr "mode"     "SF")
1427    (set_attr "length"   "8")])
1430 ;; The original R4000 has a cpu bug.  If a double-word or a variable
1431 ;; shift executes while an integer multiplication is in progress, the
1432 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
1433 ;; with the mult on the R4000.
1435 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1436 ;; (also valid for MIPS R4000MC processors):
1438 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1439 ;;      this errata description.
1440 ;;      The following code sequence causes the R4000 to incorrectly
1441 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
1442 ;;      instruction.  If the dsra32 instruction is executed during an
1443 ;;      integer multiply, the dsra32 will only shift by the amount in
1444 ;;      specified in the instruction rather than the amount plus 32
1445 ;;      bits.
1446 ;;      instruction 1:          mult    rs,rt           integer multiply
1447 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
1448 ;;                                                      right arithmetic + 32
1449 ;;      Workaround: A dsra32 instruction placed after an integer
1450 ;;      multiply should not be one of the 11 instructions after the
1451 ;;      multiply instruction."
1453 ;; and:
1455 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1456 ;;      the following description.
1457 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
1458 ;;      64-bit versions) may produce incorrect results under the
1459 ;;      following conditions:
1460 ;;      1) An integer multiply is currently executing
1461 ;;      2) These types of shift instructions are executed immediately
1462 ;;         following an integer divide instruction.
1463 ;;      Workaround:
1464 ;;      1) Make sure no integer multiply is running wihen these
1465 ;;         instruction are executed.  If this cannot be predicted at
1466 ;;         compile time, then insert a "mfhi" to R0 instruction
1467 ;;         immediately after the integer multiply instruction.  This
1468 ;;         will cause the integer multiply to complete before the shift
1469 ;;         is executed.
1470 ;;      2) Separate integer divide and these two classes of shift
1471 ;;         instructions by another instruction or a noop."
1473 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1474 ;; respectively.
1476 (define_expand "mulsi3"
1477   [(set (match_operand:SI 0 "register_operand" "")
1478         (mult:SI (match_operand:SI 1 "register_operand" "")
1479                  (match_operand:SI 2 "register_operand" "")))]
1480   ""
1482   if (GENERATE_MULT3_SI || TARGET_MAD)
1483     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1484   else if (!TARGET_FIX_R4000)
1485     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1486   else
1487     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1488   DONE;
1491 (define_insn "mulsi3_mult3"
1492   [(set (match_operand:SI 0 "register_operand" "=d,l")
1493         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1494                  (match_operand:SI 2 "register_operand" "d,d")))
1495    (clobber (match_scratch:SI 3 "=h,h"))
1496    (clobber (match_scratch:SI 4 "=l,X"))]
1497   "GENERATE_MULT3_SI
1498    || TARGET_MAD"
1500   if (which_alternative == 1)
1501     return "mult\t%1,%2";
1502   if (TARGET_MAD
1503       || TARGET_MIPS5400
1504       || TARGET_MIPS5500
1505       || TARGET_MIPS7000
1506       || TARGET_MIPS9000
1507       || ISA_MIPS32
1508       || ISA_MIPS32R2
1509       || ISA_MIPS64)
1510     return "mul\t%0,%1,%2";
1511   return "mult\t%0,%1,%2";
1513   [(set_attr "type"     "imul")
1514    (set_attr "mode"     "SI")])
1516 ;; If a register gets allocated to LO, and we spill to memory, the reload
1517 ;; will include a move from LO to a GPR.  Merge it into the multiplication
1518 ;; if it can set the GPR directly.
1520 ;; Operand 0: LO
1521 ;; Operand 1: GPR (1st multiplication operand)
1522 ;; Operand 2: GPR (2nd multiplication operand)
1523 ;; Operand 3: HI
1524 ;; Operand 4: GPR (destination)
1525 (define_peephole2
1526   [(parallel
1527        [(set (match_operand:SI 0 "register_operand" "")
1528              (mult:SI (match_operand:SI 1 "register_operand" "")
1529                       (match_operand:SI 2 "register_operand" "")))
1530         (clobber (match_operand:SI 3 "register_operand" ""))
1531         (clobber (scratch:SI))])
1532    (set (match_operand:SI 4 "register_operand" "")
1533         (match_dup 0))]
1534   "GENERATE_MULT3_SI
1535    && true_regnum (operands[0]) == LO_REGNUM
1536    && GP_REG_P (true_regnum (operands[4]))
1537    && peep2_reg_dead_p (2, operands[0])"
1538   [(parallel
1539        [(set (match_dup 4)
1540              (mult:SI (match_dup 1)
1541                       (match_dup 2)))
1542         (clobber (match_dup 3))
1543         (clobber (match_dup 0))])])
1545 (define_insn "mulsi3_internal"
1546   [(set (match_operand:SI 0 "register_operand" "=l")
1547         (mult:SI (match_operand:SI 1 "register_operand" "d")
1548                  (match_operand:SI 2 "register_operand" "d")))
1549    (clobber (match_scratch:SI 3 "=h"))]
1550   "!TARGET_FIX_R4000"
1551   "mult\t%1,%2"
1552   [(set_attr "type"     "imul")
1553    (set_attr "mode"     "SI")])
1555 (define_insn "mulsi3_r4000"
1556   [(set (match_operand:SI 0 "register_operand" "=d")
1557         (mult:SI (match_operand:SI 1 "register_operand" "d")
1558                  (match_operand:SI 2 "register_operand" "d")))
1559    (clobber (match_scratch:SI 3 "=h"))
1560    (clobber (match_scratch:SI 4 "=l"))]
1561   "TARGET_FIX_R4000"
1562   "mult\t%1,%2\;mflo\t%0"
1563   [(set_attr "type"     "imul")
1564    (set_attr "mode"     "SI")
1565    (set_attr "length"   "8")])
1567 ;; Multiply-accumulate patterns
1569 ;; For processors that can copy the output to a general register:
1571 ;; The all-d alternative is needed because the combiner will find this
1572 ;; pattern and then register alloc/reload will move registers around to
1573 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1575 ;; The last alternative should be made slightly less desirable, but adding
1576 ;; "?" to the constraint is too strong, and causes values to be loaded into
1577 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1578 ;; trick.
1579 (define_insn "*mul_acc_si"
1580   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1581         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1582                           (match_operand:SI 2 "register_operand" "d,d,d"))
1583                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1584    (clobber (match_scratch:SI 4 "=h,h,h"))
1585    (clobber (match_scratch:SI 5 "=X,3,l"))
1586    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1587   "(TARGET_MIPS3900
1588    || ISA_HAS_MADD_MSUB)
1589    && !TARGET_MIPS16"
1591   static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1592   if (which_alternative == 2)
1593     return "#";
1594   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1595     return "#";
1596   return madd[which_alternative];
1598   [(set_attr "type"     "imadd,imadd,multi")
1599    (set_attr "mode"     "SI")
1600    (set_attr "length"   "4,4,8")])
1602 ;; Split the above insn if we failed to get LO allocated.
1603 (define_split
1604   [(set (match_operand:SI 0 "register_operand" "")
1605         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1606                           (match_operand:SI 2 "register_operand" ""))
1607                  (match_operand:SI 3 "register_operand" "")))
1608    (clobber (match_scratch:SI 4 ""))
1609    (clobber (match_scratch:SI 5 ""))
1610    (clobber (match_scratch:SI 6 ""))]
1611   "reload_completed && !TARGET_DEBUG_D_MODE
1612    && GP_REG_P (true_regnum (operands[0]))
1613    && GP_REG_P (true_regnum (operands[3]))"
1614   [(parallel [(set (match_dup 6)
1615                    (mult:SI (match_dup 1) (match_dup 2)))
1616               (clobber (match_dup 4))
1617               (clobber (match_dup 5))])
1618    (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1619   "")
1621 ;; Splitter to copy result of MADD to a general register
1622 (define_split
1623   [(set (match_operand:SI                   0 "register_operand" "")
1624         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1625                           (match_operand:SI 2 "register_operand" ""))
1626                  (match_operand:SI          3 "register_operand" "")))
1627    (clobber (match_scratch:SI               4 ""))
1628    (clobber (match_scratch:SI               5 ""))
1629    (clobber (match_scratch:SI               6 ""))]
1630   "reload_completed && !TARGET_DEBUG_D_MODE
1631    && GP_REG_P (true_regnum (operands[0]))
1632    && true_regnum (operands[3]) == LO_REGNUM"
1633   [(parallel [(set (match_dup 3)
1634                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1635                             (match_dup 3)))
1636               (clobber (match_dup 4))
1637               (clobber (match_dup 5))
1638               (clobber (match_dup 6))])
1639    (set (match_dup 0) (match_dup 3))]
1640   "")
1642 (define_insn "*macc"
1643   [(set (match_operand:SI 0 "register_operand" "=l,d")
1644         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1645                           (match_operand:SI 2 "register_operand" "d,d"))
1646                  (match_operand:SI 3 "register_operand" "0,l")))
1647    (clobber (match_scratch:SI 4 "=h,h"))
1648    (clobber (match_scratch:SI 5 "=X,3"))]
1649   "ISA_HAS_MACC"
1651   if (which_alternative == 1)
1652     return "macc\t%0,%1,%2";
1653   else if (TARGET_MIPS5500)
1654     return "madd\t%1,%2";
1655   else
1656     return "macc\t%.,%1,%2";
1658   [(set_attr "type" "imadd")
1659    (set_attr "mode" "SI")])
1661 ;; Pattern generated by define_peephole2 below
1662 (define_insn "*macc2"
1663   [(set (match_operand:SI 0 "register_operand" "=l")
1664         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1665                           (match_operand:SI 2 "register_operand" "d"))
1666                  (match_dup 0)))
1667    (set (match_operand:SI 3 "register_operand" "=d")
1668         (plus:SI (mult:SI (match_dup 1)
1669                           (match_dup 2))
1670                  (match_dup 0)))
1671    (clobber (match_scratch:SI 4 "=h"))]
1672   "ISA_HAS_MACC && reload_completed"
1673   "macc\t%3,%1,%2"
1674   [(set_attr "type"     "imadd")
1675    (set_attr "mode"     "SI")])
1677 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1679 ;; Operand 0: LO
1680 ;; Operand 1: GPR (1st multiplication operand)
1681 ;; Operand 2: GPR (2nd multiplication operand)
1682 ;; Operand 3: HI
1683 ;; Operand 4: GPR (destination)
1684 (define_peephole2
1685   [(parallel
1686        [(set (match_operand:SI 0 "register_operand" "")
1687              (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1688                                (match_operand:SI 2 "register_operand" ""))
1689                       (match_dup 0)))
1690         (clobber (match_operand:SI 3 "register_operand" ""))
1691         (clobber (scratch:SI))])
1692    (set (match_operand:SI 4 "register_operand" "")
1693         (match_dup 0))]
1694   "ISA_HAS_MACC
1695    && true_regnum (operands[0]) == LO_REGNUM
1696    && GP_REG_P (true_regnum (operands[4]))"
1697   [(parallel [(set (match_dup 0)
1698                    (plus:SI (mult:SI (match_dup 1)
1699                                      (match_dup 2))
1700                             (match_dup 0)))
1701               (set (match_dup 4)
1702                    (plus:SI (mult:SI (match_dup 1)
1703                                      (match_dup 2))
1704                             (match_dup 0)))
1705               (clobber (match_dup 3))])]
1706   "")
1708 ;; When we have a three-address multiplication instruction, it should
1709 ;; be faster to do a separate multiply and add, rather than moving
1710 ;; something into LO in order to use a macc instruction.
1712 ;; This peephole needs a scratch register to cater for the case when one
1713 ;; of the multiplication operands is the same as the destination.
1715 ;; Operand 0: GPR (scratch)
1716 ;; Operand 1: LO
1717 ;; Operand 2: GPR (addend)
1718 ;; Operand 3: GPR (destination)
1719 ;; Operand 4: GPR (1st multiplication operand)
1720 ;; Operand 5: GPR (2nd multiplication operand)
1721 ;; Operand 6: HI
1722 (define_peephole2
1723   [(match_scratch:SI 0 "d")
1724    (set (match_operand:SI 1 "register_operand" "")
1725         (match_operand:SI 2 "register_operand" ""))
1726    (match_dup 0)
1727    (parallel
1728        [(set (match_operand:SI 3 "register_operand" "")
1729              (plus:SI (mult:SI (match_operand:SI 4 "register_operand" "")
1730                                (match_operand:SI 5 "register_operand" ""))
1731                       (match_dup 1)))
1732         (clobber (match_operand:SI 6 "register_operand" ""))
1733         (clobber (match_dup 1))])]
1734   "ISA_HAS_MACC && GENERATE_MULT3_SI
1735    && true_regnum (operands[1]) == LO_REGNUM
1736    && peep2_reg_dead_p (2, operands[1])
1737    && GP_REG_P (true_regnum (operands[3]))"
1738   [(parallel [(set (match_dup 0)
1739                    (mult:SI (match_dup 4)
1740                             (match_dup 5)))
1741               (clobber (match_dup 6))
1742               (clobber (match_dup 1))])
1743    (set (match_dup 3)
1744         (plus:SI (match_dup 0)
1745                  (match_dup 2)))]
1746   "")
1748 ;; Same as above, except LO is the initial target of the macc.
1750 ;; Operand 0: GPR (scratch)
1751 ;; Operand 1: LO
1752 ;; Operand 2: GPR (addend)
1753 ;; Operand 3: GPR (1st multiplication operand)
1754 ;; Operand 4: GPR (2nd multiplication operand)
1755 ;; Operand 5: HI
1756 ;; Operand 6: GPR (destination)
1757 (define_peephole2
1758   [(match_scratch:SI 0 "d")
1759    (set (match_operand:SI 1 "register_operand" "")
1760         (match_operand:SI 2 "register_operand" ""))
1761    (match_dup 0)
1762    (parallel
1763        [(set (match_dup 1)
1764              (plus:SI (mult:SI (match_operand:SI 3 "register_operand" "")
1765                                (match_operand:SI 4 "register_operand" ""))
1766                       (match_dup 1)))
1767         (clobber (match_operand:SI 5 "register_operand" ""))
1768         (clobber (scratch:SI))])
1769    (match_dup 0)
1770    (set (match_operand:SI 6 "register_operand" "")
1771         (match_dup 1))]
1772   "ISA_HAS_MACC && GENERATE_MULT3_SI
1773    && true_regnum (operands[1]) == LO_REGNUM
1774    && peep2_reg_dead_p (3, operands[1])
1775    && GP_REG_P (true_regnum (operands[6]))"
1776   [(parallel [(set (match_dup 0)
1777                    (mult:SI (match_dup 3)
1778                             (match_dup 4)))
1779               (clobber (match_dup 5))
1780               (clobber (match_dup 1))])
1781    (set (match_dup 6)
1782         (plus:SI (match_dup 0)
1783                  (match_dup 2)))]
1784   "")
1786 (define_insn "*mul_sub_si"
1787   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1788         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1789                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1790                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1791    (clobber (match_scratch:SI 4 "=h,h,h"))
1792    (clobber (match_scratch:SI 5 "=X,1,l"))
1793    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1794   "ISA_HAS_MADD_MSUB"
1795   "@
1796    msub\t%2,%3
1797    #
1798    #"
1799   [(set_attr "type"     "imadd,multi,multi")
1800    (set_attr "mode"     "SI")
1801    (set_attr "length"   "4,8,8")])
1803 ;; Split the above insn if we failed to get LO allocated.
1804 (define_split
1805   [(set (match_operand:SI 0 "register_operand" "")
1806         (minus:SI (match_operand:SI 1 "register_operand" "")
1807                   (mult:SI (match_operand:SI 2 "register_operand" "")
1808                            (match_operand:SI 3 "register_operand" ""))))
1809    (clobber (match_scratch:SI 4 ""))
1810    (clobber (match_scratch:SI 5 ""))
1811    (clobber (match_scratch:SI 6 ""))]
1812   "reload_completed && !TARGET_DEBUG_D_MODE
1813    && GP_REG_P (true_regnum (operands[0]))
1814    && GP_REG_P (true_regnum (operands[1]))"
1815   [(parallel [(set (match_dup 6)
1816                    (mult:SI (match_dup 2) (match_dup 3)))
1817               (clobber (match_dup 4))
1818               (clobber (match_dup 5))])
1819    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1820   "")
1822 ;; Splitter to copy result of MSUB to a general register
1823 (define_split
1824   [(set (match_operand:SI 0 "register_operand" "")
1825         (minus:SI (match_operand:SI 1 "register_operand" "")
1826                   (mult:SI (match_operand:SI 2 "register_operand" "")
1827                            (match_operand:SI 3 "register_operand" ""))))
1828    (clobber (match_scratch:SI 4 ""))
1829    (clobber (match_scratch:SI 5 ""))
1830    (clobber (match_scratch:SI 6 ""))]
1831   "reload_completed && !TARGET_DEBUG_D_MODE
1832    && GP_REG_P (true_regnum (operands[0]))
1833    && true_regnum (operands[1]) == LO_REGNUM"
1834   [(parallel [(set (match_dup 1)
1835                    (minus:SI (match_dup 1)
1836                              (mult:SI (match_dup 2) (match_dup 3))))
1837               (clobber (match_dup 4))
1838               (clobber (match_dup 5))
1839               (clobber (match_dup 6))])
1840    (set (match_dup 0) (match_dup 1))]
1841   "")
1843 (define_insn "*muls"
1844   [(set (match_operand:SI                  0 "register_operand" "=l,d")
1845         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1846                          (match_operand:SI 2 "register_operand" "d,d"))))
1847    (clobber (match_scratch:SI              3                    "=h,h"))
1848    (clobber (match_scratch:SI              4                    "=X,l"))]
1849   "ISA_HAS_MULS"
1850   "@
1851    muls\t$0,%1,%2
1852    muls\t%0,%1,%2"
1853   [(set_attr "type"     "imul")
1854    (set_attr "mode"     "SI")])
1856 (define_insn "*msac"
1857   [(set (match_operand:SI 0 "register_operand" "=l,d")
1858         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1859                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1860                            (match_operand:SI 3 "register_operand" "d,d"))))
1861    (clobber (match_scratch:SI 4 "=h,h"))
1862    (clobber (match_scratch:SI 5 "=X,1"))]
1863   "ISA_HAS_MSAC"
1865   if (which_alternative == 1)
1866     return "msac\t%0,%2,%3";
1867   else if (TARGET_MIPS5500)
1868     return "msub\t%2,%3";
1869   else
1870     return "msac\t$0,%2,%3";
1872   [(set_attr "type"     "imadd")
1873    (set_attr "mode"     "SI")])
1875 (define_expand "muldi3"
1876   [(set (match_operand:DI 0 "register_operand" "")
1877         (mult:DI (match_operand:DI 1 "register_operand" "")
1878                  (match_operand:DI 2 "register_operand" "")))]
1879   "TARGET_64BIT"
1881   if (GENERATE_MULT3_DI)
1882     emit_insn (gen_muldi3_mult3 (operands[0], operands[1], operands[2]));
1883   else if (!TARGET_FIX_R4000)
1884     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1885   else
1886     emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1887   DONE;
1890 (define_insn "muldi3_mult3"
1891   [(set (match_operand:DI 0 "register_operand" "=d")
1892         (mult:DI (match_operand:DI 1 "register_operand" "d")
1893                  (match_operand:DI 2 "register_operand" "d")))
1894    (clobber (match_scratch:DI 3 "=h"))
1895    (clobber (match_scratch:DI 4 "=l"))]
1896   "TARGET_64BIT && GENERATE_MULT3_DI"
1897   "dmult\t%0,%1,%2"
1898   [(set_attr "type"     "imul")
1899    (set_attr "mode"     "DI")])
1901 (define_insn "muldi3_internal"
1902   [(set (match_operand:DI 0 "register_operand" "=l")
1903         (mult:DI (match_operand:DI 1 "register_operand" "d")
1904                  (match_operand:DI 2 "register_operand" "d")))
1905    (clobber (match_scratch:DI 3 "=h"))]
1906   "TARGET_64BIT && !TARGET_FIX_R4000"
1907   "dmult\t%1,%2"
1908   [(set_attr "type"     "imul")
1909    (set_attr "mode"     "DI")])
1911 (define_insn "muldi3_r4000"
1912   [(set (match_operand:DI 0 "register_operand" "=d")
1913         (mult:DI (match_operand:DI 1 "register_operand" "d")
1914                  (match_operand:DI 2 "register_operand" "d")))
1915    (clobber (match_scratch:DI 3 "=h"))
1916    (clobber (match_scratch:DI 4 "=l"))]
1917   "TARGET_64BIT && TARGET_FIX_R4000"
1918   "dmult\t%1,%2\;mflo\t%0"
1919   [(set_attr "type"     "imul")
1920    (set_attr "mode"     "DI")
1921    (set_attr "length"   "8")])
1923 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1925 (define_expand "mulsidi3"
1926   [(parallel
1927       [(set (match_operand:DI 0 "register_operand" "")
1928             (mult:DI
1929                (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1930                (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))
1931        (clobber (scratch:DI))
1932        (clobber (scratch:DI))
1933        (clobber (scratch:DI))])]
1934   "!TARGET_64BIT || !TARGET_FIX_R4000"
1936   if (!TARGET_64BIT)
1937     {
1938       if (!TARGET_FIX_R4000)
1939         emit_insn (gen_mulsidi3_32bit_internal (operands[0], operands[1],
1940                                                 operands[2]));
1941       else
1942         emit_insn (gen_mulsidi3_32bit_r4000 (operands[0], operands[1],
1943                                              operands[2]));
1944       DONE;
1945     }
1948 (define_insn "mulsidi3_32bit_internal"
1949   [(set (match_operand:DI 0 "register_operand" "=x")
1950         (mult:DI
1951            (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1952            (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1953   "!TARGET_64BIT && !TARGET_FIX_R4000"
1954   "mult\t%1,%2"
1955   [(set_attr "type"     "imul")
1956    (set_attr "mode"     "SI")])
1958 (define_insn "mulsidi3_32bit_r4000"
1959   [(set (match_operand:DI 0 "register_operand" "=d")
1960         (mult:DI
1961            (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1962            (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1963    (clobber (match_scratch:DI 3 "=l"))
1964    (clobber (match_scratch:DI 4 "=h"))]
1965   "!TARGET_64BIT && TARGET_FIX_R4000"
1966   "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1967   [(set_attr "type"     "imul")
1968    (set_attr "mode"     "SI")
1969    (set_attr "length"   "12")])
1971 (define_insn_and_split "*mulsidi3_64bit"
1972   [(set (match_operand:DI 0 "register_operand" "=d")
1973         (mult:DI (match_operator:DI 1 "extend_operator"
1974                     [(match_operand:SI 3 "register_operand" "d")])
1975                  (match_operator:DI 2 "extend_operator"
1976                     [(match_operand:SI 4 "register_operand" "d")])))
1977    (clobber (match_scratch:DI 5 "=l"))
1978    (clobber (match_scratch:DI 6 "=h"))
1979    (clobber (match_scratch:DI 7 "=d"))]
1980   "TARGET_64BIT && !TARGET_FIX_R4000
1981    && GET_CODE (operands[1]) == GET_CODE (operands[2])"
1982   "#"
1983   "&& reload_completed"
1984   [(parallel
1985        [(set (match_dup 5)
1986              (sign_extend:DI
1987                 (mult:SI (match_dup 3)
1988                          (match_dup 4))))
1989         (set (match_dup 6)
1990              (ashiftrt:DI
1991                 (mult:DI (match_dup 1)
1992                          (match_dup 2))
1993                 (const_int 32)))])
1995    ;; OP7 <- LO, OP0 <- HI
1996    (set (match_dup 7) (match_dup 5))
1997    (set (match_dup 0) (match_dup 6))
1999    ;; Zero-extend OP7.
2000    (set (match_dup 7)
2001         (ashift:DI (match_dup 7)
2002                    (const_int 32)))
2003    (set (match_dup 7)
2004         (lshiftrt:DI (match_dup 7)
2005                      (const_int 32)))
2007    ;; Shift OP0 into place.
2008    (set (match_dup 0)
2009         (ashift:DI (match_dup 0)
2010                    (const_int 32)))
2012    ;; OR the two halves together
2013    (set (match_dup 0)
2014         (ior:DI (match_dup 0)
2015                 (match_dup 7)))]
2016   ""
2017   [(set_attr "type"     "imul")
2018    (set_attr "mode"     "SI")
2019    (set_attr "length"   "24")])
2021 (define_insn "*mulsidi3_64bit_parts"
2022   [(set (match_operand:DI 0 "register_operand" "=l")
2023         (sign_extend:DI
2024            (mult:SI (match_operand:SI 2 "register_operand" "d")
2025                     (match_operand:SI 3 "register_operand" "d"))))
2026    (set (match_operand:DI 1 "register_operand" "=h")
2027         (ashiftrt:DI
2028            (mult:DI
2029               (match_operator:DI 4 "extend_operator" [(match_dup 2)])
2030               (match_operator:DI 5 "extend_operator" [(match_dup 3)]))
2031            (const_int 32)))]
2032   "TARGET_64BIT && !TARGET_FIX_R4000
2033    && GET_CODE (operands[4]) == GET_CODE (operands[5])"
2035   if (GET_CODE (operands[4]) == SIGN_EXTEND)
2036     return "mult\t%2,%3";
2037   else
2038     return "multu\t%2,%3";
2040   [(set_attr "type" "imul")
2041    (set_attr "mode" "SI")])
2043 (define_expand "umulsidi3"
2044   [(parallel
2045       [(set (match_operand:DI 0 "register_operand" "")
2046             (mult:DI
2047                (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2048                (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
2049        (clobber (scratch:DI))
2050        (clobber (scratch:DI))
2051        (clobber (scratch:DI))])]
2052   "!TARGET_64BIT || !TARGET_FIX_R4000"
2054   if (!TARGET_64BIT)
2055     {
2056       if (!TARGET_FIX_R4000)
2057         emit_insn (gen_umulsidi3_32bit_internal (operands[0], operands[1],
2058                                                  operands[2]));
2059       else
2060         emit_insn (gen_umulsidi3_32bit_r4000 (operands[0], operands[1],
2061                                               operands[2]));
2062       DONE;
2063     }
2066 (define_insn "umulsidi3_32bit_internal"
2067   [(set (match_operand:DI 0 "register_operand" "=x")
2068         (mult:DI
2069            (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2070            (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2071   "!TARGET_64BIT && !TARGET_FIX_R4000"
2072   "multu\t%1,%2"
2073   [(set_attr "type"     "imul")
2074    (set_attr "mode"     "SI")])
2076 (define_insn "umulsidi3_32bit_r4000"
2077   [(set (match_operand:DI 0 "register_operand" "=d")
2078         (mult:DI
2079            (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2080            (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2081    (clobber (match_scratch:DI 3 "=l"))
2082    (clobber (match_scratch:DI 4 "=h"))]
2083   "!TARGET_64BIT && TARGET_FIX_R4000"
2084   "multu\t%1,%2\;mflo\t%L0;mfhi\t%M0"
2085   [(set_attr "type"     "imul")
2086    (set_attr "mode"     "SI")
2087    (set_attr "length"   "12")])
2089 ;; Widening multiply with negation.
2090 (define_insn "*muls_di"
2091   [(set (match_operand:DI 0 "register_operand" "=x")
2092         (neg:DI
2093          (mult:DI
2094           (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2095           (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2096   "!TARGET_64BIT && ISA_HAS_MULS"
2097   "muls\t$0,%1,%2"
2098   [(set_attr "type"     "imul")
2099    (set_attr "length"   "4")
2100    (set_attr "mode"     "SI")])
2102 (define_insn "*umuls_di"
2103   [(set (match_operand:DI 0 "register_operand" "=x")
2104         (neg:DI
2105          (mult:DI
2106           (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2107           (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2108   "!TARGET_64BIT && ISA_HAS_MULS"
2109   "mulsu\t$0,%1,%2"
2110   [(set_attr "type"     "imul")
2111    (set_attr "length"   "4")
2112    (set_attr "mode"     "SI")])
2114 (define_insn "*smsac_di"
2115   [(set (match_operand:DI 0 "register_operand" "=x")
2116         (minus:DI
2117            (match_operand:DI 3 "register_operand" "0")
2118            (mult:DI
2119               (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2120               (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2121   "!TARGET_64BIT && ISA_HAS_MSAC"
2123   if (TARGET_MIPS5500)
2124     return "msub\t%1,%2";
2125   else
2126     return "msac\t$0,%1,%2";
2128   [(set_attr "type"     "imadd")
2129    (set_attr "length"   "4")
2130    (set_attr "mode"     "SI")])
2132 (define_insn "*umsac_di"
2133   [(set (match_operand:DI 0 "register_operand" "=x")
2134         (minus:DI
2135            (match_operand:DI 3 "register_operand" "0")
2136            (mult:DI
2137               (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2138               (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2139   "!TARGET_64BIT && ISA_HAS_MSAC"
2141   if (TARGET_MIPS5500)
2142     return "msubu\t%1,%2";
2143   else
2144     return "msacu\t$0,%1,%2";
2146   [(set_attr "type"     "imadd")
2147    (set_attr "length"   "4")
2148    (set_attr "mode"     "SI")])
2150 ;; _highpart patterns
2151 (define_expand "umulsi3_highpart"
2152   [(set (match_operand:SI 0 "register_operand" "")
2153         (truncate:SI
2154          (lshiftrt:DI
2155           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2156                    (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
2157           (const_int 32))))]
2158   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
2160   if (ISA_HAS_MULHI)
2161     emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1],
2162                                                     operands[2]));
2163   else
2164     emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1],
2165                                               operands[2]));
2166   DONE;
2169 (define_insn "umulsi3_highpart_internal"
2170   [(set (match_operand:SI 0 "register_operand" "=h")
2171         (truncate:SI
2172          (lshiftrt:DI
2173           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2174                    (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2175           (const_int 32))))
2176    (clobber (match_scratch:SI 3 "=l"))]
2177   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
2178   "multu\t%1,%2"
2179   [(set_attr "type"   "imul")
2180    (set_attr "mode"   "SI")
2181    (set_attr "length" "4")])
2183 (define_insn "umulsi3_highpart_mulhi_internal"
2184   [(set (match_operand:SI 0 "register_operand" "=h,d")
2185         (truncate:SI
2186          (lshiftrt:DI
2187           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2188                    (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
2189           (const_int 32))))
2190    (clobber (match_scratch:SI 3 "=l,l"))
2191    (clobber (match_scratch:SI 4 "=X,h"))]
2192   "ISA_HAS_MULHI"
2193   "@
2194    multu\t%1,%2
2195    mulhiu\t%0,%1,%2"
2196   [(set_attr "type"   "imul")
2197    (set_attr "mode"   "SI")
2198    (set_attr "length" "4")])
2200 (define_insn "umulsi3_highpart_neg_mulhi_internal"
2201   [(set (match_operand:SI 0 "register_operand" "=h,d")
2202         (truncate:SI
2203          (lshiftrt:DI
2204           (neg:DI
2205            (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2206                     (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
2207           (const_int 32))))
2208    (clobber (match_scratch:SI 3 "=l,l"))
2209    (clobber (match_scratch:SI 4 "=X,h"))]
2210   "ISA_HAS_MULHI"
2211   "@
2212    mulshiu\t%.,%1,%2
2213    mulshiu\t%0,%1,%2"
2214   [(set_attr "type"   "imul")
2215    (set_attr "mode"   "SI")
2216    (set_attr "length" "4")])
2218 (define_expand "smulsi3_highpart"
2219   [(set (match_operand:SI 0 "register_operand" "")
2220         (truncate:SI
2221          (lshiftrt:DI
2222           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2223                    (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
2224          (const_int 32))))]
2225   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
2227   if (ISA_HAS_MULHI)
2228     emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1],
2229                                                     operands[2]));
2230   else
2231     emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1],
2232                                               operands[2]));
2233   DONE;
2236 (define_insn "smulsi3_highpart_internal"
2237   [(set (match_operand:SI 0 "register_operand" "=h")
2238         (truncate:SI
2239          (lshiftrt:DI
2240           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2241                    (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2242           (const_int 32))))
2243    (clobber (match_scratch:SI 3 "=l"))]
2244   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
2245   "mult\t%1,%2"
2246   [(set_attr "type"     "imul")
2247    (set_attr "mode"     "SI")
2248    (set_attr "length"   "4")])
2250 (define_insn "smulsi3_highpart_mulhi_internal"
2251   [(set (match_operand:SI 0 "register_operand" "=h,d")
2252         (truncate:SI
2253          (lshiftrt:DI
2254           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2255                    (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
2256           (const_int 32))))
2257    (clobber (match_scratch:SI 3 "=l,l"))
2258    (clobber (match_scratch:SI 4 "=X,h"))]
2259   "ISA_HAS_MULHI"
2260   "@
2261    mult\t%1,%2
2262    mulhi\t%0,%1,%2"
2263   [(set_attr "type"   "imul")
2264    (set_attr "mode"   "SI")
2265    (set_attr "length" "4")])
2267 (define_insn "smulsi3_highpart_neg_mulhi_internal"
2268   [(set (match_operand:SI 0 "register_operand" "=h,d")
2269         (truncate:SI
2270          (lshiftrt:DI
2271           (neg:DI
2272            (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2273                     (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
2274           (const_int 32))))
2275    (clobber (match_scratch:SI 3 "=l,l"))
2276    (clobber (match_scratch:SI 4 "=X,h"))]
2277   "ISA_HAS_MULHI"
2278   "@
2279    mulshi\t%.,%1,%2
2280    mulshi\t%0,%1,%2"
2281   [(set_attr "type"   "imul")
2282    (set_attr "mode"   "SI")])
2284 (define_insn "smuldi3_highpart"
2285   [(set (match_operand:DI 0 "register_operand" "=h")
2286         (truncate:DI
2287          (lshiftrt:TI
2288           (mult:TI
2289            (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
2290            (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
2291          (const_int 64))))
2292    (clobber (match_scratch:DI 3 "=l"))]
2293   "TARGET_64BIT && !TARGET_FIX_R4000"
2294   "dmult\t%1,%2"
2295   [(set_attr "type"     "imul")
2296    (set_attr "mode"     "DI")])
2298 (define_insn "umuldi3_highpart"
2299   [(set (match_operand:DI 0 "register_operand" "=h")
2300         (truncate:DI
2301          (lshiftrt:TI
2302           (mult:TI
2303            (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
2304            (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
2305           (const_int 64))))
2306    (clobber (match_scratch:DI 3 "=l"))]
2307   "TARGET_64BIT && !TARGET_FIX_R4000"
2308   "dmultu\t%1,%2"
2309   [(set_attr "type"     "imul")
2310    (set_attr "mode"     "DI")])
2313 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2314 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
2316 (define_insn "madsi"
2317   [(set (match_operand:SI 0 "register_operand" "+l")
2318         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2319                           (match_operand:SI 2 "register_operand" "d"))
2320                  (match_dup 0)))
2321    (clobber (match_scratch:SI 3 "=h"))]
2322   "TARGET_MAD"
2323   "mad\t%1,%2"
2324   [(set_attr "type"     "imadd")
2325    (set_attr "mode"     "SI")])
2327 (define_insn "*umul_acc_di"
2328   [(set (match_operand:DI 0 "register_operand" "=x")
2329         (plus:DI
2330          (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2331                   (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2332          (match_operand:DI 3 "register_operand" "0")))]
2333   "(TARGET_MAD || ISA_HAS_MACC)
2334    && !TARGET_64BIT"
2336   if (TARGET_MAD)
2337     return "madu\t%1,%2";
2338   else if (TARGET_MIPS5500)
2339     return "maddu\t%1,%2";
2340   else
2341     return "maccu\t%.,%1,%2";
2343   [(set_attr "type"   "imadd")
2344    (set_attr "mode"   "SI")])
2347 (define_insn "*smul_acc_di"
2348   [(set (match_operand:DI 0 "register_operand" "=x")
2349         (plus:DI
2350          (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2351                   (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2352          (match_operand:DI 3 "register_operand" "0")))]
2353   "(TARGET_MAD || ISA_HAS_MACC)
2354    && !TARGET_64BIT"
2356   if (TARGET_MAD)
2357     return "mad\t%1,%2";
2358   else if (TARGET_MIPS5500)
2359     return "madd\t%1,%2";
2360   else
2361     return "macc\t%.,%1,%2";
2363   [(set_attr "type"   "imadd")
2364    (set_attr "mode"   "SI")])
2366 ;; Floating point multiply accumulate instructions.
2368 (define_insn ""
2369   [(set (match_operand:DF 0 "register_operand" "=f")
2370         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2371                           (match_operand:DF 2 "register_operand" "f"))
2372                  (match_operand:DF 3 "register_operand" "f")))]
2373   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2374   "madd.d\t%0,%3,%1,%2"
2375   [(set_attr "type"     "fmadd")
2376    (set_attr "mode"     "DF")])
2378 (define_insn ""
2379   [(set (match_operand:SF 0 "register_operand" "=f")
2380         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2381                           (match_operand:SF 2 "register_operand" "f"))
2382                  (match_operand:SF 3 "register_operand" "f")))]
2383   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2384   "madd.s\t%0,%3,%1,%2"
2385   [(set_attr "type"     "fmadd")
2386    (set_attr "mode"     "SF")])
2388 (define_insn ""
2389   [(set (match_operand:DF 0 "register_operand" "=f")
2390         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2391                            (match_operand:DF 2 "register_operand" "f"))
2392                   (match_operand:DF 3 "register_operand" "f")))]
2393   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2394   "msub.d\t%0,%3,%1,%2"
2395   [(set_attr "type"     "fmadd")
2396    (set_attr "mode"     "DF")])
2398 (define_insn ""
2399   [(set (match_operand:SF 0 "register_operand" "=f")
2400         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2401                            (match_operand:SF 2 "register_operand" "f"))
2402                   (match_operand:SF 3 "register_operand" "f")))]
2404   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2405   "msub.s\t%0,%3,%1,%2"
2406   [(set_attr "type"     "fmadd")
2407    (set_attr "mode"     "SF")])
2409 (define_insn ""
2410   [(set (match_operand:DF 0 "register_operand" "=f")
2411         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2412                                   (match_operand:DF 2 "register_operand" "f"))
2413                          (match_operand:DF 3 "register_operand" "f"))))]
2414   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2415   "nmadd.d\t%0,%3,%1,%2"
2416   [(set_attr "type"     "fmadd")
2417    (set_attr "mode"     "DF")])
2419 (define_insn ""
2420   [(set (match_operand:SF 0 "register_operand" "=f")
2421         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2422                                   (match_operand:SF 2 "register_operand" "f"))
2423                          (match_operand:SF 3 "register_operand" "f"))))]
2424   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2425   "nmadd.s\t%0,%3,%1,%2"
2426   [(set_attr "type"     "fmadd")
2427    (set_attr "mode"     "SF")])
2429 (define_insn ""
2430   [(set (match_operand:DF 0 "register_operand" "=f")
2431         (minus:DF (match_operand:DF 1 "register_operand" "f")
2432                   (mult:DF (match_operand:DF 2 "register_operand" "f")
2433                            (match_operand:DF 3 "register_operand" "f"))))]
2434   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2435   "nmsub.d\t%0,%1,%2,%3"
2436   [(set_attr "type"     "fmadd")
2437    (set_attr "mode"     "DF")])
2439 (define_insn ""
2440   [(set (match_operand:SF 0 "register_operand" "=f")
2441         (minus:SF (match_operand:SF 1 "register_operand" "f")
2442                   (mult:SF (match_operand:SF 2 "register_operand" "f")
2443                            (match_operand:SF 3 "register_operand" "f"))))]
2444   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2445   "nmsub.s\t%0,%1,%2,%3"
2446   [(set_attr "type"     "fmadd")
2447    (set_attr "mode"     "SF")])
2450 ;;  ....................
2452 ;;      DIVISION and REMAINDER
2454 ;;  ....................
2457 (define_expand "divdf3"
2458   [(set (match_operand:DF 0 "register_operand" "")
2459         (div:DF (match_operand:DF 1 "reg_or_const_float_1_operand" "")
2460                 (match_operand:DF 2 "register_operand" "")))]
2461   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2463   if (const_float_1_operand (operands[1], DFmode))
2464     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2465       FAIL;
2468 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
2470 ;; If an mfc1 or dmfc1 happens to access the floating point register
2471 ;; file at the same time a long latency operation (div, sqrt, recip,
2472 ;; sqrt) iterates an intermediate result back through the floating
2473 ;; point register file bypass, then instead returning the correct
2474 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2475 ;; result of the long latency operation.
2477 ;; The workaround is to insert an unconditional 'mov' from/to the
2478 ;; long latency op destination register.
2480 (define_insn "*divdf3"
2481   [(set (match_operand:DF 0 "register_operand" "=f")
2482         (div:DF (match_operand:DF 1 "register_operand" "f")
2483                 (match_operand:DF 2 "register_operand" "f")))]
2484   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2486   if (TARGET_FIX_SB1)
2487     return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
2488   else
2489     return "div.d\t%0,%1,%2";
2491   [(set_attr "type"     "fdiv")
2492    (set_attr "mode"     "DF")
2493    (set (attr "length")
2494         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2495                       (const_int 8)
2496                       (const_int 4)))])
2499 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
2501 ;; In certain cases, div.s and div.ps may have a rounding error
2502 ;; and/or wrong inexact flag.
2504 ;; Therefore, we only allow div.s if not working around SB-1 rev2
2505 ;; errata, or if working around those errata and a slight loss of
2506 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
2507 (define_expand "divsf3"
2508   [(set (match_operand:SF 0 "register_operand" "")
2509         (div:SF (match_operand:SF 1 "reg_or_const_float_1_operand" "")
2510                 (match_operand:SF 2 "register_operand" "")))]
2511   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2513   if (const_float_1_operand (operands[1], SFmode))
2514     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2515       FAIL;
2518 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2519 ;; "divdf3" comment for details).
2521 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
2522 ;; "divsf3" comment for details).
2523 (define_insn "*divsf3"
2524   [(set (match_operand:SF 0 "register_operand" "=f")
2525         (div:SF (match_operand:SF 1 "register_operand" "f")
2526                 (match_operand:SF 2 "register_operand" "f")))]
2527   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2529   if (TARGET_FIX_SB1)
2530     return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
2531   else
2532     return "div.s\t%0,%1,%2";
2534   [(set_attr "type"     "fdiv")
2535    (set_attr "mode"     "SF")
2536    (set (attr "length")
2537         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2538                       (const_int 8)
2539                       (const_int 4)))])
2541 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2542 ;; "divdf3" comment for details).
2543 (define_insn ""
2544   [(set (match_operand:DF 0 "register_operand" "=f")
2545         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2546                 (match_operand:DF 2 "register_operand" "f")))]
2547   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2549   if (TARGET_FIX_SB1)
2550     return "recip.d\t%0,%2\;mov.d\t%0,%0";
2551   else
2552     return "recip.d\t%0,%2";
2554   [(set_attr "type"     "fdiv")
2555    (set_attr "mode"     "DF")
2556    (set (attr "length")
2557         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2558                       (const_int 8)
2559                       (const_int 4)))])
2561 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2562 ;; "divdf3" comment for details).
2563 (define_insn ""
2564   [(set (match_operand:SF 0 "register_operand" "=f")
2565         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2566                 (match_operand:SF 2 "register_operand" "f")))]
2567   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2569   if (TARGET_FIX_SB1)
2570     return "recip.s\t%0,%2\;mov.s\t%0,%0";
2571   else
2572     return "recip.s\t%0,%2";
2574   [(set_attr "type"     "fdiv")
2575    (set_attr "mode"     "SF")
2576    (set (attr "length")
2577         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2578                       (const_int 8)
2579                       (const_int 4)))])
2581 (define_insn "divmodsi4"
2582   [(set (match_operand:SI 0 "register_operand" "=l")
2583         (div:SI (match_operand:SI 1 "register_operand" "d")
2584                 (match_operand:SI 2 "register_operand" "d")))
2585    (set (match_operand:SI 3 "register_operand" "=h")
2586         (mod:SI (match_dup 1)
2587                 (match_dup 2)))]
2588   ""
2589   { return mips_output_division ("div\t$0,%1,%2", operands); }
2590   [(set_attr "type"     "idiv")
2591    (set_attr "mode"     "SI")])
2593 (define_insn "divmoddi4"
2594   [(set (match_operand:DI 0 "register_operand" "=l")
2595         (div:DI (match_operand:DI 1 "register_operand" "d")
2596                 (match_operand:DI 2 "register_operand" "d")))
2597    (set (match_operand:DI 3 "register_operand" "=h")
2598         (mod:DI (match_dup 1)
2599                 (match_dup 2)))]
2600   "TARGET_64BIT"
2601   { return mips_output_division ("ddiv\t$0,%1,%2", operands); }
2602   [(set_attr "type"     "idiv")
2603    (set_attr "mode"     "DI")])
2605 (define_insn "udivmodsi4"
2606   [(set (match_operand:SI 0 "register_operand" "=l")
2607         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2608                  (match_operand:SI 2 "register_operand" "d")))
2609    (set (match_operand:SI 3 "register_operand" "=h")
2610         (umod:SI (match_dup 1)
2611                  (match_dup 2)))]
2612   ""
2613   { return mips_output_division ("divu\t$0,%1,%2", operands); }
2614   [(set_attr "type"     "idiv")
2615    (set_attr "mode"     "SI")])
2617 (define_insn "udivmoddi4"
2618   [(set (match_operand:DI 0 "register_operand" "=l")
2619         (udiv:DI (match_operand:DI 1 "register_operand" "d")
2620                  (match_operand:DI 2 "register_operand" "d")))
2621    (set (match_operand:DI 3 "register_operand" "=h")
2622         (umod:DI (match_dup 1)
2623                  (match_dup 2)))]
2624   "TARGET_64BIT"
2625   { return mips_output_division ("ddivu\t$0,%1,%2", operands); }
2626   [(set_attr "type"     "idiv")
2627    (set_attr "mode"     "DI")])
2630 ;;  ....................
2632 ;;      SQUARE ROOT
2634 ;;  ....................
2636 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2637 ;; "divdf3" comment for details).
2638 (define_insn "sqrtdf2"
2639   [(set (match_operand:DF 0 "register_operand" "=f")
2640         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2641   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2643   if (TARGET_FIX_SB1)
2644     return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
2645   else
2646     return "sqrt.d\t%0,%1";
2648   [(set_attr "type"     "fsqrt")
2649    (set_attr "mode"     "DF")
2650    (set (attr "length")
2651         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2652                       (const_int 8)
2653                       (const_int 4)))])
2655 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2656 ;; "divdf3" comment for details).
2657 (define_insn "sqrtsf2"
2658   [(set (match_operand:SF 0 "register_operand" "=f")
2659         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2660   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2662   if (TARGET_FIX_SB1)
2663     return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
2664   else
2665     return "sqrt.s\t%0,%1";
2667   [(set_attr "type"     "fsqrt")
2668    (set_attr "mode"     "SF")
2669    (set (attr "length")
2670         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2671                       (const_int 8)
2672                       (const_int 4)))])
2674 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2675 ;; "divdf3" comment for details).
2676 (define_insn ""
2677   [(set (match_operand:DF 0 "register_operand" "=f")
2678         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2679                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2680   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2682   if (TARGET_FIX_SB1)
2683     return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2684   else
2685     return "rsqrt.d\t%0,%2";
2687   [(set_attr "type"     "frsqrt")
2688    (set_attr "mode"     "DF")
2689    (set (attr "length")
2690         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2691                       (const_int 8)
2692                       (const_int 4)))])
2694 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2695 ;; "divdf3" comment for details).
2696 (define_insn ""
2697   [(set (match_operand:SF 0 "register_operand" "=f")
2698         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2699                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2700   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2702   if (TARGET_FIX_SB1)
2703     return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2704   else
2705     return "rsqrt.s\t%0,%2";
2707   [(set_attr "type"     "frsqrt")
2708    (set_attr "mode"     "SF")
2709    (set (attr "length")
2710         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2711                       (const_int 8)
2712                       (const_int 4)))])
2715 ;;  ....................
2717 ;;      ABSOLUTE VALUE
2719 ;;  ....................
2721 ;; Do not use the integer abs macro instruction, since that signals an
2722 ;; exception on -2147483648 (sigh).
2724 (define_insn "abssi2"
2725   [(set (match_operand:SI 0 "register_operand" "=d")
2726         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2727   "!TARGET_MIPS16"
2729   operands[2] = const0_rtx;
2731   if (REGNO (operands[0]) == REGNO (operands[1]))
2732     {
2733       if (GENERATE_BRANCHLIKELY)
2734         return "%(bltzl\t%1,1f\;subu\t%0,%z2,%0\n%~1:%)";
2735       else
2736         return "bgez\t%1,1f%#\;subu\t%0,%z2,%0\n%~1:";
2737     }
2738   else
2739     return "%(bgez\t%1,1f\;move\t%0,%1\;subu\t%0,%z2,%0\n%~1:%)";
2741   [(set_attr "type"     "multi")
2742    (set_attr "mode"     "SI")
2743    (set_attr "length"   "12")])
2745 (define_insn "absdi2"
2746   [(set (match_operand:DI 0 "register_operand" "=d")
2747         (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2748   "TARGET_64BIT && !TARGET_MIPS16"
2750   unsigned int regno1;
2751   operands[2] = const0_rtx;
2753   if (GET_CODE (operands[1]) == REG)
2754     regno1 = REGNO (operands[1]);
2755   else
2756     regno1 = REGNO (XEXP (operands[1], 0));
2758   if (REGNO (operands[0]) == regno1)
2759     return "%(bltzl\t%1,1f\;dsubu\t%0,%z2,%0\n%~1:%)";
2760   else
2761     return "%(bgez\t%1,1f\;move\t%0,%1\;dsubu\t%0,%z2,%0\n%~1:%)";
2763   [(set_attr "type"     "multi")
2764    (set_attr "mode"     "DI")
2765    (set_attr "length"   "12")])
2767 (define_insn "absdf2"
2768   [(set (match_operand:DF 0 "register_operand" "=f")
2769         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2770   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2771   "abs.d\t%0,%1"
2772   [(set_attr "type"     "fabs")
2773    (set_attr "mode"     "DF")])
2775 (define_insn "abssf2"
2776   [(set (match_operand:SF 0 "register_operand" "=f")
2777         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2778   "TARGET_HARD_FLOAT"
2779   "abs.s\t%0,%1"
2780   [(set_attr "type"     "fabs")
2781    (set_attr "mode"     "SF")])
2784 ;;  ....................
2786 ;;      FIND FIRST BIT INSTRUCTION
2788 ;;  ....................
2791 (define_insn "ffssi2"
2792   [(set (match_operand:SI 0 "register_operand" "=&d")
2793         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2794    (clobber (match_scratch:SI 2 "=&d"))
2795    (clobber (match_scratch:SI 3 "=&d"))]
2796   "!TARGET_MIPS16"
2798   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2799     return "%(\
2800 move\t%0,%.\;\
2801 beq\t%1,%.,2f\n\
2802 %~1:\tand\t%2,%1,0x0001\;\
2803 addu\t%0,%0,1\;\
2804 beq\t%2,%.,1b\;\
2805 srl\t%1,%1,1\n\
2806 %~2:%)";
2808   return "%(\
2809 move\t%0,%.\;\
2810 move\t%3,%1\;\
2811 beq\t%3,%.,2f\n\
2812 %~1:\tand\t%2,%3,0x0001\;\
2813 addu\t%0,%0,1\;\
2814 beq\t%2,%.,1b\;\
2815 srl\t%3,%3,1\n\
2816 %~2:%)";
2818   [(set_attr "type"     "multi")
2819    (set_attr "mode"     "SI")
2820    (set_attr "length"   "28")])
2822 (define_insn "ffsdi2"
2823   [(set (match_operand:DI 0 "register_operand" "=&d")
2824         (ffs:DI (match_operand:DI 1 "register_operand" "d")))
2825    (clobber (match_scratch:DI 2 "=&d"))
2826    (clobber (match_scratch:DI 3 "=&d"))]
2827   "TARGET_64BIT && !TARGET_MIPS16"
2829   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2830     return "%(\
2831 move\t%0,%.\;\
2832 beq\t%1,%.,2f\n\
2833 %~1:\tand\t%2,%1,0x0001\;\
2834 daddu\t%0,%0,1\;\
2835 beq\t%2,%.,1b\;\
2836 dsrl\t%1,%1,1\n\
2837 %~2:%)";
2839   return "%(\
2840 move\t%0,%.\;\
2841 move\t%3,%1\;\
2842 beq\t%3,%.,2f\n\
2843 %~1:\tand\t%2,%3,0x0001\;\
2844 daddu\t%0,%0,1\;\
2845 beq\t%2,%.,1b\;\
2846 dsrl\t%3,%3,1\n\
2847 %~2:%)";
2849   [(set_attr "type"     "multi")
2850    (set_attr "mode"     "DI")
2851    (set_attr "length"   "28")])
2854 ;;  ...................
2856 ;;  Count leading zeroes.
2858 ;;  ...................
2861 (define_insn "clzsi2"
2862   [(set (match_operand:SI 0 "register_operand" "=d")
2863         (clz:SI (match_operand:SI 1 "register_operand" "d")))]
2864   "ISA_HAS_CLZ_CLO"
2865   "clz\t%0,%1"
2866   [(set_attr "type" "arith")
2867    (set_attr "mode" "SI")])
2869 (define_insn "clzdi2"
2870   [(set (match_operand:DI 0 "register_operand" "=d")
2871         (clz:DI (match_operand:DI 1 "register_operand" "d")))]
2872   "ISA_HAS_DCLZ_DCLO"
2873   "dclz\t%0,%1"
2874   [(set_attr "type" "arith")
2875    (set_attr "mode" "DI")])
2878 ;;  ....................
2880 ;;      NEGATION and ONE'S COMPLEMENT
2882 ;;  ....................
2884 (define_insn "negsi2"
2885   [(set (match_operand:SI 0 "register_operand" "=d")
2886         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2887   ""
2889   if (TARGET_MIPS16)
2890     return "neg\t%0,%1";
2891   else
2892     return "subu\t%0,%.,%1";
2894   [(set_attr "type"     "arith")
2895    (set_attr "mode"     "SI")])
2897 (define_expand "negdi2"
2898   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
2899                    (neg:DI (match_operand:DI 1 "register_operand" "d")))
2900               (clobber (match_dup 2))])]
2901   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
2903   if (TARGET_64BIT)
2904     {
2905       emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
2906       DONE;
2907     }
2909   operands[2] = gen_reg_rtx (SImode);
2912 (define_insn "negdi2_internal"
2913   [(set (match_operand:DI 0 "register_operand" "=d")
2914         (neg:DI (match_operand:DI 1 "register_operand" "d")))
2915    (clobber (match_operand:SI 2 "register_operand" "=d"))]
2916   "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
2917   "subu\t%L0,%.,%L1\;subu\t%M0,%.,%M1\;sltu\t%2,%.,%L0\;subu\t%M0,%M0,%2"
2918   [(set_attr "type"     "darith")
2919    (set_attr "mode"     "DI")
2920    (set_attr "length"   "16")])
2922 (define_insn "negdi2_internal_2"
2923   [(set (match_operand:DI 0 "register_operand" "=d")
2924         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2925   "TARGET_64BIT && !TARGET_MIPS16"
2926   "dsubu\t%0,%.,%1"
2927   [(set_attr "type"     "arith")
2928    (set_attr "mode"     "DI")])
2930 (define_insn "negdf2"
2931   [(set (match_operand:DF 0 "register_operand" "=f")
2932         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2933   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2934   "neg.d\t%0,%1"
2935   [(set_attr "type"     "fneg")
2936    (set_attr "mode"     "DF")])
2938 (define_insn "negsf2"
2939   [(set (match_operand:SF 0 "register_operand" "=f")
2940         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2941   "TARGET_HARD_FLOAT"
2942   "neg.s\t%0,%1"
2943   [(set_attr "type"     "fneg")
2944    (set_attr "mode"     "SF")])
2946 (define_insn "one_cmplsi2"
2947   [(set (match_operand:SI 0 "register_operand" "=d")
2948         (not:SI (match_operand:SI 1 "register_operand" "d")))]
2949   ""
2951   if (TARGET_MIPS16)
2952     return "not\t%0,%1";
2953   else
2954     return "nor\t%0,%.,%1";
2956   [(set_attr "type"     "arith")
2957    (set_attr "mode"     "SI")])
2959 (define_insn "one_cmpldi2"
2960   [(set (match_operand:DI 0 "register_operand" "=d")
2961         (not:DI (match_operand:DI 1 "register_operand" "d")))]
2962   "TARGET_64BIT"
2964   if (TARGET_MIPS16)
2965     return "not\t%0,%1";
2966   else
2967     return "nor\t%0,%.,%1";
2969   [(set_attr "type"     "darith")
2970    (set_attr "mode"     "DI")])
2973 ;;  ....................
2975 ;;      LOGICAL
2977 ;;  ....................
2980 ;; Many of these instructions use trivial define_expands, because we
2981 ;; want to use a different set of constraints when TARGET_MIPS16.
2983 (define_expand "andsi3"
2984   [(set (match_operand:SI 0 "register_operand" "=d,d")
2985         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2986                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2987   ""
2989   if (TARGET_MIPS16)
2990     {
2991       operands[1] = force_reg (SImode, operands[1]);
2992       operands[2] = force_reg (SImode, operands[2]);
2993     }
2996 (define_insn ""
2997   [(set (match_operand:SI 0 "register_operand" "=d,d")
2998         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2999                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3000   "!TARGET_MIPS16"
3001   "@
3002    and\t%0,%1,%2
3003    andi\t%0,%1,%x2"
3004   [(set_attr "type"     "arith")
3005    (set_attr "mode"     "SI")])
3007 (define_insn ""
3008   [(set (match_operand:SI 0 "register_operand" "=d")
3009         (and:SI (match_operand:SI 1 "register_operand" "%0")
3010                 (match_operand:SI 2 "register_operand" "d")))]
3011   "TARGET_MIPS16"
3012   "and\t%0,%2"
3013   [(set_attr "type"     "arith")
3014    (set_attr "mode"     "SI")])
3016 (define_expand "anddi3"
3017   [(set (match_operand:DI 0 "register_operand" "")
3018         (and:DI (match_operand:DI 1 "register_operand" "")
3019                 (match_operand:DI 2 "uns_arith_operand" "")))]
3020   "TARGET_64BIT"
3022   if (TARGET_MIPS16)
3023     {
3024       operands[1] = force_reg (DImode, operands[1]);
3025       operands[2] = force_reg (DImode, operands[2]);
3026     }
3029 (define_insn ""
3030   [(set (match_operand:DI 0 "register_operand" "=d,d")
3031         (and:DI (match_operand:DI 1 "register_operand" "d,d")
3032                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
3033   "TARGET_64BIT && !TARGET_MIPS16"
3034   "@
3035    and\t%0,%1,%2
3036    andi\t%0,%1,%x2"
3037   [(set_attr "type"     "darith")
3038    (set_attr "mode"     "DI")])
3040 (define_insn ""
3041   [(set (match_operand:DI 0 "register_operand" "=d")
3042         (and:DI (match_operand:DI 1 "register_operand" "0")
3043                 (match_operand:DI 2 "register_operand" "d")))]
3044   "TARGET_64BIT && TARGET_MIPS16"
3045   "and\t%0,%2"
3046   [(set_attr "type"     "darith")
3047    (set_attr "mode"     "DI")])
3049 (define_expand "iorsi3"
3050   [(set (match_operand:SI 0 "register_operand" "=d,d")
3051         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3052                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3053   ""
3055   if (TARGET_MIPS16)
3056     {
3057       operands[1] = force_reg (SImode, operands[1]);
3058       operands[2] = force_reg (SImode, operands[2]);
3059     }
3062 (define_insn ""
3063   [(set (match_operand:SI 0 "register_operand" "=d,d")
3064         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3065                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3066   "!TARGET_MIPS16"
3067   "@
3068    or\t%0,%1,%2
3069    ori\t%0,%1,%x2"
3070   [(set_attr "type"     "arith")
3071    (set_attr "mode"     "SI")])
3073 (define_insn ""
3074   [(set (match_operand:SI 0 "register_operand" "=d")
3075         (ior:SI (match_operand:SI 1 "register_operand" "%0")
3076                 (match_operand:SI 2 "register_operand" "d")))]
3077   "TARGET_MIPS16"
3078   "or\t%0,%2"
3079   [(set_attr "type"     "arith")
3080    (set_attr "mode"     "SI")])
3082 (define_expand "iordi3"
3083   [(set (match_operand:DI 0 "register_operand" "")
3084         (ior:DI (match_operand:DI 1 "register_operand" "")
3085                 (match_operand:DI 2 "uns_arith_operand" "")))]
3086   "TARGET_64BIT"
3088   if (TARGET_MIPS16)
3089     {
3090       operands[1] = force_reg (DImode, operands[1]);
3091       operands[2] = force_reg (DImode, operands[2]);
3092     }
3095 (define_insn ""
3096   [(set (match_operand:DI 0 "register_operand" "=d,d")
3097         (ior:DI (match_operand:DI 1 "register_operand" "d,d")
3098                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
3099   "TARGET_64BIT && !TARGET_MIPS16"
3100   "@
3101    or\t%0,%1,%2
3102    ori\t%0,%1,%x2"
3103   [(set_attr "type"     "darith")
3104    (set_attr "mode"     "DI")])
3106 (define_insn ""
3107   [(set (match_operand:DI 0 "register_operand" "=d")
3108         (ior:DI (match_operand:DI 1 "register_operand" "0")
3109                 (match_operand:DI 2 "register_operand" "d")))]
3110   "TARGET_64BIT && TARGET_MIPS16"
3111   "or\t%0,%2"
3112   [(set_attr "type"     "darith")
3113    (set_attr "mode"     "DI")])
3115 (define_expand "xorsi3"
3116   [(set (match_operand:SI 0 "register_operand" "=d,d")
3117         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3118                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3119   ""
3120   "")
3122 (define_insn ""
3123   [(set (match_operand:SI 0 "register_operand" "=d,d")
3124         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3125                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3126   "!TARGET_MIPS16"
3127   "@
3128    xor\t%0,%1,%2
3129    xori\t%0,%1,%x2"
3130   [(set_attr "type"     "arith")
3131    (set_attr "mode"     "SI")])
3133 (define_insn ""
3134   [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3135         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3136                 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3137   "TARGET_MIPS16"
3138   "@
3139    xor\t%0,%2
3140    cmpi\t%1,%2
3141    cmp\t%1,%2"
3142   [(set_attr "type"     "arith")
3143    (set_attr "mode"     "SI")
3144    (set_attr_alternative "length"
3145                 [(const_int 4)
3146                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3147                                (const_int 4)
3148                                (const_int 8))
3149                  (const_int 4)])])
3151 (define_expand "xordi3"
3152   [(set (match_operand:DI 0 "register_operand" "")
3153         (xor:DI (match_operand:DI 1 "register_operand" "")
3154                 (match_operand:DI 2 "uns_arith_operand" "")))]
3155   "TARGET_64BIT"
3157   if (TARGET_MIPS16)
3158     {
3159       operands[1] = force_reg (DImode, operands[1]);
3160       operands[2] = force_reg (DImode, operands[2]);
3161     }
3164 (define_insn ""
3165   [(set (match_operand:DI 0 "register_operand" "=d,d")
3166         (xor:DI (match_operand:DI 1 "register_operand" "d,d")
3167                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
3168   "TARGET_64BIT && !TARGET_MIPS16"
3169   "@
3170    xor\t%0,%1,%2
3171    xori\t%0,%1,%x2"
3172   [(set_attr "type"     "darith")
3173    (set_attr "mode"     "DI")])
3175 (define_insn ""
3176   [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3177         (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
3178                 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
3179   "TARGET_64BIT && TARGET_MIPS16"
3180   "@
3181    xor\t%0,%2
3182    cmpi\t%1,%2
3183    cmp\t%1,%2"
3184   [(set_attr "type"     "arith")
3185    (set_attr "mode"     "DI")
3186    (set_attr_alternative "length"
3187                 [(const_int 4)
3188                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3189                                (const_int 4)
3190                                (const_int 8))
3191                  (const_int 4)])])
3193 (define_insn "*norsi3"
3194   [(set (match_operand:SI 0 "register_operand" "=d")
3195         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3196                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3197   "!TARGET_MIPS16"
3198   "nor\t%0,%z1,%z2"
3199   [(set_attr "type"     "arith")
3200    (set_attr "mode"     "SI")])
3202 (define_insn "*nordi3"
3203   [(set (match_operand:DI 0 "register_operand" "=d")
3204         (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
3205                 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
3206   "TARGET_64BIT && !TARGET_MIPS16"
3207   "nor\t%0,%z1,%z2"
3208   [(set_attr "type"     "darith")
3209    (set_attr "mode"     "DI")])
3212 ;;  ....................
3214 ;;      TRUNCATION
3216 ;;  ....................
3220 (define_insn "truncdfsf2"
3221   [(set (match_operand:SF 0 "register_operand" "=f")
3222         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3223   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3224   "cvt.s.d\t%0,%1"
3225   [(set_attr "type"     "fcvt")
3226    (set_attr "mode"     "SF")])
3228 ;; Integer truncation patterns.  Truncating SImode values to smaller
3229 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
3230 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
3231 ;; need to make sure that the lower 32 bits are properly sign-extended
3232 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
3233 ;; smaller than SImode is equivalent to two separate truncations:
3235 ;;                        A       B
3236 ;;    DI ---> HI  ==  DI ---> SI ---> HI
3237 ;;    DI ---> QI  ==  DI ---> SI ---> QI
3239 ;; Step A needs a real instruction but step B does not.
3241 (define_insn "truncdisi2"
3242   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
3243         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
3244   "TARGET_64BIT"
3245   "@
3246     sll\t%0,%1,0
3247     sw\t%1,%0"
3248   [(set_attr "type" "darith,store")
3249    (set_attr "mode" "SI")
3250    (set_attr "extended_mips16" "yes,*")])
3252 (define_insn "truncdihi2"
3253   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
3254         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
3255   "TARGET_64BIT"
3256   "@
3257     sll\t%0,%1,0
3258     sh\t%1,%0"
3259   [(set_attr "type" "darith,store")
3260    (set_attr "mode" "SI")
3261    (set_attr "extended_mips16" "yes,*")])
3263 (define_insn "truncdiqi2"
3264   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
3265         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
3266   "TARGET_64BIT"
3267   "@
3268     sll\t%0,%1,0
3269     sb\t%1,%0"
3270   [(set_attr "type" "darith,store")
3271    (set_attr "mode" "SI")
3272    (set_attr "extended_mips16" "yes,*")])
3274 ;; Combiner patterns to optimize shift/truncate combinations.
3276 (define_insn ""
3277   [(set (match_operand:SI 0 "register_operand" "=d")
3278         (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3279                                   (match_operand:DI 2 "small_int" "I"))))]
3280   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
3281   "dsra\t%0,%1,%2"
3282   [(set_attr "type" "darith")
3283    (set_attr "mode" "SI")])
3285 (define_insn ""
3286   [(set (match_operand:SI 0 "register_operand" "=d")
3287         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3288                                   (const_int 32))))]
3289   "TARGET_64BIT && !TARGET_MIPS16"
3290   "dsra\t%0,%1,32"
3291   [(set_attr "type" "darith")
3292    (set_attr "mode" "SI")])
3295 ;; Combiner patterns for truncate/sign_extend combinations.  They use
3296 ;; the shift/truncate patterns above.
3298 (define_insn_and_split ""
3299   [(set (match_operand:SI 0 "register_operand" "=d")
3300         (sign_extend:SI
3301             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
3302   "TARGET_64BIT && !TARGET_MIPS16"
3303   "#"
3304   "&& reload_completed"
3305   [(set (match_dup 2)
3306         (ashift:DI (match_dup 1)
3307                    (const_int 48)))
3308    (set (match_dup 0)
3309         (truncate:SI (ashiftrt:DI (match_dup 2)
3310                                   (const_int 48))))]
3311   { operands[2] = gen_lowpart (DImode, operands[0]); })
3313 (define_insn_and_split ""
3314   [(set (match_operand:SI 0 "register_operand" "=d")
3315         (sign_extend:SI
3316             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3317   "TARGET_64BIT && !TARGET_MIPS16"
3318   "#"
3319   "&& reload_completed"
3320   [(set (match_dup 2)
3321         (ashift:DI (match_dup 1)
3322                    (const_int 56)))
3323    (set (match_dup 0)
3324         (truncate:SI (ashiftrt:DI (match_dup 2)
3325                                   (const_int 56))))]
3326   { operands[2] = gen_lowpart (DImode, operands[0]); })
3329 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3331 (define_insn ""
3332   [(set (match_operand:SI 0 "register_operand" "=d")
3333         (zero_extend:SI (truncate:HI
3334                          (match_operand:DI 1 "register_operand" "d"))))]
3335   "TARGET_64BIT && !TARGET_MIPS16"
3336   "andi\t%0,%1,0xffff"
3337   [(set_attr "type"     "darith")
3338    (set_attr "mode"     "SI")])
3340 (define_insn ""
3341   [(set (match_operand:SI 0 "register_operand" "=d")
3342         (zero_extend:SI (truncate:QI
3343                          (match_operand:DI 1 "register_operand" "d"))))]
3344   "TARGET_64BIT && !TARGET_MIPS16"
3345   "andi\t%0,%1,0xff"
3346   [(set_attr "type"     "darith")
3347    (set_attr "mode"     "SI")])
3349 (define_insn ""
3350   [(set (match_operand:HI 0 "register_operand" "=d")
3351         (zero_extend:HI (truncate:QI
3352                          (match_operand:DI 1 "register_operand" "d"))))]
3353   "TARGET_64BIT && !TARGET_MIPS16"
3354   "andi\t%0,%1,0xff"
3355   [(set_attr "type"     "darith")
3356    (set_attr "mode"     "HI")])
3359 ;;  ....................
3361 ;;      ZERO EXTENSION
3363 ;;  ....................
3365 ;; Extension insns.
3366 ;; Those for integer source operand are ordered widest source type first.
3368 (define_insn_and_split "zero_extendsidi2"
3369   [(set (match_operand:DI 0 "register_operand" "=d")
3370         (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
3371   "TARGET_64BIT"
3372   "#"
3373   "&& reload_completed"
3374   [(set (match_dup 0)
3375         (ashift:DI (match_dup 1) (const_int 32)))
3376    (set (match_dup 0)
3377         (lshiftrt:DI (match_dup 0) (const_int 32)))]
3378   "operands[1] = gen_lowpart (DImode, operands[1]);"
3379   [(set_attr "type" "arith")
3380    (set_attr "mode" "DI")])
3382 (define_insn "*zero_extendsidi2_mem"
3383   [(set (match_operand:DI 0 "register_operand" "=d")
3384         (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
3385   "TARGET_64BIT"
3386   "lwu\t%0,%1"
3387   [(set_attr "type"     "load")
3388    (set_attr "mode"     "DI")])
3390 (define_expand "zero_extendhisi2"
3391   [(set (match_operand:SI 0 "register_operand" "")
3392         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3393   ""
3395   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3396     {
3397       rtx op = gen_lowpart (SImode, operands[1]);
3398       rtx temp = force_reg (SImode, GEN_INT (0xffff));
3400       emit_insn (gen_andsi3 (operands[0], op, temp));
3401       DONE;
3402     }
3405 (define_insn ""
3406   [(set (match_operand:SI 0 "register_operand" "=d,d")
3407         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
3408   "!TARGET_MIPS16"
3409   "@
3410    andi\t%0,%1,0xffff
3411    lhu\t%0,%1"
3412   [(set_attr "type"     "arith,load")
3413    (set_attr "mode"     "SI")
3414    (set_attr "length"   "4,*")])
3416 (define_insn ""
3417   [(set (match_operand:SI 0 "register_operand" "=d")
3418         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3419   "TARGET_MIPS16"
3420   "lhu\t%0,%1"
3421   [(set_attr "type"     "load")
3422    (set_attr "mode"     "SI")])
3424 (define_expand "zero_extendhidi2"
3425   [(set (match_operand:DI 0 "register_operand" "")
3426         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3427   "TARGET_64BIT"
3429   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3430     {
3431       rtx op = gen_lowpart (DImode, operands[1]);
3432       rtx temp = force_reg (DImode, GEN_INT (0xffff));
3434       emit_insn (gen_anddi3 (operands[0], op, temp));
3435       DONE;
3436     }
3439 (define_insn ""
3440   [(set (match_operand:DI 0 "register_operand" "=d,d")
3441         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
3442   "TARGET_64BIT && !TARGET_MIPS16"
3443   "@
3444    andi\t%0,%1,0xffff
3445    lhu\t%0,%1"
3446   [(set_attr "type"     "arith,load")
3447    (set_attr "mode"     "DI")
3448    (set_attr "length"   "4,*")])
3450 (define_insn ""
3451   [(set (match_operand:DI 0 "register_operand" "=d")
3452         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3453   "TARGET_64BIT && TARGET_MIPS16"
3454   "lhu\t%0,%1"
3455   [(set_attr "type"     "load")
3456    (set_attr "mode"     "DI")])
3458 (define_expand "zero_extendqihi2"
3459   [(set (match_operand:HI 0 "register_operand" "")
3460         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3461   ""
3463   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3464     {
3465       rtx op0 = gen_lowpart (SImode, operands[0]);
3466       rtx op1 = gen_lowpart (SImode, operands[1]);
3467       rtx temp = force_reg (SImode, GEN_INT (0xff));
3469       emit_insn (gen_andsi3 (op0, op1, temp));
3470       DONE;
3471     }
3474 (define_insn ""
3475   [(set (match_operand:HI 0 "register_operand" "=d,d")
3476         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3477   "!TARGET_MIPS16"
3478   "@
3479    andi\t%0,%1,0x00ff
3480    lbu\t%0,%1"
3481   [(set_attr "type"     "arith,load")
3482    (set_attr "mode"     "HI")
3483    (set_attr "length"   "4,*")])
3485 (define_insn ""
3486   [(set (match_operand:HI 0 "register_operand" "=d")
3487         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3488   "TARGET_MIPS16"
3489   "lbu\t%0,%1"
3490   [(set_attr "type"     "load")
3491    (set_attr "mode"     "HI")])
3493 (define_expand "zero_extendqisi2"
3494   [(set (match_operand:SI 0 "register_operand" "")
3495         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3496   ""
3498   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3499     {
3500       rtx op = gen_lowpart (SImode, operands[1]);
3501       rtx temp = force_reg (SImode, GEN_INT (0xff));
3503       emit_insn (gen_andsi3 (operands[0], op, temp));
3504       DONE;
3505     }
3508 (define_insn ""
3509   [(set (match_operand:SI 0 "register_operand" "=d,d")
3510         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3511   "!TARGET_MIPS16"
3512   "@
3513    andi\t%0,%1,0x00ff
3514    lbu\t%0,%1"
3515   [(set_attr "type"     "arith,load")
3516    (set_attr "mode"     "SI")
3517    (set_attr "length"   "4,*")])
3519 (define_insn ""
3520   [(set (match_operand:SI 0 "register_operand" "=d")
3521         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3522   "TARGET_MIPS16"
3523   "lbu\t%0,%1"
3524   [(set_attr "type"     "load")
3525    (set_attr "mode"     "SI")])
3527 (define_expand "zero_extendqidi2"
3528   [(set (match_operand:DI 0 "register_operand" "")
3529         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3530   "TARGET_64BIT"
3532   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3533     {
3534       rtx op = gen_lowpart (DImode, operands[1]);
3535       rtx temp = force_reg (DImode, GEN_INT (0xff));
3537       emit_insn (gen_anddi3 (operands[0], op, temp));
3538       DONE;
3539     }
3542 (define_insn ""
3543   [(set (match_operand:DI 0 "register_operand" "=d,d")
3544         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3545   "TARGET_64BIT && !TARGET_MIPS16"
3546   "@
3547    andi\t%0,%1,0x00ff
3548    lbu\t%0,%1"
3549   [(set_attr "type"     "arith,load")
3550    (set_attr "mode"     "DI")
3551    (set_attr "length"   "4,*")])
3553 (define_insn ""
3554   [(set (match_operand:DI 0 "register_operand" "=d")
3555         (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3556   "TARGET_64BIT && TARGET_MIPS16"
3557   "lbu\t%0,%1"
3558   [(set_attr "type"     "load")
3559    (set_attr "mode"     "DI")])
3562 ;;  ....................
3564 ;;      SIGN EXTENSION
3566 ;;  ....................
3568 ;; Extension insns.
3569 ;; Those for integer source operand are ordered widest source type first.
3571 (define_insn "extendsidi2"
3572   [(set (match_operand:DI 0 "register_operand" "=d,d")
3573         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
3574   "TARGET_64BIT"
3575   "@
3576    sll\t%0,%1,0
3577    lw\t%0,%1"
3578   [(set_attr "type" "arith,load")
3579    (set_attr "mode" "DI")
3580    (set_attr "extended_mips16" "yes,*")])
3582 ;; These patterns originally accepted general_operands, however, slightly
3583 ;; better code is generated by only accepting register_operands, and then
3584 ;; letting combine generate the lh and lb insns.
3586 ;; These expanders originally put values in registers first. We split
3587 ;; all non-mem patterns after reload.
3589 (define_expand "extendhidi2"
3590   [(set (match_operand:DI 0 "register_operand" "")
3591         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3592   "TARGET_64BIT"
3593   "")
3595 (define_insn "*extendhidi2"
3596   [(set (match_operand:DI 0 "register_operand" "=d")
3597         (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
3598   "TARGET_64BIT"
3599   "#")
3601 (define_split
3602   [(set (match_operand:DI 0 "register_operand" "")
3603         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3604   "TARGET_64BIT && reload_completed"
3605   [(set (match_dup 0)
3606         (ashift:DI (match_dup 1) (const_int 48)))
3607    (set (match_dup 0)
3608         (ashiftrt:DI (match_dup 0) (const_int 48)))]
3609   "operands[1] = gen_lowpart (DImode, operands[1]);")
3611 (define_insn "*extendhidi2_mem"
3612   [(set (match_operand:DI 0 "register_operand" "=d")
3613         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3614   "TARGET_64BIT"
3615   "lh\t%0,%1"
3616   [(set_attr "type"     "load")
3617    (set_attr "mode"     "DI")])
3619 (define_expand "extendhisi2"
3620   [(set (match_operand:SI 0 "register_operand" "")
3621         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3622   ""
3624   if (ISA_HAS_SEB_SEH)
3625     {
3626       emit_insn (gen_extendhisi2_hw (operands[0],
3627                                      force_reg (HImode, operands[1])));
3628       DONE;
3629     }
3632 (define_insn "*extendhisi2"
3633   [(set (match_operand:SI 0 "register_operand" "=d")
3634         (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
3635   ""
3636   "#")
3638 (define_split
3639   [(set (match_operand:SI 0 "register_operand" "")
3640         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3641   "reload_completed"
3642   [(set (match_dup 0)
3643         (ashift:SI (match_dup 1) (const_int 16)))
3644    (set (match_dup 0)
3645         (ashiftrt:SI (match_dup 0) (const_int 16)))]
3646   "operands[1] = gen_lowpart (SImode, operands[1]);")
3648 (define_insn "extendhisi2_mem"
3649   [(set (match_operand:SI 0 "register_operand" "=d")
3650         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3651   ""
3652   "lh\t%0,%1"
3653   [(set_attr "type"     "load")
3654    (set_attr "mode"     "SI")])
3656 (define_insn "extendhisi2_hw"
3657   [(set (match_operand:SI 0 "register_operand" "=r")
3658         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3659   "ISA_HAS_SEB_SEH"
3660   "seh\t%0,%1"
3661   [(set_attr "type" "arith")
3662    (set_attr "mode" "SI")])
3664 (define_expand "extendqihi2"
3665   [(set (match_operand:HI 0 "register_operand" "")
3666         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3667   ""
3668   "")
3670 (define_insn "*extendqihi2"
3671   [(set (match_operand:HI 0 "register_operand" "=d")
3672         (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
3673   ""
3674   "#")
3676 (define_split
3677   [(set (match_operand:HI 0 "register_operand" "")
3678         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3679   "reload_completed"
3680   [(set (match_dup 0)
3681         (ashift:SI (match_dup 1) (const_int 24)))
3682    (set (match_dup 0)
3683         (ashiftrt:SI (match_dup 0) (const_int 24)))]
3684   "operands[0] = gen_lowpart (SImode, operands[0]);
3685    operands[1] = gen_lowpart (SImode, operands[1]);")
3687 (define_insn "*extendqihi2_internal_mem"
3688   [(set (match_operand:HI 0 "register_operand" "=d")
3689         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3690   ""
3691   "lb\t%0,%1"
3692   [(set_attr "type"     "load")
3693    (set_attr "mode"     "SI")])
3696 (define_expand "extendqisi2"
3697   [(set (match_operand:SI 0 "register_operand" "")
3698         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3699   ""
3701   if (ISA_HAS_SEB_SEH)
3702     {
3703       emit_insn (gen_extendqisi2_hw (operands[0],
3704                                      force_reg (QImode, operands[1])));
3705       DONE;
3706     }
3709 (define_insn "*extendqisi2"
3710   [(set (match_operand:SI 0 "register_operand" "=d")
3711         (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
3712   ""
3713   "#")
3715 (define_split
3716   [(set (match_operand:SI 0 "register_operand" "")
3717         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3718   "reload_completed"
3719   [(set (match_dup 0)
3720         (ashift:SI (match_dup 1) (const_int 24)))
3721    (set (match_dup 0)
3722         (ashiftrt:SI (match_dup 0) (const_int 24)))]
3723   "operands[1] = gen_lowpart (SImode, operands[1]);")
3725 (define_insn "*extendqisi2_mem"
3726   [(set (match_operand:SI 0 "register_operand" "=d")
3727         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3728   ""
3729   "lb\t%0,%1"
3730   [(set_attr "type"     "load")
3731    (set_attr "mode"     "SI")])
3733 (define_insn "extendqisi2_hw"
3734   [(set (match_operand:SI 0 "register_operand" "=r")
3735         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3736   "ISA_HAS_SEB_SEH"
3737   "seb\t%0,%1"
3738   [(set_attr "type" "arith")
3739    (set_attr "mode" "SI")])
3741 (define_expand "extendqidi2"
3742   [(set (match_operand:DI 0 "register_operand" "")
3743         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3744   "TARGET_64BIT"
3745   "")
3747 (define_insn "*extendqidi2"
3748   [(set (match_operand:DI 0 "register_operand" "=d")
3749         (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
3750   "TARGET_64BIT"
3751   "#")
3753 (define_split
3754   [(set (match_operand:DI 0 "register_operand" "")
3755         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3756   "TARGET_64BIT && reload_completed"
3757   [(set (match_dup 0)
3758         (ashift:DI (match_dup 1) (const_int 56)))
3759    (set (match_dup 0)
3760         (ashiftrt:DI (match_dup 0) (const_int 56)))]
3761   "operands[1] = gen_lowpart (DImode, operands[1]);")
3763 (define_insn "*extendqidi2_mem"
3764   [(set (match_operand:DI 0 "register_operand" "=d")
3765         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3766   "TARGET_64BIT"
3767   "lb\t%0,%1"
3768   [(set_attr "type"     "load")
3769    (set_attr "mode"     "DI")])
3771 (define_insn "extendsfdf2"
3772   [(set (match_operand:DF 0 "register_operand" "=f")
3773         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3774   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3775   "cvt.d.s\t%0,%1"
3776   [(set_attr "type"     "fcvt")
3777    (set_attr "mode"     "DF")])
3780 ;;  ....................
3782 ;;      CONVERSIONS
3784 ;;  ....................
3786 (define_expand "fix_truncdfsi2"
3787   [(set (match_operand:SI 0 "register_operand" "=f")
3788         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3789   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3791   if (!ISA_HAS_TRUNC_W)
3792     {
3793       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3794       DONE;
3795     }
3798 (define_insn "fix_truncdfsi2_insn"
3799   [(set (match_operand:SI 0 "register_operand" "=f")
3800         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3801   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3802   "trunc.w.d %0,%1"
3803   [(set_attr "type"     "fcvt")
3804    (set_attr "mode"     "DF")
3805    (set_attr "length"   "4")])
3807 (define_insn "fix_truncdfsi2_macro"
3808   [(set (match_operand:SI 0 "register_operand" "=f")
3809         (fix:SI (match_operand:DF 1 "register_operand" "f")))
3810    (clobber (match_scratch:DF 2 "=d"))]
3811   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3813   if (set_nomacro)
3814     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3815   else
3816     return "trunc.w.d %0,%1,%2";
3818   [(set_attr "type"     "fcvt")
3819    (set_attr "mode"     "DF")
3820    (set_attr "length"   "36")])
3822 (define_expand "fix_truncsfsi2"
3823   [(set (match_operand:SI 0 "register_operand" "=f")
3824         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3825   "TARGET_HARD_FLOAT"
3827   if (!ISA_HAS_TRUNC_W)
3828     {
3829       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3830       DONE;
3831     }
3834 (define_insn "fix_truncsfsi2_insn"
3835   [(set (match_operand:SI 0 "register_operand" "=f")
3836         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3837   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3838   "trunc.w.s %0,%1"
3839   [(set_attr "type"     "fcvt")
3840    (set_attr "mode"     "DF")
3841    (set_attr "length"   "4")])
3843 (define_insn "fix_truncsfsi2_macro"
3844   [(set (match_operand:SI 0 "register_operand" "=f")
3845         (fix:SI (match_operand:SF 1 "register_operand" "f")))
3846    (clobber (match_scratch:SF 2 "=d"))]
3847   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3849   if (set_nomacro)
3850     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3851   else
3852     return "trunc.w.s %0,%1,%2";
3854   [(set_attr "type"     "fcvt")
3855    (set_attr "mode"     "DF")
3856    (set_attr "length"   "36")])
3859 (define_insn "fix_truncdfdi2"
3860   [(set (match_operand:DI 0 "register_operand" "=f")
3861         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3862   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3863   "trunc.l.d %0,%1"
3864   [(set_attr "type"     "fcvt")
3865    (set_attr "mode"     "DF")
3866    (set_attr "length"   "4")])
3869 (define_insn "fix_truncsfdi2"
3870   [(set (match_operand:DI 0 "register_operand" "=f")
3871         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3872   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3873   "trunc.l.s %0,%1"
3874   [(set_attr "type"     "fcvt")
3875    (set_attr "mode"     "SF")
3876    (set_attr "length"   "4")])
3879 (define_insn "floatsidf2"
3880   [(set (match_operand:DF 0 "register_operand" "=f")
3881         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3882   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3883   "cvt.d.w\t%0,%1"
3884   [(set_attr "type"     "fcvt")
3885    (set_attr "mode"     "DF")
3886    (set_attr "length"   "4")])
3889 (define_insn "floatdidf2"
3890   [(set (match_operand:DF 0 "register_operand" "=f")
3891         (float:DF (match_operand:DI 1 "register_operand" "f")))]
3892   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3893   "cvt.d.l\t%0,%1"
3894   [(set_attr "type"     "fcvt")
3895    (set_attr "mode"     "DF")
3896    (set_attr "length"   "4")])
3899 (define_insn "floatsisf2"
3900   [(set (match_operand:SF 0 "register_operand" "=f")
3901         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3902   "TARGET_HARD_FLOAT"
3903   "cvt.s.w\t%0,%1"
3904   [(set_attr "type"     "fcvt")
3905    (set_attr "mode"     "SF")
3906    (set_attr "length"   "4")])
3909 (define_insn "floatdisf2"
3910   [(set (match_operand:SF 0 "register_operand" "=f")
3911         (float:SF (match_operand:DI 1 "register_operand" "f")))]
3912   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3913   "cvt.s.l\t%0,%1"
3914   [(set_attr "type"     "fcvt")
3915    (set_attr "mode"     "SF")
3916    (set_attr "length"   "4")])
3919 (define_expand "fixuns_truncdfsi2"
3920   [(set (match_operand:SI 0 "register_operand" "")
3921         (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
3922   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3924   rtx reg1 = gen_reg_rtx (DFmode);
3925   rtx reg2 = gen_reg_rtx (DFmode);
3926   rtx reg3 = gen_reg_rtx (SImode);
3927   rtx label1 = gen_label_rtx ();
3928   rtx label2 = gen_label_rtx ();
3929   REAL_VALUE_TYPE offset;
3931   real_2expN (&offset, 31);
3933   if (reg1)                     /* Turn off complaints about unreached code.  */
3934     {
3935       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3936       do_pending_stack_adjust ();
3938       emit_insn (gen_cmpdf (operands[1], reg1));
3939       emit_jump_insn (gen_bge (label1));
3941       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3942       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3943                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
3944       emit_barrier ();
3946       emit_label (label1);
3947       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3948       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3949                                      (BITMASK_HIGH, SImode)));
3951       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3952       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3954       emit_label (label2);
3956       /* Allow REG_NOTES to be set on last insn (labels don't have enough
3957          fields, and can't be used for REG_NOTES anyway).  */
3958       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3959       DONE;
3960     }
3964 (define_expand "fixuns_truncdfdi2"
3965   [(set (match_operand:DI 0 "register_operand" "")
3966         (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
3967   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3969   rtx reg1 = gen_reg_rtx (DFmode);
3970   rtx reg2 = gen_reg_rtx (DFmode);
3971   rtx reg3 = gen_reg_rtx (DImode);
3972   rtx label1 = gen_label_rtx ();
3973   rtx label2 = gen_label_rtx ();
3974   REAL_VALUE_TYPE offset;
3976   real_2expN (&offset, 63);
3978   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3979   do_pending_stack_adjust ();
3981   emit_insn (gen_cmpdf (operands[1], reg1));
3982   emit_jump_insn (gen_bge (label1));
3984   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3985   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3986                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3987   emit_barrier ();
3989   emit_label (label1);
3990   emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3991   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3992   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3994   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3995   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3997   emit_label (label2);
3999   /* Allow REG_NOTES to be set on last insn (labels don't have enough
4000      fields, and can't be used for REG_NOTES anyway).  */
4001   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4002   DONE;
4006 (define_expand "fixuns_truncsfsi2"
4007   [(set (match_operand:SI 0 "register_operand" "")
4008         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4009   "TARGET_HARD_FLOAT"
4011   rtx reg1 = gen_reg_rtx (SFmode);
4012   rtx reg2 = gen_reg_rtx (SFmode);
4013   rtx reg3 = gen_reg_rtx (SImode);
4014   rtx label1 = gen_label_rtx ();
4015   rtx label2 = gen_label_rtx ();
4016   REAL_VALUE_TYPE offset;
4018   real_2expN (&offset, 31);
4020   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
4021   do_pending_stack_adjust ();
4023   emit_insn (gen_cmpsf (operands[1], reg1));
4024   emit_jump_insn (gen_bge (label1));
4026   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4027   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4028                                gen_rtx_LABEL_REF (VOIDmode, label2)));
4029   emit_barrier ();
4031   emit_label (label1);
4032   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4033   emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4034                                  (BITMASK_HIGH, SImode)));
4036   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4037   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4039   emit_label (label2);
4041   /* Allow REG_NOTES to be set on last insn (labels don't have enough
4042      fields, and can't be used for REG_NOTES anyway).  */
4043   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4044   DONE;
4048 (define_expand "fixuns_truncsfdi2"
4049   [(set (match_operand:DI 0 "register_operand" "")
4050         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4051   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4053   rtx reg1 = gen_reg_rtx (SFmode);
4054   rtx reg2 = gen_reg_rtx (SFmode);
4055   rtx reg3 = gen_reg_rtx (DImode);
4056   rtx label1 = gen_label_rtx ();
4057   rtx label2 = gen_label_rtx ();
4058   REAL_VALUE_TYPE offset;
4060   real_2expN (&offset, 63);
4062   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
4063   do_pending_stack_adjust ();
4065   emit_insn (gen_cmpsf (operands[1], reg1));
4066   emit_jump_insn (gen_bge (label1));
4068   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4069   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4070                                gen_rtx_LABEL_REF (VOIDmode, label2)));
4071   emit_barrier ();
4073   emit_label (label1);
4074   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4075   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4076   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4078   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4079   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4081   emit_label (label2);
4083   /* Allow REG_NOTES to be set on last insn (labels don't have enough
4084      fields, and can't be used for REG_NOTES anyway).  */
4085   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4086   DONE;
4090 ;;  ....................
4092 ;;      DATA MOVEMENT
4094 ;;  ....................
4096 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
4098 (define_expand "extv"
4099   [(set (match_operand 0 "register_operand" "")
4100         (sign_extract (match_operand:QI 1 "memory_operand" "")
4101                       (match_operand 2 "immediate_operand" "")
4102                       (match_operand 3 "immediate_operand" "")))]
4103   "!TARGET_MIPS16"
4105   if (mips_expand_unaligned_load (operands[0], operands[1],
4106                                   INTVAL (operands[2]),
4107                                   INTVAL (operands[3])))
4108     DONE;
4109   else
4110     FAIL;
4113 (define_expand "extzv"
4114   [(set (match_operand 0 "register_operand" "")
4115         (zero_extract (match_operand:QI 1 "memory_operand" "")
4116                       (match_operand 2 "immediate_operand" "")
4117                       (match_operand 3 "immediate_operand" "")))]
4118   "!TARGET_MIPS16"
4120   if (mips_expand_unaligned_load (operands[0], operands[1],
4121                                   INTVAL (operands[2]),
4122                                   INTVAL (operands[3])))
4123     DONE;
4124   else
4125     FAIL;
4128 (define_expand "insv"
4129   [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4130                       (match_operand 1 "immediate_operand" "")
4131                       (match_operand 2 "immediate_operand" ""))
4132         (match_operand 3 "reg_or_0_operand" ""))]
4133   "!TARGET_MIPS16"
4135   if (mips_expand_unaligned_store (operands[0], operands[3],
4136                                    INTVAL (operands[1]),
4137                                    INTVAL (operands[2])))
4138     DONE;
4139   else
4140     FAIL;
4143 ;; Unaligned word moves generated by the bit field patterns.
4145 ;; As far as the rtl is concerned, both the left-part and right-part
4146 ;; instructions can access the whole field.  However, the real operand
4147 ;; refers to just the first or the last byte (depending on endianness).
4148 ;; We therefore use two memory operands to each instruction, one to
4149 ;; describe the rtl effect and one to use in the assembly output.
4151 ;; Operands 0 and 1 are the rtl-level target and source respectively.
4152 ;; This allows us to use the standard length calculations for the "load"
4153 ;; and "store" type attributes.
4155 (define_insn "mov_lwl"
4156   [(set (match_operand:SI 0 "register_operand" "=d")
4157         (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
4158                     (match_operand:QI 2 "memory_operand" "m")]
4159                    UNSPEC_LWL))]
4160   "!TARGET_MIPS16"
4161   "lwl\t%0,%2"
4162   [(set_attr "type" "load")
4163    (set_attr "mode" "SI")
4164    (set_attr "hazard" "none")])
4166 (define_insn "mov_lwr"
4167   [(set (match_operand:SI 0 "register_operand" "=d")
4168         (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
4169                     (match_operand:QI 2 "memory_operand" "m")
4170                     (match_operand:SI 3 "register_operand" "0")]
4171                    UNSPEC_LWR))]
4172   "!TARGET_MIPS16"
4173   "lwr\t%0,%2"
4174   [(set_attr "type" "load")
4175    (set_attr "mode" "SI")])
4178 (define_insn "mov_swl"
4179   [(set (match_operand:BLK 0 "memory_operand" "=m")
4180         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
4181                      (match_operand:QI 2 "memory_operand" "m")]
4182                     UNSPEC_SWL))]
4183   "!TARGET_MIPS16"
4184   "swl\t%z1,%2"
4185   [(set_attr "type" "store")
4186    (set_attr "mode" "SI")])
4188 (define_insn "mov_swr"
4189   [(set (match_operand:BLK 0 "memory_operand" "+m")
4190         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
4191                      (match_operand:QI 2 "memory_operand" "m")
4192                      (match_dup 0)]
4193                     UNSPEC_SWR))]
4194   "!TARGET_MIPS16"
4195   "swr\t%z1,%2"
4196   [(set_attr "type" "store")
4197    (set_attr "mode" "SI")])
4200 (define_insn "mov_ldl"
4201   [(set (match_operand:DI 0 "register_operand" "=d")
4202         (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
4203                     (match_operand:QI 2 "memory_operand" "m")]
4204                    UNSPEC_LDL))]
4205   "TARGET_64BIT && !TARGET_MIPS16"
4206   "ldl\t%0,%2"
4207   [(set_attr "type" "load")
4208    (set_attr "mode" "DI")])
4210 (define_insn "mov_ldr"
4211   [(set (match_operand:DI 0 "register_operand" "=d")
4212         (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
4213                     (match_operand:QI 2 "memory_operand" "m")
4214                     (match_operand:DI 3 "register_operand" "0")]
4215                    UNSPEC_LDR))]
4216   "TARGET_64BIT && !TARGET_MIPS16"
4217   "ldr\t%0,%2"
4218   [(set_attr "type" "load")
4219    (set_attr "mode" "DI")])
4222 (define_insn "mov_sdl"
4223   [(set (match_operand:BLK 0 "memory_operand" "=m")
4224         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
4225                      (match_operand:QI 2 "memory_operand" "m")]
4226                     UNSPEC_SDL))]
4227   "TARGET_64BIT && !TARGET_MIPS16"
4228   "sdl\t%z1,%2"
4229   [(set_attr "type" "store")
4230    (set_attr "mode" "DI")])
4232 (define_insn "mov_sdr"
4233   [(set (match_operand:BLK 0 "memory_operand" "+m")
4234         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
4235                      (match_operand:QI 2 "memory_operand" "m")
4236                      (match_dup 0)]
4237                     UNSPEC_SDR))]
4238   "TARGET_64BIT && !TARGET_MIPS16"
4239   "sdr\t%z1,%2"
4240   [(set_attr "type" "store")
4241    (set_attr "mode" "DI")])
4243 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
4244 ;; The required value is:
4246 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
4248 ;; which translates to:
4250 ;;      lui     op0,%highest(op1)
4251 ;;      daddiu  op0,op0,%higher(op1)
4252 ;;      dsll    op0,op0,16
4253 ;;      daddiu  op0,op0,%hi(op1)
4254 ;;      dsll    op0,op0,16
4255 (define_insn_and_split "*lea_high64"
4256   [(set (match_operand:DI 0 "register_operand" "=d")
4257         (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
4258   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4259   "#"
4260   "&& reload_completed"
4261   [(set (match_dup 0) (high:DI (match_dup 2)))
4262    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
4263    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
4264    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4265    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
4267   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4268   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
4270   [(set_attr "length" "20")])
4272 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
4273 ;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
4274 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
4275 ;; used once.  We can then use the sequence:
4277 ;;      lui     op0,%highest(op1)
4278 ;;      lui     op2,%hi(op1)
4279 ;;      daddiu  op0,op0,%higher(op1)
4280 ;;      daddiu  op2,op2,%lo(op1)
4281 ;;      dsll32  op0,op0,0
4282 ;;      daddu   op0,op0,op2
4284 ;; which takes 4 cycles on most superscalar targets.
4285 (define_insn_and_split "*lea64"
4286   [(set (match_operand:DI 0 "register_operand" "=d")
4287         (match_operand:DI 1 "general_symbolic_operand" ""))
4288    (clobber (match_scratch:DI 2 "=&d"))]
4289   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
4290   "#"
4291   "&& reload_completed"
4292   [(set (match_dup 0) (high:DI (match_dup 3)))
4293    (set (match_dup 2) (high:DI (match_dup 4)))
4294    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4295    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
4296    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
4297    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
4299   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4300   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
4302   [(set_attr "length" "24")])
4304 ;; Insns to fetch a global symbol from a big GOT.
4306 (define_insn_and_split "*xgot_hisi"
4307   [(set (match_operand:SI 0 "register_operand" "=d")
4308         (high:SI (match_operand:SI 1 "global_got_operand" "")))]
4309   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4310   "#"
4311   "&& reload_completed"
4312   [(set (match_dup 0) (high:SI (match_dup 2)))
4313    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
4315   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
4316   operands[3] = pic_offset_table_rtx;
4318   [(set_attr "got" "xgot_high")])
4320 (define_insn_and_split "*xgot_losi"
4321   [(set (match_operand:SI 0 "register_operand" "=d")
4322         (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
4323                    (match_operand:SI 2 "global_got_operand" "")))]
4324   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4325   "#"
4326   "&& reload_completed"
4327   [(set (match_dup 0)
4328         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
4329   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
4330   [(set_attr "got" "load")])
4332 (define_insn_and_split "*xgot_hidi"
4333   [(set (match_operand:DI 0 "register_operand" "=d")
4334         (high:DI (match_operand:DI 1 "global_got_operand" "")))]
4335   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4336   "#"
4337   "&& reload_completed"
4338   [(set (match_dup 0) (high:DI (match_dup 2)))
4339    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
4341   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
4342   operands[3] = pic_offset_table_rtx;
4344   [(set_attr "got" "xgot_high")])
4346 (define_insn_and_split "*xgot_lodi"
4347   [(set (match_operand:DI 0 "register_operand" "=d")
4348         (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
4349                    (match_operand:DI 2 "global_got_operand" "")))]
4350   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4351   "#"
4352   "&& reload_completed"
4353   [(set (match_dup 0)
4354         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
4355   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
4356   [(set_attr "got" "load")])
4358 ;; Insns to fetch a global symbol from a normal GOT.
4360 (define_insn_and_split "*got_dispsi"
4361   [(set (match_operand:SI 0 "register_operand" "=d")
4362         (match_operand:SI 1 "global_got_operand" ""))]
4363   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
4364   "#"
4365   "&& reload_completed"
4366   [(set (match_dup 0)
4367         (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
4369   operands[2] = pic_offset_table_rtx;
4370   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
4372   [(set_attr "got" "load")])
4374 (define_insn_and_split "*got_dispdi"
4375   [(set (match_operand:DI 0 "register_operand" "=d")
4376         (match_operand:DI 1 "global_got_operand" ""))]
4377   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
4378   "#"
4379   "&& reload_completed"
4380   [(set (match_dup 0)
4381         (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
4383   operands[2] = pic_offset_table_rtx;
4384   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
4386   [(set_attr "got" "load")])
4388 ;; Insns for loading the high part of a local symbol.
4390 (define_insn_and_split "*got_pagesi"
4391   [(set (match_operand:SI 0 "register_operand" "=d")
4392         (high:SI (match_operand:SI 1 "local_got_operand" "")))]
4393   "TARGET_EXPLICIT_RELOCS"
4394   "#"
4395   "&& reload_completed"
4396   [(set (match_dup 0)
4397         (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
4399   operands[2] = pic_offset_table_rtx;
4400   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
4402   [(set_attr "got" "load")])
4404 (define_insn_and_split "*got_pagedi"
4405   [(set (match_operand:DI 0 "register_operand" "=d")
4406         (high:DI (match_operand:DI 1 "local_got_operand" "")))]
4407   "TARGET_EXPLICIT_RELOCS"
4408   "#"
4409   "&& reload_completed"
4410   [(set (match_dup 0)
4411         (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
4413   operands[2] = pic_offset_table_rtx;
4414   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
4416   [(set_attr "got" "load")])
4418 ;; Lower-level instructions for loading an address from the GOT.
4419 ;; We could use MEMs, but an unspec gives more optimization
4420 ;; opportunities.
4422 (define_insn "*load_gotsi"
4423   [(set (match_operand:SI 0 "register_operand" "=d")
4424         (unspec:SI [(match_operand:SI 1 "register_operand" "d")
4425                     (match_operand:SI 2 "immediate_operand" "")]
4426                    UNSPEC_LOAD_GOT))]
4427   "TARGET_ABICALLS"
4428   "lw\t%0,%R2(%1)"
4429   [(set_attr "type" "load")
4430    (set_attr "length" "4")])
4432 (define_insn "*load_gotdi"
4433   [(set (match_operand:DI 0 "register_operand" "=d")
4434         (unspec:DI [(match_operand:DI 1 "register_operand" "d")
4435                     (match_operand:DI 2 "immediate_operand" "")]
4436                    UNSPEC_LOAD_GOT))]
4437   "TARGET_ABICALLS"
4438   "ld\t%0,%R2(%1)"
4439   [(set_attr "type" "load")
4440    (set_attr "length" "4")])
4442 ;; Instructions for adding the low 16 bits of an address to a register.
4443 ;; Operand 2 is the address: print_operand works out which relocation
4444 ;; should be applied.
4446 (define_insn "*lowsi"
4447   [(set (match_operand:SI 0 "register_operand" "=d")
4448         (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
4449                    (match_operand:SI 2 "immediate_operand" "")))]
4450   "!TARGET_MIPS16"
4451   "addiu\t%0,%1,%R2"
4452   [(set_attr "type"     "arith")
4453    (set_attr "mode"     "SI")])
4455 (define_insn "*lowdi"
4456   [(set (match_operand:DI 0 "register_operand" "=d")
4457         (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
4458                    (match_operand:DI 2 "immediate_operand" "")))]
4459   "!TARGET_MIPS16 && TARGET_64BIT"
4460   "daddiu\t%0,%1,%R2"
4461   [(set_attr "type"     "arith")
4462    (set_attr "mode"     "DI")])
4464 (define_insn "*lowsi_mips16"
4465   [(set (match_operand:SI 0 "register_operand" "=d")
4466         (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
4467                    (match_operand:SI 2 "immediate_operand" "")))]
4468   "TARGET_MIPS16"
4469   "addiu\t%0,%R2"
4470   [(set_attr "type"     "arith")
4471    (set_attr "mode"     "SI")
4472    (set_attr "length"   "8")])
4474 (define_insn "*lowdi_mips16"
4475   [(set (match_operand:DI 0 "register_operand" "=d")
4476         (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
4477                    (match_operand:DI 2 "immediate_operand" "")))]
4478   "TARGET_MIPS16 && TARGET_64BIT"
4479   "daddiu\t%0,%R2"
4480   [(set_attr "type"     "arith")
4481    (set_attr "mode"     "DI")
4482    (set_attr "length"   "8")])
4484 ;; 64-bit integer moves
4486 ;; Unlike most other insns, the move insns can't be split with
4487 ;; different predicates, because register spilling and other parts of
4488 ;; the compiler, have memoized the insn number already.
4490 (define_expand "movdi"
4491   [(set (match_operand:DI 0 "" "")
4492         (match_operand:DI 1 "" ""))]
4493   ""
4495   if (mips_legitimize_move (DImode, operands[0], operands[1]))
4496     DONE;
4498   /* If we are generating embedded PIC code, and we are referring to a
4499      symbol in the .text section, we must use an offset from the start
4500      of the function.  */
4501   if (TARGET_EMBEDDED_PIC
4502       && (GET_CODE (operands[1]) == LABEL_REF
4503           || (GET_CODE (operands[1]) == SYMBOL_REF
4504               && ! SYMBOL_REF_FLAG (operands[1]))))
4505     {
4506       rtx temp;
4508       temp = embedded_pic_offset (operands[1]);
4509       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
4510                            force_reg (DImode, temp));
4511       emit_move_insn (operands[0], force_reg (DImode, temp));
4512       DONE;
4513     }
4516 ;; For mips16, we need a special case to handle storing $31 into
4517 ;; memory, since we don't have a constraint to match $31.  This
4518 ;; instruction can be generated by save_restore_insns.
4520 (define_insn ""
4521   [(set (match_operand:DI 0 "stack_operand" "=m")
4522         (reg:DI 31))]
4523   "TARGET_MIPS16 && TARGET_64BIT"
4524   "sd\t$31,%0"
4525   [(set_attr "type"     "store")
4526    (set_attr "mode"     "DI")])
4528 (define_insn "*movdi_32bit"
4529   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
4530         (match_operand:DI 1 "move_operand" "d,i,m,d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
4531   "!TARGET_64BIT && !TARGET_MIPS16
4532    && (register_operand (operands[0], DImode)
4533        || reg_or_0_operand (operands[1], DImode))"
4534   { return mips_output_move (operands[0], operands[1]); }
4535   [(set_attr "type"     "move,arith,load,store,hilo,hilo,hilo,xfer,load,xfer,store")
4536    (set_attr "mode"     "DI")
4537    (set_attr "length"   "8,16,*,*,8,8,8,8,*,8,*")])
4539 (define_insn "*movdi_32bit_mips16"
4540   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4541         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4542   "!TARGET_64BIT && TARGET_MIPS16
4543    && (register_operand (operands[0], DImode)
4544        || register_operand (operands[1], DImode))"
4545   { return mips_output_move (operands[0], operands[1]); }
4546   [(set_attr "type"     "move,move,move,arith,arith,load,store,hilo")
4547    (set_attr "mode"     "DI")
4548    (set_attr "length"   "8,8,8,8,12,*,*,8")])
4550 (define_insn "*movdi_64bit"
4551   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
4552         (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
4553   "TARGET_64BIT && !TARGET_MIPS16
4554    && (register_operand (operands[0], DImode)
4555        || reg_or_0_operand (operands[1], DImode))"
4556   { return mips_output_move (operands[0], operands[1]); }
4557   [(set_attr "type"     "move,const,const,load,store,move,xfer,fpload,xfer,fpstore,hilo,hilo,hilo,xfer,load,xfer,store")
4558    (set_attr "mode"     "DI")
4559    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,8,*,8,*")])
4561 (define_insn "*movdi_64bit_mips16"
4562   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
4563         (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d,*x"))]
4564   "TARGET_64BIT && TARGET_MIPS16
4565    && (register_operand (operands[0], DImode)
4566        || register_operand (operands[1], DImode))"
4567   { return mips_output_move (operands[0], operands[1]); }
4568   [(set_attr "type"     "move,move,move,arith,arith,const,load,store,hilo")
4569    (set_attr "mode"     "DI")
4570    (set_attr_alternative "length"
4571                 [(const_int 4)
4572                  (const_int 4)
4573                  (const_int 4)
4574                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4575                                (const_int 4)
4576                                (const_int 8))
4577                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4578                                (const_int 8)
4579                                (const_int 12))
4580                  (const_string "*")
4581                  (const_string "*")
4582                  (const_string "*")
4583                  (const_int 4)])])
4586 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4587 ;; when the original load is a 4 byte instruction but the add and the
4588 ;; load are 2 2 byte instructions.
4590 (define_split
4591   [(set (match_operand:DI 0 "register_operand" "")
4592         (mem:DI (plus:DI (match_dup 0)
4593                          (match_operand:DI 1 "const_int_operand" ""))))]
4594   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4595    && !TARGET_DEBUG_D_MODE
4596    && GET_CODE (operands[0]) == REG
4597    && M16_REG_P (REGNO (operands[0]))
4598    && GET_CODE (operands[1]) == CONST_INT
4599    && ((INTVAL (operands[1]) < 0
4600         && INTVAL (operands[1]) >= -0x10)
4601        || (INTVAL (operands[1]) >= 32 * 8
4602            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4603        || (INTVAL (operands[1]) >= 0
4604            && INTVAL (operands[1]) < 32 * 8
4605            && (INTVAL (operands[1]) & 7) != 0))"
4606   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4607    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4609   HOST_WIDE_INT val = INTVAL (operands[1]);
4611   if (val < 0)
4612     operands[2] = const0_rtx;
4613   else if (val >= 32 * 8)
4614     {
4615       int off = val & 7;
4617       operands[1] = GEN_INT (0x8 + off);
4618       operands[2] = GEN_INT (val - off - 0x8);
4619     }
4620   else
4621     {
4622       int off = val & 7;
4624       operands[1] = GEN_INT (off);
4625       operands[2] = GEN_INT (val - off);
4626     }
4629 ;; 32-bit Integer moves
4631 ;; Unlike most other insns, the move insns can't be split with
4632 ;; different predicates, because register spilling and other parts of
4633 ;; the compiler, have memoized the insn number already.
4635 (define_expand "movsi"
4636   [(set (match_operand:SI 0 "" "")
4637         (match_operand:SI 1 "" ""))]
4638   ""
4640   if (mips_legitimize_move (SImode, operands[0], operands[1]))
4641     DONE;
4643   /* If we are generating embedded PIC code, and we are referring to a
4644      symbol in the .text section, we must use an offset from the start
4645      of the function.  */
4646   if (TARGET_EMBEDDED_PIC
4647       && (GET_CODE (operands[1]) == LABEL_REF
4648           || (GET_CODE (operands[1]) == SYMBOL_REF
4649               && ! SYMBOL_REF_FLAG (operands[1]))))
4650     {
4651       rtx temp;
4653       temp = embedded_pic_offset (operands[1]);
4654       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
4655                            force_reg (SImode, temp));
4656       emit_move_insn (operands[0], force_reg (SImode, temp));
4657       DONE;
4658     }
4661 ;; We can only store $ra directly into a small sp offset.
4663 (define_insn ""
4664   [(set (match_operand:SI 0 "stack_operand" "=m")
4665         (reg:SI 31))]
4666   "TARGET_MIPS16"
4667   "sw\t$31,%0"
4668   [(set_attr "type"     "store")
4669    (set_attr "mode"     "SI")])
4671 ;; The difference between these two is whether or not ints are allowed
4672 ;; in FP registers (off by default, use -mdebugh to enable).
4674 (define_insn "*movsi_internal"
4675   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
4676         (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
4677   "!TARGET_MIPS16
4678    && (register_operand (operands[0], SImode)
4679        || reg_or_0_operand (operands[1], SImode))"
4680   { return mips_output_move (operands[0], operands[1]); }
4681   [(set_attr "type"     "move,const,const,load,store,move,xfer,fpload,xfer,fpstore,xfer,xfer,hilo,hilo,hilo,xfer,load,xfer,store")
4682    (set_attr "mode"     "SI")
4683    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,4,*,4,*")])
4685 (define_insn "*movsi_mips16"
4686   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
4687         (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d,*x"))]
4688   "TARGET_MIPS16
4689    && (register_operand (operands[0], SImode)
4690        || register_operand (operands[1], SImode))"
4691   { return mips_output_move (operands[0], operands[1]); }
4692   [(set_attr "type"     "move,move,move,arith,arith,const,load,store,hilo")
4693    (set_attr "mode"     "SI")
4694    (set_attr_alternative "length"
4695                 [(const_int 4)
4696                  (const_int 4)
4697                  (const_int 4)
4698                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4699                                (const_int 4)
4700                                (const_int 8))
4701                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4702                                (const_int 8)
4703                                (const_int 12))
4704                  (const_string "*")
4705                  (const_string "*")
4706                  (const_string "*")
4707                  (const_int 4)])])
4709 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4710 ;; when the original load is a 4 byte instruction but the add and the
4711 ;; load are 2 2 byte instructions.
4713 (define_split
4714   [(set (match_operand:SI 0 "register_operand" "")
4715         (mem:SI (plus:SI (match_dup 0)
4716                          (match_operand:SI 1 "const_int_operand" ""))))]
4717   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4718    && GET_CODE (operands[0]) == REG
4719    && M16_REG_P (REGNO (operands[0]))
4720    && GET_CODE (operands[1]) == CONST_INT
4721    && ((INTVAL (operands[1]) < 0
4722         && INTVAL (operands[1]) >= -0x80)
4723        || (INTVAL (operands[1]) >= 32 * 4
4724            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4725        || (INTVAL (operands[1]) >= 0
4726            && INTVAL (operands[1]) < 32 * 4
4727            && (INTVAL (operands[1]) & 3) != 0))"
4728   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4729    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4731   HOST_WIDE_INT val = INTVAL (operands[1]);
4733   if (val < 0)
4734     operands[2] = const0_rtx;
4735   else if (val >= 32 * 4)
4736     {
4737       int off = val & 3;
4739       operands[1] = GEN_INT (0x7c + off);
4740       operands[2] = GEN_INT (val - off - 0x7c);
4741     }
4742   else
4743     {
4744       int off = val & 3;
4746       operands[1] = GEN_INT (off);
4747       operands[2] = GEN_INT (val - off);
4748     }
4751 ;; On the mips16, we can split a load of certain constants into a load
4752 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
4753 ;; instructions.
4755 (define_split
4756   [(set (match_operand:SI 0 "register_operand" "")
4757         (match_operand:SI 1 "const_int_operand" ""))]
4758   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4759    && GET_CODE (operands[0]) == REG
4760    && M16_REG_P (REGNO (operands[0]))
4761    && GET_CODE (operands[1]) == CONST_INT
4762    && INTVAL (operands[1]) >= 0x100
4763    && INTVAL (operands[1]) <= 0xff + 0x7f"
4764   [(set (match_dup 0) (match_dup 1))
4765    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4767   int val = INTVAL (operands[1]);
4769   operands[1] = GEN_INT (0xff);
4770   operands[2] = GEN_INT (val - 0xff);
4773 ;; On the mips16, we can split a load of a negative constant into a
4774 ;; load and a neg.  That's what mips_output_move will generate anyhow.
4776 (define_split
4777   [(set (match_operand:SI 0 "register_operand" "")
4778         (match_operand:SI 1 "const_int_operand" ""))]
4779   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4780    && GET_CODE (operands[0]) == REG
4781    && M16_REG_P (REGNO (operands[0]))
4782    && GET_CODE (operands[1]) == CONST_INT
4783    && INTVAL (operands[1]) < 0
4784    && INTVAL (operands[1]) > - 0x8000"
4785   [(set (match_dup 0) (match_dup 1))
4786    (set (match_dup 0) (neg:SI (match_dup 0)))]
4787   { operands[1] = GEN_INT (- INTVAL (operands[1])); })
4789 ;; This insn handles moving CCmode values.  It's really just a
4790 ;; slightly simplified copy of movsi_internal2, with additional cases
4791 ;; to move a condition register to a general register and to move
4792 ;; between the general registers and the floating point registers.
4794 (define_insn "movcc"
4795   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
4796         (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
4797   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4798   { return mips_output_move (operands[0], operands[1]); }
4799   [(set_attr "type"     "move,move,load,store,xfer,xfer,move,fpload,fpstore")
4800    (set_attr "mode"     "SI")
4801    (set_attr "length"   "8,4,*,*,4,4,4,*,*")])
4803 ;; Reload condition code registers.  reload_incc and reload_outcc
4804 ;; both handle moves from arbitrary operands into condition code
4805 ;; registers.  reload_incc handles the more common case in which
4806 ;; a source operand is constrained to be in a condition-code
4807 ;; register, but has not been allocated to one.
4809 ;; Sometimes, such as in movcc, we have a CCmode destination whose
4810 ;; constraints do not include 'z'.  reload_outcc handles the case
4811 ;; when such an operand is allocated to a condition-code register.
4813 ;; Note that reloads from a condition code register to some
4814 ;; other location can be done using ordinary moves.  Moving
4815 ;; into a GPR takes a single movcc, moving elsewhere takes
4816 ;; two.  We can leave these cases to the generic reload code.
4817 (define_expand "reload_incc"
4818   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4819         (match_operand:CC 1 "general_operand" ""))
4820    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4821   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4823   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4824   DONE;
4827 (define_expand "reload_outcc"
4828   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4829         (match_operand:CC 1 "register_operand" ""))
4830    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4831   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4833   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4834   DONE;
4837 ;; MIPS4 supports loading and storing a floating point register from
4838 ;; the sum of two general registers.  We use two versions for each of
4839 ;; these four instructions: one where the two general registers are
4840 ;; SImode, and one where they are DImode.  This is because general
4841 ;; registers will be in SImode when they hold 32 bit values, but,
4842 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
4843 ;; instructions will still work correctly.
4845 ;; ??? Perhaps it would be better to support these instructions by
4846 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
4847 ;; these instructions can only be used to load and store floating
4848 ;; point registers, that would probably cause trouble in reload.
4850 (define_insn ""
4851   [(set (match_operand:SF 0 "register_operand" "=f")
4852         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4853                          (match_operand:SI 2 "register_operand" "d"))))]
4854   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4855   "lwxc1\t%0,%1(%2)"
4856   [(set_attr "type"     "fpidxload")
4857    (set_attr "mode"     "SF")
4858    (set_attr "length"   "4")])
4860 (define_insn ""
4861   [(set (match_operand:SF 0 "register_operand" "=f")
4862         (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4863                          (match_operand:DI 2 "register_operand" "d"))))]
4864   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4865   "lwxc1\t%0,%1(%2)"
4866   [(set_attr "type"     "fpidxload")
4867    (set_attr "mode"     "SF")
4868    (set_attr "length"   "4")])
4870 (define_insn ""
4871   [(set (match_operand:DF 0 "register_operand" "=f")
4872         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4873                          (match_operand:SI 2 "register_operand" "d"))))]
4874   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4875   "ldxc1\t%0,%1(%2)"
4876   [(set_attr "type"     "fpidxload")
4877    (set_attr "mode"     "DF")
4878    (set_attr "length"   "4")])
4880 (define_insn ""
4881   [(set (match_operand:DF 0 "register_operand" "=f")
4882         (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4883                          (match_operand:DI 2 "register_operand" "d"))))]
4884   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4885   "ldxc1\t%0,%1(%2)"
4886   [(set_attr "type"     "fpidxload")
4887    (set_attr "mode"     "DF")
4888    (set_attr "length"   "4")])
4890 (define_insn ""
4891   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4892                          (match_operand:SI 2 "register_operand" "d")))
4893         (match_operand:SF 0 "register_operand" "f"))]
4894   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4895   "swxc1\t%0,%1(%2)"
4896   [(set_attr "type"     "fpidxstore")
4897    (set_attr "mode"     "SF")
4898    (set_attr "length"   "4")])
4900 (define_insn ""
4901   [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4902                          (match_operand:DI 2 "register_operand" "d")))
4903         (match_operand:SF 0 "register_operand" "f"))]
4904   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4905   "swxc1\t%0,%1(%2)"
4906   [(set_attr "type"     "fpidxstore")
4907    (set_attr "mode"     "SF")
4908    (set_attr "length"   "4")])
4910 (define_insn ""
4911   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4912                          (match_operand:SI 2 "register_operand" "d")))
4913         (match_operand:DF 0 "register_operand" "f"))]
4914   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4915   "sdxc1\t%0,%1(%2)"
4916   [(set_attr "type"     "fpidxstore")
4917    (set_attr "mode"     "DF")
4918    (set_attr "length"   "4")])
4920 (define_insn ""
4921   [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4922                          (match_operand:DI 2 "register_operand" "d")))
4923         (match_operand:DF 0 "register_operand" "f"))]
4924   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4925   "sdxc1\t%0,%1(%2)"
4926   [(set_attr "type"     "fpidxstore")
4927    (set_attr "mode"     "DF")
4928    (set_attr "length"   "4")])
4930 ;; 16-bit Integer moves
4932 ;; Unlike most other insns, the move insns can't be split with
4933 ;; different predicates, because register spilling and other parts of
4934 ;; the compiler, have memoized the insn number already.
4935 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4937 (define_expand "movhi"
4938   [(set (match_operand:HI 0 "" "")
4939         (match_operand:HI 1 "" ""))]
4940   ""
4942   if (mips_legitimize_move (HImode, operands[0], operands[1]))
4943     DONE;
4946 (define_insn "*movhi_internal"
4947   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x,*d")
4948         (match_operand:HI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d,*x"))]
4949   "!TARGET_MIPS16
4950    && (register_operand (operands[0], HImode)
4951        || reg_or_0_operand (operands[1], HImode))"
4952   "@
4953     move\t%0,%1
4954     li\t%0,%1
4955     lhu\t%0,%1
4956     sh\t%z1,%0
4957     mfc1\t%0,%1
4958     mtc1\t%1,%0
4959     mov.s\t%0,%1
4960     mt%0\t%1
4961     mf%1\t%0"
4962   [(set_attr "type"     "move,arith,load,store,xfer,xfer,move,hilo,hilo")
4963    (set_attr "mode"     "HI")
4964    (set_attr "length"   "4,4,*,*,4,4,4,4,4")])
4966 (define_insn "*movhi_mips16"
4967   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4968         (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d,*x"))]
4969   "TARGET_MIPS16
4970    && (register_operand (operands[0], HImode)
4971        || register_operand (operands[1], HImode))"
4972   "@
4973     move\t%0,%1
4974     move\t%0,%1
4975     move\t%0,%1
4976     li\t%0,%1
4977     li\t%0,%n1\;neg\t%0
4978     lhu\t%0,%1
4979     sh\t%1,%0
4980     mf%1\t%0"
4981   [(set_attr "type"     "move,move,move,arith,arith,load,store,hilo")
4982    (set_attr "mode"     "HI")
4983    (set_attr_alternative "length"
4984                 [(const_int 4)
4985                  (const_int 4)
4986                  (const_int 4)
4987                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4988                                (const_int 4)
4989                                (const_int 8))
4990                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4991                                (const_int 8)
4992                                (const_int 12))
4993                  (const_string "*")
4994                  (const_string "*")
4995                  (const_int 4)])])
4998 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4999 ;; when the original load is a 4 byte instruction but the add and the
5000 ;; load are 2 2 byte instructions.
5002 (define_split
5003   [(set (match_operand:HI 0 "register_operand" "")
5004         (mem:HI (plus:SI (match_dup 0)
5005                          (match_operand:SI 1 "const_int_operand" ""))))]
5006   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5007    && GET_CODE (operands[0]) == REG
5008    && M16_REG_P (REGNO (operands[0]))
5009    && GET_CODE (operands[1]) == CONST_INT
5010    && ((INTVAL (operands[1]) < 0
5011         && INTVAL (operands[1]) >= -0x80)
5012        || (INTVAL (operands[1]) >= 32 * 2
5013            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
5014        || (INTVAL (operands[1]) >= 0
5015            && INTVAL (operands[1]) < 32 * 2
5016            && (INTVAL (operands[1]) & 1) != 0))"
5017   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5018    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
5020   HOST_WIDE_INT val = INTVAL (operands[1]);
5022   if (val < 0)
5023     operands[2] = const0_rtx;
5024   else if (val >= 32 * 2)
5025     {
5026       int off = val & 1;
5028       operands[1] = GEN_INT (0x7e + off);
5029       operands[2] = GEN_INT (val - off - 0x7e);
5030     }
5031   else
5032     {
5033       int off = val & 1;
5035       operands[1] = GEN_INT (off);
5036       operands[2] = GEN_INT (val - off);
5037     }
5040 ;; 8-bit Integer moves
5042 ;; Unlike most other insns, the move insns can't be split with
5043 ;; different predicates, because register spilling and other parts of
5044 ;; the compiler, have memoized the insn number already.
5045 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
5047 (define_expand "movqi"
5048   [(set (match_operand:QI 0 "" "")
5049         (match_operand:QI 1 "" ""))]
5050   ""
5052   if (mips_legitimize_move (QImode, operands[0], operands[1]))
5053     DONE;
5056 (define_insn "*movqi_internal"
5057   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x,*d")
5058         (match_operand:QI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d,*x"))]
5059   "!TARGET_MIPS16
5060    && (register_operand (operands[0], QImode)
5061        || reg_or_0_operand (operands[1], QImode))"
5062   "@
5063     move\t%0,%1
5064     li\t%0,%1
5065     lbu\t%0,%1
5066     sb\t%z1,%0
5067     mfc1\t%0,%1
5068     mtc1\t%1,%0
5069     mov.s\t%0,%1
5070     mt%0\t%1
5071     mf%1\t%0"
5072   [(set_attr "type"     "move,arith,load,store,xfer,xfer,move,hilo,hilo")
5073    (set_attr "mode"     "QI")
5074    (set_attr "length"   "4,4,*,*,4,4,4,4,4")])
5076 (define_insn "*movqi_mips16"
5077   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
5078         (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d,*x"))]
5079   "TARGET_MIPS16
5080    && (register_operand (operands[0], QImode)
5081        || register_operand (operands[1], QImode))"
5082   "@
5083     move\t%0,%1
5084     move\t%0,%1
5085     move\t%0,%1
5086     li\t%0,%1
5087     li\t%0,%n1\;neg\t%0
5088     lbu\t%0,%1
5089     sb\t%1,%0
5090     mf%1\t%0"
5091   [(set_attr "type"     "move,move,move,arith,arith,load,store,hilo")
5092    (set_attr "mode"     "QI")
5093    (set_attr "length"   "4,4,4,4,8,*,*,4")])
5095 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
5096 ;; when the original load is a 4 byte instruction but the add and the
5097 ;; load are 2 2 byte instructions.
5099 (define_split
5100   [(set (match_operand:QI 0 "register_operand" "")
5101         (mem:QI (plus:SI (match_dup 0)
5102                          (match_operand:SI 1 "const_int_operand" ""))))]
5103   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5104    && GET_CODE (operands[0]) == REG
5105    && M16_REG_P (REGNO (operands[0]))
5106    && GET_CODE (operands[1]) == CONST_INT
5107    && ((INTVAL (operands[1]) < 0
5108         && INTVAL (operands[1]) >= -0x80)
5109        || (INTVAL (operands[1]) >= 32
5110            && INTVAL (operands[1]) <= 31 + 0x7f))"
5111   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5112    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
5114   HOST_WIDE_INT val = INTVAL (operands[1]);
5116   if (val < 0)
5117     operands[2] = const0_rtx;
5118   else
5119     {
5120       operands[1] = GEN_INT (0x7f);
5121       operands[2] = GEN_INT (val - 0x7f);
5122     }
5125 ;; 32-bit floating point moves
5127 (define_expand "movsf"
5128   [(set (match_operand:SF 0 "" "")
5129         (match_operand:SF 1 "" ""))]
5130   ""
5132   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
5133     DONE;
5136 (define_insn "*movsf_hardfloat"
5137   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
5138         (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
5139   "TARGET_HARD_FLOAT
5140    && (register_operand (operands[0], SFmode)
5141        || reg_or_0_operand (operands[1], SFmode))"
5142   { return mips_output_move (operands[0], operands[1]); }
5143   [(set_attr "type"     "move,xfer,fpload,fpstore,xfer,xfer,move,load,store")
5144    (set_attr "mode"     "SF")
5145    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
5147 (define_insn "*movsf_softfloat"
5148   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
5149         (match_operand:SF 1 "move_operand" "Gd,m,d"))]
5150   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
5151    && (register_operand (operands[0], SFmode)
5152        || reg_or_0_operand (operands[1], SFmode))"
5153   { return mips_output_move (operands[0], operands[1]); }
5154   [(set_attr "type"     "move,load,store")
5155    (set_attr "mode"     "SF")
5156    (set_attr "length"   "4,*,*")])
5158 (define_insn "*movsf_mips16"
5159   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
5160         (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
5161   "TARGET_MIPS16
5162    && (register_operand (operands[0], SFmode)
5163        || register_operand (operands[1], SFmode))"
5164   { return mips_output_move (operands[0], operands[1]); }
5165   [(set_attr "type"     "move,move,move,load,store")
5166    (set_attr "mode"     "SF")
5167    (set_attr "length"   "4,4,4,*,*")])
5170 ;; 64-bit floating point moves
5172 (define_expand "movdf"
5173   [(set (match_operand:DF 0 "" "")
5174         (match_operand:DF 1 "" ""))]
5175   ""
5177   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
5178     DONE;
5181 (define_insn "*movdf_hardfloat_64bit"
5182   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
5183         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
5184   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
5185    && (register_operand (operands[0], DFmode)
5186        || reg_or_0_operand (operands[1], DFmode))"
5187   { return mips_output_move (operands[0], operands[1]); }
5188   [(set_attr "type"     "move,xfer,fpload,fpstore,xfer,xfer,move,load,store")
5189    (set_attr "mode"     "DF")
5190    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
5192 (define_insn "*movdf_hardfloat_32bit"
5193   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
5194         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
5195   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
5196    && (register_operand (operands[0], DFmode)
5197        || reg_or_0_operand (operands[1], DFmode))"
5198   { return mips_output_move (operands[0], operands[1]); }
5199   [(set_attr "type"     "move,xfer,fpload,fpstore,xfer,xfer,move,load,store")
5200    (set_attr "mode"     "DF")
5201    (set_attr "length"   "4,8,*,*,8,8,8,*,*")])
5203 (define_insn "*movdf_softfloat"
5204   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
5205         (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
5206   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
5207    && (register_operand (operands[0], DFmode)
5208        || reg_or_0_operand (operands[1], DFmode))"
5209   { return mips_output_move (operands[0], operands[1]); }
5210   [(set_attr "type"     "move,load,store,xfer,xfer,move")
5211    (set_attr "mode"     "DF")
5212    (set_attr "length"   "8,*,*,4,4,4")])
5214 (define_insn "*movdf_mips16"
5215   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
5216         (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
5217   "TARGET_MIPS16
5218    && (register_operand (operands[0], DFmode)
5219        || register_operand (operands[1], DFmode))"
5220   { return mips_output_move (operands[0], operands[1]); }
5221   [(set_attr "type"     "move,move,move,load,store")
5222    (set_attr "mode"     "DF")
5223    (set_attr "length"   "8,8,8,*,*")])
5225 (define_split
5226   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5227         (match_operand:DI 1 "move_operand" ""))]
5228   "reload_completed && !TARGET_64BIT
5229    && mips_split_64bit_move_p (operands[0], operands[1])"
5230   [(const_int 0)]
5232   mips_split_64bit_move (operands[0], operands[1]);
5233   DONE;
5236 (define_split
5237   [(set (match_operand:DF 0 "nonimmediate_operand" "")
5238         (match_operand:DF 1 "move_operand" ""))]
5239   "reload_completed && !TARGET_64BIT
5240    && mips_split_64bit_move_p (operands[0], operands[1])"
5241   [(const_int 0)]
5243   mips_split_64bit_move (operands[0], operands[1]);
5244   DONE;
5247 ;; Patterns for loading or storing part of a paired floating point
5248 ;; register.  We need them because odd-numbered floating-point registers
5249 ;; are not fully independent: see mips_split_64bit_move.
5251 ;; Load the low word of operand 0 with operand 1.
5252 (define_insn "load_df_low"
5253   [(set (match_operand:DF 0 "register_operand" "=f,f")
5254         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
5255                    UNSPEC_LOAD_DF_LOW))]
5256   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5258   operands[0] = mips_subword (operands[0], 0);
5259   return mips_output_move (operands[0], operands[1]);
5261   [(set_attr "type"     "xfer,fpload")
5262    (set_attr "mode"     "SF")
5263    (set_attr "length"   "4")])
5265 ;; Load the high word of operand 0 from operand 1, preserving the value
5266 ;; in the low word.
5267 (define_insn "load_df_high"
5268   [(set (match_operand:DF 0 "register_operand" "=f,f")
5269         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
5270                     (match_operand:DF 2 "register_operand" "0,0")]
5271                    UNSPEC_LOAD_DF_HIGH))]
5272   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5274   operands[0] = mips_subword (operands[0], 1);
5275   return mips_output_move (operands[0], operands[1]);
5277   [(set_attr "type"     "xfer,fpload")
5278    (set_attr "mode"     "SF")
5279    (set_attr "length"   "4")])
5281 ;; Store the high word of operand 1 in operand 0.  The corresponding
5282 ;; low-word move is done in the normal way.
5283 (define_insn "store_df_high"
5284   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
5285         (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
5286                    UNSPEC_STORE_DF_HIGH))]
5287   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5289   operands[1] = mips_subword (operands[1], 1);
5290   return mips_output_move (operands[0], operands[1]);
5292   [(set_attr "type"     "xfer,fpstore")
5293    (set_attr "mode"     "SF")
5294    (set_attr "length"   "4")])
5296 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
5297 ;; of _gp from the start of this function.  Operand 1 is the incoming
5298 ;; function address.
5299 (define_insn_and_split "loadgp"
5300   [(unspec_volatile [(match_operand 0 "" "")
5301                      (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
5302   "TARGET_ABICALLS && TARGET_NEWABI"
5303   "#"
5304   ""
5305   [(set (match_dup 2) (match_dup 3))
5306    (set (match_dup 2) (match_dup 4))
5307    (set (match_dup 2) (match_dup 5))]
5309   operands[2] = pic_offset_table_rtx;
5310   operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
5311   operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
5312   operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
5314   [(set_attr "length" "12")])
5316 ;; The use of gp is hidden when not using explicit relocations.
5317 ;; This blockage instruction prevents the gp load from being
5318 ;; scheduled after an implicit use of gp.  It also prevents
5319 ;; the load from being deleted as dead.
5320 (define_insn "loadgp_blockage"
5321   [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
5322   ""
5323   ""
5324   [(set_attr "type"     "unknown")
5325    (set_attr "mode"     "none")
5326    (set_attr "length"   "0")])
5328 ;; Emit a .cprestore directive, which expands to a single store instruction.
5329 ;; Note that we continue to use .cprestore for explicit reloc code so that
5330 ;; jals inside inlines asms will work correctly.
5331 (define_insn "cprestore"
5332   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
5333                     UNSPEC_CPRESTORE)]
5334   ""
5335   ".cprestore\t%0"
5336   [(set_attr "type" "store")
5337    (set_attr "length" "4")])
5339 ;; Block moves, see mips.c for more details.
5340 ;; Argument 0 is the destination
5341 ;; Argument 1 is the source
5342 ;; Argument 2 is the length
5343 ;; Argument 3 is the alignment
5345 (define_expand "movstrsi"
5346   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
5347                    (match_operand:BLK 1 "general_operand" ""))
5348               (use (match_operand:SI 2 "" ""))
5349               (use (match_operand:SI 3 "const_int_operand" ""))])]
5350   "!TARGET_MIPS16 && !TARGET_MEMCPY"
5352   if (mips_expand_block_move (operands[0], operands[1], operands[2]))
5353     DONE;
5354   else
5355     FAIL;
5359 ;;  ....................
5361 ;;      SHIFTS
5363 ;;  ....................
5365 ;; Many of these instructions use trivial define_expands, because we
5366 ;; want to use a different set of constraints when TARGET_MIPS16.
5368 (define_expand "ashlsi3"
5369   [(set (match_operand:SI 0 "register_operand" "=d")
5370         (ashift:SI (match_operand:SI 1 "register_operand" "d")
5371                    (match_operand:SI 2 "arith_operand" "dI")))]
5372   ""
5374   /* On the mips16, a shift of more than 8 is a four byte instruction,
5375      so, for a shift between 8 and 16, it is just as fast to do two
5376      shifts of 8 or less.  If there is a lot of shifting going on, we
5377      may win in CSE.  Otherwise combine will put the shifts back
5378      together again.  This can be called by function_arg, so we must
5379      be careful not to allocate a new register if we've reached the
5380      reload pass.  */
5381   if (TARGET_MIPS16
5382       && optimize
5383       && GET_CODE (operands[2]) == CONST_INT
5384       && INTVAL (operands[2]) > 8
5385       && INTVAL (operands[2]) <= 16
5386       && ! reload_in_progress
5387       && ! reload_completed)
5388     {
5389       rtx temp = gen_reg_rtx (SImode);
5391       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
5392       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
5393                                         GEN_INT (INTVAL (operands[2]) - 8)));
5394       DONE;
5395     }
5398 (define_insn "ashlsi3_internal1"
5399   [(set (match_operand:SI 0 "register_operand" "=d")
5400         (ashift:SI (match_operand:SI 1 "register_operand" "d")
5401                    (match_operand:SI 2 "arith_operand" "dI")))]
5402   "!TARGET_MIPS16"
5404   if (GET_CODE (operands[2]) == CONST_INT)
5405     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5407   return "sll\t%0,%1,%2";
5409   [(set_attr "type"     "arith")
5410    (set_attr "mode"     "SI")])
5412 (define_insn "ashlsi3_internal1_extend"
5413   [(set (match_operand:DI 0 "register_operand" "=d")
5414        (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
5415                                   (match_operand:SI 2 "arith_operand" "dI"))))]
5416   "TARGET_64BIT && !TARGET_MIPS16"
5418   if (GET_CODE (operands[2]) == CONST_INT)
5419     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5421   return "sll\t%0,%1,%2";
5423   [(set_attr "type"    "arith")
5424    (set_attr "mode"    "DI")])
5427 (define_insn "ashlsi3_internal2"
5428   [(set (match_operand:SI 0 "register_operand" "=d,d")
5429         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
5430                    (match_operand:SI 2 "arith_operand" "d,I")))]
5431   "TARGET_MIPS16"
5433   if (which_alternative == 0)
5434     return "sll\t%0,%2";
5436   if (GET_CODE (operands[2]) == CONST_INT)
5437     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5439   return "sll\t%0,%1,%2";
5441   [(set_attr "type"     "arith")
5442    (set_attr "mode"     "SI")
5443    (set_attr_alternative "length"
5444                 [(const_int 4)
5445                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
5446                                (const_int 4)
5447                                (const_int 8))])])
5449 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5451 (define_split
5452   [(set (match_operand:SI 0 "register_operand" "")
5453         (ashift:SI (match_operand:SI 1 "register_operand" "")
5454                    (match_operand:SI 2 "const_int_operand" "")))]
5455   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5456    && GET_CODE (operands[2]) == CONST_INT
5457    && INTVAL (operands[2]) > 8
5458    && INTVAL (operands[2]) <= 16"
5459   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
5460    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
5461   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5463 (define_expand "ashldi3"
5464   [(parallel [(set (match_operand:DI 0 "register_operand" "")
5465                    (ashift:DI (match_operand:DI 1 "register_operand" "")
5466                               (match_operand:SI 2 "arith_operand" "")))
5467               (clobber (match_dup  3))])]
5468   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
5470   if (TARGET_64BIT)
5471     {
5472       /* On the mips16, a shift of more than 8 is a four byte
5473          instruction, so, for a shift between 8 and 16, it is just as
5474          fast to do two shifts of 8 or less.  If there is a lot of
5475          shifting going on, we may win in CSE.  Otherwise combine will
5476          put the shifts back together again.  This can be called by
5477          function_arg, so we must be careful not to allocate a new
5478          register if we've reached the reload pass.  */
5479       if (TARGET_MIPS16
5480           && optimize
5481           && GET_CODE (operands[2]) == CONST_INT
5482           && INTVAL (operands[2]) > 8
5483           && INTVAL (operands[2]) <= 16
5484           && ! reload_in_progress
5485           && ! reload_completed)
5486         {
5487           rtx temp = gen_reg_rtx (DImode);
5489           emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
5490           emit_insn (gen_ashldi3_internal4 (operands[0], temp,
5491                                             GEN_INT (INTVAL (operands[2]) - 8)));
5492           DONE;
5493         }
5495       emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
5496                                         operands[2]));
5497       DONE;
5498     }
5500   operands[3] = gen_reg_rtx (SImode);
5504 (define_insn "ashldi3_internal"
5505   [(set (match_operand:DI 0 "register_operand" "=&d")
5506         (ashift:DI (match_operand:DI 1 "register_operand" "d")
5507                    (match_operand:SI 2 "register_operand" "d")))
5508    (clobber (match_operand:SI 3 "register_operand" "=d"))]
5509   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
5510   "sll\t%3,%2,26\;\
5511 bgez\t%3,1f%#\;\
5512 sll\t%M0,%L1,%2\;\
5513 %(b\t3f\;\
5514 move\t%L0,%.%)\
5515 \n\n\
5516 %~1:\;\
5517 %(beq\t%3,%.,2f\;\
5518 sll\t%M0,%M1,%2%)\
5519 \n\;\
5520 subu\t%3,%.,%2\;\
5521 srl\t%3,%L1,%3\;\
5522 or\t%M0,%M0,%3\n\
5523 %~2:\;\
5524 sll\t%L0,%L1,%2\n\
5525 %~3:"
5526   [(set_attr "type"     "darith")
5527    (set_attr "mode"     "SI")
5528    (set_attr "length"   "48")])
5531 (define_insn "ashldi3_internal2"
5532   [(set (match_operand:DI 0 "register_operand" "=d")
5533         (ashift:DI (match_operand:DI 1 "register_operand" "d")
5534                    (match_operand:SI 2 "small_int" "IJK")))
5535    (clobber (match_operand:SI 3 "register_operand" "=d"))]
5536   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5537    && (INTVAL (operands[2]) & 32) != 0"
5539   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5540   return "sll\t%M0,%L1,%2\;move\t%L0,%.";
5542   [(set_attr "type"     "darith")
5543    (set_attr "mode"     "DI")
5544    (set_attr "length"   "8")])
5547 (define_split
5548   [(set (match_operand:DI 0 "register_operand" "")
5549         (ashift:DI (match_operand:DI 1 "register_operand" "")
5550                    (match_operand:SI 2 "small_int" "")))
5551    (clobber (match_operand:SI 3 "register_operand" ""))]
5552   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5553    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5554    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5555    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5556    && (INTVAL (operands[2]) & 32) != 0"
5558   [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
5559    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
5561   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
5564 (define_split
5565   [(set (match_operand:DI 0 "register_operand" "")
5566         (ashift:DI (match_operand:DI 1 "register_operand" "")
5567                    (match_operand:SI 2 "small_int" "")))
5568    (clobber (match_operand:SI 3 "register_operand" ""))]
5569   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5570    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5571    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5572    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5573    && (INTVAL (operands[2]) & 32) != 0"
5575   [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
5576    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
5578   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
5581 (define_insn "ashldi3_internal3"
5582   [(set (match_operand:DI 0 "register_operand" "=d")
5583         (ashift:DI (match_operand:DI 1 "register_operand" "d")
5584                    (match_operand:SI 2 "small_int" "IJK")))
5585    (clobber (match_operand:SI 3 "register_operand" "=d"))]
5586   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5587    && (INTVAL (operands[2]) & 63) < 32
5588    && (INTVAL (operands[2]) & 63) != 0"
5590   int amount = INTVAL (operands[2]);
5592   operands[2] = GEN_INT (amount & 31);
5593   operands[4] = GEN_INT ((-amount) & 31);
5595   return "sll\t%M0,%M1,%2\;srl\t%3,%L1,%4\;or\t%M0,%M0,%3\;sll\t%L0,%L1,%2";
5597   [(set_attr "type"     "darith")
5598    (set_attr "mode"     "DI")
5599    (set_attr "length"   "16")])
5602 (define_split
5603   [(set (match_operand:DI 0 "register_operand" "")
5604         (ashift:DI (match_operand:DI 1 "register_operand" "")
5605                    (match_operand:SI 2 "small_int" "")))
5606    (clobber (match_operand:SI 3 "register_operand" ""))]
5607   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5608    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5609    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5610    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5611    && (INTVAL (operands[2]) & 63) < 32
5612    && (INTVAL (operands[2]) & 63) != 0"
5614   [(set (subreg:SI (match_dup 0) 4)
5615         (ashift:SI (subreg:SI (match_dup 1) 4)
5616                    (match_dup 2)))
5618    (set (match_dup 3)
5619         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
5620                      (match_dup 4)))
5622    (set (subreg:SI (match_dup 0) 4)
5623         (ior:SI (subreg:SI (match_dup 0) 4)
5624                 (match_dup 3)))
5626    (set (subreg:SI (match_dup 0) 0)
5627         (ashift:SI (subreg:SI (match_dup 1) 0)
5628                    (match_dup 2)))]
5630   int amount = INTVAL (operands[2]);
5631   operands[2] = GEN_INT (amount & 31);
5632   operands[4] = GEN_INT ((-amount) & 31);
5636 (define_split
5637   [(set (match_operand:DI 0 "register_operand" "")
5638         (ashift:DI (match_operand:DI 1 "register_operand" "")
5639                    (match_operand:SI 2 "small_int" "")))
5640    (clobber (match_operand:SI 3 "register_operand" ""))]
5641   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5642    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5643    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5644    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5645    && (INTVAL (operands[2]) & 63) < 32
5646    && (INTVAL (operands[2]) & 63) != 0"
5648   [(set (subreg:SI (match_dup 0) 0)
5649         (ashift:SI (subreg:SI (match_dup 1) 0)
5650                    (match_dup 2)))
5652    (set (match_dup 3)
5653         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
5654                      (match_dup 4)))
5656    (set (subreg:SI (match_dup 0) 0)
5657         (ior:SI (subreg:SI (match_dup 0) 0)
5658                 (match_dup 3)))
5660    (set (subreg:SI (match_dup 0) 4)
5661         (ashift:SI (subreg:SI (match_dup 1) 4)
5662                    (match_dup 2)))]
5664   int amount = INTVAL (operands[2]);
5665   operands[2] = GEN_INT (amount & 31);
5666   operands[4] = GEN_INT ((-amount) & 31);
5670 (define_insn "ashldi3_internal4"
5671   [(set (match_operand:DI 0 "register_operand" "=d")
5672         (ashift:DI (match_operand:DI 1 "register_operand" "d")
5673                    (match_operand:SI 2 "arith_operand" "dI")))]
5674   "TARGET_64BIT && !TARGET_MIPS16"
5676   if (GET_CODE (operands[2]) == CONST_INT)
5677     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5679   return "dsll\t%0,%1,%2";
5681   [(set_attr "type"     "arith")
5682    (set_attr "mode"     "DI")])
5684 (define_insn ""
5685   [(set (match_operand:DI 0 "register_operand" "=d,d")
5686         (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
5687                    (match_operand:SI 2 "arith_operand" "d,I")))]
5688   "TARGET_64BIT && TARGET_MIPS16"
5690   if (which_alternative == 0)
5691     return "dsll\t%0,%2";
5693   if (GET_CODE (operands[2]) == CONST_INT)
5694     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5696   return "dsll\t%0,%1,%2";
5698   [(set_attr "type"     "arith")
5699    (set_attr "mode"     "DI")
5700    (set_attr_alternative "length"
5701                 [(const_int 4)
5702                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
5703                                (const_int 4)
5704                                (const_int 8))])])
5707 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5709 (define_split
5710   [(set (match_operand:DI 0 "register_operand" "")
5711         (ashift:DI (match_operand:DI 1 "register_operand" "")
5712                    (match_operand:SI 2 "const_int_operand" "")))]
5713   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5714    && reload_completed
5715    && GET_CODE (operands[2]) == CONST_INT
5716    && INTVAL (operands[2]) > 8
5717    && INTVAL (operands[2]) <= 16"
5718   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
5719    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
5720   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5722 (define_expand "ashrsi3"
5723   [(set (match_operand:SI 0 "register_operand" "=d")
5724         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5725                      (match_operand:SI 2 "arith_operand" "dI")))]
5726   ""
5728   /* On the mips16, a shift of more than 8 is a four byte instruction,
5729      so, for a shift between 8 and 16, it is just as fast to do two
5730      shifts of 8 or less.  If there is a lot of shifting going on, we
5731      may win in CSE.  Otherwise combine will put the shifts back
5732      together again.  */
5733   if (TARGET_MIPS16
5734       && optimize
5735       && GET_CODE (operands[2]) == CONST_INT
5736       && INTVAL (operands[2]) > 8
5737       && INTVAL (operands[2]) <= 16)
5738     {
5739       rtx temp = gen_reg_rtx (SImode);
5741       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5742       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
5743                                         GEN_INT (INTVAL (operands[2]) - 8)));
5744       DONE;
5745     }
5748 (define_insn "ashrsi3_internal1"
5749   [(set (match_operand:SI 0 "register_operand" "=d")
5750         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5751                      (match_operand:SI 2 "arith_operand" "dI")))]
5752   "!TARGET_MIPS16"
5754   if (GET_CODE (operands[2]) == CONST_INT)
5755     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5757   return "sra\t%0,%1,%2";
5759   [(set_attr "type"     "arith")
5760    (set_attr "mode"     "SI")])
5762 (define_insn "ashrsi3_internal2"
5763   [(set (match_operand:SI 0 "register_operand" "=d,d")
5764         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5765                      (match_operand:SI 2 "arith_operand" "d,I")))]
5766   "TARGET_MIPS16"
5768   if (which_alternative == 0)
5769     return "sra\t%0,%2";
5771   if (GET_CODE (operands[2]) == CONST_INT)
5772     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5774   return "sra\t%0,%1,%2";
5776   [(set_attr "type"     "arith")
5777    (set_attr "mode"     "SI")
5778    (set_attr_alternative "length"
5779                 [(const_int 4)
5780                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
5781                                (const_int 4)
5782                                (const_int 8))])])
5785 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5787 (define_split
5788   [(set (match_operand:SI 0 "register_operand" "")
5789         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
5790                      (match_operand:SI 2 "const_int_operand" "")))]
5791   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5792    && GET_CODE (operands[2]) == CONST_INT
5793    && INTVAL (operands[2]) > 8
5794    && INTVAL (operands[2]) <= 16"
5795   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
5796    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
5797   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5799 (define_expand "ashrdi3"
5800   [(parallel [(set (match_operand:DI 0 "register_operand" "")
5801                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5802                                 (match_operand:SI 2 "arith_operand" "")))
5803               (clobber (match_dup  3))])]
5804   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
5806   if (TARGET_64BIT)
5807     {
5808       /* On the mips16, a shift of more than 8 is a four byte
5809          instruction, so, for a shift between 8 and 16, it is just as
5810          fast to do two shifts of 8 or less.  If there is a lot of
5811          shifting going on, we may win in CSE.  Otherwise combine will
5812          put the shifts back together again.  */
5813       if (TARGET_MIPS16
5814           && optimize
5815           && GET_CODE (operands[2]) == CONST_INT
5816           && INTVAL (operands[2]) > 8
5817           && INTVAL (operands[2]) <= 16)
5818         {
5819           rtx temp = gen_reg_rtx (DImode);
5821           emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
5822           emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
5823                                             GEN_INT (INTVAL (operands[2]) - 8)));
5824           DONE;
5825         }
5827       emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
5828                                         operands[2]));
5829       DONE;
5830     }
5832   operands[3] = gen_reg_rtx (SImode);
5836 (define_insn "ashrdi3_internal"
5837   [(set (match_operand:DI 0 "register_operand" "=&d")
5838         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5839                      (match_operand:SI 2 "register_operand" "d")))
5840    (clobber (match_operand:SI 3 "register_operand" "=d"))]
5841   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
5842   "sll\t%3,%2,26\;\
5843 bgez\t%3,1f%#\;\
5844 sra\t%L0,%M1,%2\;\
5845 %(b\t3f\;\
5846 sra\t%M0,%M1,31%)\
5847 \n\n\
5848 %~1:\;\
5849 %(beq\t%3,%.,2f\;\
5850 srl\t%L0,%L1,%2%)\
5851 \n\;\
5852 subu\t%3,%.,%2\;\
5853 sll\t%3,%M1,%3\;\
5854 or\t%L0,%L0,%3\n\
5855 %~2:\;\
5856 sra\t%M0,%M1,%2\n\
5857 %~3:"
5858   [(set_attr "type"     "darith")
5859    (set_attr "mode"     "DI")
5860    (set_attr "length"   "48")])
5863 (define_insn "ashrdi3_internal2"
5864   [(set (match_operand:DI 0 "register_operand" "=d")
5865         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5866                      (match_operand:SI 2 "small_int" "IJK")))
5867    (clobber (match_operand:SI 3 "register_operand" "=d"))]
5868   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
5870   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5871   return "sra\t%L0,%M1,%2\;sra\t%M0,%M1,31";
5873   [(set_attr "type"     "darith")
5874    (set_attr "mode"     "DI")
5875    (set_attr "length"   "8")])
5878 (define_split
5879   [(set (match_operand:DI 0 "register_operand" "")
5880         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5881                      (match_operand:SI 2 "small_int" "")))
5882    (clobber (match_operand:SI 3 "register_operand" ""))]
5883   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5884    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5885    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5886    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5887    && (INTVAL (operands[2]) & 32) != 0"
5889   [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
5890    (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
5892   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
5895 (define_split
5896   [(set (match_operand:DI 0 "register_operand" "")
5897         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5898                      (match_operand:SI 2 "small_int" "")))
5899    (clobber (match_operand:SI 3 "register_operand" ""))]
5900   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5901    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5902    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5903    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5904    && (INTVAL (operands[2]) & 32) != 0"
5906   [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
5907    (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
5909   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
5912 (define_insn "ashrdi3_internal3"
5913   [(set (match_operand:DI 0 "register_operand" "=d")
5914         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5915                      (match_operand:SI 2 "small_int" "IJK")))
5916    (clobber (match_operand:SI 3 "register_operand" "=d"))]
5917   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5918    && (INTVAL (operands[2]) & 63) < 32
5919    && (INTVAL (operands[2]) & 63) != 0"
5921   int amount = INTVAL (operands[2]);
5923   operands[2] = GEN_INT (amount & 31);
5924   operands[4] = GEN_INT ((-amount) & 31);
5926   return "srl\t%L0,%L1,%2\;sll\t%3,%M1,%4\;or\t%L0,%L0,%3\;sra\t%M0,%M1,%2";
5928   [(set_attr "type"     "darith")
5929    (set_attr "mode"     "DI")
5930    (set_attr "length"   "16")])
5933 (define_split
5934   [(set (match_operand:DI 0 "register_operand" "")
5935         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5936                      (match_operand:SI 2 "small_int" "")))
5937    (clobber (match_operand:SI 3 "register_operand" ""))]
5938   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5939    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5940    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5941    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5942    && (INTVAL (operands[2]) & 63) < 32
5943    && (INTVAL (operands[2]) & 63) != 0"
5945   [(set (subreg:SI (match_dup 0) 0)
5946         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
5947                      (match_dup 2)))
5949    (set (match_dup 3)
5950         (ashift:SI (subreg:SI (match_dup 1) 4)
5951                    (match_dup 4)))
5953    (set (subreg:SI (match_dup 0) 0)
5954         (ior:SI (subreg:SI (match_dup 0) 0)
5955                 (match_dup 3)))
5957    (set (subreg:SI (match_dup 0) 4)
5958         (ashiftrt:SI (subreg:SI (match_dup 1) 4)
5959                      (match_dup 2)))]
5961   int amount = INTVAL (operands[2]);
5962   operands[2] = GEN_INT (amount & 31);
5963   operands[4] = GEN_INT ((-amount) & 31);
5967 (define_split
5968   [(set (match_operand:DI 0 "register_operand" "")
5969         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5970                      (match_operand:SI 2 "small_int" "")))
5971    (clobber (match_operand:SI 3 "register_operand" ""))]
5972   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5973    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5974    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5975    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5976    && (INTVAL (operands[2]) & 63) < 32
5977    && (INTVAL (operands[2]) & 63) != 0"
5979   [(set (subreg:SI (match_dup 0) 4)
5980         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
5981                      (match_dup 2)))
5983    (set (match_dup 3)
5984         (ashift:SI (subreg:SI (match_dup 1) 0)
5985                    (match_dup 4)))
5987    (set (subreg:SI (match_dup 0) 4)
5988         (ior:SI (subreg:SI (match_dup 0) 4)
5989                 (match_dup 3)))
5991    (set (subreg:SI (match_dup 0) 0)
5992         (ashiftrt:SI (subreg:SI (match_dup 1) 0)
5993                      (match_dup 2)))]
5995   int amount = INTVAL (operands[2]);
5996   operands[2] = GEN_INT (amount & 31);
5997   operands[4] = GEN_INT ((-amount) & 31);
6001 (define_insn "ashrdi3_internal4"
6002   [(set (match_operand:DI 0 "register_operand" "=d")
6003         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6004                      (match_operand:SI 2 "arith_operand" "dI")))]
6005   "TARGET_64BIT && !TARGET_MIPS16"
6007   if (GET_CODE (operands[2]) == CONST_INT)
6008     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6010   return "dsra\t%0,%1,%2";
6012   [(set_attr "type"     "arith")
6013    (set_attr "mode"     "DI")])
6015 (define_insn ""
6016   [(set (match_operand:DI 0 "register_operand" "=d,d")
6017         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
6018                      (match_operand:SI 2 "arith_operand" "d,I")))]
6019   "TARGET_64BIT && TARGET_MIPS16"
6021   if (GET_CODE (operands[2]) == CONST_INT)
6022     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6024   return "dsra\t%0,%2";
6026   [(set_attr "type"     "arith")
6027    (set_attr "mode"     "DI")
6028    (set_attr_alternative "length"
6029                 [(const_int 4)
6030                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6031                                (const_int 4)
6032                                (const_int 8))])])
6034 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6036 (define_split
6037   [(set (match_operand:DI 0 "register_operand" "")
6038         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6039                      (match_operand:SI 2 "const_int_operand" "")))]
6040   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
6041    && reload_completed
6042    && GET_CODE (operands[2]) == CONST_INT
6043    && INTVAL (operands[2]) > 8
6044    && INTVAL (operands[2]) <= 16"
6045   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
6046    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
6047   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
6049 (define_expand "lshrsi3"
6050   [(set (match_operand:SI 0 "register_operand" "=d")
6051         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
6052                      (match_operand:SI 2 "arith_operand" "dI")))]
6053   ""
6055   /* On the mips16, a shift of more than 8 is a four byte instruction,
6056      so, for a shift between 8 and 16, it is just as fast to do two
6057      shifts of 8 or less.  If there is a lot of shifting going on, we
6058      may win in CSE.  Otherwise combine will put the shifts back
6059      together again.  */
6060   if (TARGET_MIPS16
6061       && optimize
6062       && GET_CODE (operands[2]) == CONST_INT
6063       && INTVAL (operands[2]) > 8
6064       && INTVAL (operands[2]) <= 16)
6065     {
6066       rtx temp = gen_reg_rtx (SImode);
6068       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6069       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
6070                                         GEN_INT (INTVAL (operands[2]) - 8)));
6071       DONE;
6072     }
6075 (define_insn "lshrsi3_internal1"
6076   [(set (match_operand:SI 0 "register_operand" "=d")
6077         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
6078                      (match_operand:SI 2 "arith_operand" "dI")))]
6079   "!TARGET_MIPS16"
6081   if (GET_CODE (operands[2]) == CONST_INT)
6082     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6084   return "srl\t%0,%1,%2";
6086   [(set_attr "type"     "arith")
6087    (set_attr "mode"     "SI")])
6089 (define_insn "lshrsi3_internal2"
6090   [(set (match_operand:SI 0 "register_operand" "=d,d")
6091         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6092                      (match_operand:SI 2 "arith_operand" "d,I")))]
6093   "TARGET_MIPS16"
6095   if (which_alternative == 0)
6096     return "srl\t%0,%2";
6098   if (GET_CODE (operands[2]) == CONST_INT)
6099     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6101   return "srl\t%0,%1,%2";
6103   [(set_attr "type"     "arith")
6104    (set_attr "mode"     "SI")
6105    (set_attr_alternative "length"
6106                 [(const_int 4)
6107                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6108                                (const_int 4)
6109                                (const_int 8))])])
6112 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6114 (define_split
6115   [(set (match_operand:SI 0 "register_operand" "")
6116         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
6117                      (match_operand:SI 2 "const_int_operand" "")))]
6118   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6119    && GET_CODE (operands[2]) == CONST_INT
6120    && INTVAL (operands[2]) > 8
6121    && INTVAL (operands[2]) <= 16"
6122   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
6123    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
6124   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
6126 ;; If we load a byte on the mips16 as a bitfield, the resulting
6127 ;; sequence of instructions is too complicated for combine, because it
6128 ;; involves four instructions: a load, a shift, a constant load into a
6129 ;; register, and an and (the key problem here is that the mips16 does
6130 ;; not have and immediate).  We recognize a shift of a load in order
6131 ;; to make it simple enough for combine to understand.
6133 ;; The length here is the worst case: the length of the split version
6134 ;; will be more accurate. 
6135 (define_insn_and_split ""
6136   [(set (match_operand:SI 0 "register_operand" "=d")
6137         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6138                      (match_operand:SI 2 "immediate_operand" "I")))]
6139   "TARGET_MIPS16"
6140   "#"
6141   ""
6142   [(set (match_dup 0) (match_dup 1))
6143    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
6144   ""
6145   [(set_attr "type"     "load")
6146    (set_attr "mode"     "SI")
6147    (set_attr "length"   "16")])
6149 (define_expand "lshrdi3"
6150   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6151                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6152                                 (match_operand:SI 2 "arith_operand" "")))
6153               (clobber (match_dup  3))])]
6154   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6156   if (TARGET_64BIT)
6157     {
6158       /* On the mips16, a shift of more than 8 is a four byte
6159          instruction, so, for a shift between 8 and 16, it is just as
6160          fast to do two shifts of 8 or less.  If there is a lot of
6161          shifting going on, we may win in CSE.  Otherwise combine will
6162          put the shifts back together again.  */
6163       if (TARGET_MIPS16
6164           && optimize
6165           && GET_CODE (operands[2]) == CONST_INT
6166           && INTVAL (operands[2]) > 8
6167           && INTVAL (operands[2]) <= 16)
6168         {
6169           rtx temp = gen_reg_rtx (DImode);
6171           emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
6172           emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
6173                                             GEN_INT (INTVAL (operands[2]) - 8)));
6174           DONE;
6175         }
6177       emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
6178                                         operands[2]));
6179       DONE;
6180     }
6182   operands[3] = gen_reg_rtx (SImode);
6186 (define_insn "lshrdi3_internal"
6187   [(set (match_operand:DI 0 "register_operand" "=&d")
6188         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
6189                      (match_operand:SI 2 "register_operand" "d")))
6190    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6191   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6192   "sll\t%3,%2,26\;\
6193 bgez\t%3,1f%#\;\
6194 srl\t%L0,%M1,%2\;\
6195 %(b\t3f\;\
6196 move\t%M0,%.%)\
6197 \n\n\
6198 %~1:\;\
6199 %(beq\t%3,%.,2f\;\
6200 srl\t%L0,%L1,%2%)\
6201 \n\;\
6202 subu\t%3,%.,%2\;\
6203 sll\t%3,%M1,%3\;\
6204 or\t%L0,%L0,%3\n\
6205 %~2:\;\
6206 srl\t%M0,%M1,%2\n\
6207 %~3:"
6208   [(set_attr "type"     "darith")
6209    (set_attr "mode"     "DI")
6210    (set_attr "length"   "48")])
6213 (define_insn "lshrdi3_internal2"
6214   [(set (match_operand:DI 0 "register_operand" "=d")
6215         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
6216                      (match_operand:SI 2 "small_int" "IJK")))
6217    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6218   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6219    && (INTVAL (operands[2]) & 32) != 0"
6221   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6222   return "srl\t%L0,%M1,%2\;move\t%M0,%.";
6224   [(set_attr "type"     "darith")
6225    (set_attr "mode"     "DI")
6226    (set_attr "length"   "8")])
6229 (define_split
6230   [(set (match_operand:DI 0 "register_operand" "")
6231         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6232                      (match_operand:SI 2 "small_int" "")))
6233    (clobber (match_operand:SI 3 "register_operand" ""))]
6234   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6235    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6236    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6237    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6238    && (INTVAL (operands[2]) & 32) != 0"
6240   [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6241    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
6243   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6246 (define_split
6247   [(set (match_operand:DI 0 "register_operand" "")
6248         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6249                      (match_operand:SI 2 "small_int" "")))
6250    (clobber (match_operand:SI 3 "register_operand" ""))]
6251   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6252    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6253    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6254    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6255    && (INTVAL (operands[2]) & 32) != 0"
6257   [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6258    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6260   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6263 (define_insn "lshrdi3_internal3"
6264   [(set (match_operand:DI 0 "register_operand" "=d")
6265         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
6266                    (match_operand:SI 2 "small_int" "IJK")))
6267    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6268   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6269    && (INTVAL (operands[2]) & 63) < 32
6270    && (INTVAL (operands[2]) & 63) != 0"
6272   int amount = INTVAL (operands[2]);
6274   operands[2] = GEN_INT (amount & 31);
6275   operands[4] = GEN_INT ((-amount) & 31);
6277   return "srl\t%L0,%L1,%2\;sll\t%3,%M1,%4\;or\t%L0,%L0,%3\;srl\t%M0,%M1,%2";
6279   [(set_attr "type"     "darith")
6280    (set_attr "mode"     "DI")
6281    (set_attr "length"   "16")])
6284 (define_split
6285   [(set (match_operand:DI 0 "register_operand" "")
6286         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6287                      (match_operand:SI 2 "small_int" "")))
6288    (clobber (match_operand:SI 3 "register_operand" ""))]
6289   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6290    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6291    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6292    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6293    && (INTVAL (operands[2]) & 63) < 32
6294    && (INTVAL (operands[2]) & 63) != 0"
6296   [(set (subreg:SI (match_dup 0) 0)
6297         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6298                      (match_dup 2)))
6300    (set (match_dup 3)
6301         (ashift:SI (subreg:SI (match_dup 1) 4)
6302                    (match_dup 4)))
6304    (set (subreg:SI (match_dup 0) 0)
6305         (ior:SI (subreg:SI (match_dup 0) 0)
6306                 (match_dup 3)))
6308    (set (subreg:SI (match_dup 0) 4)
6309         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6310                      (match_dup 2)))]
6312   int amount = INTVAL (operands[2]);
6313   operands[2] = GEN_INT (amount & 31);
6314   operands[4] = GEN_INT ((-amount) & 31);
6318 (define_split
6319   [(set (match_operand:DI 0 "register_operand" "")
6320         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6321                      (match_operand:SI 2 "small_int" "")))
6322    (clobber (match_operand:SI 3 "register_operand" ""))]
6323   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6324    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6325    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6326    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6327    && (INTVAL (operands[2]) & 63) < 32
6328    && (INTVAL (operands[2]) & 63) != 0"
6330   [(set (subreg:SI (match_dup 0) 4)
6331         (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6332                      (match_dup 2)))
6334    (set (match_dup 3)
6335         (ashift:SI (subreg:SI (match_dup 1) 0)
6336                    (match_dup 4)))
6338    (set (subreg:SI (match_dup 0) 4)
6339         (ior:SI (subreg:SI (match_dup 0) 4)
6340                 (match_dup 3)))
6342    (set (subreg:SI (match_dup 0) 0)
6343         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6344                      (match_dup 2)))]
6346   int amount = INTVAL (operands[2]);
6347   operands[2] = GEN_INT (amount & 31);
6348   operands[4] = GEN_INT ((-amount) & 31);
6352 (define_insn "lshrdi3_internal4"
6353   [(set (match_operand:DI 0 "register_operand" "=d")
6354         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
6355                      (match_operand:SI 2 "arith_operand" "dI")))]
6356   "TARGET_64BIT && !TARGET_MIPS16"
6358   if (GET_CODE (operands[2]) == CONST_INT)
6359     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6361   return "dsrl\t%0,%1,%2";
6363   [(set_attr "type"     "arith")
6364    (set_attr "mode"     "DI")])
6366 (define_insn ""
6367   [(set (match_operand:DI 0 "register_operand" "=d,d")
6368         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
6369                      (match_operand:SI 2 "arith_operand" "d,I")))]
6370   "TARGET_64BIT && TARGET_MIPS16"
6372   if (GET_CODE (operands[2]) == CONST_INT)
6373     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6375   return "dsrl\t%0,%2";
6377   [(set_attr "type"     "arith")
6378    (set_attr "mode"     "DI")
6379    (set_attr_alternative "length"
6380                 [(const_int 4)
6381                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6382                                (const_int 4)
6383                                (const_int 8))])])
6385 (define_insn "rotrsi3"
6386   [(set (match_operand:SI              0 "register_operand" "=d")
6387         (rotatert:SI (match_operand:SI 1 "register_operand" "d")
6388                      (match_operand:SI 2 "arith_operand"    "dn")))]
6389   "ISA_HAS_ROTR_SI"
6391   if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
6392     return "rorv\t%0,%1,%2";
6394   if ((GET_CODE (operands[2]) == CONST_INT)
6395       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
6396     abort ();
6398   return "ror\t%0,%1,%2";
6400   [(set_attr "type"     "arith")
6401    (set_attr "mode"     "SI")])
6403 (define_insn "rotrdi3"
6404   [(set (match_operand:DI              0 "register_operand" "=d")
6405         (rotatert:DI (match_operand:DI 1 "register_operand" "d")
6406                      (match_operand:DI 2 "arith_operand"    "dn")))]
6407   "ISA_HAS_ROTR_DI"
6409   if (TARGET_SR71K)
6410     {
6411       if (GET_CODE (operands[2]) != CONST_INT)
6412         return "drorv\t%0,%1,%2";
6414       if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
6415         return "dror32\t%0,%1,%2";
6416     }
6418   if ((GET_CODE (operands[2]) == CONST_INT)
6419       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
6420     abort ();
6422   return "dror\t%0,%1,%2";
6424   [(set_attr "type"     "arith")
6425    (set_attr "mode"     "DI")])
6428 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6430 (define_split
6431   [(set (match_operand:DI 0 "register_operand" "")
6432         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6433                      (match_operand:SI 2 "const_int_operand" "")))]
6434   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6435    && GET_CODE (operands[2]) == CONST_INT
6436    && INTVAL (operands[2]) > 8
6437    && INTVAL (operands[2]) <= 16"
6438   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
6439    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
6440   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
6443 ;;  ....................
6445 ;;      COMPARISONS
6447 ;;  ....................
6449 ;; Flow here is rather complex:
6451 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the
6452 ;;      arguments into the branch_cmp array, and the type into
6453 ;;      branch_type.  No RTL is generated.
6455 ;;  2)  The appropriate branch define_expand is called, which then
6456 ;;      creates the appropriate RTL for the comparison and branch.
6457 ;;      Different CC modes are used, based on what type of branch is
6458 ;;      done, so that we can constrain things appropriately.  There
6459 ;;      are assumptions in the rest of GCC that break if we fold the
6460 ;;      operands into the branches for integer operations, and use cc0
6461 ;;      for floating point, so we use the fp status register instead.
6462 ;;      If needed, an appropriate temporary is created to hold the
6463 ;;      of the integer compare.
6465 (define_expand "cmpsi"
6466   [(set (cc0)
6467         (compare:CC (match_operand:SI 0 "register_operand" "")
6468                     (match_operand:SI 1 "arith_operand" "")))]
6469   ""
6471   branch_cmp[0] = operands[0];
6472   branch_cmp[1] = operands[1];
6473   branch_type = CMP_SI;
6474   DONE;
6477 (define_expand "cmpdi"
6478   [(set (cc0)
6479         (compare:CC (match_operand:DI 0 "register_operand" "")
6480                     (match_operand:DI 1 "arith_operand" "")))]
6481   "TARGET_64BIT"
6483   branch_cmp[0] = operands[0];
6484   branch_cmp[1] = operands[1];
6485   branch_type = CMP_DI;
6486   DONE;
6489 (define_expand "cmpdf"
6490   [(set (cc0)
6491         (compare:CC (match_operand:DF 0 "register_operand" "")
6492                     (match_operand:DF 1 "register_operand" "")))]
6493   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6495   branch_cmp[0] = operands[0];
6496   branch_cmp[1] = operands[1];
6497   branch_type = CMP_DF;
6498   DONE;
6501 (define_expand "cmpsf"
6502   [(set (cc0)
6503         (compare:CC (match_operand:SF 0 "register_operand" "")
6504                     (match_operand:SF 1 "register_operand" "")))]
6505   "TARGET_HARD_FLOAT"
6507   branch_cmp[0] = operands[0];
6508   branch_cmp[1] = operands[1];
6509   branch_type = CMP_SF;
6510   DONE;
6514 ;;  ....................
6516 ;;      CONDITIONAL BRANCHES
6518 ;;  ....................
6520 ;; Conditional branches on floating-point equality tests.
6522 (define_insn "branch_fp"
6523   [(set (pc)
6524         (if_then_else
6525          (match_operator:CC 0 "cmp_op"
6526                             [(match_operand:CC 2 "register_operand" "z")
6527                              (const_int 0)])
6528          (label_ref (match_operand 1 "" ""))
6529          (pc)))]
6530   "TARGET_HARD_FLOAT"
6532   return mips_output_conditional_branch (insn,
6533                                          operands,
6534                                          /*two_operands_p=*/0,
6535                                          /*float_p=*/1,
6536                                          /*inverted_p=*/0,
6537                                          get_attr_length (insn));
6539   [(set_attr "type"     "branch")
6540    (set_attr "mode"     "none")])
6542 (define_insn "branch_fp_inverted"
6543   [(set (pc)
6544         (if_then_else
6545          (match_operator:CC 0 "cmp_op"
6546                             [(match_operand:CC 2 "register_operand" "z")
6547                              (const_int 0)])
6548          (pc)
6549          (label_ref (match_operand 1 "" ""))))]
6550   "TARGET_HARD_FLOAT"
6552   return mips_output_conditional_branch (insn,
6553                                          operands,
6554                                          /*two_operands_p=*/0,
6555                                          /*float_p=*/1,
6556                                          /*inverted_p=*/1,
6557                                          get_attr_length (insn));
6559   [(set_attr "type"     "branch")
6560    (set_attr "mode"     "none")])
6562 ;; Conditional branches on comparisons with zero.
6564 (define_insn "branch_zero"
6565   [(set (pc)
6566         (if_then_else
6567          (match_operator:SI 0 "cmp_op"
6568                             [(match_operand:SI 2 "register_operand" "d")
6569                              (const_int 0)])
6570         (label_ref (match_operand 1 "" ""))
6571         (pc)))]
6572   "!TARGET_MIPS16"
6574   return mips_output_conditional_branch (insn,
6575                                          operands,
6576                                          /*two_operands_p=*/0,
6577                                          /*float_p=*/0,
6578                                          /*inverted_p=*/0,
6579                                          get_attr_length (insn));
6581   [(set_attr "type"     "branch")
6582    (set_attr "mode"     "none")])
6584 (define_insn "branch_zero_inverted"
6585   [(set (pc)
6586         (if_then_else
6587          (match_operator:SI 0 "cmp_op"
6588                             [(match_operand:SI 2 "register_operand" "d")
6589                              (const_int 0)])
6590         (pc)
6591         (label_ref (match_operand 1 "" ""))))]
6592   "!TARGET_MIPS16"
6594   return mips_output_conditional_branch (insn,
6595                                          operands,
6596                                          /*two_operands_p=*/0,
6597                                          /*float_p=*/0,
6598                                          /*inverted_p=*/1,
6599                                          get_attr_length (insn));
6601   [(set_attr "type"     "branch")
6602    (set_attr "mode"     "none")])
6604 (define_insn "branch_zero_di"
6605   [(set (pc)
6606         (if_then_else
6607          (match_operator:DI 0 "cmp_op"
6608                             [(match_operand:DI 2 "register_operand" "d")
6609                              (const_int 0)])
6610         (label_ref (match_operand 1 "" ""))
6611         (pc)))]
6612   "!TARGET_MIPS16"
6614   return mips_output_conditional_branch (insn,
6615                                          operands,
6616                                          /*two_operands_p=*/0,
6617                                          /*float_p=*/0,
6618                                          /*inverted_p=*/0,
6619                                          get_attr_length (insn));
6621   [(set_attr "type"     "branch")
6622    (set_attr "mode"     "none")])
6624 (define_insn "branch_zero_di_inverted"
6625   [(set (pc)
6626         (if_then_else
6627          (match_operator:DI 0 "cmp_op"
6628                             [(match_operand:DI 2 "register_operand" "d")
6629                              (const_int 0)])
6630         (pc)
6631         (label_ref (match_operand 1 "" ""))))]
6632   "!TARGET_MIPS16"
6634   return mips_output_conditional_branch (insn,
6635                                          operands,
6636                                          /*two_operands_p=*/0,
6637                                          /*float_p=*/0,
6638                                          /*inverted_p=*/1,
6639                                          get_attr_length (insn));
6641   [(set_attr "type"     "branch")
6642    (set_attr "mode"     "none")])
6644 ;; Conditional branch on equality comparison.
6646 (define_insn "branch_equality"
6647   [(set (pc)
6648         (if_then_else
6649          (match_operator:SI 0 "equality_op"
6650                             [(match_operand:SI 2 "register_operand" "d")
6651                              (match_operand:SI 3 "register_operand" "d")])
6652          (label_ref (match_operand 1 "" ""))
6653          (pc)))]
6654   "!TARGET_MIPS16"
6656   return mips_output_conditional_branch (insn,
6657                                          operands,
6658                                          /*two_operands_p=*/1,
6659                                          /*float_p=*/0,
6660                                          /*inverted_p=*/0,
6661                                          get_attr_length (insn));
6663   [(set_attr "type"     "branch")
6664    (set_attr "mode"     "none")])
6666 (define_insn "branch_equality_di"
6667   [(set (pc)
6668         (if_then_else
6669          (match_operator:DI 0 "equality_op"
6670                             [(match_operand:DI 2 "register_operand" "d")
6671                              (match_operand:DI 3 "register_operand" "d")])
6672         (label_ref (match_operand 1 "" ""))
6673         (pc)))]
6674   "!TARGET_MIPS16"
6676   return mips_output_conditional_branch (insn,
6677                                          operands,
6678                                          /*two_operands_p=*/1,
6679                                          /*float_p=*/0,
6680                                          /*inverted_p=*/0,
6681                                          get_attr_length (insn));
6683   [(set_attr "type"     "branch")
6684    (set_attr "mode"     "none")])
6686 (define_insn "branch_equality_inverted"
6687   [(set (pc)
6688         (if_then_else
6689          (match_operator:SI 0 "equality_op"
6690                             [(match_operand:SI 2 "register_operand" "d")
6691                              (match_operand:SI 3 "register_operand" "d")])
6692          (pc)
6693          (label_ref (match_operand 1 "" ""))))]
6694   "!TARGET_MIPS16"
6696   return mips_output_conditional_branch (insn,
6697                                          operands,
6698                                          /*two_operands_p=*/1,
6699                                          /*float_p=*/0,
6700                                          /*inverted_p=*/1,
6701                                          get_attr_length (insn));
6703   [(set_attr "type"     "branch")
6704    (set_attr "mode"     "none")])
6706 (define_insn "branch_equality_di_inverted"
6707   [(set (pc)
6708         (if_then_else
6709          (match_operator:DI 0 "equality_op"
6710                             [(match_operand:DI 2 "register_operand" "d")
6711                              (match_operand:DI 3 "register_operand" "d")])
6712         (pc)
6713         (label_ref (match_operand 1 "" ""))))]
6714   "!TARGET_MIPS16"
6716   return mips_output_conditional_branch (insn,
6717                                          operands,
6718                                          /*two_operands_p=*/1,
6719                                          /*float_p=*/0,
6720                                          /*inverted_p=*/1,
6721                                          get_attr_length (insn));
6723   [(set_attr "type"     "branch")
6724    (set_attr "mode"     "none")])
6726 ;; MIPS16 branches
6728 (define_insn ""
6729   [(set (pc)
6730         (if_then_else (match_operator:SI 0 "equality_op"
6731                                          [(match_operand:SI 1 "register_operand" "d,t")
6732                                           (const_int 0)])
6733         (match_operand 2 "pc_or_label_operand" "")
6734         (match_operand 3 "pc_or_label_operand" "")))]
6735   "TARGET_MIPS16"
6737   if (operands[2] != pc_rtx)
6738     {
6739       if (which_alternative == 0)
6740         return "b%C0z\t%1,%2";
6741       else
6742         return "bt%C0z\t%2";
6743     }
6744   else
6745     {
6746       if (which_alternative == 0)
6747         return "b%N0z\t%1,%3";
6748       else
6749         return "bt%N0z\t%3";
6750     }
6752   [(set_attr "type"     "branch")
6753    (set_attr "mode"     "none")
6754    (set_attr "length"   "8")])
6756 (define_insn ""
6757   [(set (pc)
6758         (if_then_else (match_operator:DI 0 "equality_op"
6759                                          [(match_operand:DI 1 "register_operand" "d,t")
6760                                           (const_int 0)])
6761         (match_operand 2 "pc_or_label_operand" "")
6762         (match_operand 3 "pc_or_label_operand" "")))]
6763   "TARGET_MIPS16"
6765   if (operands[2] != pc_rtx)
6766     {
6767       if (which_alternative == 0)
6768         return "b%C0z\t%1,%2";
6769       else
6770         return "bt%C0z\t%2";
6771     }
6772   else
6773     {
6774       if (which_alternative == 0)
6775         return "b%N0z\t%1,%3";
6776       else
6777         return "bt%N0z\t%3";
6778     }
6780   [(set_attr "type"     "branch")
6781    (set_attr "mode"     "none")
6782    (set_attr "length"   "8")])
6784 (define_expand "bunordered"
6785   [(set (pc)
6786         (if_then_else (unordered:CC (cc0)
6787                                     (const_int 0))
6788                       (label_ref (match_operand 0 "" ""))
6789                       (pc)))]
6790   ""
6792   gen_conditional_branch (operands, UNORDERED);
6793   DONE;
6796 (define_expand "bordered"
6797   [(set (pc)
6798         (if_then_else (ordered:CC (cc0)
6799                                   (const_int 0))
6800                       (label_ref (match_operand 0 "" ""))
6801                       (pc)))]
6802   ""
6804   gen_conditional_branch (operands, ORDERED);
6805   DONE;
6808 (define_expand "bunlt"
6809   [(set (pc)
6810         (if_then_else (unlt:CC (cc0)
6811                                (const_int 0))
6812                       (label_ref (match_operand 0 "" ""))
6813                       (pc)))]
6814   ""
6816   gen_conditional_branch (operands, UNLT);
6817   DONE;
6820 (define_expand "bunge"
6821   [(set (pc)
6822         (if_then_else (unge:CC (cc0)
6823                                (const_int 0))
6824                       (label_ref (match_operand 0 "" ""))
6825                       (pc)))]
6826   ""
6828   gen_conditional_branch (operands, UNGE);
6829   DONE;
6832 (define_expand "buneq"
6833   [(set (pc)
6834         (if_then_else (uneq:CC (cc0)
6835                                (const_int 0))
6836                       (label_ref (match_operand 0 "" ""))
6837                       (pc)))]
6838   ""
6840   gen_conditional_branch (operands, UNEQ);
6841   DONE;
6844 (define_expand "bltgt"
6845   [(set (pc)
6846         (if_then_else (ltgt:CC (cc0)
6847                                (const_int 0))
6848                       (label_ref (match_operand 0 "" ""))
6849                       (pc)))]
6850   ""
6852   gen_conditional_branch (operands, LTGT);
6853   DONE;
6856 (define_expand "bunle"
6857   [(set (pc)
6858         (if_then_else (unle:CC (cc0)
6859                                (const_int 0))
6860                       (label_ref (match_operand 0 "" ""))
6861                       (pc)))]
6862   ""
6864   gen_conditional_branch (operands, UNLE);
6865   DONE;
6868 (define_expand "bungt"
6869   [(set (pc)
6870         (if_then_else (ungt:CC (cc0)
6871                                (const_int 0))
6872                       (label_ref (match_operand 0 "" ""))
6873                       (pc)))]
6874   ""
6876   gen_conditional_branch (operands, UNGT);
6877   DONE;
6880 (define_expand "beq"
6881   [(set (pc)
6882         (if_then_else (eq:CC (cc0)
6883                              (const_int 0))
6884                       (label_ref (match_operand 0 "" ""))
6885                       (pc)))]
6886   ""
6888   gen_conditional_branch (operands, EQ);
6889   DONE;
6892 (define_expand "bne"
6893   [(set (pc)
6894         (if_then_else (ne:CC (cc0)
6895                              (const_int 0))
6896                       (label_ref (match_operand 0 "" ""))
6897                       (pc)))]
6898   ""
6900   gen_conditional_branch (operands, NE);
6901   DONE;
6904 (define_expand "bgt"
6905   [(set (pc)
6906         (if_then_else (gt:CC (cc0)
6907                              (const_int 0))
6908                       (label_ref (match_operand 0 "" ""))
6909                       (pc)))]
6910   ""
6912   gen_conditional_branch (operands, GT);
6913   DONE;
6916 (define_expand "bge"
6917   [(set (pc)
6918         (if_then_else (ge:CC (cc0)
6919                              (const_int 0))
6920                       (label_ref (match_operand 0 "" ""))
6921                       (pc)))]
6922   ""
6924   gen_conditional_branch (operands, GE);
6925   DONE;
6928 (define_expand "blt"
6929   [(set (pc)
6930         (if_then_else (lt:CC (cc0)
6931                              (const_int 0))
6932                       (label_ref (match_operand 0 "" ""))
6933                       (pc)))]
6934   ""
6936   gen_conditional_branch (operands, LT);
6937   DONE;
6940 (define_expand "ble"
6941   [(set (pc)
6942         (if_then_else (le:CC (cc0)
6943                              (const_int 0))
6944                       (label_ref (match_operand 0 "" ""))
6945                       (pc)))]
6946   ""
6948   gen_conditional_branch (operands, LE);
6949   DONE;
6952 (define_expand "bgtu"
6953   [(set (pc)
6954         (if_then_else (gtu:CC (cc0)
6955                               (const_int 0))
6956                       (label_ref (match_operand 0 "" ""))
6957                       (pc)))]
6958   ""
6960   gen_conditional_branch (operands, GTU);
6961   DONE;
6964 (define_expand "bgeu"
6965   [(set (pc)
6966         (if_then_else (geu:CC (cc0)
6967                               (const_int 0))
6968                       (label_ref (match_operand 0 "" ""))
6969                       (pc)))]
6970   ""
6972   gen_conditional_branch (operands, GEU);
6973   DONE;
6976 (define_expand "bltu"
6977   [(set (pc)
6978         (if_then_else (ltu:CC (cc0)
6979                               (const_int 0))
6980                       (label_ref (match_operand 0 "" ""))
6981                       (pc)))]
6982   ""
6984   gen_conditional_branch (operands, LTU);
6985   DONE;
6988 (define_expand "bleu"
6989   [(set (pc)
6990         (if_then_else (leu:CC (cc0)
6991                               (const_int 0))
6992                       (label_ref (match_operand 0 "" ""))
6993                       (pc)))]
6994   ""
6996   gen_conditional_branch (operands, LEU);
6997   DONE;
7001 ;;  ....................
7003 ;;      SETTING A REGISTER FROM A COMPARISON
7005 ;;  ....................
7007 (define_expand "seq"
7008   [(set (match_operand:SI 0 "register_operand" "=d")
7009         (eq:SI (match_dup 1)
7010                (match_dup 2)))]
7011   ""
7013   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7014     FAIL;
7016   /* Set up operands from compare.  */
7017   operands[1] = branch_cmp[0];
7018   operands[2] = branch_cmp[1];
7020   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7021     {
7022       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
7023       DONE;
7024     }
7026   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
7027     operands[2] = force_reg (SImode, operands[2]);
7029   /* Fall through and generate default code.  */
7033 (define_insn "seq_si_zero"
7034   [(set (match_operand:SI 0 "register_operand" "=d")
7035         (eq:SI (match_operand:SI 1 "register_operand" "d")
7036                (const_int 0)))]
7037   "!TARGET_MIPS16"
7038   "sltu\t%0,%1,1"
7039   [(set_attr "type"     "arith")
7040    (set_attr "mode"     "SI")])
7042 (define_insn ""
7043   [(set (match_operand:SI 0 "register_operand" "=t")
7044         (eq:SI (match_operand:SI 1 "register_operand" "d")
7045                (const_int 0)))]
7046   "TARGET_MIPS16"
7047   "sltu\t%1,1"
7048   [(set_attr "type"     "arith")
7049    (set_attr "mode"     "SI")])
7051 (define_insn "seq_di_zero"
7052   [(set (match_operand:DI 0 "register_operand" "=d")
7053         (eq:DI (match_operand:DI 1 "register_operand" "d")
7054                (const_int 0)))]
7055   "TARGET_64BIT && !TARGET_MIPS16"
7056   "sltu\t%0,%1,1"
7057   [(set_attr "type"     "arith")
7058    (set_attr "mode"     "DI")])
7060 (define_insn ""
7061   [(set (match_operand:DI 0 "register_operand" "=t")
7062         (eq:DI (match_operand:DI 1 "register_operand" "d")
7063                (const_int 0)))]
7064   "TARGET_64BIT && TARGET_MIPS16"
7065   "sltu\t%1,1"
7066   [(set_attr "type"     "arith")
7067    (set_attr "mode"     "DI")])
7069 (define_insn "seq_si"
7070   [(set (match_operand:SI 0 "register_operand" "=d,d")
7071         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
7072                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
7073   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7074   "@
7075    xor\t%0,%1,%2\;sltu\t%0,%0,1
7076    xori\t%0,%1,%2\;sltu\t%0,%0,1"
7077   [(set_attr "type"     "arith")
7078    (set_attr "mode"     "SI")
7079    (set_attr "length"   "8")])
7081 (define_split
7082   [(set (match_operand:SI 0 "register_operand" "")
7083         (eq:SI (match_operand:SI 1 "register_operand" "")
7084                (match_operand:SI 2 "uns_arith_operand" "")))]
7085   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
7086     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
7087   [(set (match_dup 0)
7088         (xor:SI (match_dup 1)
7089                 (match_dup 2)))
7090    (set (match_dup 0)
7091         (ltu:SI (match_dup 0)
7092                 (const_int 1)))]
7093   "")
7095 (define_insn "seq_di"
7096   [(set (match_operand:DI 0 "register_operand" "=d,d")
7097         (eq:DI (match_operand:DI 1 "register_operand" "%d,d")
7098                (match_operand:DI 2 "uns_arith_operand" "d,K")))]
7099   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7100   "@
7101    xor\t%0,%1,%2\;sltu\t%0,%0,1
7102    xori\t%0,%1,%2\;sltu\t%0,%0,1"
7103   [(set_attr "type"     "arith")
7104    (set_attr "mode"     "DI")
7105    (set_attr "length"   "8")])
7107 (define_split
7108   [(set (match_operand:DI 0 "register_operand" "")
7109         (eq:DI (match_operand:DI 1 "register_operand" "")
7110                (match_operand:DI 2 "uns_arith_operand" "")))]
7111   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7112     && !TARGET_MIPS16
7113     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
7114   [(set (match_dup 0)
7115         (xor:DI (match_dup 1)
7116                 (match_dup 2)))
7117    (set (match_dup 0)
7118         (ltu:DI (match_dup 0)
7119                 (const_int 1)))]
7120   "")
7122 ;; On the mips16 the default code is better than using sltu.
7124 (define_expand "sne"
7125   [(set (match_operand:SI 0 "register_operand" "=d")
7126         (ne:SI (match_dup 1)
7127                (match_dup 2)))]
7128   "!TARGET_MIPS16"
7130   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7131     FAIL;
7133   /* Set up operands from compare.  */
7134   operands[1] = branch_cmp[0];
7135   operands[2] = branch_cmp[1];
7137   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
7138     {
7139       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
7140       DONE;
7141     }
7143   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
7144     operands[2] = force_reg (SImode, operands[2]);
7146   /* Fall through and generate default code.  */
7149 (define_insn "sne_si_zero"
7150   [(set (match_operand:SI 0 "register_operand" "=d")
7151         (ne:SI (match_operand:SI 1 "register_operand" "d")
7152                (const_int 0)))]
7153   "!TARGET_MIPS16"
7154   "sltu\t%0,%.,%1"
7155   [(set_attr "type"     "arith")
7156    (set_attr "mode"     "SI")])
7158 (define_insn "sne_di_zero"
7159   [(set (match_operand:DI 0 "register_operand" "=d")
7160         (ne:DI (match_operand:DI 1 "register_operand" "d")
7161                (const_int 0)))]
7162   "TARGET_64BIT && !TARGET_MIPS16"
7163   "sltu\t%0,%.,%1"
7164   [(set_attr "type"     "arith")
7165    (set_attr "mode"     "DI")])
7167 (define_insn "sne_si"
7168   [(set (match_operand:SI 0 "register_operand" "=d,d")
7169         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
7170                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
7171   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7172   "@
7173     xor\t%0,%1,%2\;sltu\t%0,%.,%0
7174     xori\t%0,%1,%x2\;sltu\t%0,%.,%0"
7175   [(set_attr "type"     "arith")
7176    (set_attr "mode"     "SI")
7177    (set_attr "length"   "8")])
7179 (define_split
7180   [(set (match_operand:SI 0 "register_operand" "")
7181         (ne:SI (match_operand:SI 1 "register_operand" "")
7182                (match_operand:SI 2 "uns_arith_operand" "")))]
7183   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
7184     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
7185   [(set (match_dup 0)
7186         (xor:SI (match_dup 1)
7187                 (match_dup 2)))
7188    (set (match_dup 0)
7189         (gtu:SI (match_dup 0)
7190                 (const_int 0)))]
7191   "")
7193 (define_insn "sne_di"
7194   [(set (match_operand:DI 0 "register_operand" "=d,d")
7195         (ne:DI (match_operand:DI 1 "register_operand" "%d,d")
7196                (match_operand:DI 2 "uns_arith_operand" "d,K")))]
7197   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7198   "@
7199     xor\t%0,%1,%2\;sltu\t%0,%.,%0
7200     xori\t%0,%1,%x2\;sltu\t%0,%.,%0"
7201   [(set_attr "type"     "arith")
7202    (set_attr "mode"     "DI")
7203    (set_attr "length"   "8")])
7205 (define_split
7206   [(set (match_operand:DI 0 "register_operand" "")
7207         (ne:DI (match_operand:DI 1 "register_operand" "")
7208                (match_operand:DI 2 "uns_arith_operand" "")))]
7209   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7210     && !TARGET_MIPS16
7211     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
7212   [(set (match_dup 0)
7213         (xor:DI (match_dup 1)
7214                 (match_dup 2)))
7215    (set (match_dup 0)
7216         (gtu:DI (match_dup 0)
7217                 (const_int 0)))]
7218   "")
7220 (define_expand "sgt"
7221   [(set (match_operand:SI 0 "register_operand" "=d")
7222         (gt:SI (match_dup 1)
7223                (match_dup 2)))]
7224   ""
7226   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7227     FAIL;
7229   /* Set up operands from compare.  */
7230   operands[1] = branch_cmp[0];
7231   operands[2] = branch_cmp[1];
7233   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7234     {
7235       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
7236       DONE;
7237     }
7239   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
7240     operands[2] = force_reg (SImode, operands[2]);
7242   /* Fall through and generate default code.  */
7245 (define_insn "sgt_si"
7246   [(set (match_operand:SI 0 "register_operand" "=d")
7247         (gt:SI (match_operand:SI 1 "register_operand" "d")
7248                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
7249   "!TARGET_MIPS16"
7250   "slt\t%0,%z2,%1"
7251   [(set_attr "type"     "arith")
7252    (set_attr "mode"     "SI")])
7254 (define_insn ""
7255   [(set (match_operand:SI 0 "register_operand" "=t")
7256         (gt:SI (match_operand:SI 1 "register_operand" "d")
7257                (match_operand:SI 2 "register_operand" "d")))]
7258   "TARGET_MIPS16"
7259   "slt\t%2,%1"
7260   [(set_attr "type"     "arith")
7261    (set_attr "mode"     "SI")])
7263 (define_insn "sgt_di"
7264   [(set (match_operand:DI 0 "register_operand" "=d")
7265         (gt:DI (match_operand:DI 1 "register_operand" "d")
7266                (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
7267   "TARGET_64BIT && !TARGET_MIPS16"
7268   "slt\t%0,%z2,%1"
7269   [(set_attr "type"     "arith")
7270    (set_attr "mode"     "DI")])
7272 (define_insn ""
7273   [(set (match_operand:DI 0 "register_operand" "=d")
7274         (gt:DI (match_operand:DI 1 "register_operand" "d")
7275                (match_operand:DI 2 "register_operand" "d")))]
7276   "TARGET_64BIT && TARGET_MIPS16"
7277   "slt\t%2,%1"
7278   [(set_attr "type"     "arith")
7279    (set_attr "mode"     "DI")])
7281 (define_expand "sge"
7282   [(set (match_operand:SI 0 "register_operand" "=d")
7283         (ge:SI (match_dup 1)
7284                (match_dup 2)))]
7285   ""
7287   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7288     FAIL;
7290   /* Set up operands from compare.  */
7291   operands[1] = branch_cmp[0];
7292   operands[2] = branch_cmp[1];
7294   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7295     {
7296       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
7297       DONE;
7298     }
7300   /* Fall through and generate default code.  */
7303 (define_insn "sge_si"
7304   [(set (match_operand:SI 0 "register_operand" "=d")
7305         (ge:SI (match_operand:SI 1 "register_operand" "d")
7306                (match_operand:SI 2 "arith_operand" "dI")))]
7307   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7308   "slt\t%0,%1,%2\;xori\t%0,%0,0x0001"
7309   [(set_attr "type"     "arith")
7310    (set_attr "mode"     "SI")
7311    (set_attr "length"   "8")])
7313 (define_split
7314   [(set (match_operand:SI 0 "register_operand" "")
7315         (ge:SI (match_operand:SI 1 "register_operand" "")
7316                (match_operand:SI 2 "arith_operand" "")))]
7317   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7318   [(set (match_dup 0)
7319         (lt:SI (match_dup 1)
7320                (match_dup 2)))
7321    (set (match_dup 0)
7322         (xor:SI (match_dup 0)
7323                 (const_int 1)))]
7324   "")
7326 (define_insn "sge_di"
7327   [(set (match_operand:DI 0 "register_operand" "=d")
7328         (ge:DI (match_operand:DI 1 "register_operand" "d")
7329                (match_operand:DI 2 "arith_operand" "dI")))]
7330   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7331   "slt\t%0,%1,%2\;xori\t%0,%0,0x0001"
7332   [(set_attr "type"     "arith")
7333    (set_attr "mode"     "DI")
7334    (set_attr "length"   "8")])
7336 (define_split
7337   [(set (match_operand:DI 0 "register_operand" "")
7338         (ge:DI (match_operand:DI 1 "register_operand" "")
7339                (match_operand:DI 2 "arith_operand" "")))]
7340   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7341    && !TARGET_MIPS16"
7342   [(set (match_dup 0)
7343         (lt:DI (match_dup 1)
7344                (match_dup 2)))
7345    (set (match_dup 0)
7346         (xor:DI (match_dup 0)
7347                 (const_int 1)))]
7348   "")
7350 (define_expand "slt"
7351   [(set (match_operand:SI 0 "register_operand" "=d")
7352         (lt:SI (match_dup 1)
7353                (match_dup 2)))]
7354   ""
7356   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7357     FAIL;
7359   /* Set up operands from compare.  */
7360   operands[1] = branch_cmp[0];
7361   operands[2] = branch_cmp[1];
7363   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7364     {
7365       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
7366       DONE;
7367     }
7369   /* Fall through and generate default code.  */
7372 (define_insn "slt_si"
7373   [(set (match_operand:SI 0 "register_operand" "=d")
7374         (lt:SI (match_operand:SI 1 "register_operand" "d")
7375                (match_operand:SI 2 "arith_operand" "dI")))]
7376   "!TARGET_MIPS16"
7377   "slt\t%0,%1,%2"
7378   [(set_attr "type"     "arith")
7379    (set_attr "mode"     "SI")])
7381 (define_insn ""
7382   [(set (match_operand:SI 0 "register_operand" "=t,t")
7383         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
7384                (match_operand:SI 2 "arith_operand" "d,I")))]
7385   "TARGET_MIPS16"
7386   "slt\t%1,%2"
7387   [(set_attr "type"     "arith")
7388    (set_attr "mode"     "SI")
7389    (set_attr_alternative "length"
7390                 [(const_int 4)
7391                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
7392                                (const_int 4)
7393                                (const_int 8))])])
7395 (define_insn "slt_di"
7396   [(set (match_operand:DI 0 "register_operand" "=d")
7397         (lt:DI (match_operand:DI 1 "register_operand" "d")
7398                (match_operand:DI 2 "arith_operand" "dI")))]
7399   "TARGET_64BIT && !TARGET_MIPS16"
7400   "slt\t%0,%1,%2"
7401   [(set_attr "type"     "arith")
7402    (set_attr "mode"     "DI")])
7404 (define_insn ""
7405   [(set (match_operand:DI 0 "register_operand" "=t,t")
7406         (lt:DI (match_operand:DI 1 "register_operand" "d,d")
7407                (match_operand:DI 2 "arith_operand" "d,I")))]
7408   "TARGET_64BIT && TARGET_MIPS16"
7409   "slt\t%1,%2"
7410   [(set_attr "type"     "arith")
7411    (set_attr "mode"     "DI")
7412    (set_attr_alternative "length"
7413                 [(const_int 4)
7414                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
7415                                (const_int 4)
7416                                (const_int 8))])])
7418 (define_expand "sle"
7419   [(set (match_operand:SI 0 "register_operand" "=d")
7420         (le:SI (match_dup 1)
7421                (match_dup 2)))]
7422   ""
7424   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7425     FAIL;
7427   /* Set up operands from compare.  */
7428   operands[1] = branch_cmp[0];
7429   operands[2] = branch_cmp[1];
7431   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7432     {
7433       gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
7434       DONE;
7435     }
7437   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
7438     operands[2] = force_reg (SImode, operands[2]);
7440   /* Fall through and generate default code.  */
7443 (define_insn "sle_si_const"
7444   [(set (match_operand:SI 0 "register_operand" "=d")
7445         (le:SI (match_operand:SI 1 "register_operand" "d")
7446                (match_operand:SI 2 "small_int" "I")))]
7447   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7449   operands[2] = GEN_INT (INTVAL (operands[2])+1);
7450   return "slt\t%0,%1,%2";
7452   [(set_attr "type"     "arith")
7453    (set_attr "mode"     "SI")])
7455 (define_insn ""
7456   [(set (match_operand:SI 0 "register_operand" "=t")
7457         (le:SI (match_operand:SI 1 "register_operand" "d")
7458                (match_operand:SI 2 "small_int" "I")))]
7459   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7461   operands[2] = GEN_INT (INTVAL (operands[2])+1);
7462   return "slt\t%1,%2";
7464   [(set_attr "type"     "arith")
7465    (set_attr "mode"     "SI")
7466    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
7467                                       (const_int 4)
7468                                       (const_int 8)))])
7470 (define_insn "sle_di_const"
7471   [(set (match_operand:DI 0 "register_operand" "=d")
7472         (le:DI (match_operand:DI 1 "register_operand" "d")
7473                (match_operand:DI 2 "small_int" "I")))]
7474   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7476   operands[2] = GEN_INT (INTVAL (operands[2])+1);
7477   return "slt\t%0,%1,%2";
7479   [(set_attr "type"     "arith")
7480    (set_attr "mode"     "DI")])
7482 (define_insn ""
7483   [(set (match_operand:DI 0 "register_operand" "=t")
7484         (le:DI (match_operand:DI 1 "register_operand" "d")
7485                (match_operand:DI 2 "small_int" "I")))]
7486   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7488   operands[2] = GEN_INT (INTVAL (operands[2])+1);
7489   return "slt\t%1,%2";
7491   [(set_attr "type"     "arith")
7492    (set_attr "mode"     "DI")
7493    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
7494                                       (const_int 4)
7495                                       (const_int 8)))])
7497 (define_insn "sle_si_reg"
7498   [(set (match_operand:SI 0 "register_operand" "=d")
7499         (le:SI (match_operand:SI 1 "register_operand" "d")
7500                (match_operand:SI 2 "register_operand" "d")))]
7501   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7502   "slt\t%0,%z2,%1\;xori\t%0,%0,0x0001"
7503   [(set_attr "type"     "arith")
7504    (set_attr "mode"     "SI")
7505    (set_attr "length"   "8")])
7507 (define_split
7508   [(set (match_operand:SI 0 "register_operand" "")
7509         (le:SI (match_operand:SI 1 "register_operand" "")
7510                (match_operand:SI 2 "register_operand" "")))]
7511   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7512   [(set (match_dup 0)
7513         (lt:SI (match_dup 2)
7514                (match_dup 1)))
7515    (set (match_dup 0)
7516         (xor:SI (match_dup 0)
7517                 (const_int 1)))]
7518   "")
7520 (define_insn "sle_di_reg"
7521   [(set (match_operand:DI 0 "register_operand" "=d")
7522         (le:DI (match_operand:DI 1 "register_operand" "d")
7523                (match_operand:DI 2 "register_operand" "d")))]
7524   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7525   "slt\t%0,%z2,%1\;xori\t%0,%0,0x0001"
7526   [(set_attr "type"     "arith")
7527    (set_attr "mode"     "DI")
7528    (set_attr "length"   "8")])
7530 (define_split
7531   [(set (match_operand:DI 0 "register_operand" "")
7532         (le:DI (match_operand:DI 1 "register_operand" "")
7533                (match_operand:DI 2 "register_operand" "")))]
7534   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7535    && !TARGET_MIPS16"
7536   [(set (match_dup 0)
7537         (lt:DI (match_dup 2)
7538                (match_dup 1)))
7539    (set (match_dup 0)
7540         (xor:DI (match_dup 0)
7541                 (const_int 1)))]
7542   "")
7544 (define_expand "sgtu"
7545   [(set (match_operand:SI 0 "register_operand" "=d")
7546         (gtu:SI (match_dup 1)
7547                 (match_dup 2)))]
7548   ""
7550   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7551     FAIL;
7553   /* Set up operands from compare.  */
7554   operands[1] = branch_cmp[0];
7555   operands[2] = branch_cmp[1];
7557   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7558     {
7559       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
7560       DONE;
7561     }
7563   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
7564     operands[2] = force_reg (SImode, operands[2]);
7566   /* Fall through and generate default code.  */
7569 (define_insn "sgtu_si"
7570   [(set (match_operand:SI 0 "register_operand" "=d")
7571         (gtu:SI (match_operand:SI 1 "register_operand" "d")
7572                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
7573   "!TARGET_MIPS16"
7574   "sltu\t%0,%z2,%1"
7575   [(set_attr "type"     "arith")
7576    (set_attr "mode"     "SI")])
7578 (define_insn ""
7579   [(set (match_operand:SI 0 "register_operand" "=t")
7580         (gtu:SI (match_operand:SI 1 "register_operand" "d")
7581                 (match_operand:SI 2 "register_operand" "d")))]
7582   "TARGET_MIPS16"
7583   "sltu\t%2,%1"
7584   [(set_attr "type"     "arith")
7585    (set_attr "mode"     "SI")])
7587 (define_insn "sgtu_di"
7588   [(set (match_operand:DI 0 "register_operand" "=d")
7589         (gtu:DI (match_operand:DI 1 "register_operand" "d")
7590                 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
7591   "TARGET_64BIT && !TARGET_MIPS16"
7592   "sltu\t%0,%z2,%1"
7593   [(set_attr "type"     "arith")
7594    (set_attr "mode"     "DI")])
7596 (define_insn ""
7597   [(set (match_operand:DI 0 "register_operand" "=t")
7598         (gtu:DI (match_operand:DI 1 "register_operand" "d")
7599                 (match_operand:DI 2 "register_operand" "d")))]
7600   "TARGET_64BIT && TARGET_MIPS16"
7601   "sltu\t%2,%1"
7602   [(set_attr "type"     "arith")
7603    (set_attr "mode"     "DI")])
7605 (define_expand "sgeu"
7606   [(set (match_operand:SI 0 "register_operand" "=d")
7607         (geu:SI (match_dup 1)
7608                 (match_dup 2)))]
7609   ""
7611   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7612     FAIL;
7614   /* Set up operands from compare.  */
7615   operands[1] = branch_cmp[0];
7616   operands[2] = branch_cmp[1];
7618   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7619     {
7620       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
7621       DONE;
7622     }
7624   /* Fall through and generate default code.  */
7627 (define_insn "sgeu_si"
7628   [(set (match_operand:SI 0 "register_operand" "=d")
7629         (geu:SI (match_operand:SI 1 "register_operand" "d")
7630                 (match_operand:SI 2 "arith_operand" "dI")))]
7631   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7632   "sltu\t%0,%1,%2\;xori\t%0,%0,0x0001"
7633   [(set_attr "type"     "arith")
7634    (set_attr "mode"     "SI")
7635    (set_attr "length"   "8")])
7637 (define_split
7638   [(set (match_operand:SI 0 "register_operand" "")
7639         (geu:SI (match_operand:SI 1 "register_operand" "")
7640                 (match_operand:SI 2 "arith_operand" "")))]
7641   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7642   [(set (match_dup 0)
7643         (ltu:SI (match_dup 1)
7644                 (match_dup 2)))
7645    (set (match_dup 0)
7646         (xor:SI (match_dup 0)
7647                 (const_int 1)))]
7648   "")
7650 (define_insn "sgeu_di"
7651   [(set (match_operand:DI 0 "register_operand" "=d")
7652         (geu:DI (match_operand:DI 1 "register_operand" "d")
7653                 (match_operand:DI 2 "arith_operand" "dI")))]
7654   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7655   "sltu\t%0,%1,%2\;xori\t%0,%0,0x0001"
7656   [(set_attr "type"     "arith")
7657    (set_attr "mode"     "DI")
7658    (set_attr "length"   "8")])
7660 (define_split
7661   [(set (match_operand:DI 0 "register_operand" "")
7662         (geu:DI (match_operand:DI 1 "register_operand" "")
7663                 (match_operand:DI 2 "arith_operand" "")))]
7664   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7665    && !TARGET_MIPS16"
7666   [(set (match_dup 0)
7667         (ltu:DI (match_dup 1)
7668                 (match_dup 2)))
7669    (set (match_dup 0)
7670         (xor:DI (match_dup 0)
7671                 (const_int 1)))]
7672   "")
7674 (define_expand "sltu"
7675   [(set (match_operand:SI 0 "register_operand" "=d")
7676         (ltu:SI (match_dup 1)
7677                 (match_dup 2)))]
7678   ""
7680   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7681     FAIL;
7683   /* Set up operands from compare.  */
7684   operands[1] = branch_cmp[0];
7685   operands[2] = branch_cmp[1];
7687   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7688     {
7689       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
7690       DONE;
7691     }
7693   /* Fall through and generate default code.  */
7696 (define_insn "sltu_si"
7697   [(set (match_operand:SI 0 "register_operand" "=d")
7698         (ltu:SI (match_operand:SI 1 "register_operand" "d")
7699                 (match_operand:SI 2 "arith_operand" "dI")))]
7700   "!TARGET_MIPS16"
7701   "sltu\t%0,%1,%2"
7702   [(set_attr "type"     "arith")
7703    (set_attr "mode"     "SI")])
7705 (define_insn ""
7706   [(set (match_operand:SI 0 "register_operand" "=t,t")
7707         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
7708                 (match_operand:SI 2 "arith_operand" "d,I")))]
7709   "TARGET_MIPS16"
7710   "sltu\t%1,%2"
7711   [(set_attr "type"     "arith")
7712    (set_attr "mode"     "SI")
7713    (set_attr_alternative "length"
7714                 [(const_int 4)
7715                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
7716                                (const_int 4)
7717                                (const_int 8))])])
7719 (define_insn "sltu_di"
7720   [(set (match_operand:DI 0 "register_operand" "=d")
7721         (ltu:DI (match_operand:DI 1 "register_operand" "d")
7722                 (match_operand:DI 2 "arith_operand" "dI")))]
7723   "TARGET_64BIT && !TARGET_MIPS16"
7724   "sltu\t%0,%1,%2"
7725   [(set_attr "type"     "arith")
7726    (set_attr "mode"     "DI")])
7728 (define_insn ""
7729   [(set (match_operand:DI 0 "register_operand" "=t,t")
7730         (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
7731                 (match_operand:DI 2 "arith_operand" "d,I")))]
7732   "TARGET_64BIT && TARGET_MIPS16"
7733   "sltu\t%1,%2"
7734   [(set_attr "type"     "arith")
7735    (set_attr "mode"     "DI")
7736    (set_attr_alternative "length"
7737                 [(const_int 4)
7738                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
7739                                (const_int 4)
7740                                (const_int 8))])])
7742 (define_expand "sleu"
7743   [(set (match_operand:SI 0 "register_operand" "=d")
7744         (leu:SI (match_dup 1)
7745                 (match_dup 2)))]
7746   ""
7748   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7749     FAIL;
7751   /* Set up operands from compare.  */
7752   operands[1] = branch_cmp[0];
7753   operands[2] = branch_cmp[1];
7755   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7756     {
7757       gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
7758       DONE;
7759     }
7761   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
7762     operands[2] = force_reg (SImode, operands[2]);
7764   /* Fall through and generate default code.  */
7767 (define_insn "sleu_si_const"
7768   [(set (match_operand:SI 0 "register_operand" "=d")
7769         (leu:SI (match_operand:SI 1 "register_operand" "d")
7770                 (match_operand:SI 2 "small_int" "I")))]
7771   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7773   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
7774   return "sltu\t%0,%1,%2";
7776   [(set_attr "type"     "arith")
7777    (set_attr "mode"     "SI")])
7779 (define_insn ""
7780   [(set (match_operand:SI 0 "register_operand" "=t")
7781         (leu:SI (match_operand:SI 1 "register_operand" "d")
7782                 (match_operand:SI 2 "small_int" "I")))]
7783   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7785   operands[2] = GEN_INT (INTVAL (operands[2])+1);
7786   return "sltu\t%1,%2";
7788   [(set_attr "type"     "arith")
7789    (set_attr "mode"     "SI")
7790    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
7791                                       (const_int 4)
7792                                       (const_int 8)))])
7794 (define_insn "sleu_di_const"
7795   [(set (match_operand:DI 0 "register_operand" "=d")
7796         (leu:DI (match_operand:DI 1 "register_operand" "d")
7797                 (match_operand:DI 2 "small_int" "I")))]
7798   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7800   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
7801   return "sltu\t%0,%1,%2";
7803   [(set_attr "type"     "arith")
7804    (set_attr "mode"     "DI")])
7806 (define_insn ""
7807   [(set (match_operand:DI 0 "register_operand" "=t")
7808         (leu:DI (match_operand:DI 1 "register_operand" "d")
7809                 (match_operand:DI 2 "small_int" "I")))]
7810   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7812   operands[2] = GEN_INT (INTVAL (operands[2])+1);
7813   return "sltu\t%1,%2";
7815   [(set_attr "type"     "arith")
7816    (set_attr "mode"     "DI")
7817    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
7818                                       (const_int 4)
7819                                       (const_int 8)))])
7821 (define_insn "sleu_si_reg"
7822   [(set (match_operand:SI 0 "register_operand" "=d")
7823         (leu:SI (match_operand:SI 1 "register_operand" "d")
7824                 (match_operand:SI 2 "register_operand" "d")))]
7825   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7826   "sltu\t%0,%z2,%1\;xori\t%0,%0,0x0001"
7827   [(set_attr "type"     "arith")
7828    (set_attr "mode"     "SI")
7829    (set_attr "length"   "8")])
7831 (define_split
7832   [(set (match_operand:SI 0 "register_operand" "")
7833         (leu:SI (match_operand:SI 1 "register_operand" "")
7834                 (match_operand:SI 2 "register_operand" "")))]
7835   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7836   [(set (match_dup 0)
7837         (ltu:SI (match_dup 2)
7838                 (match_dup 1)))
7839    (set (match_dup 0)
7840         (xor:SI (match_dup 0)
7841                 (const_int 1)))]
7842   "")
7844 (define_insn "sleu_di_reg"
7845   [(set (match_operand:DI 0 "register_operand" "=d")
7846         (leu:DI (match_operand:DI 1 "register_operand" "d")
7847                 (match_operand:DI 2 "register_operand" "d")))]
7848   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7849   "sltu\t%0,%z2,%1\;xori\t%0,%0,0x0001"
7850   [(set_attr "type"     "arith")
7851    (set_attr "mode"     "DI")
7852    (set_attr "length"   "8")])
7854 (define_split
7855   [(set (match_operand:DI 0 "register_operand" "")
7856         (leu:DI (match_operand:DI 1 "register_operand" "")
7857                 (match_operand:DI 2 "register_operand" "")))]
7858   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7859    && !TARGET_MIPS16"
7860   [(set (match_dup 0)
7861         (ltu:DI (match_dup 2)
7862                 (match_dup 1)))
7863    (set (match_dup 0)
7864         (xor:DI (match_dup 0)
7865                 (const_int 1)))]
7866   "")
7869 ;;  ....................
7871 ;;      FLOATING POINT COMPARISONS
7873 ;;  ....................
7875 (define_insn "sunordered_df"
7876   [(set (match_operand:CC 0 "register_operand" "=z")
7877         (unordered:CC (match_operand:DF 1 "register_operand" "f")
7878                       (match_operand:DF 2 "register_operand" "f")))]
7879   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7880   "c.un.d\t%Z0%1,%2"
7881   [(set_attr "type" "fcmp")
7882    (set_attr "mode" "FPSW")])
7884 (define_insn "sunlt_df"
7885   [(set (match_operand:CC 0 "register_operand" "=z")
7886         (unlt:CC (match_operand:DF 1 "register_operand" "f")
7887                  (match_operand:DF 2 "register_operand" "f")))]
7888   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7889   "c.ult.d\t%Z0%1,%2"
7890   [(set_attr "type" "fcmp")
7891    (set_attr "mode" "FPSW")])
7893 (define_insn "suneq_df"
7894   [(set (match_operand:CC 0 "register_operand" "=z")
7895         (uneq:CC (match_operand:DF 1 "register_operand" "f")
7896                  (match_operand:DF 2 "register_operand" "f")))]
7897   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7898   "c.ueq.d\t%Z0%1,%2"
7899   [(set_attr "type" "fcmp")
7900    (set_attr "mode" "FPSW")])
7902 (define_insn "sunle_df"
7903   [(set (match_operand:CC 0 "register_operand" "=z")
7904         (unle:CC (match_operand:DF 1 "register_operand" "f")
7905                  (match_operand:DF 2 "register_operand" "f")))]
7906   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7907   "c.ule.d\t%Z0%1,%2"
7908   [(set_attr "type" "fcmp")
7909    (set_attr "mode" "FPSW")])
7911 (define_insn "seq_df"
7912   [(set (match_operand:CC 0 "register_operand" "=z")
7913         (eq:CC (match_operand:DF 1 "register_operand" "f")
7914                (match_operand:DF 2 "register_operand" "f")))]
7915   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7916   "c.eq.d\t%Z0%1,%2"
7917   [(set_attr "type" "fcmp")
7918    (set_attr "mode" "FPSW")])
7920 (define_insn "slt_df"
7921   [(set (match_operand:CC 0 "register_operand" "=z")
7922         (lt:CC (match_operand:DF 1 "register_operand" "f")
7923                (match_operand:DF 2 "register_operand" "f")))]
7924   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7925   "c.lt.d\t%Z0%1,%2"
7926   [(set_attr "type" "fcmp")
7927    (set_attr "mode" "FPSW")])
7929 (define_insn "sle_df"
7930   [(set (match_operand:CC 0 "register_operand" "=z")
7931         (le:CC (match_operand:DF 1 "register_operand" "f")
7932                (match_operand:DF 2 "register_operand" "f")))]
7933   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7934   "c.le.d\t%Z0%1,%2"
7935   [(set_attr "type" "fcmp")
7936    (set_attr "mode" "FPSW")])
7938 (define_insn "sgt_df"
7939   [(set (match_operand:CC 0 "register_operand" "=z")
7940         (gt:CC (match_operand:DF 1 "register_operand" "f")
7941                (match_operand:DF 2 "register_operand" "f")))]
7942   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7943   "c.lt.d\t%Z0%2,%1"
7944   [(set_attr "type" "fcmp")
7945    (set_attr "mode" "FPSW")])
7947 (define_insn "sge_df"
7948   [(set (match_operand:CC 0 "register_operand" "=z")
7949         (ge:CC (match_operand:DF 1 "register_operand" "f")
7950                (match_operand:DF 2 "register_operand" "f")))]
7951   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7952   "c.le.d\t%Z0%2,%1"
7953   [(set_attr "type" "fcmp")
7954    (set_attr "mode" "FPSW")])
7956 (define_insn "sunordered_sf"
7957   [(set (match_operand:CC 0 "register_operand" "=z")
7958         (unordered:CC (match_operand:SF 1 "register_operand" "f")
7959                       (match_operand:SF 2 "register_operand" "f")))]
7960   "TARGET_HARD_FLOAT"
7961   "c.un.s\t%Z0%1,%2"
7962   [(set_attr "type" "fcmp")
7963    (set_attr "mode" "FPSW")])
7965 (define_insn "sunlt_sf"
7966   [(set (match_operand:CC 0 "register_operand" "=z")
7967         (unlt:CC (match_operand:SF 1 "register_operand" "f")
7968                  (match_operand:SF 2 "register_operand" "f")))]
7969   "TARGET_HARD_FLOAT"
7970   "c.ult.s\t%Z0%1,%2"
7971   [(set_attr "type" "fcmp")
7972    (set_attr "mode" "FPSW")])
7974 (define_insn "suneq_sf"
7975   [(set (match_operand:CC 0 "register_operand" "=z")
7976         (uneq:CC (match_operand:SF 1 "register_operand" "f")
7977                  (match_operand:SF 2 "register_operand" "f")))]
7978   "TARGET_HARD_FLOAT"
7979   "c.ueq.s\t%Z0%1,%2"
7980   [(set_attr "type" "fcmp")
7981    (set_attr "mode" "FPSW")])
7983 (define_insn "sunle_sf"
7984   [(set (match_operand:CC 0 "register_operand" "=z")
7985         (unle:CC (match_operand:SF 1 "register_operand" "f")
7986                  (match_operand:SF 2 "register_operand" "f")))]
7987   "TARGET_HARD_FLOAT"
7988   "c.ule.s\t%Z0%1,%2"
7989   [(set_attr "type" "fcmp")
7990    (set_attr "mode" "FPSW")])
7992 (define_insn "seq_sf"
7993   [(set (match_operand:CC 0 "register_operand" "=z")
7994         (eq:CC (match_operand:SF 1 "register_operand" "f")
7995                (match_operand:SF 2 "register_operand" "f")))]
7996   "TARGET_HARD_FLOAT"
7997   "c.eq.s\t%Z0%1,%2"
7998   [(set_attr "type" "fcmp")
7999    (set_attr "mode" "FPSW")])
8001 (define_insn "slt_sf"
8002   [(set (match_operand:CC 0 "register_operand" "=z")
8003         (lt:CC (match_operand:SF 1 "register_operand" "f")
8004                (match_operand:SF 2 "register_operand" "f")))]
8005   "TARGET_HARD_FLOAT"
8006   "c.lt.s\t%Z0%1,%2"
8007   [(set_attr "type" "fcmp")
8008    (set_attr "mode" "FPSW")])
8010 (define_insn "sle_sf"
8011   [(set (match_operand:CC 0 "register_operand" "=z")
8012         (le:CC (match_operand:SF 1 "register_operand" "f")
8013                (match_operand:SF 2 "register_operand" "f")))]
8014   "TARGET_HARD_FLOAT"
8015   "c.le.s\t%Z0%1,%2"
8016   [(set_attr "type" "fcmp")
8017    (set_attr "mode" "FPSW")])
8019 (define_insn "sgt_sf"
8020   [(set (match_operand:CC 0 "register_operand" "=z")
8021         (gt:CC (match_operand:SF 1 "register_operand" "f")
8022                (match_operand:SF 2 "register_operand" "f")))]
8023   "TARGET_HARD_FLOAT"
8024   "c.lt.s\t%Z0%2,%1"
8025   [(set_attr "type" "fcmp")
8026    (set_attr "mode" "FPSW")])
8028 (define_insn "sge_sf"
8029   [(set (match_operand:CC 0 "register_operand" "=z")
8030         (ge:CC (match_operand:SF 1 "register_operand" "f")
8031                (match_operand:SF 2 "register_operand" "f")))]
8032   "TARGET_HARD_FLOAT"
8033   "c.le.s\t%Z0%2,%1"
8034   [(set_attr "type" "fcmp")
8035    (set_attr "mode" "FPSW")])
8038 ;;  ....................
8040 ;;      UNCONDITIONAL BRANCHES
8042 ;;  ....................
8044 ;; Unconditional branches.
8046 (define_insn "jump"
8047   [(set (pc)
8048         (label_ref (match_operand 0 "" "")))]
8049   "!TARGET_MIPS16"
8051   if (flag_pic && ! TARGET_EMBEDDED_PIC)
8052     {
8053       if (get_attr_length (insn) <= 8)
8054         return "%*b\t%l0%/";
8055       else
8056         {
8057           output_asm_insn (mips_output_load_label (), operands);
8058           return "%*jr\t%@%/%]";
8059         }
8060     }
8061   else
8062     return "%*j\t%l0%/";
8064   [(set_attr "type"     "jump")
8065    (set_attr "mode"     "none")
8066    (set (attr "length")
8067         ;; we can't use `j' when emitting non-embedded PIC, so we emit
8068         ;; branch, if it's in range, or load the address of the branch
8069         ;; target into $at in a PIC-compatible way and then jump to it.
8070         (if_then_else
8071          (ior (eq (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
8072                   (const_int 0))
8073               (lt (abs (minus (match_dup 0)
8074                               (plus (pc) (const_int 4))))
8075                   (const_int 131072)))
8076          (const_int 4) (const_int 16)))])
8078 ;; We need a different insn for the mips16, because a mips16 branch
8079 ;; does not have a delay slot.
8081 (define_insn ""
8082   [(set (pc)
8083         (label_ref (match_operand 0 "" "")))]
8084   "TARGET_MIPS16"
8085   "b\t%l0"
8086   [(set_attr "type"     "branch")
8087    (set_attr "mode"     "none")
8088    (set_attr "length"   "8")])
8090 (define_expand "indirect_jump"
8091   [(set (pc) (match_operand 0 "register_operand" "d"))]
8092   ""
8094   rtx dest;
8096   dest = operands[0];
8097   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
8098     operands[0] = copy_to_mode_reg (Pmode, dest);
8100   if (!(Pmode == DImode))
8101     emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
8102   else
8103     emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
8105   DONE;
8108 (define_insn "indirect_jump_internal1"
8109   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
8110   "!(Pmode == DImode)"
8111   "%*j\t%0%/"
8112   [(set_attr "type"     "jump")
8113    (set_attr "mode"     "none")])
8115 (define_insn "indirect_jump_internal2"
8116   [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
8117   "Pmode == DImode"
8118   "%*j\t%0%/"
8119   [(set_attr "type"     "jump")
8120    (set_attr "mode"     "none")])
8122 (define_expand "tablejump"
8123   [(set (pc)
8124         (match_operand 0 "register_operand" "d"))
8125    (use (label_ref (match_operand 1 "" "")))]
8126   ""
8128   if (TARGET_MIPS16)
8129     {
8130       if (GET_MODE (operands[0]) != HImode)
8131         abort ();
8132       if (!(Pmode == DImode))
8133         emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
8134       else
8135         emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
8136       DONE;
8137     }
8139   if (GET_MODE (operands[0]) != ptr_mode)
8140     abort ();
8142   if (TARGET_GPWORD)
8143     operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
8144                                 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
8146   if (Pmode == SImode)
8147     emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
8148   else
8149     emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
8150   DONE;
8153 (define_insn "tablejump_internal1"
8154   [(set (pc)
8155         (match_operand:SI 0 "register_operand" "d"))
8156    (use (label_ref (match_operand 1 "" "")))]
8157   ""
8158   "%*j\t%0%/"
8159   [(set_attr "type"     "jump")
8160    (set_attr "mode"     "none")])
8162 (define_insn "tablejump_internal2"
8163   [(set (pc)
8164         (match_operand:DI 0 "register_operand" "d"))
8165    (use (label_ref (match_operand 1 "" "")))]
8166   "TARGET_64BIT"
8167   "%*j\t%0%/"
8168   [(set_attr "type"     "jump")
8169    (set_attr "mode"     "none")])
8171 (define_expand "tablejump_mips161"
8172   [(set (pc) (plus:SI (sign_extend:SI
8173                        (match_operand:HI 0 "register_operand" "d"))
8174                       (label_ref:SI (match_operand 1 "" ""))))]
8175   "TARGET_MIPS16 && !(Pmode == DImode)"
8177   rtx t1, t2, t3;
8179   t1 = gen_reg_rtx (SImode);
8180   t2 = gen_reg_rtx (SImode);
8181   t3 = gen_reg_rtx (SImode);
8182   emit_insn (gen_extendhisi2 (t1, operands[0]));
8183   emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
8184   emit_insn (gen_addsi3 (t3, t1, t2));
8185   emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
8186   DONE;
8189 (define_expand "tablejump_mips162"
8190   [(set (pc) (plus:DI (sign_extend:DI
8191                        (match_operand:HI 0 "register_operand" "d"))
8192                       (label_ref:DI (match_operand 1 "" ""))))]
8193   "TARGET_MIPS16 && Pmode == DImode"
8195   rtx t1, t2, t3;
8197   t1 = gen_reg_rtx (DImode);
8198   t2 = gen_reg_rtx (DImode);
8199   t3 = gen_reg_rtx (DImode);
8200   emit_insn (gen_extendhidi2 (t1, operands[0]));
8201   emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
8202   emit_insn (gen_adddi3 (t3, t1, t2));
8203   emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
8204   DONE;
8207 ;; Implement a switch statement when generating embedded PIC code.
8208 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
8210 (define_expand "casesi"
8211   [(set (match_dup 5)
8212         (minus:SI (match_operand:SI 0 "register_operand" "")
8213                   (match_operand:SI 1 "const_int_operand" "")))
8214    (set (cc0)
8215         (compare:CC (match_dup 5)
8216                     (match_operand:SI 2 "arith_operand" "")))
8217    (set (pc)
8218         (if_then_else (gtu (cc0)
8219                            (const_int 0))
8220                       (label_ref (match_operand 4 "" ""))
8221                       (pc)))
8222    (parallel
8223     [(set (pc)
8224           (mem:SI (plus:SI (mult:SI (match_dup 5)
8225                                     (const_int 4))
8226                            (label_ref (match_operand 3 "" "")))))
8227      (clobber (match_scratch:SI 6 ""))
8228      (clobber (reg:SI 31))])]
8229   "TARGET_EMBEDDED_PIC"
8231   rtx index;
8233   /* If the index is too large, go to the default label.  */
8234   index = expand_binop (SImode, sub_optab, operands[0],
8235                         operands[1], 0, 0, OPTAB_WIDEN);
8236   emit_insn (gen_cmpsi (index, operands[2]));
8237   emit_insn (gen_bgtu (operands[4]));
8239   /* Do the PIC jump.  */
8240   if (Pmode != DImode)
8241     emit_jump_insn (gen_casesi_internal (index, operands[3],
8242                                          gen_reg_rtx (SImode)));
8243   else
8244     emit_jump_insn (gen_casesi_internal_di (index, operands[3],
8245                                             gen_reg_rtx (DImode)));
8247   DONE;
8250 ;; An embedded PIC switch statement looks like this:
8251 ;;      bal     $LS1
8252 ;;      sll     $reg,$index,2
8253 ;; $LS1:
8254 ;;      addu    $reg,$reg,$31
8255 ;;      lw      $reg,$L1-$LS1($reg)
8256 ;;      addu    $reg,$reg,$31
8257 ;;      j       $reg
8258 ;; $L1:
8259 ;;      .word   case1-$LS1
8260 ;;      .word   case2-$LS1
8261 ;;      ...
8263 (define_insn "casesi_internal"
8264   [(set (pc)
8265         (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
8266                                   (const_int 4))
8267                          (label_ref (match_operand 1 "" "")))))
8268    (clobber (match_operand:SI 2 "register_operand" "=d"))
8269    (clobber (reg:SI 31))]
8270   "TARGET_EMBEDDED_PIC"
8271   {
8272     if (set_nomacro)
8273       return "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
8274 .set macro\;lw\\t%2,%1-%S1(%2)\;.set nomacro\;addu\\t%2,%2,$31\\n\\t%*j\\t%2%/";
8275     return
8276   "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
8277 lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
8278     ;
8279   }
8280   [(set_attr "type"     "jump")
8281    (set_attr "mode"     "none")
8282    (set_attr "length"   "24")])
8284 ;; This code assumes that the table index will never be >= 29 bits wide,
8285 ;; which allows the 'sign extend' from SI to DI be a no-op.
8286 (define_insn "casesi_internal_di"
8287   [(set (pc)
8288         (mem:DI (plus:DI (sign_extend:DI
8289                           (mult:SI (match_operand:SI 0 "register_operand" "d")
8290                                   (const_int 8)))
8291                          (label_ref (match_operand 1 "" "")))))
8292    (clobber (match_operand:DI 2 "register_operand" "=d"))
8293    (clobber (reg:DI 31))]
8294   "TARGET_EMBEDDED_PIC"
8295   {
8296     if (set_nomacro)
8297       return "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
8298 .set macro\;ld\\t%2,%1-%S1(%2)\;.set nomacro\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/";
8299     return
8300   "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
8301 ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
8302     ;
8303   }
8304   [(set_attr "type"     "jump")
8305    (set_attr "mode"     "none")
8306    (set_attr "length"   "24")])
8308 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
8309 ;; While it is possible to either pull it off the stack (in the
8310 ;; o32 case) or recalculate it given t9 and our target label,
8311 ;; it takes 3 or 4 insns to do so.
8313 (define_expand "builtin_setjmp_setup"
8314   [(use (match_operand 0 "register_operand" ""))]
8315   "TARGET_ABICALLS"
8317   rtx addr;
8319   addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
8320   emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
8321   DONE;
8324 ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
8325 ;; that older code did recalculate the gp from $25.  Continue to jump through
8326 ;; $25 for compatibility (we lose nothing by doing so).
8328 (define_expand "builtin_longjmp"
8329   [(use (match_operand 0 "register_operand" "r"))]
8330   "TARGET_ABICALLS"
8332   /* The elements of the buffer are, in order:  */
8333   int W = GET_MODE_SIZE (Pmode);
8334   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
8335   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
8336   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
8337   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
8338   rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
8339   /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
8340      The target is bound to be using $28 as the global pointer
8341      but the current function might not be.  */
8342   rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
8344   /* This bit is similar to expand_builtin_longjmp except that it
8345      restores $gp as well.  */
8346   emit_move_insn (hard_frame_pointer_rtx, fp);
8347   emit_move_insn (pv, lab);
8348   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
8349   emit_move_insn (gp, gpv);
8350   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
8351   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8352   emit_insn (gen_rtx_USE (VOIDmode, gp));
8353   emit_indirect_jump (pv);
8354   DONE;
8358 ;;  ....................
8360 ;;      Function prologue/epilogue
8362 ;;  ....................
8365 (define_expand "prologue"
8366   [(const_int 1)]
8367   ""
8369   mips_expand_prologue ();
8370   DONE;
8373 ;; Block any insns from being moved before this point, since the
8374 ;; profiling call to mcount can use various registers that aren't
8375 ;; saved or used to pass arguments.
8377 (define_insn "blockage"
8378   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
8379   ""
8380   ""
8381   [(set_attr "type"     "unknown")
8382    (set_attr "mode"     "none")
8383    (set_attr "length"   "0")])
8385 (define_expand "epilogue"
8386   [(const_int 2)]
8387   ""
8389   mips_expand_epilogue (false);
8390   DONE;
8393 (define_expand "sibcall_epilogue"
8394   [(const_int 2)]
8395   ""
8397   mips_expand_epilogue (true);
8398   DONE;
8401 ;; Trivial return.  Make it look like a normal return insn as that
8402 ;; allows jump optimizations to work better.
8404 (define_insn "return"
8405   [(return)]
8406   "mips_can_use_return_insn ()"
8407   "%*j\t$31%/"
8408   [(set_attr "type"     "jump")
8409    (set_attr "mode"     "none")])
8411 ;; Normal return.
8413 (define_insn "return_internal"
8414   [(return)
8415    (use (match_operand 0 "pmode_register_operand" ""))]
8416   ""
8417   "%*j\t%0%/"
8418   [(set_attr "type"     "jump")
8419    (set_attr "mode"     "none")])
8421 ;; When generating embedded PIC code we need to get the address of the
8422 ;; current function.  This specialized instruction does just that.
8424 (define_insn "get_fnaddr"
8425   [(set (match_operand 0 "register_operand" "=d")
8426         (unspec [(match_operand 1 "" "")] UNSPEC_GET_FNADDR))
8427    (clobber (reg:SI 31))]
8428   "TARGET_EMBEDDED_PIC
8429    && GET_CODE (operands[1]) == SYMBOL_REF"
8430   "%($LF%= = . + 8\;bal\t$LF%=\;nop;la\t%0,%1-$LF%=%)\;addu\t%0,%0,$31"
8431   [(set_attr "type"     "call")
8432    (set_attr "mode"     "none")
8433    (set_attr "length"   "20")])
8435 ;; This is used in compiling the unwind routines.
8436 (define_expand "eh_return"
8437   [(use (match_operand 0 "general_operand" ""))]
8438   ""
8440   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
8442   if (GET_MODE (operands[0]) != gpr_mode)
8443     operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
8444   if (TARGET_64BIT)
8445     emit_insn (gen_eh_set_lr_di (operands[0]));
8446   else
8447     emit_insn (gen_eh_set_lr_si (operands[0]));
8449   DONE;
8452 ;; Clobber the return address on the stack.  We can't expand this
8453 ;; until we know where it will be put in the stack frame.
8455 (define_insn "eh_set_lr_si"
8456   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
8457    (clobber (match_scratch:SI 1 "=&d"))]
8458   "! TARGET_64BIT"
8459   "#")
8461 (define_insn "eh_set_lr_di"
8462   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
8463    (clobber (match_scratch:DI 1 "=&d"))]
8464   "TARGET_64BIT"
8465   "#")
8467 (define_split
8468   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
8469    (clobber (match_scratch 1 ""))]
8470   "reload_completed && !TARGET_DEBUG_D_MODE"
8471   [(const_int 0)]
8473   mips_set_return_address (operands[0], operands[1]);
8474   DONE;
8477 (define_insn "exception_receiver"
8478   [(set (reg:SI 28)
8479         (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
8480   "TARGET_ABICALLS && TARGET_OLDABI"
8482   operands[0] = pic_offset_table_rtx;
8483   operands[1] = mips_gp_save_slot ();
8484   return mips_output_move (operands[0], operands[1]);
8486   [(set_attr "type"   "load")
8487    (set_attr "length" "8")])
8490 ;;  ....................
8492 ;;      FUNCTION CALLS
8494 ;;  ....................
8496 ;; Instructions to load a call address from the GOT.  The address might
8497 ;; point to a function or to a lazy binding stub.  In the latter case,
8498 ;; the stub will use the dynamic linker to resolve the function, which
8499 ;; in turn will change the GOT entry to point to the function's real
8500 ;; address.
8502 ;; This means that every call, even pure and constant ones, can
8503 ;; potentially modify the GOT entry.  And once a stub has been called,
8504 ;; we must not call it again.
8506 ;; We represent this restriction using an imaginary fixed register that
8507 ;; acts like a GOT version number.  By making the register call-clobbered,
8508 ;; we tell the target-independent code that the address could be changed
8509 ;; by any call insn.
8510 (define_insn "load_callsi"
8511   [(set (match_operand:SI 0 "register_operand" "=c")
8512         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8513                     (match_operand:SI 2 "immediate_operand" "")
8514                     (reg:SI FAKE_CALL_REGNO)]
8515                    UNSPEC_LOAD_CALL))]
8516   "TARGET_ABICALLS"
8517   "lw\t%0,%R2(%1)"
8518   [(set_attr "type" "load")
8519    (set_attr "length" "4")])
8521 (define_insn "load_calldi"
8522   [(set (match_operand:DI 0 "register_operand" "=c")
8523         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8524                     (match_operand:DI 2 "immediate_operand" "")
8525                     (reg:DI FAKE_CALL_REGNO)]
8526                    UNSPEC_LOAD_CALL))]
8527   "TARGET_ABICALLS"
8528   "ld\t%0,%R2(%1)"
8529   [(set_attr "type" "load")
8530    (set_attr "length" "4")])
8532 ;; Sibling calls.  All these patterns use jump instructions.
8534 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
8535 ;; addresses if a direct jump is acceptable.  Since the 'S' constraint
8536 ;; is defined in terms of call_insn_operand, the same is true of the
8537 ;; constraints.
8539 ;; When we use an indirect jump, we need a register that will be
8540 ;; preserved by the epilogue.  Since TARGET_ABICALLS forces us to
8541 ;; use $25 for this purpose -- and $25 is never clobbered by the
8542 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
8544 (define_expand "sibcall"
8545   [(parallel [(call (match_operand 0 "" "")
8546                     (match_operand 1 "" ""))
8547               (use (match_operand 2 "" ""))     ;; next_arg_reg
8548               (use (match_operand 3 "" ""))])]  ;; struct_value_size_rtx
8549   "TARGET_SIBCALLS"
8551   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
8552   DONE;
8555 (define_insn "sibcall_internal"
8556   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
8557          (match_operand 1 "" ""))]
8558   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
8559   "@
8560     %*jr\t%0%/
8561     %*j\t%0%/"
8562   [(set_attr "type" "call")])
8564 (define_expand "sibcall_value"
8565   [(parallel [(set (match_operand 0 "" "")
8566                    (call (match_operand 1 "" "")
8567                          (match_operand 2 "" "")))
8568               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
8569   "TARGET_SIBCALLS"
8571   mips_expand_call (operands[0], XEXP (operands[1], 0),
8572                     operands[2], operands[3], true);
8573   DONE;
8576 (define_insn "sibcall_value_internal"
8577   [(set (match_operand 0 "register_operand" "=df,df")
8578         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
8579               (match_operand 2 "" "")))]
8580   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
8581   "@
8582     %*jr\t%1%/
8583     %*j\t%1%/"
8584   [(set_attr "type" "call")])
8586 (define_insn "sibcall_value_multiple_internal"
8587   [(set (match_operand 0 "register_operand" "=df,df")
8588         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
8589               (match_operand 2 "" "")))
8590    (set (match_operand 3 "register_operand" "=df,df")
8591         (call (mem:SI (match_dup 1))
8592               (match_dup 2)))]
8593   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
8594   "@
8595     %*jr\t%1%/
8596     %*j\t%1%/"
8597   [(set_attr "type" "call")])
8599 (define_expand "call"
8600   [(parallel [(call (match_operand 0 "" "")
8601                     (match_operand 1 "" ""))
8602               (use (match_operand 2 "" ""))     ;; next_arg_reg
8603               (use (match_operand 3 "" ""))])]  ;; struct_value_size_rtx
8604   ""
8606   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
8607   DONE;
8610 ;; This instruction directly corresponds to an assembly-language "jal".
8611 ;; There are four cases:
8613 ;;    - -mno-abicalls:
8614 ;;        Both symbolic and register destinations are OK.  The pattern
8615 ;;        always expands to a single mips instruction.
8617 ;;    - -mabicalls/-mno-explicit-relocs:
8618 ;;        Again, both symbolic and register destinations are OK.
8619 ;;        The call is treated as a multi-instruction black box.
8621 ;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
8622 ;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
8623 ;;        instruction.
8625 ;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
8626 ;;        Only "jal $25" is allowed.  The call is actually two instructions:
8627 ;;        "jalr $25" followed by an insn to reload $gp.
8629 ;; In the last case, we can generate the individual instructions with
8630 ;; a define_split.  There are several things to be wary of:
8632 ;;   - We can't expose the load of $gp before reload.  If we did,
8633 ;;     it might get removed as dead, but reload can introduce new
8634 ;;     uses of $gp by rematerializing constants.
8636 ;;   - We shouldn't restore $gp after calls that never return.
8637 ;;     It isn't valid to insert instructions between a noreturn
8638 ;;     call and the following barrier.
8640 ;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
8641 ;;     instruction preserves $gp and so have no effect on its liveness.
8642 ;;     But once we generate the separate insns, it becomes obvious that
8643 ;;     $gp is not live on entry to the call.
8645 ;; ??? The operands[2] = insn check is a hack to make the original insn
8646 ;; available to the splitter.
8647 (define_insn_and_split "call_internal"
8648   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
8649          (match_operand 1 "" ""))
8650    (clobber (reg:SI 31))]
8651   ""
8652   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
8653   "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
8654   [(const_int 0)]
8656   emit_call_insn (gen_call_split (operands[0], operands[1]));
8657   if (!find_reg_note (operands[2], REG_NORETURN, 0))
8658     emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
8659   DONE;
8661   [(set_attr "jal" "indirect,direct")
8662    (set_attr "extended_mips16" "no,yes")])
8664 (define_insn "call_split"
8665   [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
8666          (match_operand 1 "" ""))
8667    (clobber (reg:SI 31))
8668    (clobber (reg:SI 28))]
8669   "TARGET_SPLIT_CALLS"
8670   "%*jalr\t%0%/"
8671   [(set_attr "type" "call")])
8673 (define_expand "call_value"
8674   [(parallel [(set (match_operand 0 "" "")
8675                    (call (match_operand 1 "" "")
8676                          (match_operand 2 "" "")))
8677               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
8678   ""
8680   mips_expand_call (operands[0], XEXP (operands[1], 0),
8681                     operands[2], operands[3], false);
8682   DONE;
8685 ;; See comment for call_internal.
8686 (define_insn_and_split "call_value_internal"
8687   [(set (match_operand 0 "register_operand" "=df,df")
8688         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
8689               (match_operand 2 "" "")))
8690    (clobber (reg:SI 31))]
8691   ""
8692   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
8693   "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
8694   [(const_int 0)]
8696   emit_call_insn (gen_call_value_split (operands[0], operands[1],
8697                                         operands[2]));
8698   if (!find_reg_note (operands[3], REG_NORETURN, 0))
8699     emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
8700   DONE;
8702   [(set_attr "jal" "indirect,direct")
8703    (set_attr "extended_mips16" "no,yes")])
8705 (define_insn "call_value_split"
8706   [(set (match_operand 0 "register_operand" "=df")
8707         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
8708               (match_operand 2 "" "")))
8709    (clobber (reg:SI 31))
8710    (clobber (reg:SI 28))]
8711   "TARGET_SPLIT_CALLS"
8712   "%*jalr\t%1%/"
8713   [(set_attr "type" "call")])
8715 ;; See comment for call_internal.
8716 (define_insn_and_split "call_value_multiple_internal"
8717   [(set (match_operand 0 "register_operand" "=df,df")
8718         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
8719               (match_operand 2 "" "")))
8720    (set (match_operand 3 "register_operand" "=df,df")
8721         (call (mem:SI (match_dup 1))
8722               (match_dup 2)))
8723    (clobber (reg:SI 31))]
8724   ""
8725   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
8726   "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
8727   [(const_int 0)]
8729   emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
8730                                                  operands[2], operands[3]));
8731   if (!find_reg_note (operands[4], REG_NORETURN, 0))
8732     emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
8733   DONE;
8735   [(set_attr "jal" "indirect,direct")
8736    (set_attr "extended_mips16" "no,yes")])
8738 (define_insn "call_value_multiple_split"
8739   [(set (match_operand 0 "register_operand" "=df")
8740         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
8741               (match_operand 2 "" "")))
8742    (set (match_operand 3 "register_operand" "=df")
8743         (call (mem:SI (match_dup 1))
8744               (match_dup 2)))
8745    (clobber (reg:SI 31))
8746    (clobber (reg:SI 28))]
8747   "TARGET_SPLIT_CALLS"
8748   "%*jalr\t%1%/"
8749   [(set_attr "type" "call")])
8751 ;; Call subroutine returning any type.
8753 (define_expand "untyped_call"
8754   [(parallel [(call (match_operand 0 "" "")
8755                     (const_int 0))
8756               (match_operand 1 "" "")
8757               (match_operand 2 "" "")])]
8758   ""
8760   int i;
8762   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
8764   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8765     {
8766       rtx set = XVECEXP (operands[2], 0, i);
8767       emit_move_insn (SET_DEST (set), SET_SRC (set));
8768     }
8770   emit_insn (gen_blockage ());
8771   DONE;
8775 ;;  ....................
8777 ;;      MISC.
8779 ;;  ....................
8783 (define_expand "prefetch"
8784   [(prefetch (match_operand 0 "address_operand" "")
8785              (match_operand 1 "const_int_operand" "")
8786              (match_operand 2 "const_int_operand" ""))]
8787   "ISA_HAS_PREFETCH"
8789   if (symbolic_operand (operands[0], GET_MODE (operands[0])))
8790     operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
8793 (define_insn "prefetch_si_address"
8794   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
8795                       (match_operand:SI 3 "const_int_operand" "I"))
8796              (match_operand:SI 1 "const_int_operand" "n")
8797              (match_operand:SI 2 "const_int_operand" "n"))]
8798   "ISA_HAS_PREFETCH && Pmode == SImode"
8799   { return mips_emit_prefetch (operands); }
8800   [(set_attr "type" "prefetch")])
8802 (define_insn "prefetch_indexed_si"
8803   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
8804                       (match_operand:SI 3 "register_operand" "r"))
8805              (match_operand:SI 1 "const_int_operand" "n")
8806              (match_operand:SI 2 "const_int_operand" "n"))]
8807   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
8808   { return mips_emit_prefetch (operands); }
8809   [(set_attr "type" "prefetchx")])
8811 (define_insn "prefetch_si"
8812   [(prefetch (match_operand:SI 0 "register_operand" "r")
8813              (match_operand:SI 1 "const_int_operand" "n")
8814              (match_operand:SI 2 "const_int_operand" "n"))]
8815   "ISA_HAS_PREFETCH && Pmode == SImode"
8817   operands[3] = const0_rtx;
8818   return mips_emit_prefetch (operands);
8820   [(set_attr "type" "prefetch")])
8822 (define_insn "prefetch_di_address"
8823   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
8824                       (match_operand:DI 3 "const_int_operand" "I"))
8825              (match_operand:DI 1 "const_int_operand" "n")
8826              (match_operand:DI 2 "const_int_operand" "n"))]
8827   "ISA_HAS_PREFETCH && Pmode == DImode"
8828   { return mips_emit_prefetch (operands); }
8829   [(set_attr "type" "prefetch")])
8831 (define_insn "prefetch_indexed_di"
8832   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
8833                       (match_operand:DI 3 "register_operand" "r"))
8834              (match_operand:DI 1 "const_int_operand" "n")
8835              (match_operand:DI 2 "const_int_operand" "n"))]
8836   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
8837   { return mips_emit_prefetch (operands); }
8838   [(set_attr "type" "prefetchx")])
8840 (define_insn "prefetch_di"
8841   [(prefetch (match_operand:DI 0 "register_operand" "r")
8842              (match_operand:DI 1 "const_int_operand" "n")
8843              (match_operand:DI 2 "const_int_operand" "n"))]
8844   "ISA_HAS_PREFETCH && Pmode == DImode"
8846   operands[3] = const0_rtx;
8847   return mips_emit_prefetch (operands);
8849   [(set_attr "type" "prefetch")])
8851 (define_insn "nop"
8852   [(const_int 0)]
8853   ""
8854   "%(nop%)"
8855   [(set_attr "type"     "nop")
8856    (set_attr "mode"     "none")])
8858 ;; Like nop, but commented out when outside a .set noreorder block.
8859 (define_insn "hazard_nop"
8860   [(const_int 1)]
8861   ""
8862   {
8863     if (set_noreorder)
8864       return "nop";
8865     else
8866       return "#nop";
8867   }
8868   [(set_attr "type"     "arith")])
8870 ;; MIPS4 Conditional move instructions.
8872 (define_insn ""
8873   [(set (match_operand:SI 0 "register_operand" "=d,d")
8874         (if_then_else:SI
8875          (match_operator 4 "equality_op"
8876                          [(match_operand:SI 1 "register_operand" "d,d")
8877                           (const_int 0)])
8878          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
8879          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
8880   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8881   "@
8882     mov%B4\t%0,%z2,%1
8883     mov%b4\t%0,%z3,%1"
8884   [(set_attr "type" "condmove")
8885    (set_attr "mode" "SI")])
8887 (define_insn ""
8888   [(set (match_operand:SI 0 "register_operand" "=d,d")
8889         (if_then_else:SI
8890          (match_operator 4 "equality_op"
8891                          [(match_operand:DI 1 "register_operand" "d,d")
8892                           (const_int 0)])
8893          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
8894          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
8895   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8896   "@
8897     mov%B4\t%0,%z2,%1
8898     mov%b4\t%0,%z3,%1"
8899   [(set_attr "type" "condmove")
8900    (set_attr "mode" "SI")])
8902 (define_insn ""
8903   [(set (match_operand:SI 0 "register_operand" "=d,d")
8904         (if_then_else:SI
8905          (match_operator 3 "equality_op" [(match_operand:CC 4
8906                                                             "register_operand"
8907                                                             "z,z")
8908                                           (const_int 0)])
8909          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
8910          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
8911   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8912   "@
8913     mov%T3\t%0,%z1,%4
8914     mov%t3\t%0,%z2,%4"
8915   [(set_attr "type" "condmove")
8916    (set_attr "mode" "SI")])
8918 (define_insn ""
8919   [(set (match_operand:DI 0 "register_operand" "=d,d")
8920         (if_then_else:DI
8921          (match_operator 4 "equality_op"
8922                          [(match_operand:SI 1 "register_operand" "d,d")
8923                           (const_int 0)])
8924          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
8925          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
8926   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8927   "@
8928     mov%B4\t%0,%z2,%1
8929     mov%b4\t%0,%z3,%1"
8930   [(set_attr "type" "condmove")
8931    (set_attr "mode" "DI")])
8933 (define_insn ""
8934   [(set (match_operand:DI 0 "register_operand" "=d,d")
8935         (if_then_else:DI
8936          (match_operator 4 "equality_op"
8937                          [(match_operand:DI 1 "register_operand" "d,d")
8938                           (const_int 0)])
8939          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
8940          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
8941   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8942   "@
8943     mov%B4\t%0,%z2,%1
8944     mov%b4\t%0,%z3,%1"
8945   [(set_attr "type" "condmove")
8946    (set_attr "mode" "DI")])
8948 (define_insn ""
8949   [(set (match_operand:DI 0 "register_operand" "=d,d")
8950         (if_then_else:DI
8951          (match_operator 3 "equality_op" [(match_operand:CC 4
8952                                                             "register_operand"
8953                                                             "z,z")
8954                                           (const_int 0)])
8955          (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
8956          (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
8957   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
8958   "@
8959     mov%T3\t%0,%z1,%4
8960     mov%t3\t%0,%z2,%4"
8961   [(set_attr "type" "condmove")
8962    (set_attr "mode" "DI")])
8964 (define_insn ""
8965   [(set (match_operand:SF 0 "register_operand" "=f,f")
8966         (if_then_else:SF
8967          (match_operator 4 "equality_op"
8968                          [(match_operand:SI 1 "register_operand" "d,d")
8969                           (const_int 0)])
8970          (match_operand:SF 2 "register_operand" "f,0")
8971          (match_operand:SF 3 "register_operand" "0,f")))]
8972   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8973   "@
8974     mov%B4.s\t%0,%2,%1
8975     mov%b4.s\t%0,%3,%1"
8976   [(set_attr "type" "condmove")
8977    (set_attr "mode" "SF")])
8979 (define_insn ""
8980   [(set (match_operand:SF 0 "register_operand" "=f,f")
8981         (if_then_else:SF
8982          (match_operator 4 "equality_op"
8983                          [(match_operand:DI 1 "register_operand" "d,d")
8984                           (const_int 0)])
8985          (match_operand:SF 2 "register_operand" "f,0")
8986          (match_operand:SF 3 "register_operand" "0,f")))]
8987   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8988   "@
8989     mov%B4.s\t%0,%2,%1
8990     mov%b4.s\t%0,%3,%1"
8991   [(set_attr "type" "condmove")
8992    (set_attr "mode" "SF")])
8994 (define_insn ""
8995   [(set (match_operand:SF 0 "register_operand" "=f,f")
8996         (if_then_else:SF
8997          (match_operator 3 "equality_op" [(match_operand:CC 4
8998                                                             "register_operand"
8999                                                             "z,z")
9000                                           (const_int 0)])
9001          (match_operand:SF 1 "register_operand" "f,0")
9002          (match_operand:SF 2 "register_operand" "0,f")))]
9003   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
9004   "@
9005     mov%T3.s\t%0,%1,%4
9006     mov%t3.s\t%0,%2,%4"
9007   [(set_attr "type" "condmove")
9008    (set_attr "mode" "SF")])
9010 (define_insn ""
9011   [(set (match_operand:DF 0 "register_operand" "=f,f")
9012         (if_then_else:DF
9013          (match_operator 4 "equality_op"
9014                          [(match_operand:SI 1 "register_operand" "d,d")
9015                           (const_int 0)])
9016          (match_operand:DF 2 "register_operand" "f,0")
9017          (match_operand:DF 3 "register_operand" "0,f")))]
9018   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9019   "@
9020     mov%B4.d\t%0,%2,%1
9021     mov%b4.d\t%0,%3,%1"
9022   [(set_attr "type" "condmove")
9023    (set_attr "mode" "DF")])
9025 (define_insn ""
9026   [(set (match_operand:DF 0 "register_operand" "=f,f")
9027         (if_then_else:DF
9028          (match_operator 4 "equality_op"
9029                          [(match_operand:DI 1 "register_operand" "d,d")
9030                           (const_int 0)])
9031          (match_operand:DF 2 "register_operand" "f,0")
9032          (match_operand:DF 3 "register_operand" "0,f")))]
9033   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9034   "@
9035     mov%B4.d\t%0,%2,%1
9036     mov%b4.d\t%0,%3,%1"
9037   [(set_attr "type" "condmove")
9038    (set_attr "mode" "DF")])
9040 (define_insn ""
9041   [(set (match_operand:DF 0 "register_operand" "=f,f")
9042         (if_then_else:DF
9043          (match_operator 3 "equality_op" [(match_operand:CC 4
9044                                                             "register_operand"
9045                                                             "z,z")
9046                                           (const_int 0)])
9047          (match_operand:DF 1 "register_operand" "f,0")
9048          (match_operand:DF 2 "register_operand" "0,f")))]
9049   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9050   "@
9051     mov%T3.d\t%0,%1,%4
9052     mov%t3.d\t%0,%2,%4"
9053   [(set_attr "type" "condmove")
9054    (set_attr "mode" "DF")])
9056 ;; These are the main define_expand's used to make conditional moves.
9058 (define_expand "movsicc"
9059   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
9060    (set (match_operand:SI 0 "register_operand" "")
9061         (if_then_else:SI (match_dup 5)
9062                          (match_operand:SI 2 "reg_or_0_operand" "")
9063                          (match_operand:SI 3 "reg_or_0_operand" "")))]
9064   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
9066   gen_conditional_move (operands);
9067   DONE;
9070 (define_expand "movdicc"
9071   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
9072    (set (match_operand:DI 0 "register_operand" "")
9073         (if_then_else:DI (match_dup 5)
9074                          (match_operand:DI 2 "reg_or_0_operand" "")
9075                          (match_operand:DI 3 "reg_or_0_operand" "")))]
9076   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
9078   gen_conditional_move (operands);
9079   DONE;
9082 (define_expand "movsfcc"
9083   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
9084    (set (match_operand:SF 0 "register_operand" "")
9085         (if_then_else:SF (match_dup 5)
9086                          (match_operand:SF 2 "register_operand" "")
9087                          (match_operand:SF 3 "register_operand" "")))]
9088   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
9090   gen_conditional_move (operands);
9091   DONE;
9094 (define_expand "movdfcc"
9095   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
9096    (set (match_operand:DF 0 "register_operand" "")
9097         (if_then_else:DF (match_dup 5)
9098                          (match_operand:DF 2 "register_operand" "")
9099                          (match_operand:DF 3 "register_operand" "")))]
9100   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9102   gen_conditional_move (operands);
9103   DONE;
9107 ;;  ....................
9109 ;;      mips16 inline constant tables
9111 ;;  ....................
9114 (define_insn "consttable_qi"
9115   [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")]
9116                     UNSPEC_CONSTTABLE_QI)]
9117   "TARGET_MIPS16"
9119   assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
9120   return "";
9122   [(set_attr "type"     "unknown")
9123    (set_attr "mode"     "QI")
9124    (set_attr "length"   "8")])
9126 (define_insn "consttable_hi"
9127   [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")]
9128                     UNSPEC_CONSTTABLE_HI)]
9129   "TARGET_MIPS16"
9131   assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9132   return "";
9134   [(set_attr "type"     "unknown")
9135    (set_attr "mode"     "HI")
9136    (set_attr "length"   "8")])
9138 (define_insn "consttable_si"
9139   [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")]
9140                     UNSPEC_CONSTTABLE_SI)]
9141   "TARGET_MIPS16"
9143   assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9144   return "";
9146   [(set_attr "type"     "unknown")
9147    (set_attr "mode"     "SI")
9148    (set_attr "length"   "8")])
9150 (define_insn "consttable_di"
9151   [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")]
9152                     UNSPEC_CONSTTABLE_DI)]
9153   "TARGET_MIPS16"
9155   assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9156   return "";
9158   [(set_attr "type"     "unknown")
9159    (set_attr "mode"     "DI")
9160    (set_attr "length"   "16")])
9162 (define_insn "consttable_sf"
9163   [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")]
9164                     UNSPEC_CONSTTABLE_SF)]
9165   "TARGET_MIPS16"
9167   REAL_VALUE_TYPE d;
9169   if (GET_CODE (operands[0]) != CONST_DOUBLE)
9170     abort ();
9171   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9172   assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9173   return "";
9175   [(set_attr "type"     "unknown")
9176    (set_attr "mode"     "SF")
9177    (set_attr "length"   "8")])
9179 (define_insn "consttable_df"
9180   [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")]
9181                     UNSPEC_CONSTTABLE_DF)]
9182   "TARGET_MIPS16"
9184   REAL_VALUE_TYPE d;
9186   if (GET_CODE (operands[0]) != CONST_DOUBLE)
9187     abort ();
9188   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9189   assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9190   return "";
9192   [(set_attr "type"     "unknown")
9193    (set_attr "mode"     "DF")
9194    (set_attr "length"   "16")])
9196 (define_insn "align_2"
9197   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_2)]
9198   "TARGET_MIPS16"
9199   ".align 1"
9200   [(set_attr "type"     "unknown")
9201    (set_attr "mode"     "HI")
9202    (set_attr "length"   "8")])
9204 (define_insn "align_4"
9205   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_4)]
9206   "TARGET_MIPS16"
9207   ".align 2"
9208   [(set_attr "type"     "unknown")
9209    (set_attr "mode"     "SI")
9210    (set_attr "length"   "8")])
9212 (define_insn "align_8"
9213   [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_8)]
9214   "TARGET_MIPS16"
9215   ".align 3"
9216   [(set_attr "type"     "unknown")
9217    (set_attr "mode"     "DI")
9218    (set_attr "length"   "12")])
9221 ;;  ....................
9223 ;;      mips16 peepholes
9225 ;;  ....................
9228 ;; On the mips16, reload will sometimes decide that a pseudo register
9229 ;; should go into $24, and then later on have to reload that register.
9230 ;; When that happens, we get a load of a general register followed by
9231 ;; a move from the general register to $24 followed by a branch.
9232 ;; These peepholes catch the common case, and fix it to just use the
9233 ;; general register for the branch.
9235 (define_peephole
9236   [(set (match_operand:SI 0 "register_operand" "=t")
9237         (match_operand:SI 1 "register_operand" "d"))
9238    (set (pc)
9239         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
9240                                                           (const_int 0)])
9241                       (match_operand 3 "pc_or_label_operand" "")
9242                       (match_operand 4 "pc_or_label_operand" "")))]
9243   "TARGET_MIPS16
9244    && GET_CODE (operands[0]) == REG
9245    && REGNO (operands[0]) == 24
9246    && dead_or_set_p (insn, operands[0])
9247    && GET_CODE (operands[1]) == REG
9248    && M16_REG_P (REGNO (operands[1]))"
9250   if (operands[3] != pc_rtx)
9251     return "b%C2z\t%1,%3";
9252   else
9253     return "b%N2z\t%1,%4";
9255   [(set_attr "type"     "branch")
9256    (set_attr "mode"     "none")
9257    (set_attr "length"   "8")])
9259 (define_peephole
9260   [(set (match_operand:DI 0 "register_operand" "=t")
9261         (match_operand:DI 1 "register_operand" "d"))
9262    (set (pc)
9263         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
9264                                                           (const_int 0)])
9265                       (match_operand 3 "pc_or_label_operand" "")
9266                       (match_operand 4 "pc_or_label_operand" "")))]
9267   "TARGET_MIPS16 && TARGET_64BIT
9268    && GET_CODE (operands[0]) == REG
9269    && REGNO (operands[0]) == 24
9270    && dead_or_set_p (insn, operands[0])
9271    && GET_CODE (operands[1]) == REG
9272    && M16_REG_P (REGNO (operands[1]))"
9274   if (operands[3] != pc_rtx)
9275     return "b%C2z\t%1,%3";
9276   else
9277     return "b%N2z\t%1,%4";
9279   [(set_attr "type"     "branch")
9280    (set_attr "mode"     "none")
9281    (set_attr "length"   "8")])
9283 ;; We can also have the reverse reload: reload will spill $24 into
9284 ;; another register, and then do a branch on that register when it
9285 ;; could have just stuck with $24.
9287 (define_peephole
9288   [(set (match_operand:SI 0 "register_operand" "=d")
9289         (match_operand:SI 1 "register_operand" "t"))
9290    (set (pc)
9291         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
9292                                                           (const_int 0)])
9293                       (match_operand 3 "pc_or_label_operand" "")
9294                       (match_operand 4 "pc_or_label_operand" "")))]
9295   "TARGET_MIPS16
9296    && GET_CODE (operands[1]) == REG
9297    && REGNO (operands[1]) == 24
9298    && GET_CODE (operands[0]) == REG
9299    && M16_REG_P (REGNO (operands[0]))
9300    && dead_or_set_p (insn, operands[0])"
9302   if (operands[3] != pc_rtx)
9303     return "bt%C2z\t%3";
9304   else
9305     return "bt%N2z\t%4";
9307   [(set_attr "type"     "branch")
9308    (set_attr "mode"     "none")
9309    (set_attr "length"   "8")])
9311 (define_peephole
9312   [(set (match_operand:DI 0 "register_operand" "=d")
9313         (match_operand:DI 1 "register_operand" "t"))
9314    (set (pc)
9315         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
9316                                                           (const_int 0)])
9317                       (match_operand 3 "pc_or_label_operand" "")
9318                       (match_operand 4 "pc_or_label_operand" "")))]
9319   "TARGET_MIPS16 && TARGET_64BIT
9320    && GET_CODE (operands[1]) == REG
9321    && REGNO (operands[1]) == 24
9322    && GET_CODE (operands[0]) == REG
9323    && M16_REG_P (REGNO (operands[0]))
9324    && dead_or_set_p (insn, operands[0])"
9326   if (operands[3] != pc_rtx)
9327     return "bt%C2z\t%3";
9328   else
9329     return "bt%N2z\t%4";
9331   [(set_attr "type"     "branch")
9332    (set_attr "mode"     "none")
9333    (set_attr "length"   "8")])
9335 (define_split
9336   [(match_operand 0 "small_data_pattern" "")]
9337   "reload_completed"
9338   [(match_dup 0)]
9339   { operands[0] = mips_rewrite_small_data (operands[0]); })