2004-06-23 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / config / mips / mips.md
blob3dfb98dc005d482a9e1c83a35d35b65355b5c716
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_INT        8)
39    (UNSPEC_CONSTTABLE_FLOAT      9)
40    (UNSPEC_ALIGN                14)
41    (UNSPEC_HIGH                 17)
42    (UNSPEC_LWL                  18)
43    (UNSPEC_LWR                  19)
44    (UNSPEC_SWL                  20)
45    (UNSPEC_SWR                  21)
46    (UNSPEC_LDL                  22)
47    (UNSPEC_LDR                  23)
48    (UNSPEC_SDL                  24)
49    (UNSPEC_SDR                  25)
50    (UNSPEC_LOADGP               26)
51    (UNSPEC_LOAD_CALL            27)
52    (UNSPEC_LOAD_GOT             28)
53    (UNSPEC_GP                   29)
54    (UNSPEC_MFHILO               30)
56    (UNSPEC_ADDRESS_FIRST        100)
58    (FAKE_CALL_REGNO             79)])
60 ;; ....................
62 ;;      Attributes
64 ;; ....................
66 (define_attr "got" "unset,xgot_high,load"
67   (const_string "unset"))
69 ;; For jal instructions, this attribute is DIRECT when the target address
70 ;; is symbolic and INDIRECT when it is a register.
71 (define_attr "jal" "unset,direct,indirect"
72   (const_string "unset"))
74 ;; This attribute is YES if the instruction is a jal macro (not a
75 ;; real jal instruction).
77 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
78 ;; restore $gp.  Direct jals are also macros in NewABI PIC since they
79 ;; load the target address into $25.
80 (define_attr "jal_macro" "no,yes"
81   (cond [(eq_attr "jal" "direct")
82          (symbol_ref "TARGET_ABICALLS != 0")
83          (eq_attr "jal" "indirect")
84          (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
85         (const_string "no")))
87 ;; Classification of each insn.
88 ;; branch       conditional branch
89 ;; jump         unconditional jump
90 ;; call         unconditional call
91 ;; load         load instruction(s)
92 ;; fpload       floating point load
93 ;; fpidxload    floating point indexed load
94 ;; store        store instruction(s)
95 ;; fpstore      floating point store
96 ;; fpidxstore   floating point indexed store
97 ;; prefetch     memory prefetch (register + offset)
98 ;; prefetchx    memory indexed prefetch (register + register)
99 ;; condmove     conditional moves
100 ;; xfer         transfer to/from coprocessor
101 ;; mthilo       transfer to hi/lo registers
102 ;; mfhilo       transfer from hi/lo registers
103 ;; const        load constant
104 ;; arith        integer arithmetic and logical instructions
105 ;; shift        integer shift instructions
106 ;; slt          set less than instructions
107 ;; clz          the clz and clo instructions
108 ;; trap         trap if instructions
109 ;; imul         integer multiply
110 ;; imadd        integer multiply-add
111 ;; idiv         integer divide
112 ;; fmove        floating point register move
113 ;; fadd         floating point add/subtract
114 ;; fmul         floating point multiply
115 ;; fmadd        floating point multiply-add
116 ;; fdiv         floating point divide
117 ;; fabs         floating point absolute value
118 ;; fneg         floating point negation
119 ;; fcmp         floating point compare
120 ;; fcvt         floating point convert
121 ;; fsqrt        floating point square root
122 ;; frsqrt       floating point reciprocal square root
123 ;; multi        multiword sequence (or user asm statements)
124 ;; nop          no operation
125 (define_attr "type"
126   "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
127   (cond [(eq_attr "jal" "!unset") (const_string "call")
128          (eq_attr "got" "load") (const_string "load")]
129         (const_string "unknown")))
131 ;; Main data type used by the insn
132 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
133   (const_string "unknown"))
135 ;; Is this an extended instruction in mips16 mode?
136 (define_attr "extended_mips16" "no,yes"
137   (const_string "no"))
139 ;; Length of instruction in bytes.
140 (define_attr "length" ""
141    (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
142           ;; If a branch is outside this range, we have a choice of two
143           ;; sequences.  For PIC, an out-of-range branch like:
144           ;;
145           ;;    bne     r1,r2,target
146           ;;    dslot
147           ;;
148           ;; becomes the equivalent of:
149           ;;
150           ;;    beq     r1,r2,1f
151           ;;    dslot
152           ;;    la      $at,target
153           ;;    jr      $at
154           ;;    nop
155           ;; 1:
156           ;;
157           ;; where the load address can be up to three instructions long
158           ;; (lw, nop, addiu).
159           ;;
160           ;; The non-PIC case is similar except that we use a direct
161           ;; jump instead of an la/jr pair.  Since the target of this
162           ;; jump is an absolute 28-bit bit address (the other bits
163           ;; coming from the address of the delay slot) this form cannot
164           ;; cross a 256MB boundary.  We could provide the option of
165           ;; using la/jr in this case too, but we do not do so at
166           ;; present.
167           ;;
168           ;; Note that this value does not account for the delay slot
169           ;; instruction, whose length is added separately.  If the RTL
170           ;; pattern has no explicit delay slot, mips_adjust_insn_length
171           ;; will add the length of the implicit nop.  The values for
172           ;; forward and backward branches will be different as well.
173           (eq_attr "type" "branch")
174           (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
175                       (le (minus (pc) (match_dup 1)) (const_int 131068)))
176                   (const_int 4)
177                  (ne (symbol_ref "flag_pic") (const_int 0))
178                  (const_int 24)
179                  ] (const_int 12))
181           (eq_attr "got" "load")
182           (const_int 4)
183           (eq_attr "got" "xgot_high")
184           (const_int 8)
186           (eq_attr "type" "const")
187           (symbol_ref "mips_const_insns (operands[1]) * 4")
188           (eq_attr "type" "load,fpload,fpidxload")
189           (symbol_ref "mips_fetch_insns (operands[1]) * 4")
190           (eq_attr "type" "store,fpstore,fpidxstore")
191           (symbol_ref "mips_fetch_insns (operands[0]) * 4")
193           ;; In the worst case, a call macro will take 8 instructions:
194           ;;
195           ;;     lui $25,%call_hi(FOO)
196           ;;     addu $25,$25,$28
197           ;;     lw $25,%call_lo(FOO)($25)
198           ;;     nop
199           ;;     jalr $25
200           ;;     nop
201           ;;     lw $gp,X($sp)
202           ;;     nop
203           (eq_attr "jal_macro" "yes")
204           (const_int 32)
206           (and (eq_attr "extended_mips16" "yes")
207                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
208           (const_int 8)
210           ;; Various VR4120 errata require a nop to be inserted after a macc
211           ;; instruction.  The assembler does this for us, so account for
212           ;; the worst-case length here.
213           (and (eq_attr "type" "imadd")
214                (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
215           (const_int 8)
217           ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
218           ;; the result of the second one is missed.  The assembler should work
219           ;; around this by inserting a nop after the first dmult.
220           (and (eq_attr "type" "imul")
221                (and (eq_attr "mode" "DI")
222                     (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
223           (const_int 8)
225           (eq_attr "type" "idiv")
226           (symbol_ref "mips_idiv_insns () * 4")
227           ] (const_int 4)))
229 ;; Attribute describing the processor.  This attribute must match exactly
230 ;; with the processor_type enumeration in mips.h.
231 (define_attr "cpu"
232   "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
233   (const (symbol_ref "mips_tune")))
235 ;; The type of hardware hazard associated with this instruction.
236 ;; DELAY means that the next instruction cannot read the result
237 ;; of this one.  HILO means that the next two instructions cannot
238 ;; write to HI or LO.
239 (define_attr "hazard" "none,delay,hilo"
240   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
241               (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
242          (const_string "delay")
244          (and (eq_attr "type" "xfer")
245               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
246          (const_string "delay")
248          (and (eq_attr "type" "fcmp")
249               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
250          (const_string "delay")
252          ;; The r4000 multiplication patterns include an mflo instruction.
253          (and (eq_attr "type" "imul")
254               (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
255          (const_string "hilo")
257          (and (eq_attr "type" "mfhilo")
258               (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
259          (const_string "hilo")]
260         (const_string "none")))
262 ;; Is it a single instruction?
263 (define_attr "single_insn" "no,yes"
264   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
266 ;; Can the instruction be put into a delay slot?
267 (define_attr "can_delay" "no,yes"
268   (if_then_else (and (eq_attr "type" "!branch,call,jump")
269                      (and (eq_attr "hazard" "none")
270                           (eq_attr "single_insn" "yes")))
271                 (const_string "yes")
272                 (const_string "no")))
274 ;; Attribute defining whether or not we can use the branch-likely instructions
275 (define_attr "branch_likely" "no,yes"
276   (const
277    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
278                  (const_string "yes")
279                  (const_string "no"))))
281 ;; True if an instruction might assign to hi or lo when reloaded.
282 ;; This is used by the TUNE_MACC_CHAINS code.
283 (define_attr "may_clobber_hilo" "no,yes"
284   (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
285                 (const_string "yes")
286                 (const_string "no")))
288 ;; Describe a user's asm statement.
289 (define_asm_attributes
290   [(set_attr "type" "multi")])
292 ;; .........................
294 ;;      Branch, call and jump delay slots
296 ;; .........................
298 (define_delay (and (eq_attr "type" "branch")
299                    (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
300   [(eq_attr "can_delay" "yes")
301    (nil)
302    (and (eq_attr "branch_likely" "yes")
303         (eq_attr "can_delay" "yes"))])
305 (define_delay (eq_attr "type" "jump")
306   [(eq_attr "can_delay" "yes")
307    (nil)
308    (nil)])
310 (define_delay (and (eq_attr "type" "call")
311                    (eq_attr "jal_macro" "no"))
312   [(eq_attr "can_delay" "yes")
313    (nil)
314    (nil)])
316 ;; .........................
318 ;;      Functional units
320 ;; .........................
322 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
323 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
325 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
327 (define_function_unit "memory" 1 0
328   (and (eq_attr "type" "load,fpload,fpidxload")
329        (eq_attr "cpu" "r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
330   3 0)
332 (define_function_unit "memory" 1 0
333   (and (eq_attr "type" "load,fpload,fpidxload")
334        (eq_attr "cpu" "r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
335   2 0)
337 (define_function_unit "memory"   1 0
338   (eq_attr "type" "store,fpstore,fpidxstore")
339   1 0)
341 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
343 (define_function_unit "imuldiv"  1 0
344   (eq_attr "type" "mthilo,mfhilo")
345   1 3)
347 (define_function_unit "imuldiv"  1 0
348   (and (eq_attr "type" "imul,imadd")
349        (eq_attr "cpu" "r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
350   17 17)
352 ;; On them mips16, we want to stronly discourage a mult from appearing
353 ;; after an mflo, since that requires explicit nop instructions.  We
354 ;; do this by pretending that mflo ties up the function unit for long
355 ;; enough that the scheduler will ignore load stalls and the like when
356 ;; selecting instructions to between the two instructions.
358 (define_function_unit "imuldiv" 1 0
359   (and (eq_attr "type" "mfhilo") (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
360   1 5)
362 (define_function_unit "imuldiv"  1 0
363   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r3900"))
364   12 12)
366 (define_function_unit "imuldiv"  1 0
367   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4000,r4600"))
368   10 10)
370 (define_function_unit "imuldiv"  1 0
371   (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4650"))
372   4 4)
374 (define_function_unit "imuldiv"  1 0
375   (and (eq_attr "type" "imul,imadd")
376        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
377   1 1)
379 (define_function_unit "imuldiv"  1 0
380   (and (eq_attr "type" "imul,imadd")
381        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
382   4 4)
384 (define_function_unit "imuldiv"  1 0
385   (and (eq_attr "type" "imul,imadd")
386        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
387   5 5)
389 (define_function_unit "imuldiv"  1 0
390   (and (eq_attr "type" "imul,imadd")
391        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
392   8 8)
394 (define_function_unit "imuldiv"  1 0
395   (and (eq_attr "type" "imul,imadd")
396        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
397   9 9)
399 (define_function_unit "imuldiv"  1 0
400   (and (eq_attr "type" "idiv")
401        (eq_attr "cpu" "r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
402   38 38)
404 (define_function_unit "imuldiv"  1 0
405   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3900"))
406   35 35)
408 (define_function_unit "imuldiv"  1 0
409   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
410   42 42)
412 (define_function_unit "imuldiv"  1 0
413   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
414   36 36)
416 (define_function_unit "imuldiv"  1 0
417   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
418   69 69)
420 (define_function_unit "imuldiv" 1 0
421   (and (eq_attr "type" "idiv")
422        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
423   35 35)
425 (define_function_unit "imuldiv" 1 0
426   (and (eq_attr "type" "idiv")
427        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
428   67 67)
430 (define_function_unit "imuldiv" 1 0
431   (and (eq_attr "type" "idiv")
432        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
433   37 37)
435 (define_function_unit "imuldiv" 1 0
436   (and (eq_attr "type" "idiv")
437        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
438   69 69)
440 (define_function_unit "imuldiv" 1 0
441   (and (eq_attr "type" "idiv")
442        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
443   36 36)
445 (define_function_unit "imuldiv" 1 0
446   (and (eq_attr "type" "idiv")
447        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
448   68 68)
450 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
451 ;; the FP hardware is part of the normal ALU circuitry.  This means FP
452 ;; instructions affect the pipe-line, and no functional unit
453 ;; parallelism can occur on R4300 processors.  To force GCC into coding
454 ;; for only a single functional unit, we force the R4300 FP
455 ;; instructions to be processed in the "imuldiv" unit.
457 (define_function_unit "adder" 1 1
458   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3900,r6000,r4300,r5000"))
459   3 0)
461 (define_function_unit "adder" 1 1
462   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3900,r6000"))
463   2 0)
465 (define_function_unit "adder" 1 1
466   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
467   1 0)
469 (define_function_unit "adder" 1 1
470   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3900,r6000,r4300"))
471   4 0)
473 (define_function_unit "adder" 1 1
474   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3900"))
475   2 0)
477 (define_function_unit "adder" 1 1
478   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
479   3 0)
481 (define_function_unit "adder" 1 1
482   (and (eq_attr "type" "fabs,fneg,fmove")
483        (eq_attr "cpu" "r3900,r4600,r4650,r4300,r5000"))
484   2 0)
486 (define_function_unit "adder" 1 1
487   (and (eq_attr "type" "fabs,fneg,fmove") (eq_attr "cpu" "r3900,r4600,r4650,r5000"))
488   1 0)
490 (define_function_unit "mult" 1 1
491   (and (eq_attr "type" "fmul")
492        (and (eq_attr "mode" "SF")
493             (eq_attr "cpu" "r3900,r6000,r4600,r4650,r4300,r5000")))
494   7 0)
496 (define_function_unit "mult" 1 1
497   (and (eq_attr "type" "fmul")
498        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3900,r5000")))
499   4 0)
501 (define_function_unit "mult" 1 1
502   (and (eq_attr "type" "fmul")
503        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
504   5 0)
506 (define_function_unit "mult" 1 1
507   (and (eq_attr "type" "fmul")
508        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
509   8 0)
511 (define_function_unit "mult" 1 1
512   (and (eq_attr "type" "fmul")
513        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3900,r6000,r4300,r5000")))
514   8 0)
516 (define_function_unit "mult" 1 1
517   (and (eq_attr "type" "fmul")
518        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3900,r5000")))
519   5 0)
521 (define_function_unit "mult" 1 1
522   (and (eq_attr "type" "fmul")
523        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
524   6 0)
526 (define_function_unit "divide" 1 1
527   (and (eq_attr "type" "fdiv")
528        (and (eq_attr "mode" "SF")
529             (eq_attr "cpu" "r3900,r6000,r4600,r4650,r4300,r5000")))
530   23 0)
532 (define_function_unit "divide" 1 1
533   (and (eq_attr "type" "fdiv")
534        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3900")))
535   12 0)
537 (define_function_unit "divide" 1 1
538   (and (eq_attr "type" "fdiv")
539        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
540   15 0)
542 (define_function_unit "divide" 1 1
543   (and (eq_attr "type" "fdiv")
544        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
545   32 0)
547 (define_function_unit "divide" 1 1
548   (and (eq_attr "type" "fdiv")
549        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
550   21 0)
552 (define_function_unit "divide" 1 1
553   (and (eq_attr "type" "fdiv")
554        (and (eq_attr "mode" "DF")
555             (eq_attr "cpu" "r3900,r6000,r4600,r4650,r4300")))
556   36 0)
558 (define_function_unit "divide" 1 1
559   (and (eq_attr "type" "fdiv")
560        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3900")))
561   19 0)
563 (define_function_unit "divide" 1 1
564   (and (eq_attr "type" "fdiv")
565        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
566   16 0)
568 (define_function_unit "divide" 1 1
569   (and (eq_attr "type" "fdiv")
570        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
571   61 0)
573 ;;; ??? Is this number right?
574 (define_function_unit "divide" 1 1
575   (and (eq_attr "type" "fsqrt,frsqrt")
576        (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
577   54 0)
579 (define_function_unit "divide" 1 1
580   (and (eq_attr "type" "fsqrt,frsqrt")
581        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
582   31 0)
584 (define_function_unit "divide" 1 1
585   (and (eq_attr "type" "fsqrt,frsqrt")
586        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
587   21 0)
589 ;;; ??? Is this number right?
590 (define_function_unit "divide" 1 1
591   (and (eq_attr "type" "fsqrt,frsqrt")
592        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
593   112 0)
595 (define_function_unit "divide" 1 1
596   (and (eq_attr "type" "fsqrt,frsqrt")
597        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
598   60 0)
600 (define_function_unit "divide" 1 1
601   (and (eq_attr "type" "fsqrt,frsqrt")
602        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
603   36 0)
605 ;; R4300 FP instruction classes treated as part of the "imuldiv"
606 ;; functional unit:
608 (define_function_unit "imuldiv" 1 0
609   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
610   3 3)
612 (define_function_unit "imuldiv" 1 0
613   (and (eq_attr "type" "fcmp,fabs,fneg,fmove") (eq_attr "cpu" "r4300"))
614   1 1)
616 (define_function_unit "imuldiv" 1 0
617   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
618   5 5)
619 (define_function_unit "imuldiv" 1 0
620   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
621   8 8)
623 (define_function_unit "imuldiv" 1 0
624   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
625        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
626   29 29)
627 (define_function_unit "imuldiv" 1 0
628   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
629        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
630   58 58)
632 ;; Include scheduling descriptions.
634 (include "3000.md")
635 (include "4130.md")
636 (include "5400.md")
637 (include "5500.md")
638 (include "7000.md")
639 (include "9000.md")
640 (include "sb1.md")
641 (include "sr71k.md")
644 ;;  ....................
646 ;;      CONDITIONAL TRAPS
648 ;;  ....................
651 (define_insn "trap"
652   [(trap_if (const_int 1) (const_int 0))]
653   ""
655   if (ISA_HAS_COND_TRAP)
656     return "teq\t$0,$0";
657   /* The IRIX 6 O32 assembler requires the first break operand.  */
658   else if (TARGET_MIPS16 || !TARGET_GAS)
659     return "break 0";
660   else
661     return "break";
663   [(set_attr "type"     "trap")])
665 (define_expand "conditional_trap"
666   [(trap_if (match_operator 0 "cmp_op"
667                             [(match_dup 2) (match_dup 3)])
668             (match_operand 1 "const_int_operand"))]
669   "ISA_HAS_COND_TRAP"
671   if (operands[1] == const0_rtx)
672     {
673       mips_gen_conditional_trap (operands);
674       DONE;
675     }
676   else
677     FAIL;
680 (define_insn ""
681   [(trap_if (match_operator 0 "trap_cmp_op"
682                             [(match_operand:SI 1 "reg_or_0_operand" "dJ")
683                              (match_operand:SI 2 "arith_operand" "dI")])
684             (const_int 0))]
685   "ISA_HAS_COND_TRAP"
686   "t%C0\t%z1,%z2"
687   [(set_attr "type"     "trap")])
689 (define_insn ""
690   [(trap_if (match_operator 0 "trap_cmp_op"
691                             [(match_operand:DI 1 "reg_or_0_operand" "dJ")
692                              (match_operand:DI 2 "arith_operand" "dI")])
693             (const_int 0))]
694   "TARGET_64BIT && ISA_HAS_COND_TRAP"
695   "t%C0\t%z1,%z2"
696   [(set_attr "type"     "trap")])
699 ;;  ....................
701 ;;      ADDITION
703 ;;  ....................
706 (define_insn "adddf3"
707   [(set (match_operand:DF 0 "register_operand" "=f")
708         (plus:DF (match_operand:DF 1 "register_operand" "f")
709                  (match_operand:DF 2 "register_operand" "f")))]
710   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
711   "add.d\t%0,%1,%2"
712   [(set_attr "type"     "fadd")
713    (set_attr "mode"     "DF")])
715 (define_insn "addsf3"
716   [(set (match_operand:SF 0 "register_operand" "=f")
717         (plus:SF (match_operand:SF 1 "register_operand" "f")
718                  (match_operand:SF 2 "register_operand" "f")))]
719   "TARGET_HARD_FLOAT"
720   "add.s\t%0,%1,%2"
721   [(set_attr "type"     "fadd")
722    (set_attr "mode"     "SF")])
724 (define_expand "addsi3"
725   [(set (match_operand:SI 0 "register_operand")
726         (plus:SI (match_operand:SI 1 "reg_or_0_operand")
727                  (match_operand:SI 2 "arith_operand")))]
728   ""
730   /* If a large stack adjustment was forced into a register, we may be
731      asked to generate rtx such as:
733         (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
735      but no such instruction is available in mips16.  Handle it by
736      using a temporary.  */
737   if (TARGET_MIPS16
738       && REGNO (operands[0]) == STACK_POINTER_REGNUM
739       && ((GET_CODE (operands[1]) == REG
740            && REGNO (operands[1]) != STACK_POINTER_REGNUM)
741           || GET_CODE (operands[2]) != CONST_INT))
742     {
743       rtx tmp = gen_reg_rtx (SImode);
745       emit_move_insn (tmp, operands[1]);
746       emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
747       emit_move_insn (operands[0], tmp);
748       DONE;
749     }
752 (define_insn "addsi3_internal"
753   [(set (match_operand:SI 0 "register_operand" "=d,d")
754         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
755                  (match_operand:SI 2 "arith_operand" "d,Q")))]
756   "!TARGET_MIPS16"
757   "@
758     addu\t%0,%z1,%2
759     addiu\t%0,%z1,%2"
760   [(set_attr "type"     "arith")
761    (set_attr "mode"     "SI")])
763 ;; For the mips16, we need to recognize stack pointer additions
764 ;; explicitly, since we don't have a constraint for $sp.  These insns
765 ;; will be generated by the save_restore_insns functions.
767 (define_insn ""
768   [(set (reg:SI 29)
769         (plus:SI (reg:SI 29)
770                  (match_operand:SI 0 "small_int" "I")))]
771   "TARGET_MIPS16"
772   "addu\t%$,%$,%0"
773   [(set_attr "type"     "arith")
774    (set_attr "mode"     "SI")
775    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
776                                       (const_int 4)
777                                       (const_int 8)))])
779 (define_insn ""
780   [(set (match_operand:SI 0 "register_operand" "=d")
781         (plus:SI (reg:SI 29)
782                  (match_operand:SI 1 "small_int" "I")))]
783   "TARGET_MIPS16"
784   "addu\t%0,%$,%1"
785   [(set_attr "type"     "arith")
786    (set_attr "mode"     "SI")
787    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4")
788                                       (const_int 4)
789                                       (const_int 8)))])
791 (define_insn ""
792   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
793         (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
794                  (match_operand:SI 2 "arith_operand" "Q,O,d")))]
795   "TARGET_MIPS16
796    && (GET_CODE (operands[1]) != REG
797        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
798        || M16_REG_P (REGNO (operands[1]))
799        || REGNO (operands[1]) == ARG_POINTER_REGNUM
800        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
801        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
802    && (GET_CODE (operands[2]) != REG
803        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
804        || M16_REG_P (REGNO (operands[2]))
805        || REGNO (operands[2]) == ARG_POINTER_REGNUM
806        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
807        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
809   if (REGNO (operands[0]) == REGNO (operands[1]))
810     return "addu\t%0,%2";
811   else
812     return "addu\t%0,%1,%2";
814   [(set_attr "type"     "arith")
815    (set_attr "mode"     "SI")
816    (set_attr_alternative "length"
817                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
818                                (const_int 4)
819                                (const_int 8))
820                  (if_then_else (match_operand:VOID 2 "m16_simm4_1")
821                                (const_int 4)
822                                (const_int 8))
823                  (const_int 4)])])
826 ;; On the mips16, we can sometimes split an add of a constant which is
827 ;; a 4 byte instruction into two adds which are both 2 byte
828 ;; instructions.  There are two cases: one where we are adding a
829 ;; constant plus a register to another register, and one where we are
830 ;; simply adding a constant to a register.
832 (define_split
833   [(set (match_operand:SI 0 "register_operand")
834         (plus:SI (match_dup 0)
835                  (match_operand:SI 1 "const_int_operand")))]
836   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
837    && GET_CODE (operands[0]) == REG
838    && M16_REG_P (REGNO (operands[0]))
839    && GET_CODE (operands[1]) == CONST_INT
840    && ((INTVAL (operands[1]) > 0x7f
841         && INTVAL (operands[1]) <= 0x7f + 0x7f)
842        || (INTVAL (operands[1]) < - 0x80
843            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
844   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
845    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
847   HOST_WIDE_INT val = INTVAL (operands[1]);
849   if (val >= 0)
850     {
851       operands[1] = GEN_INT (0x7f);
852       operands[2] = GEN_INT (val - 0x7f);
853     }
854   else
855     {
856       operands[1] = GEN_INT (- 0x80);
857       operands[2] = GEN_INT (val + 0x80);
858     }
861 (define_split
862   [(set (match_operand:SI 0 "register_operand")
863         (plus:SI (match_operand:SI 1 "register_operand")
864                  (match_operand:SI 2 "const_int_operand")))]
865   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
866    && GET_CODE (operands[0]) == REG
867    && M16_REG_P (REGNO (operands[0]))
868    && GET_CODE (operands[1]) == REG
869    && M16_REG_P (REGNO (operands[1]))
870    && REGNO (operands[0]) != REGNO (operands[1])
871    && GET_CODE (operands[2]) == CONST_INT
872    && ((INTVAL (operands[2]) > 0x7
873         && INTVAL (operands[2]) <= 0x7 + 0x7f)
874        || (INTVAL (operands[2]) < - 0x8
875            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
876   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
877    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
879   HOST_WIDE_INT val = INTVAL (operands[2]);
881   if (val >= 0)
882     {
883       operands[2] = GEN_INT (0x7);
884       operands[3] = GEN_INT (val - 0x7);
885     }
886   else
887     {
888       operands[2] = GEN_INT (- 0x8);
889       operands[3] = GEN_INT (val + 0x8);
890     }
893 (define_expand "adddi3"
894   [(set (match_operand:DI 0 "register_operand")
895         (plus:DI (match_operand:DI 1 "register_operand")
896                  (match_operand:DI 2 "arith_operand")))]
897   "TARGET_64BIT"
899   /* If a large stack adjustment was forced into a register, we may be
900      asked to generate rtx such as:
902         (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
904      but no such instruction is available in mips16.  Handle it by
905      using a temporary.  */
906   if (TARGET_MIPS16
907       && REGNO (operands[0]) == STACK_POINTER_REGNUM
908       && ((GET_CODE (operands[1]) == REG
909            && REGNO (operands[1]) != STACK_POINTER_REGNUM)
910           || GET_CODE (operands[2]) != CONST_INT))
911     {
912       rtx tmp = gen_reg_rtx (DImode);
914       emit_move_insn (tmp, operands[1]);
915       emit_insn (gen_adddi3 (tmp, tmp, operands[2]));
916       emit_move_insn (operands[0], tmp);
917       DONE;
918     }
921 (define_insn "adddi3_internal"
922   [(set (match_operand:DI 0 "register_operand" "=d,d")
923         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")
924                  (match_operand:DI 2 "arith_operand" "d,Q")))]
925   "TARGET_64BIT && !TARGET_MIPS16"
926   "@
927     daddu\t%0,%z1,%2
928     daddiu\t%0,%z1,%2"
929   [(set_attr "type"     "arith")
930    (set_attr "mode"     "DI")])
932 ;; For the mips16, we need to recognize stack pointer additions
933 ;; explicitly, since we don't have a constraint for $sp.  These insns
934 ;; will be generated by the save_restore_insns functions.
936 (define_insn ""
937   [(set (reg:DI 29)
938         (plus:DI (reg:DI 29)
939                  (match_operand:DI 0 "small_int" "I")))]
940   "TARGET_MIPS16 && TARGET_64BIT"
941   "daddu\t%$,%$,%0"
942   [(set_attr "type"     "arith")
943    (set_attr "mode"     "DI")
944    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
945                                       (const_int 4)
946                                       (const_int 8)))])
948 (define_insn ""
949   [(set (match_operand:DI 0 "register_operand" "=d")
950         (plus:DI (reg:DI 29)
951                  (match_operand:DI 1 "small_int" "I")))]
952   "TARGET_MIPS16 && TARGET_64BIT"
953   "daddu\t%0,%$,%1"
954   [(set_attr "type"     "arith")
955    (set_attr "mode"     "DI")
956    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4")
957                                       (const_int 4)
958                                       (const_int 8)))])
960 (define_insn ""
961   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
962         (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
963                  (match_operand:DI 2 "arith_operand" "Q,O,d")))]
964   "TARGET_MIPS16 && TARGET_64BIT
965    && (GET_CODE (operands[1]) != REG
966        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
967        || M16_REG_P (REGNO (operands[1]))
968        || REGNO (operands[1]) == ARG_POINTER_REGNUM
969        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
970        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
971    && (GET_CODE (operands[2]) != REG
972        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
973        || M16_REG_P (REGNO (operands[2]))
974        || REGNO (operands[2]) == ARG_POINTER_REGNUM
975        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
976        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
978   if (REGNO (operands[0]) == REGNO (operands[1]))
979     return "daddu\t%0,%2";
980   else
981     return "daddu\t%0,%1,%2";
983   [(set_attr "type"     "arith")
984    (set_attr "mode"     "DI")
985    (set_attr_alternative "length"
986                 [(if_then_else (match_operand:VOID 2 "m16_simm5_1")
987                                (const_int 4)
988                                (const_int 8))
989                  (if_then_else (match_operand:VOID 2 "m16_simm4_1")
990                                (const_int 4)
991                                (const_int 8))
992                  (const_int 4)])])
995 ;; On the mips16, we can sometimes split an add of a constant which is
996 ;; a 4 byte instruction into two adds which are both 2 byte
997 ;; instructions.  There are two cases: one where we are adding a
998 ;; constant plus a register to another register, and one where we are
999 ;; simply adding a constant to a register.
1001 (define_split
1002   [(set (match_operand:DI 0 "register_operand")
1003         (plus:DI (match_dup 0)
1004                  (match_operand:DI 1 "const_int_operand")))]
1005   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1006    && GET_CODE (operands[0]) == REG
1007    && M16_REG_P (REGNO (operands[0]))
1008    && GET_CODE (operands[1]) == CONST_INT
1009    && ((INTVAL (operands[1]) > 0xf
1010         && INTVAL (operands[1]) <= 0xf + 0xf)
1011        || (INTVAL (operands[1]) < - 0x10
1012            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1013   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1014    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1016   HOST_WIDE_INT val = INTVAL (operands[1]);
1018   if (val >= 0)
1019     {
1020       operands[1] = GEN_INT (0xf);
1021       operands[2] = GEN_INT (val - 0xf);
1022     }
1023   else
1024     {
1025       operands[1] = GEN_INT (- 0x10);
1026       operands[2] = GEN_INT (val + 0x10);
1027     }
1030 (define_split
1031   [(set (match_operand:DI 0 "register_operand")
1032         (plus:DI (match_operand:DI 1 "register_operand")
1033                  (match_operand:DI 2 "const_int_operand")))]
1034   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1035    && GET_CODE (operands[0]) == REG
1036    && M16_REG_P (REGNO (operands[0]))
1037    && GET_CODE (operands[1]) == REG
1038    && M16_REG_P (REGNO (operands[1]))
1039    && REGNO (operands[0]) != REGNO (operands[1])
1040    && GET_CODE (operands[2]) == CONST_INT
1041    && ((INTVAL (operands[2]) > 0x7
1042         && INTVAL (operands[2]) <= 0x7 + 0xf)
1043        || (INTVAL (operands[2]) < - 0x8
1044            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1045   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1046    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1048   HOST_WIDE_INT val = INTVAL (operands[2]);
1050   if (val >= 0)
1051     {
1052       operands[2] = GEN_INT (0x7);
1053       operands[3] = GEN_INT (val - 0x7);
1054     }
1055   else
1056     {
1057       operands[2] = GEN_INT (- 0x8);
1058       operands[3] = GEN_INT (val + 0x8);
1059     }
1062 (define_insn "addsi3_internal_2"
1063   [(set (match_operand:DI 0 "register_operand" "=d,d")
1064         (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
1065                                  (match_operand:SI 2 "arith_operand" "d,Q"))))]
1066   "TARGET_64BIT && !TARGET_MIPS16"
1067   "@
1068     addu\t%0,%z1,%2
1069     addiu\t%0,%z1,%2"
1070   [(set_attr "type"     "arith")
1071    (set_attr "mode"     "SI")])
1073 (define_insn ""
1074   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1075         (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1076                                  (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
1077   "TARGET_MIPS16 && TARGET_64BIT"
1079   if (REGNO (operands[0]) == REGNO (operands[1]))
1080     return "addu\t%0,%2";
1081   else
1082     return "addu\t%0,%1,%2";
1084   [(set_attr "type"     "arith")
1085    (set_attr "mode"     "SI")
1086    (set_attr_alternative "length"
1087                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
1088                                (const_int 4)
1089                                (const_int 8))
1090                  (if_then_else (match_operand:VOID 2 "m16_simm4_1")
1091                                (const_int 4)
1092                                (const_int 8))
1093                  (const_int 4)])])
1096 ;;  ....................
1098 ;;      SUBTRACTION
1100 ;;  ....................
1103 (define_insn "subdf3"
1104   [(set (match_operand:DF 0 "register_operand" "=f")
1105         (minus:DF (match_operand:DF 1 "register_operand" "f")
1106                   (match_operand:DF 2 "register_operand" "f")))]
1107   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1108   "sub.d\t%0,%1,%2"
1109   [(set_attr "type"     "fadd")
1110    (set_attr "mode"     "DF")])
1112 (define_insn "subsf3"
1113   [(set (match_operand:SF 0 "register_operand" "=f")
1114         (minus:SF (match_operand:SF 1 "register_operand" "f")
1115                   (match_operand:SF 2 "register_operand" "f")))]
1116   "TARGET_HARD_FLOAT"
1117   "sub.s\t%0,%1,%2"
1118   [(set_attr "type"     "fadd")
1119    (set_attr "mode"     "SF")])
1121 (define_expand "subsi3"
1122   [(set (match_operand:SI 0 "register_operand")
1123         (minus:SI (match_operand:SI 1 "register_operand")
1124                   (match_operand:SI 2 "register_operand")))]
1125   ""
1126   "")
1128 (define_insn "subsi3_internal"
1129   [(set (match_operand:SI 0 "register_operand" "=d")
1130         (minus:SI (match_operand:SI 1 "register_operand" "d")
1131                   (match_operand:SI 2 "register_operand" "d")))]
1132   ""
1133   "subu\t%0,%z1,%2"
1134   [(set_attr "type"     "arith")
1135    (set_attr "mode"     "SI")])
1137 (define_insn "subdi3"
1138   [(set (match_operand:DI 0 "register_operand" "=d")
1139         (minus:DI (match_operand:DI 1 "register_operand" "d")
1140                   (match_operand:DI 2 "register_operand" "d")))]
1141   "TARGET_64BIT"
1142   "dsubu\t%0,%1,%2"
1143   [(set_attr "type"     "arith")
1144    (set_attr "mode"     "DI")])
1146 (define_insn "subsi3_internal_2"
1147   [(set (match_operand:DI 0 "register_operand" "=d")
1148         (sign_extend:DI
1149             (minus:SI (match_operand:SI 1 "register_operand" "d")
1150                       (match_operand:SI 2 "register_operand" "d"))))]
1151   "TARGET_64BIT"
1152   "subu\t%0,%1,%2"
1153   [(set_attr "type"     "arith")
1154    (set_attr "mode"     "DI")])
1157 ;;  ....................
1159 ;;      MULTIPLICATION
1161 ;;  ....................
1164 (define_expand "muldf3"
1165   [(set (match_operand:DF 0 "register_operand")
1166         (mult:DF (match_operand:DF 1 "register_operand")
1167                  (match_operand:DF 2 "register_operand")))]
1168   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1169   "")
1171 (define_insn "muldf3_internal"
1172   [(set (match_operand:DF 0 "register_operand" "=f")
1173         (mult:DF (match_operand:DF 1 "register_operand" "f")
1174                  (match_operand:DF 2 "register_operand" "f")))]
1175   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
1176   "mul.d\t%0,%1,%2"
1177   [(set_attr "type"     "fmul")
1178    (set_attr "mode"     "DF")])
1180 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1181 ;; operands may corrupt immediately following multiplies. This is a
1182 ;; simple fix to insert NOPs.
1184 (define_insn "muldf3_r4300"
1185   [(set (match_operand:DF 0 "register_operand" "=f")
1186         (mult:DF (match_operand:DF 1 "register_operand" "f")
1187                  (match_operand:DF 2 "register_operand" "f")))]
1188   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
1189   "mul.d\t%0,%1,%2\;nop"
1190   [(set_attr "type"     "fmul")
1191    (set_attr "mode"     "DF")
1192    (set_attr "length"   "8")])
1194 (define_expand "mulsf3"
1195   [(set (match_operand:SF 0 "register_operand")
1196         (mult:SF (match_operand:SF 1 "register_operand")
1197                  (match_operand:SF 2 "register_operand")))]
1198   "TARGET_HARD_FLOAT"
1199   "")
1201 (define_insn "mulsf3_internal"
1202   [(set (match_operand:SF 0 "register_operand" "=f")
1203         (mult:SF (match_operand:SF 1 "register_operand" "f")
1204                  (match_operand:SF 2 "register_operand" "f")))]
1205   "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
1206   "mul.s\t%0,%1,%2"
1207   [(set_attr "type"     "fmul")
1208    (set_attr "mode"     "SF")])
1210 ;; See muldf3_r4300.
1212 (define_insn "mulsf3_r4300"
1213   [(set (match_operand:SF 0 "register_operand" "=f")
1214         (mult:SF (match_operand:SF 1 "register_operand" "f")
1215                  (match_operand:SF 2 "register_operand" "f")))]
1216   "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
1217   "mul.s\t%0,%1,%2\;nop"
1218   [(set_attr "type"     "fmul")
1219    (set_attr "mode"     "SF")
1220    (set_attr "length"   "8")])
1223 ;; The original R4000 has a cpu bug.  If a double-word or a variable
1224 ;; shift executes while an integer multiplication is in progress, the
1225 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
1226 ;; with the mult on the R4000.
1228 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1229 ;; (also valid for MIPS R4000MC processors):
1231 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1232 ;;      this errata description.
1233 ;;      The following code sequence causes the R4000 to incorrectly
1234 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
1235 ;;      instruction.  If the dsra32 instruction is executed during an
1236 ;;      integer multiply, the dsra32 will only shift by the amount in
1237 ;;      specified in the instruction rather than the amount plus 32
1238 ;;      bits.
1239 ;;      instruction 1:          mult    rs,rt           integer multiply
1240 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
1241 ;;                                                      right arithmetic + 32
1242 ;;      Workaround: A dsra32 instruction placed after an integer
1243 ;;      multiply should not be one of the 11 instructions after the
1244 ;;      multiply instruction."
1246 ;; and:
1248 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1249 ;;      the following description.
1250 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
1251 ;;      64-bit versions) may produce incorrect results under the
1252 ;;      following conditions:
1253 ;;      1) An integer multiply is currently executing
1254 ;;      2) These types of shift instructions are executed immediately
1255 ;;         following an integer divide instruction.
1256 ;;      Workaround:
1257 ;;      1) Make sure no integer multiply is running wihen these
1258 ;;         instruction are executed.  If this cannot be predicted at
1259 ;;         compile time, then insert a "mfhi" to R0 instruction
1260 ;;         immediately after the integer multiply instruction.  This
1261 ;;         will cause the integer multiply to complete before the shift
1262 ;;         is executed.
1263 ;;      2) Separate integer divide and these two classes of shift
1264 ;;         instructions by another instruction or a noop."
1266 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1267 ;; respectively.
1269 (define_expand "mulsi3"
1270   [(set (match_operand:SI 0 "register_operand")
1271         (mult:SI (match_operand:SI 1 "register_operand")
1272                  (match_operand:SI 2 "register_operand")))]
1273   ""
1275   if (GENERATE_MULT3_SI || TARGET_MAD)
1276     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1277   else if (!TARGET_FIX_R4000)
1278     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1279   else
1280     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1281   DONE;
1284 (define_insn "mulsi3_mult3"
1285   [(set (match_operand:SI 0 "register_operand" "=d,l")
1286         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1287                  (match_operand:SI 2 "register_operand" "d,d")))
1288    (clobber (match_scratch:SI 3 "=h,h"))
1289    (clobber (match_scratch:SI 4 "=l,X"))]
1290   "GENERATE_MULT3_SI
1291    || TARGET_MAD"
1293   if (which_alternative == 1)
1294     return "mult\t%1,%2";
1295   if (TARGET_MAD
1296       || TARGET_MIPS5400
1297       || TARGET_MIPS5500
1298       || TARGET_MIPS7000
1299       || TARGET_MIPS9000
1300       || ISA_MIPS32
1301       || ISA_MIPS32R2
1302       || ISA_MIPS64)
1303     return "mul\t%0,%1,%2";
1304   return "mult\t%0,%1,%2";
1306   [(set_attr "type"     "imul")
1307    (set_attr "mode"     "SI")])
1309 ;; If a register gets allocated to LO, and we spill to memory, the reload
1310 ;; will include a move from LO to a GPR.  Merge it into the multiplication
1311 ;; if it can set the GPR directly.
1313 ;; Operand 0: LO
1314 ;; Operand 1: GPR (1st multiplication operand)
1315 ;; Operand 2: GPR (2nd multiplication operand)
1316 ;; Operand 3: HI
1317 ;; Operand 4: GPR (destination)
1318 (define_peephole2
1319   [(parallel
1320        [(set (match_operand:SI 0 "register_operand")
1321              (mult:SI (match_operand:SI 1 "register_operand")
1322                       (match_operand:SI 2 "register_operand")))
1323         (clobber (match_operand:SI 3 "register_operand"))
1324         (clobber (scratch:SI))])
1325    (set (match_operand:SI 4 "register_operand")
1326         (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1327   "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
1328   [(parallel
1329        [(set (match_dup 4)
1330              (mult:SI (match_dup 1)
1331                       (match_dup 2)))
1332         (clobber (match_dup 3))
1333         (clobber (match_dup 0))])])
1335 (define_insn "mulsi3_internal"
1336   [(set (match_operand:SI 0 "register_operand" "=l")
1337         (mult:SI (match_operand:SI 1 "register_operand" "d")
1338                  (match_operand:SI 2 "register_operand" "d")))
1339    (clobber (match_scratch:SI 3 "=h"))]
1340   "!TARGET_FIX_R4000"
1341   "mult\t%1,%2"
1342   [(set_attr "type"     "imul")
1343    (set_attr "mode"     "SI")])
1345 (define_insn "mulsi3_r4000"
1346   [(set (match_operand:SI 0 "register_operand" "=d")
1347         (mult:SI (match_operand:SI 1 "register_operand" "d")
1348                  (match_operand:SI 2 "register_operand" "d")))
1349    (clobber (match_scratch:SI 3 "=h"))
1350    (clobber (match_scratch:SI 4 "=l"))]
1351   "TARGET_FIX_R4000"
1352   "mult\t%1,%2\;mflo\t%0"
1353   [(set_attr "type"     "imul")
1354    (set_attr "mode"     "SI")
1355    (set_attr "length"   "8")])
1357 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1358 ;; of "mult; mflo".  They have the same latency, but the first form gives
1359 ;; us an extra cycle to compute the operands.
1361 ;; Operand 0: LO
1362 ;; Operand 1: GPR (1st multiplication operand)
1363 ;; Operand 2: GPR (2nd multiplication operand)
1364 ;; Operand 3: HI
1365 ;; Operand 4: GPR (destination)
1366 (define_peephole2
1367   [(parallel
1368        [(set (match_operand:SI 0 "register_operand")
1369              (mult:SI (match_operand:SI 1 "register_operand")
1370                       (match_operand:SI 2 "register_operand")))
1371         (clobber (match_operand:SI 3 "register_operand"))])
1372    (set (match_operand:SI 4 "register_operand")
1373         (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1374   "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1375   [(set (match_dup 0)
1376         (const_int 0))
1377    (parallel
1378        [(set (match_dup 0)
1379              (plus:SI (mult:SI (match_dup 1)
1380                                (match_dup 2))
1381                       (match_dup 0)))
1382         (set (match_dup 4)
1383              (plus:SI (mult:SI (match_dup 1)
1384                                (match_dup 2))
1385                       (match_dup 0)))
1386         (clobber (match_dup 3))])])
1388 ;; Multiply-accumulate patterns
1390 ;; For processors that can copy the output to a general register:
1392 ;; The all-d alternative is needed because the combiner will find this
1393 ;; pattern and then register alloc/reload will move registers around to
1394 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1396 ;; The last alternative should be made slightly less desirable, but adding
1397 ;; "?" to the constraint is too strong, and causes values to be loaded into
1398 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1399 ;; trick.
1400 (define_insn "*mul_acc_si"
1401   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1402         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1403                           (match_operand:SI 2 "register_operand" "d,d,d"))
1404                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1405    (clobber (match_scratch:SI 4 "=h,h,h"))
1406    (clobber (match_scratch:SI 5 "=X,3,l"))
1407    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1408   "(TARGET_MIPS3900
1409    || ISA_HAS_MADD_MSUB)
1410    && !TARGET_MIPS16"
1412   static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1413   if (which_alternative == 2)
1414     return "#";
1415   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1416     return "#";
1417   return madd[which_alternative];
1419   [(set_attr "type"     "imadd,imadd,multi")
1420    (set_attr "mode"     "SI")
1421    (set_attr "length"   "4,4,8")])
1423 ;; Split the above insn if we failed to get LO allocated.
1424 (define_split
1425   [(set (match_operand:SI 0 "register_operand")
1426         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1427                           (match_operand:SI 2 "register_operand"))
1428                  (match_operand:SI 3 "register_operand")))
1429    (clobber (match_scratch:SI 4))
1430    (clobber (match_scratch:SI 5))
1431    (clobber (match_scratch:SI 6))]
1432   "reload_completed && !TARGET_DEBUG_D_MODE
1433    && GP_REG_P (true_regnum (operands[0]))
1434    && GP_REG_P (true_regnum (operands[3]))"
1435   [(parallel [(set (match_dup 6)
1436                    (mult:SI (match_dup 1) (match_dup 2)))
1437               (clobber (match_dup 4))
1438               (clobber (match_dup 5))])
1439    (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1440   "")
1442 ;; Splitter to copy result of MADD to a general register
1443 (define_split
1444   [(set (match_operand:SI                   0 "register_operand")
1445         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1446                           (match_operand:SI 2 "register_operand"))
1447                  (match_operand:SI          3 "register_operand")))
1448    (clobber (match_scratch:SI               4))
1449    (clobber (match_scratch:SI               5))
1450    (clobber (match_scratch:SI               6))]
1451   "reload_completed && !TARGET_DEBUG_D_MODE
1452    && GP_REG_P (true_regnum (operands[0]))
1453    && true_regnum (operands[3]) == LO_REGNUM"
1454   [(parallel [(set (match_dup 3)
1455                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1456                             (match_dup 3)))
1457               (clobber (match_dup 4))
1458               (clobber (match_dup 5))
1459               (clobber (match_dup 6))])
1460    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1461   "")
1463 (define_insn "*macc"
1464   [(set (match_operand:SI 0 "register_operand" "=l,d")
1465         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1466                           (match_operand:SI 2 "register_operand" "d,d"))
1467                  (match_operand:SI 3 "register_operand" "0,l")))
1468    (clobber (match_scratch:SI 4 "=h,h"))
1469    (clobber (match_scratch:SI 5 "=X,3"))]
1470   "ISA_HAS_MACC"
1472   if (which_alternative == 1)
1473     return "macc\t%0,%1,%2";
1474   else if (TARGET_MIPS5500)
1475     return "madd\t%1,%2";
1476   else
1477     /* The VR4130 assumes that there is a two-cycle latency between a macc
1478        that "writes" to $0 and an instruction that reads from it.  We avoid
1479        this by assigning to $1 instead.  */
1480     return "%[macc\t%@,%1,%2%]";
1482   [(set_attr "type" "imadd")
1483    (set_attr "mode" "SI")])
1485 (define_insn "*msac"
1486   [(set (match_operand:SI 0 "register_operand" "=l,d")
1487         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1488                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1489                            (match_operand:SI 3 "register_operand" "d,d"))))
1490    (clobber (match_scratch:SI 4 "=h,h"))
1491    (clobber (match_scratch:SI 5 "=X,1"))]
1492   "ISA_HAS_MSAC"
1494   if (which_alternative == 1)
1495     return "msac\t%0,%2,%3";
1496   else if (TARGET_MIPS5500)
1497     return "msub\t%2,%3";
1498   else
1499     return "msac\t$0,%2,%3";
1501   [(set_attr "type"     "imadd")
1502    (set_attr "mode"     "SI")])
1504 ;; An msac-like instruction implemented using negation and a macc.
1505 (define_insn_and_split "*msac_using_macc"
1506   [(set (match_operand:SI 0 "register_operand" "=l,d")
1507         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1508                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1509                            (match_operand:SI 3 "register_operand" "d,d"))))
1510    (clobber (match_scratch:SI 4 "=h,h"))
1511    (clobber (match_scratch:SI 5 "=X,1"))
1512    (clobber (match_scratch:SI 6 "=d,d"))]
1513   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1514   "#"
1515   "&& reload_completed"
1516   [(set (match_dup 6)
1517         (neg:SI (match_dup 3)))
1518    (parallel
1519        [(set (match_dup 0)
1520              (plus:SI (mult:SI (match_dup 2)
1521                                (match_dup 6))
1522                       (match_dup 1)))
1523         (clobber (match_dup 4))
1524         (clobber (match_dup 5))])]
1525   ""
1526   [(set_attr "type"     "imadd")
1527    (set_attr "length"   "8")])
1529 ;; Patterns generated by the define_peephole2 below.
1531 (define_insn "*macc2"
1532   [(set (match_operand:SI 0 "register_operand" "=l")
1533         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1534                           (match_operand:SI 2 "register_operand" "d"))
1535                  (match_dup 0)))
1536    (set (match_operand:SI 3 "register_operand" "=d")
1537         (plus:SI (mult:SI (match_dup 1)
1538                           (match_dup 2))
1539                  (match_dup 0)))
1540    (clobber (match_scratch:SI 4 "=h"))]
1541   "ISA_HAS_MACC && reload_completed"
1542   "macc\t%3,%1,%2"
1543   [(set_attr "type"     "imadd")
1544    (set_attr "mode"     "SI")])
1546 (define_insn "*msac2"
1547   [(set (match_operand:SI 0 "register_operand" "=l")
1548         (minus:SI (match_dup 0)
1549                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1550                            (match_operand:SI 2 "register_operand" "d"))))
1551    (set (match_operand:SI 3 "register_operand" "=d")
1552         (minus:SI (match_dup 0)
1553                   (mult:SI (match_dup 1)
1554                            (match_dup 2))))
1555    (clobber (match_scratch:SI 4 "=h"))]
1556   "ISA_HAS_MSAC && reload_completed"
1557   "msac\t%3,%1,%2"
1558   [(set_attr "type"     "imadd")
1559    (set_attr "mode"     "SI")])
1561 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1562 ;; Similarly msac.
1564 ;; Operand 0: LO
1565 ;; Operand 1: macc/msac
1566 ;; Operand 2: HI
1567 ;; Operand 3: GPR (destination)
1568 (define_peephole2
1569   [(parallel
1570        [(set (match_operand:SI 0 "register_operand")
1571              (match_operand:SI 1 "macc_msac_operand"))
1572         (clobber (match_operand:SI 2 "register_operand"))
1573         (clobber (scratch:SI))])
1574    (set (match_operand:SI 3 "register_operand")
1575         (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1576   ""
1577   [(parallel [(set (match_dup 0)
1578                    (match_dup 1))
1579               (set (match_dup 3)
1580                    (match_dup 1))
1581               (clobber (match_dup 2))])]
1582   "")
1584 ;; When we have a three-address multiplication instruction, it should
1585 ;; be faster to do a separate multiply and add, rather than moving
1586 ;; something into LO in order to use a macc instruction.
1588 ;; This peephole needs a scratch register to cater for the case when one
1589 ;; of the multiplication operands is the same as the destination.
1591 ;; Operand 0: GPR (scratch)
1592 ;; Operand 1: LO
1593 ;; Operand 2: GPR (addend)
1594 ;; Operand 3: GPR (destination)
1595 ;; Operand 4: macc/msac
1596 ;; Operand 5: HI
1597 ;; Operand 6: new multiplication
1598 ;; Operand 7: new addition/subtraction
1599 (define_peephole2
1600   [(match_scratch:SI 0 "d")
1601    (set (match_operand:SI 1 "register_operand")
1602         (match_operand:SI 2 "register_operand"))
1603    (match_dup 0)
1604    (parallel
1605        [(set (match_operand:SI 3 "register_operand")
1606              (match_operand:SI 4 "macc_msac_operand"))
1607         (clobber (match_operand:SI 5 "register_operand"))
1608         (clobber (match_dup 1))])]
1609   "GENERATE_MULT3_SI
1610    && true_regnum (operands[1]) == LO_REGNUM
1611    && peep2_reg_dead_p (2, operands[1])
1612    && GP_REG_P (true_regnum (operands[3]))"
1613   [(parallel [(set (match_dup 0)
1614                    (match_dup 6))
1615               (clobber (match_dup 5))
1616               (clobber (match_dup 1))])
1617    (set (match_dup 3)
1618         (match_dup 7))]
1620   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1621   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1622                                 operands[2], operands[0]);
1625 ;; Same as above, except LO is the initial target of the macc.
1627 ;; Operand 0: GPR (scratch)
1628 ;; Operand 1: LO
1629 ;; Operand 2: GPR (addend)
1630 ;; Operand 3: macc/msac
1631 ;; Operand 4: HI
1632 ;; Operand 5: GPR (destination)
1633 ;; Operand 6: new multiplication
1634 ;; Operand 7: new addition/subtraction
1635 (define_peephole2
1636   [(match_scratch:SI 0 "d")
1637    (set (match_operand:SI 1 "register_operand")
1638         (match_operand:SI 2 "register_operand"))
1639    (match_dup 0)
1640    (parallel
1641        [(set (match_dup 1)
1642              (match_operand:SI 3 "macc_msac_operand"))
1643         (clobber (match_operand:SI 4 "register_operand"))
1644         (clobber (scratch:SI))])
1645    (match_dup 0)
1646    (set (match_operand:SI 5 "register_operand")
1647         (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1648   "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1649   [(parallel [(set (match_dup 0)
1650                    (match_dup 6))
1651               (clobber (match_dup 4))
1652               (clobber (match_dup 1))])
1653    (set (match_dup 5)
1654         (match_dup 7))]
1656   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1657   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1658                                 operands[2], operands[0]);
1661 (define_insn "*mul_sub_si"
1662   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1663         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1664                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1665                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1666    (clobber (match_scratch:SI 4 "=h,h,h"))
1667    (clobber (match_scratch:SI 5 "=X,1,l"))
1668    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1669   "ISA_HAS_MADD_MSUB"
1670   "@
1671    msub\t%2,%3
1672    #
1673    #"
1674   [(set_attr "type"     "imadd,multi,multi")
1675    (set_attr "mode"     "SI")
1676    (set_attr "length"   "4,8,8")])
1678 ;; Split the above insn if we failed to get LO allocated.
1679 (define_split
1680   [(set (match_operand:SI 0 "register_operand")
1681         (minus:SI (match_operand:SI 1 "register_operand")
1682                   (mult:SI (match_operand:SI 2 "register_operand")
1683                            (match_operand:SI 3 "register_operand"))))
1684    (clobber (match_scratch:SI 4))
1685    (clobber (match_scratch:SI 5))
1686    (clobber (match_scratch:SI 6))]
1687   "reload_completed && !TARGET_DEBUG_D_MODE
1688    && GP_REG_P (true_regnum (operands[0]))
1689    && GP_REG_P (true_regnum (operands[1]))"
1690   [(parallel [(set (match_dup 6)
1691                    (mult:SI (match_dup 2) (match_dup 3)))
1692               (clobber (match_dup 4))
1693               (clobber (match_dup 5))])
1694    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1695   "")
1697 ;; Splitter to copy result of MSUB to a general register
1698 (define_split
1699   [(set (match_operand:SI 0 "register_operand")
1700         (minus:SI (match_operand:SI 1 "register_operand")
1701                   (mult:SI (match_operand:SI 2 "register_operand")
1702                            (match_operand:SI 3 "register_operand"))))
1703    (clobber (match_scratch:SI 4))
1704    (clobber (match_scratch:SI 5))
1705    (clobber (match_scratch:SI 6))]
1706   "reload_completed && !TARGET_DEBUG_D_MODE
1707    && GP_REG_P (true_regnum (operands[0]))
1708    && true_regnum (operands[1]) == LO_REGNUM"
1709   [(parallel [(set (match_dup 1)
1710                    (minus:SI (match_dup 1)
1711                              (mult:SI (match_dup 2) (match_dup 3))))
1712               (clobber (match_dup 4))
1713               (clobber (match_dup 5))
1714               (clobber (match_dup 6))])
1715    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1716   "")
1718 (define_insn "*muls"
1719   [(set (match_operand:SI                  0 "register_operand" "=l,d")
1720         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1721                          (match_operand:SI 2 "register_operand" "d,d"))))
1722    (clobber (match_scratch:SI              3                    "=h,h"))
1723    (clobber (match_scratch:SI              4                    "=X,l"))]
1724   "ISA_HAS_MULS"
1725   "@
1726    muls\t$0,%1,%2
1727    muls\t%0,%1,%2"
1728   [(set_attr "type"     "imul")
1729    (set_attr "mode"     "SI")])
1731 (define_expand "muldi3"
1732   [(set (match_operand:DI 0 "register_operand")
1733         (mult:DI (match_operand:DI 1 "register_operand")
1734                  (match_operand:DI 2 "register_operand")))]
1735   "TARGET_64BIT"
1737   if (GENERATE_MULT3_DI)
1738     emit_insn (gen_muldi3_mult3 (operands[0], operands[1], operands[2]));
1739   else if (!TARGET_FIX_R4000)
1740     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1741   else
1742     emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1743   DONE;
1746 (define_insn "muldi3_mult3"
1747   [(set (match_operand:DI 0 "register_operand" "=d")
1748         (mult:DI (match_operand:DI 1 "register_operand" "d")
1749                  (match_operand:DI 2 "register_operand" "d")))
1750    (clobber (match_scratch:DI 3 "=h"))
1751    (clobber (match_scratch:DI 4 "=l"))]
1752   "TARGET_64BIT && GENERATE_MULT3_DI"
1753   "dmult\t%0,%1,%2"
1754   [(set_attr "type"     "imul")
1755    (set_attr "mode"     "DI")])
1757 (define_insn "muldi3_internal"
1758   [(set (match_operand:DI 0 "register_operand" "=l")
1759         (mult:DI (match_operand:DI 1 "register_operand" "d")
1760                  (match_operand:DI 2 "register_operand" "d")))
1761    (clobber (match_scratch:DI 3 "=h"))]
1762   "TARGET_64BIT && !TARGET_FIX_R4000"
1763   "dmult\t%1,%2"
1764   [(set_attr "type"     "imul")
1765    (set_attr "mode"     "DI")])
1767 (define_insn "muldi3_r4000"
1768   [(set (match_operand:DI 0 "register_operand" "=d")
1769         (mult:DI (match_operand:DI 1 "register_operand" "d")
1770                  (match_operand:DI 2 "register_operand" "d")))
1771    (clobber (match_scratch:DI 3 "=h"))
1772    (clobber (match_scratch:DI 4 "=l"))]
1773   "TARGET_64BIT && TARGET_FIX_R4000"
1774   "dmult\t%1,%2\;mflo\t%0"
1775   [(set_attr "type"     "imul")
1776    (set_attr "mode"     "DI")
1777    (set_attr "length"   "8")])
1779 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1781 (define_expand "mulsidi3"
1782   [(parallel
1783       [(set (match_operand:DI 0 "register_operand")
1784             (mult:DI
1785                (sign_extend:DI (match_operand:SI 1 "register_operand"))
1786                (sign_extend:DI (match_operand:SI 2 "register_operand"))))
1787        (clobber (scratch:DI))
1788        (clobber (scratch:DI))
1789        (clobber (scratch:DI))])]
1790   "!TARGET_64BIT || !TARGET_FIX_R4000"
1792   if (!TARGET_64BIT)
1793     {
1794       if (!TARGET_FIX_R4000)
1795         emit_insn (gen_mulsidi3_32bit_internal (operands[0], operands[1],
1796                                                 operands[2]));
1797       else
1798         emit_insn (gen_mulsidi3_32bit_r4000 (operands[0], operands[1],
1799                                              operands[2]));
1800       DONE;
1801     }
1804 (define_insn "mulsidi3_32bit_internal"
1805   [(set (match_operand:DI 0 "register_operand" "=x")
1806         (mult:DI
1807            (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1808            (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1809   "!TARGET_64BIT && !TARGET_FIX_R4000"
1810   "mult\t%1,%2"
1811   [(set_attr "type"     "imul")
1812    (set_attr "mode"     "SI")])
1814 (define_insn "mulsidi3_32bit_r4000"
1815   [(set (match_operand:DI 0 "register_operand" "=d")
1816         (mult:DI
1817            (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1818            (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1819    (clobber (match_scratch:DI 3 "=l"))
1820    (clobber (match_scratch:DI 4 "=h"))]
1821   "!TARGET_64BIT && TARGET_FIX_R4000"
1822   "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1823   [(set_attr "type"     "imul")
1824    (set_attr "mode"     "SI")
1825    (set_attr "length"   "12")])
1827 (define_insn_and_split "*mulsidi3_64bit"
1828   [(set (match_operand:DI 0 "register_operand" "=d")
1829         (mult:DI (match_operator:DI 1 "extend_operator"
1830                     [(match_operand:SI 3 "register_operand" "d")])
1831                  (match_operator:DI 2 "extend_operator"
1832                     [(match_operand:SI 4 "register_operand" "d")])))
1833    (clobber (match_scratch:DI 5 "=l"))
1834    (clobber (match_scratch:DI 6 "=h"))
1835    (clobber (match_scratch:DI 7 "=d"))]
1836   "TARGET_64BIT && !TARGET_FIX_R4000
1837    && GET_CODE (operands[1]) == GET_CODE (operands[2])"
1838   "#"
1839   "&& reload_completed"
1840   [(parallel
1841        [(set (match_dup 5)
1842              (sign_extend:DI
1843                 (mult:SI (match_dup 3)
1844                          (match_dup 4))))
1845         (set (match_dup 6)
1846              (ashiftrt:DI
1847                 (mult:DI (match_dup 1)
1848                          (match_dup 2))
1849                 (const_int 32)))])
1851    ;; OP7 <- LO, OP0 <- HI
1852    (set (match_dup 7) (unspec:DI [(match_dup 5) (match_dup 6)] UNSPEC_MFHILO))
1853    (set (match_dup 0) (unspec:DI [(match_dup 6) (match_dup 5)] UNSPEC_MFHILO))
1855    ;; Zero-extend OP7.
1856    (set (match_dup 7)
1857         (ashift:DI (match_dup 7)
1858                    (const_int 32)))
1859    (set (match_dup 7)
1860         (lshiftrt:DI (match_dup 7)
1861                      (const_int 32)))
1863    ;; Shift OP0 into place.
1864    (set (match_dup 0)
1865         (ashift:DI (match_dup 0)
1866                    (const_int 32)))
1868    ;; OR the two halves together
1869    (set (match_dup 0)
1870         (ior:DI (match_dup 0)
1871                 (match_dup 7)))]
1872   ""
1873   [(set_attr "type"     "imul")
1874    (set_attr "mode"     "SI")
1875    (set_attr "length"   "24")])
1877 (define_insn "*mulsidi3_64bit_parts"
1878   [(set (match_operand:DI 0 "register_operand" "=l")
1879         (sign_extend:DI
1880            (mult:SI (match_operand:SI 2 "register_operand" "d")
1881                     (match_operand:SI 3 "register_operand" "d"))))
1882    (set (match_operand:DI 1 "register_operand" "=h")
1883         (ashiftrt:DI
1884            (mult:DI
1885               (match_operator:DI 4 "extend_operator" [(match_dup 2)])
1886               (match_operator:DI 5 "extend_operator" [(match_dup 3)]))
1887            (const_int 32)))]
1888   "TARGET_64BIT && !TARGET_FIX_R4000
1889    && GET_CODE (operands[4]) == GET_CODE (operands[5])"
1891   if (GET_CODE (operands[4]) == SIGN_EXTEND)
1892     return "mult\t%2,%3";
1893   else
1894     return "multu\t%2,%3";
1896   [(set_attr "type" "imul")
1897    (set_attr "mode" "SI")])
1899 (define_expand "umulsidi3"
1900   [(parallel
1901       [(set (match_operand:DI 0 "register_operand")
1902             (mult:DI
1903                (zero_extend:DI (match_operand:SI 1 "register_operand"))
1904                (zero_extend:DI (match_operand:SI 2 "register_operand"))))
1905        (clobber (scratch:DI))
1906        (clobber (scratch:DI))
1907        (clobber (scratch:DI))])]
1908   "!TARGET_64BIT || !TARGET_FIX_R4000"
1910   if (!TARGET_64BIT)
1911     {
1912       if (!TARGET_FIX_R4000)
1913         emit_insn (gen_umulsidi3_32bit_internal (operands[0], operands[1],
1914                                                  operands[2]));
1915       else
1916         emit_insn (gen_umulsidi3_32bit_r4000 (operands[0], operands[1],
1917                                               operands[2]));
1918       DONE;
1919     }
1922 (define_insn "umulsidi3_32bit_internal"
1923   [(set (match_operand:DI 0 "register_operand" "=x")
1924         (mult:DI
1925            (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1926            (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1927   "!TARGET_64BIT && !TARGET_FIX_R4000"
1928   "multu\t%1,%2"
1929   [(set_attr "type"     "imul")
1930    (set_attr "mode"     "SI")])
1932 (define_insn "umulsidi3_32bit_r4000"
1933   [(set (match_operand:DI 0 "register_operand" "=d")
1934         (mult:DI
1935            (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1936            (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1937    (clobber (match_scratch:DI 3 "=l"))
1938    (clobber (match_scratch:DI 4 "=h"))]
1939   "!TARGET_64BIT && TARGET_FIX_R4000"
1940   "multu\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1941   [(set_attr "type"     "imul")
1942    (set_attr "mode"     "SI")
1943    (set_attr "length"   "12")])
1945 ;; Widening multiply with negation.
1946 (define_insn "*muls_di"
1947   [(set (match_operand:DI 0 "register_operand" "=x")
1948         (neg:DI
1949          (mult:DI
1950           (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1951           (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1952   "!TARGET_64BIT && ISA_HAS_MULS"
1953   "muls\t$0,%1,%2"
1954   [(set_attr "type"     "imul")
1955    (set_attr "length"   "4")
1956    (set_attr "mode"     "SI")])
1958 (define_insn "*umuls_di"
1959   [(set (match_operand:DI 0 "register_operand" "=x")
1960         (neg:DI
1961          (mult:DI
1962           (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1963           (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1964   "!TARGET_64BIT && ISA_HAS_MULS"
1965   "mulsu\t$0,%1,%2"
1966   [(set_attr "type"     "imul")
1967    (set_attr "length"   "4")
1968    (set_attr "mode"     "SI")])
1970 (define_insn "*smsac_di"
1971   [(set (match_operand:DI 0 "register_operand" "=x")
1972         (minus:DI
1973            (match_operand:DI 3 "register_operand" "0")
1974            (mult:DI
1975               (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1976               (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1977   "!TARGET_64BIT && ISA_HAS_MSAC"
1979   if (TARGET_MIPS5500)
1980     return "msub\t%1,%2";
1981   else
1982     return "msac\t$0,%1,%2";
1984   [(set_attr "type"     "imadd")
1985    (set_attr "length"   "4")
1986    (set_attr "mode"     "SI")])
1988 (define_insn "*umsac_di"
1989   [(set (match_operand:DI 0 "register_operand" "=x")
1990         (minus:DI
1991            (match_operand:DI 3 "register_operand" "0")
1992            (mult:DI
1993               (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1994               (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1995   "!TARGET_64BIT && ISA_HAS_MSAC"
1997   if (TARGET_MIPS5500)
1998     return "msubu\t%1,%2";
1999   else
2000     return "msacu\t$0,%1,%2";
2002   [(set_attr "type"     "imadd")
2003    (set_attr "length"   "4")
2004    (set_attr "mode"     "SI")])
2006 ;; _highpart patterns
2007 (define_expand "umulsi3_highpart"
2008   [(set (match_operand:SI 0 "register_operand")
2009         (truncate:SI
2010          (lshiftrt:DI
2011           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"))
2012                    (zero_extend:DI (match_operand:SI 2 "register_operand")))
2013           (const_int 32))))]
2014   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
2016   if (ISA_HAS_MULHI)
2017     emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1],
2018                                                     operands[2]));
2019   else
2020     emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1],
2021                                               operands[2]));
2022   DONE;
2025 (define_insn "umulsi3_highpart_internal"
2026   [(set (match_operand:SI 0 "register_operand" "=h")
2027         (truncate:SI
2028          (lshiftrt:DI
2029           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2030                    (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2031           (const_int 32))))
2032    (clobber (match_scratch:SI 3 "=l"))]
2033   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
2034   "multu\t%1,%2"
2035   [(set_attr "type"   "imul")
2036    (set_attr "mode"   "SI")
2037    (set_attr "length" "4")])
2039 (define_insn "umulsi3_highpart_mulhi_internal"
2040   [(set (match_operand:SI 0 "register_operand" "=h,d")
2041         (truncate:SI
2042          (lshiftrt:DI
2043           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2044                    (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
2045           (const_int 32))))
2046    (clobber (match_scratch:SI 3 "=l,l"))
2047    (clobber (match_scratch:SI 4 "=X,h"))]
2048   "ISA_HAS_MULHI"
2049   "@
2050    multu\t%1,%2
2051    mulhiu\t%0,%1,%2"
2052   [(set_attr "type"   "imul")
2053    (set_attr "mode"   "SI")
2054    (set_attr "length" "4")])
2056 (define_insn "umulsi3_highpart_neg_mulhi_internal"
2057   [(set (match_operand:SI 0 "register_operand" "=h,d")
2058         (truncate:SI
2059          (lshiftrt:DI
2060           (neg:DI
2061            (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2062                     (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
2063           (const_int 32))))
2064    (clobber (match_scratch:SI 3 "=l,l"))
2065    (clobber (match_scratch:SI 4 "=X,h"))]
2066   "ISA_HAS_MULHI"
2067   "@
2068    mulshiu\t%.,%1,%2
2069    mulshiu\t%0,%1,%2"
2070   [(set_attr "type"   "imul")
2071    (set_attr "mode"   "SI")
2072    (set_attr "length" "4")])
2074 (define_expand "smulsi3_highpart"
2075   [(set (match_operand:SI 0 "register_operand")
2076         (truncate:SI
2077          (lshiftrt:DI
2078           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"))
2079                    (sign_extend:DI (match_operand:SI 2 "register_operand")))
2080          (const_int 32))))]
2081   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
2083   if (ISA_HAS_MULHI)
2084     emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1],
2085                                                     operands[2]));
2086   else
2087     emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1],
2088                                               operands[2]));
2089   DONE;
2092 (define_insn "smulsi3_highpart_internal"
2093   [(set (match_operand:SI 0 "register_operand" "=h")
2094         (truncate:SI
2095          (lshiftrt:DI
2096           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2097                    (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2098           (const_int 32))))
2099    (clobber (match_scratch:SI 3 "=l"))]
2100   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
2101   "mult\t%1,%2"
2102   [(set_attr "type"     "imul")
2103    (set_attr "mode"     "SI")
2104    (set_attr "length"   "4")])
2106 (define_insn "smulsi3_highpart_mulhi_internal"
2107   [(set (match_operand:SI 0 "register_operand" "=h,d")
2108         (truncate:SI
2109          (lshiftrt:DI
2110           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2111                    (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
2112           (const_int 32))))
2113    (clobber (match_scratch:SI 3 "=l,l"))
2114    (clobber (match_scratch:SI 4 "=X,h"))]
2115   "ISA_HAS_MULHI"
2116   "@
2117    mult\t%1,%2
2118    mulhi\t%0,%1,%2"
2119   [(set_attr "type"   "imul")
2120    (set_attr "mode"   "SI")
2121    (set_attr "length" "4")])
2123 (define_insn "smulsi3_highpart_neg_mulhi_internal"
2124   [(set (match_operand:SI 0 "register_operand" "=h,d")
2125         (truncate:SI
2126          (lshiftrt:DI
2127           (neg:DI
2128            (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2129                     (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
2130           (const_int 32))))
2131    (clobber (match_scratch:SI 3 "=l,l"))
2132    (clobber (match_scratch:SI 4 "=X,h"))]
2133   "ISA_HAS_MULHI"
2134   "@
2135    mulshi\t%.,%1,%2
2136    mulshi\t%0,%1,%2"
2137   [(set_attr "type"   "imul")
2138    (set_attr "mode"   "SI")])
2140 (define_insn "smuldi3_highpart"
2141   [(set (match_operand:DI 0 "register_operand" "=h")
2142         (truncate:DI
2143          (lshiftrt:TI
2144           (mult:TI
2145            (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
2146            (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
2147          (const_int 64))))
2148    (clobber (match_scratch:DI 3 "=l"))]
2149   "TARGET_64BIT && !TARGET_FIX_R4000"
2150   "dmult\t%1,%2"
2151   [(set_attr "type"     "imul")
2152    (set_attr "mode"     "DI")])
2154 ;; Disable this pattern for -mfix-vr4120.  This is for VR4120 errata MD(0),
2155 ;; which says that dmultu does not always produce the correct result.
2156 (define_insn "umuldi3_highpart"
2157   [(set (match_operand:DI 0 "register_operand" "=h")
2158         (truncate:DI
2159          (lshiftrt:TI
2160           (mult:TI
2161            (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
2162            (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
2163           (const_int 64))))
2164    (clobber (match_scratch:DI 3 "=l"))]
2165   "TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_FIX_VR4120"
2166   "dmultu\t%1,%2"
2167   [(set_attr "type"     "imul")
2168    (set_attr "mode"     "DI")])
2171 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2172 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
2174 (define_insn "madsi"
2175   [(set (match_operand:SI 0 "register_operand" "+l")
2176         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2177                           (match_operand:SI 2 "register_operand" "d"))
2178                  (match_dup 0)))
2179    (clobber (match_scratch:SI 3 "=h"))]
2180   "TARGET_MAD"
2181   "mad\t%1,%2"
2182   [(set_attr "type"     "imadd")
2183    (set_attr "mode"     "SI")])
2185 (define_insn "*umul_acc_di"
2186   [(set (match_operand:DI 0 "register_operand" "=x")
2187         (plus:DI
2188          (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2189                   (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2190          (match_operand:DI 3 "register_operand" "0")))]
2191   "(TARGET_MAD || ISA_HAS_MACC)
2192    && !TARGET_64BIT"
2194   if (TARGET_MAD)
2195     return "madu\t%1,%2";
2196   else if (TARGET_MIPS5500)
2197     return "maddu\t%1,%2";
2198   else
2199     /* See comment in *macc.  */
2200     return "%[maccu\t%@,%1,%2%]";
2202   [(set_attr "type"   "imadd")
2203    (set_attr "mode"   "SI")])
2206 (define_insn "*smul_acc_di"
2207   [(set (match_operand:DI 0 "register_operand" "=x")
2208         (plus:DI
2209          (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2210                   (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2211          (match_operand:DI 3 "register_operand" "0")))]
2212   "(TARGET_MAD || ISA_HAS_MACC)
2213    && !TARGET_64BIT"
2215   if (TARGET_MAD)
2216     return "mad\t%1,%2";
2217   else if (TARGET_MIPS5500)
2218     return "madd\t%1,%2";
2219   else
2220     /* See comment in *macc.  */
2221     return "%[macc\t%@,%1,%2%]";
2223   [(set_attr "type"   "imadd")
2224    (set_attr "mode"   "SI")])
2226 ;; Floating point multiply accumulate instructions.
2228 (define_insn ""
2229   [(set (match_operand:DF 0 "register_operand" "=f")
2230         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2231                           (match_operand:DF 2 "register_operand" "f"))
2232                  (match_operand:DF 3 "register_operand" "f")))]
2233   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2234   "madd.d\t%0,%3,%1,%2"
2235   [(set_attr "type"     "fmadd")
2236    (set_attr "mode"     "DF")])
2238 (define_insn ""
2239   [(set (match_operand:SF 0 "register_operand" "=f")
2240         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2241                           (match_operand:SF 2 "register_operand" "f"))
2242                  (match_operand:SF 3 "register_operand" "f")))]
2243   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2244   "madd.s\t%0,%3,%1,%2"
2245   [(set_attr "type"     "fmadd")
2246    (set_attr "mode"     "SF")])
2248 (define_insn ""
2249   [(set (match_operand:DF 0 "register_operand" "=f")
2250         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2251                            (match_operand:DF 2 "register_operand" "f"))
2252                   (match_operand:DF 3 "register_operand" "f")))]
2253   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2254   "msub.d\t%0,%3,%1,%2"
2255   [(set_attr "type"     "fmadd")
2256    (set_attr "mode"     "DF")])
2258 (define_insn ""
2259   [(set (match_operand:SF 0 "register_operand" "=f")
2260         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2261                            (match_operand:SF 2 "register_operand" "f"))
2262                   (match_operand:SF 3 "register_operand" "f")))]
2264   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2265   "msub.s\t%0,%3,%1,%2"
2266   [(set_attr "type"     "fmadd")
2267    (set_attr "mode"     "SF")])
2269 (define_insn ""
2270   [(set (match_operand:DF 0 "register_operand" "=f")
2271         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2272                                   (match_operand:DF 2 "register_operand" "f"))
2273                          (match_operand:DF 3 "register_operand" "f"))))]
2274   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2275   "nmadd.d\t%0,%3,%1,%2"
2276   [(set_attr "type"     "fmadd")
2277    (set_attr "mode"     "DF")])
2279 (define_insn ""
2280   [(set (match_operand:SF 0 "register_operand" "=f")
2281         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2282                                   (match_operand:SF 2 "register_operand" "f"))
2283                          (match_operand:SF 3 "register_operand" "f"))))]
2284   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2285   "nmadd.s\t%0,%3,%1,%2"
2286   [(set_attr "type"     "fmadd")
2287    (set_attr "mode"     "SF")])
2289 (define_insn ""
2290   [(set (match_operand:DF 0 "register_operand" "=f")
2291         (minus:DF (match_operand:DF 1 "register_operand" "f")
2292                   (mult:DF (match_operand:DF 2 "register_operand" "f")
2293                            (match_operand:DF 3 "register_operand" "f"))))]
2294   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2295   "nmsub.d\t%0,%1,%2,%3"
2296   [(set_attr "type"     "fmadd")
2297    (set_attr "mode"     "DF")])
2299 (define_insn ""
2300   [(set (match_operand:SF 0 "register_operand" "=f")
2301         (minus:SF (match_operand:SF 1 "register_operand" "f")
2302                   (mult:SF (match_operand:SF 2 "register_operand" "f")
2303                            (match_operand:SF 3 "register_operand" "f"))))]
2304   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2305   "nmsub.s\t%0,%1,%2,%3"
2306   [(set_attr "type"     "fmadd")
2307    (set_attr "mode"     "SF")])
2310 ;;  ....................
2312 ;;      DIVISION and REMAINDER
2314 ;;  ....................
2317 (define_expand "divdf3"
2318   [(set (match_operand:DF 0 "register_operand")
2319         (div:DF (match_operand:DF 1 "reg_or_const_float_1_operand")
2320                 (match_operand:DF 2 "register_operand")))]
2321   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2323   if (const_float_1_operand (operands[1], DFmode))
2324     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2325       FAIL;
2328 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
2330 ;; If an mfc1 or dmfc1 happens to access the floating point register
2331 ;; file at the same time a long latency operation (div, sqrt, recip,
2332 ;; sqrt) iterates an intermediate result back through the floating
2333 ;; point register file bypass, then instead returning the correct
2334 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2335 ;; result of the long latency operation.
2337 ;; The workaround is to insert an unconditional 'mov' from/to the
2338 ;; long latency op destination register.
2340 (define_insn "*divdf3"
2341   [(set (match_operand:DF 0 "register_operand" "=f")
2342         (div:DF (match_operand:DF 1 "register_operand" "f")
2343                 (match_operand:DF 2 "register_operand" "f")))]
2344   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2346   if (TARGET_FIX_SB1)
2347     return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
2348   else
2349     return "div.d\t%0,%1,%2";
2351   [(set_attr "type"     "fdiv")
2352    (set_attr "mode"     "DF")
2353    (set (attr "length")
2354         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2355                       (const_int 8)
2356                       (const_int 4)))])
2359 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
2361 ;; In certain cases, div.s and div.ps may have a rounding error
2362 ;; and/or wrong inexact flag.
2364 ;; Therefore, we only allow div.s if not working around SB-1 rev2
2365 ;; errata, or if working around those errata and a slight loss of
2366 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
2367 (define_expand "divsf3"
2368   [(set (match_operand:SF 0 "register_operand")
2369         (div:SF (match_operand:SF 1 "reg_or_const_float_1_operand")
2370                 (match_operand:SF 2 "register_operand")))]
2371   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2373   if (const_float_1_operand (operands[1], SFmode))
2374     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2375       FAIL;
2378 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2379 ;; "divdf3" comment for details).
2381 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
2382 ;; "divsf3" comment for details).
2383 (define_insn "*divsf3"
2384   [(set (match_operand:SF 0 "register_operand" "=f")
2385         (div:SF (match_operand:SF 1 "register_operand" "f")
2386                 (match_operand:SF 2 "register_operand" "f")))]
2387   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2389   if (TARGET_FIX_SB1)
2390     return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
2391   else
2392     return "div.s\t%0,%1,%2";
2394   [(set_attr "type"     "fdiv")
2395    (set_attr "mode"     "SF")
2396    (set (attr "length")
2397         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2398                       (const_int 8)
2399                       (const_int 4)))])
2401 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2402 ;; "divdf3" comment for details).
2403 (define_insn ""
2404   [(set (match_operand:DF 0 "register_operand" "=f")
2405         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2406                 (match_operand:DF 2 "register_operand" "f")))]
2407   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2409   if (TARGET_FIX_SB1)
2410     return "recip.d\t%0,%2\;mov.d\t%0,%0";
2411   else
2412     return "recip.d\t%0,%2";
2414   [(set_attr "type"     "fdiv")
2415    (set_attr "mode"     "DF")
2416    (set (attr "length")
2417         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2418                       (const_int 8)
2419                       (const_int 4)))])
2421 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2422 ;; "divdf3" comment for details).
2423 (define_insn ""
2424   [(set (match_operand:SF 0 "register_operand" "=f")
2425         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2426                 (match_operand:SF 2 "register_operand" "f")))]
2427   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2429   if (TARGET_FIX_SB1)
2430     return "recip.s\t%0,%2\;mov.s\t%0,%0";
2431   else
2432     return "recip.s\t%0,%2";
2434   [(set_attr "type"     "fdiv")
2435    (set_attr "mode"     "SF")
2436    (set (attr "length")
2437         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2438                       (const_int 8)
2439                       (const_int 4)))])
2441 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2442 ;; with negative operands.  We use special libgcc functions instead.
2443 (define_insn "divmodsi4"
2444   [(set (match_operand:SI 0 "register_operand" "=l")
2445         (div:SI (match_operand:SI 1 "register_operand" "d")
2446                 (match_operand:SI 2 "register_operand" "d")))
2447    (set (match_operand:SI 3 "register_operand" "=h")
2448         (mod:SI (match_dup 1)
2449                 (match_dup 2)))]
2450   "!TARGET_FIX_VR4120"
2451   { return mips_output_division ("div\t$0,%1,%2", operands); }
2452   [(set_attr "type"     "idiv")
2453    (set_attr "mode"     "SI")])
2455 (define_insn "divmoddi4"
2456   [(set (match_operand:DI 0 "register_operand" "=l")
2457         (div:DI (match_operand:DI 1 "register_operand" "d")
2458                 (match_operand:DI 2 "register_operand" "d")))
2459    (set (match_operand:DI 3 "register_operand" "=h")
2460         (mod:DI (match_dup 1)
2461                 (match_dup 2)))]
2462   "TARGET_64BIT && !TARGET_FIX_VR4120"
2463   { return mips_output_division ("ddiv\t$0,%1,%2", operands); }
2464   [(set_attr "type"     "idiv")
2465    (set_attr "mode"     "DI")])
2467 (define_insn "udivmodsi4"
2468   [(set (match_operand:SI 0 "register_operand" "=l")
2469         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2470                  (match_operand:SI 2 "register_operand" "d")))
2471    (set (match_operand:SI 3 "register_operand" "=h")
2472         (umod:SI (match_dup 1)
2473                  (match_dup 2)))]
2474   ""
2475   { return mips_output_division ("divu\t$0,%1,%2", operands); }
2476   [(set_attr "type"     "idiv")
2477    (set_attr "mode"     "SI")])
2479 (define_insn "udivmoddi4"
2480   [(set (match_operand:DI 0 "register_operand" "=l")
2481         (udiv:DI (match_operand:DI 1 "register_operand" "d")
2482                  (match_operand:DI 2 "register_operand" "d")))
2483    (set (match_operand:DI 3 "register_operand" "=h")
2484         (umod:DI (match_dup 1)
2485                  (match_dup 2)))]
2486   "TARGET_64BIT"
2487   { return mips_output_division ("ddivu\t$0,%1,%2", operands); }
2488   [(set_attr "type"     "idiv")
2489    (set_attr "mode"     "DI")])
2492 ;;  ....................
2494 ;;      SQUARE ROOT
2496 ;;  ....................
2498 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2499 ;; "divdf3" comment for details).
2500 (define_insn "sqrtdf2"
2501   [(set (match_operand:DF 0 "register_operand" "=f")
2502         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2503   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2505   if (TARGET_FIX_SB1)
2506     return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
2507   else
2508     return "sqrt.d\t%0,%1";
2510   [(set_attr "type"     "fsqrt")
2511    (set_attr "mode"     "DF")
2512    (set (attr "length")
2513         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2514                       (const_int 8)
2515                       (const_int 4)))])
2517 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2518 ;; "divdf3" comment for details).
2519 (define_insn "sqrtsf2"
2520   [(set (match_operand:SF 0 "register_operand" "=f")
2521         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2522   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2524   if (TARGET_FIX_SB1)
2525     return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
2526   else
2527     return "sqrt.s\t%0,%1";
2529   [(set_attr "type"     "fsqrt")
2530    (set_attr "mode"     "SF")
2531    (set (attr "length")
2532         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2533                       (const_int 8)
2534                       (const_int 4)))])
2536 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2537 ;; "divdf3" comment for details).
2538 (define_insn ""
2539   [(set (match_operand:DF 0 "register_operand" "=f")
2540         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2541                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2542   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2544   if (TARGET_FIX_SB1)
2545     return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2546   else
2547     return "rsqrt.d\t%0,%2";
2549   [(set_attr "type"     "frsqrt")
2550    (set_attr "mode"     "DF")
2551    (set (attr "length")
2552         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2553                       (const_int 8)
2554                       (const_int 4)))])
2556 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2557 ;; "divdf3" comment for details).
2558 (define_insn ""
2559   [(set (match_operand:SF 0 "register_operand" "=f")
2560         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2561                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2562   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2564   if (TARGET_FIX_SB1)
2565     return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2566   else
2567     return "rsqrt.s\t%0,%2";
2569   [(set_attr "type"     "frsqrt")
2570    (set_attr "mode"     "SF")
2571    (set (attr "length")
2572         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2573                       (const_int 8)
2574                       (const_int 4)))])
2577 ;;  ....................
2579 ;;      ABSOLUTE VALUE
2581 ;;  ....................
2583 ;; Do not use the integer abs macro instruction, since that signals an
2584 ;; exception on -2147483648 (sigh).
2586 (define_insn "abssi2"
2587   [(set (match_operand:SI 0 "register_operand" "=d")
2588         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2589   "!TARGET_MIPS16"
2591   operands[2] = const0_rtx;
2593   if (REGNO (operands[0]) == REGNO (operands[1]))
2594     {
2595       if (GENERATE_BRANCHLIKELY)
2596         return "%(bltzl\t%1,1f\;subu\t%0,%z2,%0\n%~1:%)";
2597       else
2598         return "bgez\t%1,1f%#\;subu\t%0,%z2,%0\n%~1:";
2599     }
2600   else
2601     return "%(bgez\t%1,1f\;move\t%0,%1\;subu\t%0,%z2,%0\n%~1:%)";
2603   [(set_attr "type"     "multi")
2604    (set_attr "mode"     "SI")
2605    (set_attr "length"   "12")])
2607 (define_insn "absdi2"
2608   [(set (match_operand:DI 0 "register_operand" "=d")
2609         (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2610   "TARGET_64BIT && !TARGET_MIPS16"
2612   unsigned int regno1;
2613   operands[2] = const0_rtx;
2615   if (GET_CODE (operands[1]) == REG)
2616     regno1 = REGNO (operands[1]);
2617   else
2618     regno1 = REGNO (XEXP (operands[1], 0));
2620   if (REGNO (operands[0]) == regno1)
2621     return "%(bltzl\t%1,1f\;dsubu\t%0,%z2,%0\n%~1:%)";
2622   else
2623     return "%(bgez\t%1,1f\;move\t%0,%1\;dsubu\t%0,%z2,%0\n%~1:%)";
2625   [(set_attr "type"     "multi")
2626    (set_attr "mode"     "DI")
2627    (set_attr "length"   "12")])
2629 (define_insn "absdf2"
2630   [(set (match_operand:DF 0 "register_operand" "=f")
2631         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2632   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2633   "abs.d\t%0,%1"
2634   [(set_attr "type"     "fabs")
2635    (set_attr "mode"     "DF")])
2637 (define_insn "abssf2"
2638   [(set (match_operand:SF 0 "register_operand" "=f")
2639         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2640   "TARGET_HARD_FLOAT"
2641   "abs.s\t%0,%1"
2642   [(set_attr "type"     "fabs")
2643    (set_attr "mode"     "SF")])
2646 ;;  ....................
2648 ;;      FIND FIRST BIT INSTRUCTION
2650 ;;  ....................
2653 (define_insn "ffssi2"
2654   [(set (match_operand:SI 0 "register_operand" "=&d")
2655         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2656    (clobber (match_scratch:SI 2 "=&d"))
2657    (clobber (match_scratch:SI 3 "=&d"))]
2658   "!TARGET_MIPS16"
2660   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2661     return "%(\
2662 move\t%0,%.\;\
2663 beq\t%1,%.,2f\n\
2664 %~1:\tand\t%2,%1,0x0001\;\
2665 addu\t%0,%0,1\;\
2666 beq\t%2,%.,1b\;\
2667 srl\t%1,%1,1\n\
2668 %~2:%)";
2670   return "%(\
2671 move\t%0,%.\;\
2672 move\t%3,%1\;\
2673 beq\t%3,%.,2f\n\
2674 %~1:\tand\t%2,%3,0x0001\;\
2675 addu\t%0,%0,1\;\
2676 beq\t%2,%.,1b\;\
2677 srl\t%3,%3,1\n\
2678 %~2:%)";
2680   [(set_attr "type"     "multi")
2681    (set_attr "mode"     "SI")
2682    (set_attr "length"   "28")])
2684 (define_insn "ffsdi2"
2685   [(set (match_operand:DI 0 "register_operand" "=&d")
2686         (ffs:DI (match_operand:DI 1 "register_operand" "d")))
2687    (clobber (match_scratch:DI 2 "=&d"))
2688    (clobber (match_scratch:DI 3 "=&d"))]
2689   "TARGET_64BIT && !TARGET_MIPS16"
2691   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2692     return "%(\
2693 move\t%0,%.\;\
2694 beq\t%1,%.,2f\n\
2695 %~1:\tand\t%2,%1,0x0001\;\
2696 daddu\t%0,%0,1\;\
2697 beq\t%2,%.,1b\;\
2698 dsrl\t%1,%1,1\n\
2699 %~2:%)";
2701   return "%(\
2702 move\t%0,%.\;\
2703 move\t%3,%1\;\
2704 beq\t%3,%.,2f\n\
2705 %~1:\tand\t%2,%3,0x0001\;\
2706 daddu\t%0,%0,1\;\
2707 beq\t%2,%.,1b\;\
2708 dsrl\t%3,%3,1\n\
2709 %~2:%)";
2711   [(set_attr "type"     "multi")
2712    (set_attr "mode"     "DI")
2713    (set_attr "length"   "28")])
2716 ;;  ...................
2718 ;;  Count leading zeroes.
2720 ;;  ...................
2723 (define_insn "clzsi2"
2724   [(set (match_operand:SI 0 "register_operand" "=d")
2725         (clz:SI (match_operand:SI 1 "register_operand" "d")))]
2726   "ISA_HAS_CLZ_CLO"
2727   "clz\t%0,%1"
2728   [(set_attr "type" "clz")
2729    (set_attr "mode" "SI")])
2731 (define_insn "clzdi2"
2732   [(set (match_operand:DI 0 "register_operand" "=d")
2733         (clz:DI (match_operand:DI 1 "register_operand" "d")))]
2734   "ISA_HAS_DCLZ_DCLO"
2735   "dclz\t%0,%1"
2736   [(set_attr "type" "clz")
2737    (set_attr "mode" "DI")])
2740 ;;  ....................
2742 ;;      NEGATION and ONE'S COMPLEMENT
2744 ;;  ....................
2746 (define_insn "negsi2"
2747   [(set (match_operand:SI 0 "register_operand" "=d")
2748         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2749   ""
2751   if (TARGET_MIPS16)
2752     return "neg\t%0,%1";
2753   else
2754     return "subu\t%0,%.,%1";
2756   [(set_attr "type"     "arith")
2757    (set_attr "mode"     "SI")])
2759 (define_insn "negdi2"
2760   [(set (match_operand:DI 0 "register_operand" "=d")
2761         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2762   "TARGET_64BIT && !TARGET_MIPS16"
2763   "dsubu\t%0,%.,%1"
2764   [(set_attr "type"     "arith")
2765    (set_attr "mode"     "DI")])
2767 (define_insn "negdf2"
2768   [(set (match_operand:DF 0 "register_operand" "=f")
2769         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2770   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2771   "neg.d\t%0,%1"
2772   [(set_attr "type"     "fneg")
2773    (set_attr "mode"     "DF")])
2775 (define_insn "negsf2"
2776   [(set (match_operand:SF 0 "register_operand" "=f")
2777         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2778   "TARGET_HARD_FLOAT"
2779   "neg.s\t%0,%1"
2780   [(set_attr "type"     "fneg")
2781    (set_attr "mode"     "SF")])
2783 (define_insn "one_cmplsi2"
2784   [(set (match_operand:SI 0 "register_operand" "=d")
2785         (not:SI (match_operand:SI 1 "register_operand" "d")))]
2786   ""
2788   if (TARGET_MIPS16)
2789     return "not\t%0,%1";
2790   else
2791     return "nor\t%0,%.,%1";
2793   [(set_attr "type"     "arith")
2794    (set_attr "mode"     "SI")])
2796 (define_insn "one_cmpldi2"
2797   [(set (match_operand:DI 0 "register_operand" "=d")
2798         (not:DI (match_operand:DI 1 "register_operand" "d")))]
2799   "TARGET_64BIT"
2801   if (TARGET_MIPS16)
2802     return "not\t%0,%1";
2803   else
2804     return "nor\t%0,%.,%1";
2806   [(set_attr "type"     "arith")
2807    (set_attr "mode"     "DI")])
2810 ;;  ....................
2812 ;;      LOGICAL
2814 ;;  ....................
2817 ;; Many of these instructions use trivial define_expands, because we
2818 ;; want to use a different set of constraints when TARGET_MIPS16.
2820 (define_expand "andsi3"
2821   [(set (match_operand:SI 0 "register_operand")
2822         (and:SI (match_operand:SI 1 "uns_arith_operand")
2823                 (match_operand:SI 2 "uns_arith_operand")))]
2824   ""
2826   if (TARGET_MIPS16)
2827     {
2828       operands[1] = force_reg (SImode, operands[1]);
2829       operands[2] = force_reg (SImode, operands[2]);
2830     }
2833 (define_insn ""
2834   [(set (match_operand:SI 0 "register_operand" "=d,d")
2835         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2836                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2837   "!TARGET_MIPS16"
2838   "@
2839    and\t%0,%1,%2
2840    andi\t%0,%1,%x2"
2841   [(set_attr "type"     "arith")
2842    (set_attr "mode"     "SI")])
2844 (define_insn ""
2845   [(set (match_operand:SI 0 "register_operand" "=d")
2846         (and:SI (match_operand:SI 1 "register_operand" "%0")
2847                 (match_operand:SI 2 "register_operand" "d")))]
2848   "TARGET_MIPS16"
2849   "and\t%0,%2"
2850   [(set_attr "type"     "arith")
2851    (set_attr "mode"     "SI")])
2853 (define_expand "anddi3"
2854   [(set (match_operand:DI 0 "register_operand")
2855         (and:DI (match_operand:DI 1 "register_operand")
2856                 (match_operand:DI 2 "uns_arith_operand")))]
2857   "TARGET_64BIT"
2859   if (TARGET_MIPS16)
2860     {
2861       operands[1] = force_reg (DImode, operands[1]);
2862       operands[2] = force_reg (DImode, operands[2]);
2863     }
2866 (define_insn ""
2867   [(set (match_operand:DI 0 "register_operand" "=d,d")
2868         (and:DI (match_operand:DI 1 "register_operand" "d,d")
2869                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2870   "TARGET_64BIT && !TARGET_MIPS16"
2871   "@
2872    and\t%0,%1,%2
2873    andi\t%0,%1,%x2"
2874   [(set_attr "type"     "arith")
2875    (set_attr "mode"     "DI")])
2877 (define_insn ""
2878   [(set (match_operand:DI 0 "register_operand" "=d")
2879         (and:DI (match_operand:DI 1 "register_operand" "0")
2880                 (match_operand:DI 2 "register_operand" "d")))]
2881   "TARGET_64BIT && TARGET_MIPS16"
2882   "and\t%0,%2"
2883   [(set_attr "type"     "arith")
2884    (set_attr "mode"     "DI")])
2886 (define_expand "iorsi3"
2887   [(set (match_operand:SI 0 "register_operand")
2888         (ior:SI (match_operand:SI 1 "uns_arith_operand")
2889                 (match_operand:SI 2 "uns_arith_operand")))]
2890   ""
2892   if (TARGET_MIPS16)
2893     {
2894       operands[1] = force_reg (SImode, operands[1]);
2895       operands[2] = force_reg (SImode, operands[2]);
2896     }
2899 (define_insn ""
2900   [(set (match_operand:SI 0 "register_operand" "=d,d")
2901         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2902                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2903   "!TARGET_MIPS16"
2904   "@
2905    or\t%0,%1,%2
2906    ori\t%0,%1,%x2"
2907   [(set_attr "type"     "arith")
2908    (set_attr "mode"     "SI")])
2910 (define_insn ""
2911   [(set (match_operand:SI 0 "register_operand" "=d")
2912         (ior:SI (match_operand:SI 1 "register_operand" "%0")
2913                 (match_operand:SI 2 "register_operand" "d")))]
2914   "TARGET_MIPS16"
2915   "or\t%0,%2"
2916   [(set_attr "type"     "arith")
2917    (set_attr "mode"     "SI")])
2919 (define_expand "iordi3"
2920   [(set (match_operand:DI 0 "register_operand")
2921         (ior:DI (match_operand:DI 1 "register_operand")
2922                 (match_operand:DI 2 "uns_arith_operand")))]
2923   "TARGET_64BIT"
2925   if (TARGET_MIPS16)
2926     {
2927       operands[1] = force_reg (DImode, operands[1]);
2928       operands[2] = force_reg (DImode, operands[2]);
2929     }
2932 (define_insn ""
2933   [(set (match_operand:DI 0 "register_operand" "=d,d")
2934         (ior:DI (match_operand:DI 1 "register_operand" "d,d")
2935                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2936   "TARGET_64BIT && !TARGET_MIPS16"
2937   "@
2938    or\t%0,%1,%2
2939    ori\t%0,%1,%x2"
2940   [(set_attr "type"     "arith")
2941    (set_attr "mode"     "DI")])
2943 (define_insn ""
2944   [(set (match_operand:DI 0 "register_operand" "=d")
2945         (ior:DI (match_operand:DI 1 "register_operand" "0")
2946                 (match_operand:DI 2 "register_operand" "d")))]
2947   "TARGET_64BIT && TARGET_MIPS16"
2948   "or\t%0,%2"
2949   [(set_attr "type"     "arith")
2950    (set_attr "mode"     "DI")])
2952 (define_expand "xorsi3"
2953   [(set (match_operand:SI 0 "register_operand")
2954         (xor:SI (match_operand:SI 1 "uns_arith_operand")
2955                 (match_operand:SI 2 "uns_arith_operand")))]
2956   ""
2957   "")
2959 (define_insn ""
2960   [(set (match_operand:SI 0 "register_operand" "=d,d")
2961         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2962                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2963   "!TARGET_MIPS16"
2964   "@
2965    xor\t%0,%1,%2
2966    xori\t%0,%1,%x2"
2967   [(set_attr "type"     "arith")
2968    (set_attr "mode"     "SI")])
2970 (define_insn ""
2971   [(set (match_operand:SI 0 "register_operand" "=d,t,t")
2972         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
2973                 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
2974   "TARGET_MIPS16"
2975   "@
2976    xor\t%0,%2
2977    cmpi\t%1,%2
2978    cmp\t%1,%2"
2979   [(set_attr "type"     "arith")
2980    (set_attr "mode"     "SI")
2981    (set_attr_alternative "length"
2982                 [(const_int 4)
2983                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2984                                (const_int 4)
2985                                (const_int 8))
2986                  (const_int 4)])])
2988 (define_expand "xordi3"
2989   [(set (match_operand:DI 0 "register_operand")
2990         (xor:DI (match_operand:DI 1 "register_operand")
2991                 (match_operand:DI 2 "uns_arith_operand")))]
2992   "TARGET_64BIT"
2994   if (TARGET_MIPS16)
2995     {
2996       operands[1] = force_reg (DImode, operands[1]);
2997       operands[2] = force_reg (DImode, operands[2]);
2998     }
3001 (define_insn ""
3002   [(set (match_operand:DI 0 "register_operand" "=d,d")
3003         (xor:DI (match_operand:DI 1 "register_operand" "d,d")
3004                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
3005   "TARGET_64BIT && !TARGET_MIPS16"
3006   "@
3007    xor\t%0,%1,%2
3008    xori\t%0,%1,%x2"
3009   [(set_attr "type"     "arith")
3010    (set_attr "mode"     "DI")])
3012 (define_insn ""
3013   [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3014         (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
3015                 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
3016   "TARGET_64BIT && TARGET_MIPS16"
3017   "@
3018    xor\t%0,%2
3019    cmpi\t%1,%2
3020    cmp\t%1,%2"
3021   [(set_attr "type"     "arith")
3022    (set_attr "mode"     "DI")
3023    (set_attr_alternative "length"
3024                 [(const_int 4)
3025                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
3026                                (const_int 4)
3027                                (const_int 8))
3028                  (const_int 4)])])
3030 (define_insn "*norsi3"
3031   [(set (match_operand:SI 0 "register_operand" "=d")
3032         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3033                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3034   "!TARGET_MIPS16"
3035   "nor\t%0,%z1,%z2"
3036   [(set_attr "type"     "arith")
3037    (set_attr "mode"     "SI")])
3039 (define_insn "*nordi3"
3040   [(set (match_operand:DI 0 "register_operand" "=d")
3041         (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
3042                 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
3043   "TARGET_64BIT && !TARGET_MIPS16"
3044   "nor\t%0,%z1,%z2"
3045   [(set_attr "type"     "arith")
3046    (set_attr "mode"     "DI")])
3049 ;;  ....................
3051 ;;      TRUNCATION
3053 ;;  ....................
3057 (define_insn "truncdfsf2"
3058   [(set (match_operand:SF 0 "register_operand" "=f")
3059         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3060   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3061   "cvt.s.d\t%0,%1"
3062   [(set_attr "type"     "fcvt")
3063    (set_attr "mode"     "SF")])
3065 ;; Integer truncation patterns.  Truncating SImode values to smaller
3066 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
3067 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
3068 ;; need to make sure that the lower 32 bits are properly sign-extended
3069 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
3070 ;; smaller than SImode is equivalent to two separate truncations:
3072 ;;                        A       B
3073 ;;    DI ---> HI  ==  DI ---> SI ---> HI
3074 ;;    DI ---> QI  ==  DI ---> SI ---> QI
3076 ;; Step A needs a real instruction but step B does not.
3078 (define_insn "truncdisi2"
3079   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
3080         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
3081   "TARGET_64BIT"
3082   "@
3083     sll\t%0,%1,0
3084     sw\t%1,%0"
3085   [(set_attr "type" "shift,store")
3086    (set_attr "mode" "SI")
3087    (set_attr "extended_mips16" "yes,*")])
3089 (define_insn "truncdihi2"
3090   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
3091         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
3092   "TARGET_64BIT"
3093   "@
3094     sll\t%0,%1,0
3095     sh\t%1,%0"
3096   [(set_attr "type" "shift,store")
3097    (set_attr "mode" "SI")
3098    (set_attr "extended_mips16" "yes,*")])
3100 (define_insn "truncdiqi2"
3101   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
3102         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
3103   "TARGET_64BIT"
3104   "@
3105     sll\t%0,%1,0
3106     sb\t%1,%0"
3107   [(set_attr "type" "shift,store")
3108    (set_attr "mode" "SI")
3109    (set_attr "extended_mips16" "yes,*")])
3111 ;; Combiner patterns to optimize shift/truncate combinations.
3113 (define_insn ""
3114   [(set (match_operand:SI 0 "register_operand" "=d")
3115         (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3116                                   (match_operand:DI 2 "small_int" "I"))))]
3117   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
3118   "dsra\t%0,%1,%2"
3119   [(set_attr "type" "shift")
3120    (set_attr "mode" "SI")])
3122 (define_insn ""
3123   [(set (match_operand:SI 0 "register_operand" "=d")
3124         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3125                                   (const_int 32))))]
3126   "TARGET_64BIT && !TARGET_MIPS16"
3127   "dsra\t%0,%1,32"
3128   [(set_attr "type" "shift")
3129    (set_attr "mode" "SI")])
3132 ;; Combiner patterns for truncate/sign_extend combinations.  They use
3133 ;; the shift/truncate patterns above.
3135 (define_insn_and_split ""
3136   [(set (match_operand:SI 0 "register_operand" "=d")
3137         (sign_extend:SI
3138             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
3139   "TARGET_64BIT && !TARGET_MIPS16"
3140   "#"
3141   "&& reload_completed"
3142   [(set (match_dup 2)
3143         (ashift:DI (match_dup 1)
3144                    (const_int 48)))
3145    (set (match_dup 0)
3146         (truncate:SI (ashiftrt:DI (match_dup 2)
3147                                   (const_int 48))))]
3148   { operands[2] = gen_lowpart (DImode, operands[0]); })
3150 (define_insn_and_split ""
3151   [(set (match_operand:SI 0 "register_operand" "=d")
3152         (sign_extend:SI
3153             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3154   "TARGET_64BIT && !TARGET_MIPS16"
3155   "#"
3156   "&& reload_completed"
3157   [(set (match_dup 2)
3158         (ashift:DI (match_dup 1)
3159                    (const_int 56)))
3160    (set (match_dup 0)
3161         (truncate:SI (ashiftrt:DI (match_dup 2)
3162                                   (const_int 56))))]
3163   { operands[2] = gen_lowpart (DImode, operands[0]); })
3166 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3168 (define_insn ""
3169   [(set (match_operand:SI 0 "register_operand" "=d")
3170         (zero_extend:SI (truncate:HI
3171                          (match_operand:DI 1 "register_operand" "d"))))]
3172   "TARGET_64BIT && !TARGET_MIPS16"
3173   "andi\t%0,%1,0xffff"
3174   [(set_attr "type"     "arith")
3175    (set_attr "mode"     "SI")])
3177 (define_insn ""
3178   [(set (match_operand:SI 0 "register_operand" "=d")
3179         (zero_extend:SI (truncate:QI
3180                          (match_operand:DI 1 "register_operand" "d"))))]
3181   "TARGET_64BIT && !TARGET_MIPS16"
3182   "andi\t%0,%1,0xff"
3183   [(set_attr "type"     "arith")
3184    (set_attr "mode"     "SI")])
3186 (define_insn ""
3187   [(set (match_operand:HI 0 "register_operand" "=d")
3188         (zero_extend:HI (truncate:QI
3189                          (match_operand:DI 1 "register_operand" "d"))))]
3190   "TARGET_64BIT && !TARGET_MIPS16"
3191   "andi\t%0,%1,0xff"
3192   [(set_attr "type"     "arith")
3193    (set_attr "mode"     "HI")])
3196 ;;  ....................
3198 ;;      ZERO EXTENSION
3200 ;;  ....................
3202 ;; Extension insns.
3203 ;; Those for integer source operand are ordered widest source type first.
3205 (define_insn_and_split "zero_extendsidi2"
3206   [(set (match_operand:DI 0 "register_operand" "=d")
3207         (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
3208   "TARGET_64BIT"
3209   "#"
3210   "&& reload_completed"
3211   [(set (match_dup 0)
3212         (ashift:DI (match_dup 1) (const_int 32)))
3213    (set (match_dup 0)
3214         (lshiftrt:DI (match_dup 0) (const_int 32)))]
3215   "operands[1] = gen_lowpart (DImode, operands[1]);"
3216   [(set_attr "type" "multi")
3217    (set_attr "mode" "DI")
3218    (set_attr "length" "8")])
3220 (define_insn "*zero_extendsidi2_mem"
3221   [(set (match_operand:DI 0 "register_operand" "=d")
3222         (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
3223   "TARGET_64BIT"
3224   "lwu\t%0,%1"
3225   [(set_attr "type"     "load")
3226    (set_attr "mode"     "DI")])
3228 (define_expand "zero_extendhisi2"
3229   [(set (match_operand:SI 0 "register_operand")
3230         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3231   ""
3233   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3234     {
3235       rtx op = gen_lowpart (SImode, operands[1]);
3236       rtx temp = force_reg (SImode, GEN_INT (0xffff));
3238       emit_insn (gen_andsi3 (operands[0], op, temp));
3239       DONE;
3240     }
3243 (define_insn ""
3244   [(set (match_operand:SI 0 "register_operand" "=d,d")
3245         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
3246   "!TARGET_MIPS16"
3247   "@
3248    andi\t%0,%1,0xffff
3249    lhu\t%0,%1"
3250   [(set_attr "type"     "arith,load")
3251    (set_attr "mode"     "SI")
3252    (set_attr "length"   "4,*")])
3254 (define_insn ""
3255   [(set (match_operand:SI 0 "register_operand" "=d")
3256         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3257   "TARGET_MIPS16"
3258   "lhu\t%0,%1"
3259   [(set_attr "type"     "load")
3260    (set_attr "mode"     "SI")])
3262 (define_expand "zero_extendhidi2"
3263   [(set (match_operand:DI 0 "register_operand")
3264         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
3265   "TARGET_64BIT"
3267   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3268     {
3269       rtx op = gen_lowpart (DImode, operands[1]);
3270       rtx temp = force_reg (DImode, GEN_INT (0xffff));
3272       emit_insn (gen_anddi3 (operands[0], op, temp));
3273       DONE;
3274     }
3277 (define_insn ""
3278   [(set (match_operand:DI 0 "register_operand" "=d,d")
3279         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
3280   "TARGET_64BIT && !TARGET_MIPS16"
3281   "@
3282    andi\t%0,%1,0xffff
3283    lhu\t%0,%1"
3284   [(set_attr "type"     "arith,load")
3285    (set_attr "mode"     "DI")
3286    (set_attr "length"   "4,*")])
3288 (define_insn ""
3289   [(set (match_operand:DI 0 "register_operand" "=d")
3290         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3291   "TARGET_64BIT && TARGET_MIPS16"
3292   "lhu\t%0,%1"
3293   [(set_attr "type"     "load")
3294    (set_attr "mode"     "DI")])
3296 (define_expand "zero_extendqihi2"
3297   [(set (match_operand:HI 0 "register_operand")
3298         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3299   ""
3301   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3302     {
3303       rtx op0 = gen_lowpart (SImode, operands[0]);
3304       rtx op1 = gen_lowpart (SImode, operands[1]);
3305       rtx temp = force_reg (SImode, GEN_INT (0xff));
3307       emit_insn (gen_andsi3 (op0, op1, temp));
3308       DONE;
3309     }
3312 (define_insn ""
3313   [(set (match_operand:HI 0 "register_operand" "=d,d")
3314         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3315   "!TARGET_MIPS16"
3316   "@
3317    andi\t%0,%1,0x00ff
3318    lbu\t%0,%1"
3319   [(set_attr "type"     "arith,load")
3320    (set_attr "mode"     "HI")
3321    (set_attr "length"   "4,*")])
3323 (define_insn ""
3324   [(set (match_operand:HI 0 "register_operand" "=d")
3325         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3326   "TARGET_MIPS16"
3327   "lbu\t%0,%1"
3328   [(set_attr "type"     "load")
3329    (set_attr "mode"     "HI")])
3331 (define_expand "zero_extendqisi2"
3332   [(set (match_operand:SI 0 "register_operand")
3333         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3334   ""
3336   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3337     {
3338       rtx op = gen_lowpart (SImode, operands[1]);
3339       rtx temp = force_reg (SImode, GEN_INT (0xff));
3341       emit_insn (gen_andsi3 (operands[0], op, temp));
3342       DONE;
3343     }
3346 (define_insn ""
3347   [(set (match_operand:SI 0 "register_operand" "=d,d")
3348         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3349   "!TARGET_MIPS16"
3350   "@
3351    andi\t%0,%1,0x00ff
3352    lbu\t%0,%1"
3353   [(set_attr "type"     "arith,load")
3354    (set_attr "mode"     "SI")
3355    (set_attr "length"   "4,*")])
3357 (define_insn ""
3358   [(set (match_operand:SI 0 "register_operand" "=d")
3359         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3360   "TARGET_MIPS16"
3361   "lbu\t%0,%1"
3362   [(set_attr "type"     "load")
3363    (set_attr "mode"     "SI")])
3365 (define_expand "zero_extendqidi2"
3366   [(set (match_operand:DI 0 "register_operand")
3367         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3368   "TARGET_64BIT"
3370   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3371     {
3372       rtx op = gen_lowpart (DImode, operands[1]);
3373       rtx temp = force_reg (DImode, GEN_INT (0xff));
3375       emit_insn (gen_anddi3 (operands[0], op, temp));
3376       DONE;
3377     }
3380 (define_insn ""
3381   [(set (match_operand:DI 0 "register_operand" "=d,d")
3382         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3383   "TARGET_64BIT && !TARGET_MIPS16"
3384   "@
3385    andi\t%0,%1,0x00ff
3386    lbu\t%0,%1"
3387   [(set_attr "type"     "arith,load")
3388    (set_attr "mode"     "DI")
3389    (set_attr "length"   "4,*")])
3391 (define_insn ""
3392   [(set (match_operand:DI 0 "register_operand" "=d")
3393         (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3394   "TARGET_64BIT && TARGET_MIPS16"
3395   "lbu\t%0,%1"
3396   [(set_attr "type"     "load")
3397    (set_attr "mode"     "DI")])
3400 ;;  ....................
3402 ;;      SIGN EXTENSION
3404 ;;  ....................
3406 ;; Extension insns.
3407 ;; Those for integer source operand are ordered widest source type first.
3409 ;; When TARGET_64BIT, all SImode integer registers should already be in
3410 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
3411 ;; therefore get rid of register->register instructions if we constrain
3412 ;; the source to be in the same register as the destination.
3414 ;; The register alternative has type "arith" so that the pre-reload
3415 ;; scheduler will treat it as a move.  This reflects what happens if
3416 ;; the register alternative needs a reload.
3417 (define_insn_and_split "extendsidi2"
3418   [(set (match_operand:DI 0 "register_operand" "=d,d")
3419         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
3420   "TARGET_64BIT"
3421   "@
3422    #
3423    lw\t%0,%1"
3424   "&& reload_completed && register_operand (operands[1], VOIDmode)"
3425   [(const_int 0)]
3427   emit_note (NOTE_INSN_DELETED);
3428   DONE;
3430   [(set_attr "type" "arith,load")
3431    (set_attr "mode" "DI")])
3433 ;; These patterns originally accepted general_operands, however, slightly
3434 ;; better code is generated by only accepting register_operands, and then
3435 ;; letting combine generate the lh and lb insns.
3437 ;; These expanders originally put values in registers first. We split
3438 ;; all non-mem patterns after reload.
3440 (define_expand "extendhidi2"
3441   [(set (match_operand:DI 0 "register_operand")
3442         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
3443   "TARGET_64BIT"
3444   "")
3446 (define_insn "*extendhidi2"
3447   [(set (match_operand:DI 0 "register_operand" "=d")
3448         (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
3449   "TARGET_64BIT"
3450   "#")
3452 (define_split
3453   [(set (match_operand:DI 0 "register_operand")
3454         (sign_extend:DI (match_operand:HI 1 "register_operand")))]
3455   "TARGET_64BIT && reload_completed"
3456   [(set (match_dup 0)
3457         (ashift:DI (match_dup 1) (const_int 48)))
3458    (set (match_dup 0)
3459         (ashiftrt:DI (match_dup 0) (const_int 48)))]
3460   "operands[1] = gen_lowpart (DImode, operands[1]);")
3462 (define_insn "*extendhidi2_mem"
3463   [(set (match_operand:DI 0 "register_operand" "=d")
3464         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3465   "TARGET_64BIT"
3466   "lh\t%0,%1"
3467   [(set_attr "type"     "load")
3468    (set_attr "mode"     "DI")])
3470 (define_expand "extendhisi2"
3471   [(set (match_operand:SI 0 "register_operand")
3472         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3473   ""
3475   if (ISA_HAS_SEB_SEH)
3476     {
3477       emit_insn (gen_extendhisi2_hw (operands[0],
3478                                      force_reg (HImode, operands[1])));
3479       DONE;
3480     }
3483 (define_insn "*extendhisi2"
3484   [(set (match_operand:SI 0 "register_operand" "=d")
3485         (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
3486   ""
3487   "#")
3489 (define_split
3490   [(set (match_operand:SI 0 "register_operand")
3491         (sign_extend:SI (match_operand:HI 1 "register_operand")))]
3492   "reload_completed"
3493   [(set (match_dup 0)
3494         (ashift:SI (match_dup 1) (const_int 16)))
3495    (set (match_dup 0)
3496         (ashiftrt:SI (match_dup 0) (const_int 16)))]
3497   "operands[1] = gen_lowpart (SImode, operands[1]);")
3499 (define_insn "extendhisi2_mem"
3500   [(set (match_operand:SI 0 "register_operand" "=d")
3501         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3502   ""
3503   "lh\t%0,%1"
3504   [(set_attr "type"     "load")
3505    (set_attr "mode"     "SI")])
3507 (define_insn "extendhisi2_hw"
3508   [(set (match_operand:SI 0 "register_operand" "=r")
3509         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3510   "ISA_HAS_SEB_SEH"
3511   "seh\t%0,%1"
3512   [(set_attr "type" "arith")
3513    (set_attr "mode" "SI")])
3515 (define_expand "extendqihi2"
3516   [(set (match_operand:HI 0 "register_operand")
3517         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3518   ""
3519   "")
3521 (define_insn "*extendqihi2"
3522   [(set (match_operand:HI 0 "register_operand" "=d")
3523         (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
3524   ""
3525   "#")
3527 (define_split
3528   [(set (match_operand:HI 0 "register_operand")
3529         (sign_extend:HI (match_operand:QI 1 "register_operand")))]
3530   "reload_completed"
3531   [(set (match_dup 0)
3532         (ashift:SI (match_dup 1) (const_int 24)))
3533    (set (match_dup 0)
3534         (ashiftrt:SI (match_dup 0) (const_int 24)))]
3535   "operands[0] = gen_lowpart (SImode, operands[0]);
3536    operands[1] = gen_lowpart (SImode, operands[1]);")
3538 (define_insn "*extendqihi2_internal_mem"
3539   [(set (match_operand:HI 0 "register_operand" "=d")
3540         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3541   ""
3542   "lb\t%0,%1"
3543   [(set_attr "type"     "load")
3544    (set_attr "mode"     "SI")])
3547 (define_expand "extendqisi2"
3548   [(set (match_operand:SI 0 "register_operand")
3549         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3550   ""
3552   if (ISA_HAS_SEB_SEH)
3553     {
3554       emit_insn (gen_extendqisi2_hw (operands[0],
3555                                      force_reg (QImode, operands[1])));
3556       DONE;
3557     }
3560 (define_insn "*extendqisi2"
3561   [(set (match_operand:SI 0 "register_operand" "=d")
3562         (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
3563   ""
3564   "#")
3566 (define_split
3567   [(set (match_operand:SI 0 "register_operand")
3568         (sign_extend:SI (match_operand:QI 1 "register_operand")))]
3569   "reload_completed"
3570   [(set (match_dup 0)
3571         (ashift:SI (match_dup 1) (const_int 24)))
3572    (set (match_dup 0)
3573         (ashiftrt:SI (match_dup 0) (const_int 24)))]
3574   "operands[1] = gen_lowpart (SImode, operands[1]);")
3576 (define_insn "*extendqisi2_mem"
3577   [(set (match_operand:SI 0 "register_operand" "=d")
3578         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3579   ""
3580   "lb\t%0,%1"
3581   [(set_attr "type"     "load")
3582    (set_attr "mode"     "SI")])
3584 (define_insn "extendqisi2_hw"
3585   [(set (match_operand:SI 0 "register_operand" "=r")
3586         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3587   "ISA_HAS_SEB_SEH"
3588   "seb\t%0,%1"
3589   [(set_attr "type" "arith")
3590    (set_attr "mode" "SI")])
3592 (define_expand "extendqidi2"
3593   [(set (match_operand:DI 0 "register_operand")
3594         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3595   "TARGET_64BIT"
3596   "")
3598 (define_insn "*extendqidi2"
3599   [(set (match_operand:DI 0 "register_operand" "=d")
3600         (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
3601   "TARGET_64BIT"
3602   "#")
3604 (define_split
3605   [(set (match_operand:DI 0 "register_operand")
3606         (sign_extend:DI (match_operand:QI 1 "register_operand")))]
3607   "TARGET_64BIT && reload_completed"
3608   [(set (match_dup 0)
3609         (ashift:DI (match_dup 1) (const_int 56)))
3610    (set (match_dup 0)
3611         (ashiftrt:DI (match_dup 0) (const_int 56)))]
3612   "operands[1] = gen_lowpart (DImode, operands[1]);")
3614 (define_insn "*extendqidi2_mem"
3615   [(set (match_operand:DI 0 "register_operand" "=d")
3616         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3617   "TARGET_64BIT"
3618   "lb\t%0,%1"
3619   [(set_attr "type"     "load")
3620    (set_attr "mode"     "DI")])
3622 (define_insn "extendsfdf2"
3623   [(set (match_operand:DF 0 "register_operand" "=f")
3624         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3625   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3626   "cvt.d.s\t%0,%1"
3627   [(set_attr "type"     "fcvt")
3628    (set_attr "mode"     "DF")])
3631 ;;  ....................
3633 ;;      CONVERSIONS
3635 ;;  ....................
3637 (define_expand "fix_truncdfsi2"
3638   [(set (match_operand:SI 0 "register_operand")
3639         (fix:SI (match_operand:DF 1 "register_operand")))]
3640   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3642   if (!ISA_HAS_TRUNC_W)
3643     {
3644       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3645       DONE;
3646     }
3649 (define_insn "fix_truncdfsi2_insn"
3650   [(set (match_operand:SI 0 "register_operand" "=f")
3651         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3652   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3653   "trunc.w.d %0,%1"
3654   [(set_attr "type"     "fcvt")
3655    (set_attr "mode"     "DF")
3656    (set_attr "length"   "4")])
3658 (define_insn "fix_truncdfsi2_macro"
3659   [(set (match_operand:SI 0 "register_operand" "=f")
3660         (fix:SI (match_operand:DF 1 "register_operand" "f")))
3661    (clobber (match_scratch:DF 2 "=d"))]
3662   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3664   if (set_nomacro)
3665     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3666   else
3667     return "trunc.w.d %0,%1,%2";
3669   [(set_attr "type"     "fcvt")
3670    (set_attr "mode"     "DF")
3671    (set_attr "length"   "36")])
3673 (define_expand "fix_truncsfsi2"
3674   [(set (match_operand:SI 0 "register_operand")
3675         (fix:SI (match_operand:SF 1 "register_operand")))]
3676   "TARGET_HARD_FLOAT"
3678   if (!ISA_HAS_TRUNC_W)
3679     {
3680       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3681       DONE;
3682     }
3685 (define_insn "fix_truncsfsi2_insn"
3686   [(set (match_operand:SI 0 "register_operand" "=f")
3687         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3688   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3689   "trunc.w.s %0,%1"
3690   [(set_attr "type"     "fcvt")
3691    (set_attr "mode"     "DF")
3692    (set_attr "length"   "4")])
3694 (define_insn "fix_truncsfsi2_macro"
3695   [(set (match_operand:SI 0 "register_operand" "=f")
3696         (fix:SI (match_operand:SF 1 "register_operand" "f")))
3697    (clobber (match_scratch:SF 2 "=d"))]
3698   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3700   if (set_nomacro)
3701     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3702   else
3703     return "trunc.w.s %0,%1,%2";
3705   [(set_attr "type"     "fcvt")
3706    (set_attr "mode"     "DF")
3707    (set_attr "length"   "36")])
3710 (define_insn "fix_truncdfdi2"
3711   [(set (match_operand:DI 0 "register_operand" "=f")
3712         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3713   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3714   "trunc.l.d %0,%1"
3715   [(set_attr "type"     "fcvt")
3716    (set_attr "mode"     "DF")
3717    (set_attr "length"   "4")])
3720 (define_insn "fix_truncsfdi2"
3721   [(set (match_operand:DI 0 "register_operand" "=f")
3722         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3723   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3724   "trunc.l.s %0,%1"
3725   [(set_attr "type"     "fcvt")
3726    (set_attr "mode"     "SF")
3727    (set_attr "length"   "4")])
3730 (define_insn "floatsidf2"
3731   [(set (match_operand:DF 0 "register_operand" "=f")
3732         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3733   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3734   "cvt.d.w\t%0,%1"
3735   [(set_attr "type"     "fcvt")
3736    (set_attr "mode"     "DF")
3737    (set_attr "length"   "4")])
3740 (define_insn "floatdidf2"
3741   [(set (match_operand:DF 0 "register_operand" "=f")
3742         (float:DF (match_operand:DI 1 "register_operand" "f")))]
3743   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3744   "cvt.d.l\t%0,%1"
3745   [(set_attr "type"     "fcvt")
3746    (set_attr "mode"     "DF")
3747    (set_attr "length"   "4")])
3750 (define_insn "floatsisf2"
3751   [(set (match_operand:SF 0 "register_operand" "=f")
3752         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3753   "TARGET_HARD_FLOAT"
3754   "cvt.s.w\t%0,%1"
3755   [(set_attr "type"     "fcvt")
3756    (set_attr "mode"     "SF")
3757    (set_attr "length"   "4")])
3760 (define_insn "floatdisf2"
3761   [(set (match_operand:SF 0 "register_operand" "=f")
3762         (float:SF (match_operand:DI 1 "register_operand" "f")))]
3763   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3764   "cvt.s.l\t%0,%1"
3765   [(set_attr "type"     "fcvt")
3766    (set_attr "mode"     "SF")
3767    (set_attr "length"   "4")])
3770 (define_expand "fixuns_truncdfsi2"
3771   [(set (match_operand:SI 0 "register_operand")
3772         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3773   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3775   rtx reg1 = gen_reg_rtx (DFmode);
3776   rtx reg2 = gen_reg_rtx (DFmode);
3777   rtx reg3 = gen_reg_rtx (SImode);
3778   rtx label1 = gen_label_rtx ();
3779   rtx label2 = gen_label_rtx ();
3780   REAL_VALUE_TYPE offset;
3782   real_2expN (&offset, 31);
3784   if (reg1)                     /* Turn off complaints about unreached code.  */
3785     {
3786       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3787       do_pending_stack_adjust ();
3789       emit_insn (gen_cmpdf (operands[1], reg1));
3790       emit_jump_insn (gen_bge (label1));
3792       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3793       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3794                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
3795       emit_barrier ();
3797       emit_label (label1);
3798       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3799       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3800                                      (BITMASK_HIGH, SImode)));
3802       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3803       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3805       emit_label (label2);
3807       /* Allow REG_NOTES to be set on last insn (labels don't have enough
3808          fields, and can't be used for REG_NOTES anyway).  */
3809       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3810       DONE;
3811     }
3815 (define_expand "fixuns_truncdfdi2"
3816   [(set (match_operand:DI 0 "register_operand")
3817         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3818   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3820   rtx reg1 = gen_reg_rtx (DFmode);
3821   rtx reg2 = gen_reg_rtx (DFmode);
3822   rtx reg3 = gen_reg_rtx (DImode);
3823   rtx label1 = gen_label_rtx ();
3824   rtx label2 = gen_label_rtx ();
3825   REAL_VALUE_TYPE offset;
3827   real_2expN (&offset, 63);
3829   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3830   do_pending_stack_adjust ();
3832   emit_insn (gen_cmpdf (operands[1], reg1));
3833   emit_jump_insn (gen_bge (label1));
3835   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3836   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3837                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3838   emit_barrier ();
3840   emit_label (label1);
3841   emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3842   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3843   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3845   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3846   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3848   emit_label (label2);
3850   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3851      fields, and can't be used for REG_NOTES anyway).  */
3852   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3853   DONE;
3857 (define_expand "fixuns_truncsfsi2"
3858   [(set (match_operand:SI 0 "register_operand")
3859         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3860   "TARGET_HARD_FLOAT"
3862   rtx reg1 = gen_reg_rtx (SFmode);
3863   rtx reg2 = gen_reg_rtx (SFmode);
3864   rtx reg3 = gen_reg_rtx (SImode);
3865   rtx label1 = gen_label_rtx ();
3866   rtx label2 = gen_label_rtx ();
3867   REAL_VALUE_TYPE offset;
3869   real_2expN (&offset, 31);
3871   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3872   do_pending_stack_adjust ();
3874   emit_insn (gen_cmpsf (operands[1], reg1));
3875   emit_jump_insn (gen_bge (label1));
3877   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3878   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3879                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3880   emit_barrier ();
3882   emit_label (label1);
3883   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3884   emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3885                                  (BITMASK_HIGH, SImode)));
3887   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3888   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3890   emit_label (label2);
3892   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3893      fields, and can't be used for REG_NOTES anyway).  */
3894   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3895   DONE;
3899 (define_expand "fixuns_truncsfdi2"
3900   [(set (match_operand:DI 0 "register_operand")
3901         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3902   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3904   rtx reg1 = gen_reg_rtx (SFmode);
3905   rtx reg2 = gen_reg_rtx (SFmode);
3906   rtx reg3 = gen_reg_rtx (DImode);
3907   rtx label1 = gen_label_rtx ();
3908   rtx label2 = gen_label_rtx ();
3909   REAL_VALUE_TYPE offset;
3911   real_2expN (&offset, 63);
3913   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3914   do_pending_stack_adjust ();
3916   emit_insn (gen_cmpsf (operands[1], reg1));
3917   emit_jump_insn (gen_bge (label1));
3919   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3920   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3921                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3922   emit_barrier ();
3924   emit_label (label1);
3925   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3926   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3927   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3929   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3930   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3932   emit_label (label2);
3934   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3935      fields, and can't be used for REG_NOTES anyway).  */
3936   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3937   DONE;
3941 ;;  ....................
3943 ;;      DATA MOVEMENT
3945 ;;  ....................
3947 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3949 (define_expand "extv"
3950   [(set (match_operand 0 "register_operand")
3951         (sign_extract (match_operand:QI 1 "memory_operand")
3952                       (match_operand 2 "immediate_operand")
3953                       (match_operand 3 "immediate_operand")))]
3954   "!TARGET_MIPS16"
3956   if (mips_expand_unaligned_load (operands[0], operands[1],
3957                                   INTVAL (operands[2]),
3958                                   INTVAL (operands[3])))
3959     DONE;
3960   else
3961     FAIL;
3964 (define_expand "extzv"
3965   [(set (match_operand 0 "register_operand")
3966         (zero_extract (match_operand:QI 1 "memory_operand")
3967                       (match_operand 2 "immediate_operand")
3968                       (match_operand 3 "immediate_operand")))]
3969   "!TARGET_MIPS16"
3971   if (mips_expand_unaligned_load (operands[0], operands[1],
3972                                   INTVAL (operands[2]),
3973                                   INTVAL (operands[3])))
3974     DONE;
3975   else
3976     FAIL;
3979 (define_expand "insv"
3980   [(set (zero_extract (match_operand:QI 0 "memory_operand")
3981                       (match_operand 1 "immediate_operand")
3982                       (match_operand 2 "immediate_operand"))
3983         (match_operand 3 "reg_or_0_operand"))]
3984   "!TARGET_MIPS16"
3986   if (mips_expand_unaligned_store (operands[0], operands[3],
3987                                    INTVAL (operands[1]),
3988                                    INTVAL (operands[2])))
3989     DONE;
3990   else
3991     FAIL;
3994 ;; Unaligned word moves generated by the bit field patterns.
3996 ;; As far as the rtl is concerned, both the left-part and right-part
3997 ;; instructions can access the whole field.  However, the real operand
3998 ;; refers to just the first or the last byte (depending on endianness).
3999 ;; We therefore use two memory operands to each instruction, one to
4000 ;; describe the rtl effect and one to use in the assembly output.
4002 ;; Operands 0 and 1 are the rtl-level target and source respectively.
4003 ;; This allows us to use the standard length calculations for the "load"
4004 ;; and "store" type attributes.
4006 (define_insn "mov_lwl"
4007   [(set (match_operand:SI 0 "register_operand" "=d")
4008         (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
4009                     (match_operand:QI 2 "memory_operand" "m")]
4010                    UNSPEC_LWL))]
4011   "!TARGET_MIPS16"
4012   "lwl\t%0,%2"
4013   [(set_attr "type" "load")
4014    (set_attr "mode" "SI")
4015    (set_attr "hazard" "none")])
4017 (define_insn "mov_lwr"
4018   [(set (match_operand:SI 0 "register_operand" "=d")
4019         (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
4020                     (match_operand:QI 2 "memory_operand" "m")
4021                     (match_operand:SI 3 "register_operand" "0")]
4022                    UNSPEC_LWR))]
4023   "!TARGET_MIPS16"
4024   "lwr\t%0,%2"
4025   [(set_attr "type" "load")
4026    (set_attr "mode" "SI")])
4029 (define_insn "mov_swl"
4030   [(set (match_operand:BLK 0 "memory_operand" "=m")
4031         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
4032                      (match_operand:QI 2 "memory_operand" "m")]
4033                     UNSPEC_SWL))]
4034   "!TARGET_MIPS16"
4035   "swl\t%z1,%2"
4036   [(set_attr "type" "store")
4037    (set_attr "mode" "SI")])
4039 (define_insn "mov_swr"
4040   [(set (match_operand:BLK 0 "memory_operand" "+m")
4041         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
4042                      (match_operand:QI 2 "memory_operand" "m")
4043                      (match_dup 0)]
4044                     UNSPEC_SWR))]
4045   "!TARGET_MIPS16"
4046   "swr\t%z1,%2"
4047   [(set_attr "type" "store")
4048    (set_attr "mode" "SI")])
4051 (define_insn "mov_ldl"
4052   [(set (match_operand:DI 0 "register_operand" "=d")
4053         (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
4054                     (match_operand:QI 2 "memory_operand" "m")]
4055                    UNSPEC_LDL))]
4056   "TARGET_64BIT && !TARGET_MIPS16"
4057   "ldl\t%0,%2"
4058   [(set_attr "type" "load")
4059    (set_attr "mode" "DI")])
4061 (define_insn "mov_ldr"
4062   [(set (match_operand:DI 0 "register_operand" "=d")
4063         (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
4064                     (match_operand:QI 2 "memory_operand" "m")
4065                     (match_operand:DI 3 "register_operand" "0")]
4066                    UNSPEC_LDR))]
4067   "TARGET_64BIT && !TARGET_MIPS16"
4068   "ldr\t%0,%2"
4069   [(set_attr "type" "load")
4070    (set_attr "mode" "DI")])
4073 (define_insn "mov_sdl"
4074   [(set (match_operand:BLK 0 "memory_operand" "=m")
4075         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
4076                      (match_operand:QI 2 "memory_operand" "m")]
4077                     UNSPEC_SDL))]
4078   "TARGET_64BIT && !TARGET_MIPS16"
4079   "sdl\t%z1,%2"
4080   [(set_attr "type" "store")
4081    (set_attr "mode" "DI")])
4083 (define_insn "mov_sdr"
4084   [(set (match_operand:BLK 0 "memory_operand" "+m")
4085         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
4086                      (match_operand:QI 2 "memory_operand" "m")
4087                      (match_dup 0)]
4088                     UNSPEC_SDR))]
4089   "TARGET_64BIT && !TARGET_MIPS16"
4090   "sdr\t%z1,%2"
4091   [(set_attr "type" "store")
4092    (set_attr "mode" "DI")])
4094 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
4095 ;; The required value is:
4097 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
4099 ;; which translates to:
4101 ;;      lui     op0,%highest(op1)
4102 ;;      daddiu  op0,op0,%higher(op1)
4103 ;;      dsll    op0,op0,16
4104 ;;      daddiu  op0,op0,%hi(op1)
4105 ;;      dsll    op0,op0,16
4106 (define_insn_and_split "*lea_high64"
4107   [(set (match_operand:DI 0 "register_operand" "=d")
4108         (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
4109   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4110   "#"
4111   "&& reload_completed"
4112   [(set (match_dup 0) (high:DI (match_dup 2)))
4113    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
4114    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
4115    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4116    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
4118   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4119   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
4121   [(set_attr "length" "20")])
4123 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
4124 ;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
4125 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
4126 ;; used once.  We can then use the sequence:
4128 ;;      lui     op0,%highest(op1)
4129 ;;      lui     op2,%hi(op1)
4130 ;;      daddiu  op0,op0,%higher(op1)
4131 ;;      daddiu  op2,op2,%lo(op1)
4132 ;;      dsll32  op0,op0,0
4133 ;;      daddu   op0,op0,op2
4135 ;; which takes 4 cycles on most superscalar targets.
4136 (define_insn_and_split "*lea64"
4137   [(set (match_operand:DI 0 "register_operand" "=d")
4138         (match_operand:DI 1 "general_symbolic_operand" ""))
4139    (clobber (match_scratch:DI 2 "=&d"))]
4140   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
4141   "#"
4142   "&& reload_completed"
4143   [(set (match_dup 0) (high:DI (match_dup 3)))
4144    (set (match_dup 2) (high:DI (match_dup 4)))
4145    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4146    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
4147    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
4148    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
4150   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4151   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
4153   [(set_attr "length" "24")])
4155 ;; Insns to fetch a global symbol from a big GOT.
4157 (define_insn_and_split "*xgot_hisi"
4158   [(set (match_operand:SI 0 "register_operand" "=d")
4159         (high:SI (match_operand:SI 1 "global_got_operand" "")))]
4160   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4161   "#"
4162   "&& reload_completed"
4163   [(set (match_dup 0) (high:SI (match_dup 2)))
4164    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
4166   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
4167   operands[3] = pic_offset_table_rtx;
4169   [(set_attr "got" "xgot_high")])
4171 (define_insn_and_split "*xgot_losi"
4172   [(set (match_operand:SI 0 "register_operand" "=d")
4173         (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
4174                    (match_operand:SI 2 "global_got_operand" "")))]
4175   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4176   "#"
4177   "&& reload_completed"
4178   [(set (match_dup 0)
4179         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
4180   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
4181   [(set_attr "got" "load")])
4183 (define_insn_and_split "*xgot_hidi"
4184   [(set (match_operand:DI 0 "register_operand" "=d")
4185         (high:DI (match_operand:DI 1 "global_got_operand" "")))]
4186   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4187   "#"
4188   "&& reload_completed"
4189   [(set (match_dup 0) (high:DI (match_dup 2)))
4190    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
4192   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
4193   operands[3] = pic_offset_table_rtx;
4195   [(set_attr "got" "xgot_high")])
4197 (define_insn_and_split "*xgot_lodi"
4198   [(set (match_operand:DI 0 "register_operand" "=d")
4199         (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
4200                    (match_operand:DI 2 "global_got_operand" "")))]
4201   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4202   "#"
4203   "&& reload_completed"
4204   [(set (match_dup 0)
4205         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
4206   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
4207   [(set_attr "got" "load")])
4209 ;; Insns to fetch a global symbol from a normal GOT.
4211 (define_insn_and_split "*got_dispsi"
4212   [(set (match_operand:SI 0 "register_operand" "=d")
4213         (match_operand:SI 1 "global_got_operand" ""))]
4214   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
4215   "#"
4216   "&& reload_completed"
4217   [(set (match_dup 0)
4218         (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
4220   operands[2] = pic_offset_table_rtx;
4221   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
4223   [(set_attr "got" "load")])
4225 (define_insn_and_split "*got_dispdi"
4226   [(set (match_operand:DI 0 "register_operand" "=d")
4227         (match_operand:DI 1 "global_got_operand" ""))]
4228   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
4229   "#"
4230   "&& reload_completed"
4231   [(set (match_dup 0)
4232         (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
4234   operands[2] = pic_offset_table_rtx;
4235   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
4237   [(set_attr "got" "load")])
4239 ;; Insns for loading the high part of a local symbol.
4241 (define_insn_and_split "*got_pagesi"
4242   [(set (match_operand:SI 0 "register_operand" "=d")
4243         (high:SI (match_operand:SI 1 "local_got_operand" "")))]
4244   "TARGET_EXPLICIT_RELOCS"
4245   "#"
4246   "&& reload_completed"
4247   [(set (match_dup 0)
4248         (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
4250   operands[2] = pic_offset_table_rtx;
4251   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
4253   [(set_attr "got" "load")])
4255 (define_insn_and_split "*got_pagedi"
4256   [(set (match_operand:DI 0 "register_operand" "=d")
4257         (high:DI (match_operand:DI 1 "local_got_operand" "")))]
4258   "TARGET_EXPLICIT_RELOCS"
4259   "#"
4260   "&& reload_completed"
4261   [(set (match_dup 0)
4262         (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
4264   operands[2] = pic_offset_table_rtx;
4265   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
4267   [(set_attr "got" "load")])
4269 ;; Lower-level instructions for loading an address from the GOT.
4270 ;; We could use MEMs, but an unspec gives more optimization
4271 ;; opportunities.
4273 (define_insn "*load_gotsi"
4274   [(set (match_operand:SI 0 "register_operand" "=d")
4275         (unspec:SI [(match_operand:SI 1 "register_operand" "d")
4276                     (match_operand:SI 2 "immediate_operand" "")]
4277                    UNSPEC_LOAD_GOT))]
4278   "TARGET_ABICALLS"
4279   "lw\t%0,%R2(%1)"
4280   [(set_attr "type" "load")
4281    (set_attr "length" "4")])
4283 (define_insn "*load_gotdi"
4284   [(set (match_operand:DI 0 "register_operand" "=d")
4285         (unspec:DI [(match_operand:DI 1 "register_operand" "d")
4286                     (match_operand:DI 2 "immediate_operand" "")]
4287                    UNSPEC_LOAD_GOT))]
4288   "TARGET_ABICALLS"
4289   "ld\t%0,%R2(%1)"
4290   [(set_attr "type" "load")
4291    (set_attr "length" "4")])
4293 ;; Instructions for adding the low 16 bits of an address to a register.
4294 ;; Operand 2 is the address: print_operand works out which relocation
4295 ;; should be applied.
4297 (define_insn "*lowsi"
4298   [(set (match_operand:SI 0 "register_operand" "=d")
4299         (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
4300                    (match_operand:SI 2 "immediate_operand" "")))]
4301   "!TARGET_MIPS16"
4302   "addiu\t%0,%1,%R2"
4303   [(set_attr "type"     "arith")
4304    (set_attr "mode"     "SI")])
4306 (define_insn "*lowdi"
4307   [(set (match_operand:DI 0 "register_operand" "=d")
4308         (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
4309                    (match_operand:DI 2 "immediate_operand" "")))]
4310   "!TARGET_MIPS16 && TARGET_64BIT"
4311   "daddiu\t%0,%1,%R2"
4312   [(set_attr "type"     "arith")
4313    (set_attr "mode"     "DI")])
4315 (define_insn "*lowsi_mips16"
4316   [(set (match_operand:SI 0 "register_operand" "=d")
4317         (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
4318                    (match_operand:SI 2 "immediate_operand" "")))]
4319   "TARGET_MIPS16"
4320   "addiu\t%0,%R2"
4321   [(set_attr "type"     "arith")
4322    (set_attr "mode"     "SI")
4323    (set_attr "length"   "8")])
4325 (define_insn "*lowdi_mips16"
4326   [(set (match_operand:DI 0 "register_operand" "=d")
4327         (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
4328                    (match_operand:DI 2 "immediate_operand" "")))]
4329   "TARGET_MIPS16 && TARGET_64BIT"
4330   "daddiu\t%0,%R2"
4331   [(set_attr "type"     "arith")
4332    (set_attr "mode"     "DI")
4333    (set_attr "length"   "8")])
4335 ;; 64-bit integer moves
4337 ;; Unlike most other insns, the move insns can't be split with
4338 ;; different predicates, because register spilling and other parts of
4339 ;; the compiler, have memoized the insn number already.
4341 (define_expand "movdi"
4342   [(set (match_operand:DI 0 "")
4343         (match_operand:DI 1 ""))]
4344   ""
4346   if (mips_legitimize_move (DImode, operands[0], operands[1]))
4347     DONE;
4350 ;; For mips16, we need a special case to handle storing $31 into
4351 ;; memory, since we don't have a constraint to match $31.  This
4352 ;; instruction can be generated by save_restore_insns.
4354 (define_insn ""
4355   [(set (match_operand:DI 0 "stack_operand" "=m")
4356         (reg:DI 31))]
4357   "TARGET_MIPS16 && TARGET_64BIT"
4358   "sd\t$31,%0"
4359   [(set_attr "type"     "store")
4360    (set_attr "mode"     "DI")])
4362 (define_insn "*movdi_32bit"
4363   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
4364         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
4365   "!TARGET_64BIT && !TARGET_MIPS16
4366    && (register_operand (operands[0], DImode)
4367        || reg_or_0_operand (operands[1], DImode))"
4368   { return mips_output_move (operands[0], operands[1]); }
4369   [(set_attr "type"     "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
4370    (set_attr "mode"     "DI")
4371    (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
4373 (define_insn "*movdi_32bit_mips16"
4374   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4375         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4376   "!TARGET_64BIT && TARGET_MIPS16
4377    && (register_operand (operands[0], DImode)
4378        || register_operand (operands[1], DImode))"
4379   { return mips_output_move (operands[0], operands[1]); }
4380   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store,mfhilo")
4381    (set_attr "mode"     "DI")
4382    (set_attr "length"   "8,8,8,8,12,*,*,8")])
4384 (define_insn "*movdi_64bit"
4385   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*B*C*D,*B*C*D,*d,*m")
4386         (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J*d,*d,*m,*B*C*D,*B*C*D"))]
4387   "TARGET_64BIT && !TARGET_MIPS16
4388    && (register_operand (operands[0], DImode)
4389        || reg_or_0_operand (operands[1], DImode))"
4390   { return mips_output_move (operands[0], operands[1]); }
4391   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
4392    (set_attr "mode"     "DI")
4393    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
4395 (define_insn "*movdi_64bit_mips16"
4396   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4397         (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4398   "TARGET_64BIT && TARGET_MIPS16
4399    && (register_operand (operands[0], DImode)
4400        || register_operand (operands[1], DImode))"
4401   { return mips_output_move (operands[0], operands[1]); }
4402   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
4403    (set_attr "mode"     "DI")
4404    (set_attr_alternative "length"
4405                 [(const_int 4)
4406                  (const_int 4)
4407                  (const_int 4)
4408                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4409                                (const_int 4)
4410                                (const_int 8))
4411                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4412                                (const_int 8)
4413                                (const_int 12))
4414                  (const_string "*")
4415                  (const_string "*")
4416                  (const_string "*")])])
4419 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4420 ;; when the original load is a 4 byte instruction but the add and the
4421 ;; load are 2 2 byte instructions.
4423 (define_split
4424   [(set (match_operand:DI 0 "register_operand")
4425         (mem:DI (plus:DI (match_dup 0)
4426                          (match_operand:DI 1 "const_int_operand"))))]
4427   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4428    && !TARGET_DEBUG_D_MODE
4429    && GET_CODE (operands[0]) == REG
4430    && M16_REG_P (REGNO (operands[0]))
4431    && GET_CODE (operands[1]) == CONST_INT
4432    && ((INTVAL (operands[1]) < 0
4433         && INTVAL (operands[1]) >= -0x10)
4434        || (INTVAL (operands[1]) >= 32 * 8
4435            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4436        || (INTVAL (operands[1]) >= 0
4437            && INTVAL (operands[1]) < 32 * 8
4438            && (INTVAL (operands[1]) & 7) != 0))"
4439   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4440    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4442   HOST_WIDE_INT val = INTVAL (operands[1]);
4444   if (val < 0)
4445     operands[2] = const0_rtx;
4446   else if (val >= 32 * 8)
4447     {
4448       int off = val & 7;
4450       operands[1] = GEN_INT (0x8 + off);
4451       operands[2] = GEN_INT (val - off - 0x8);
4452     }
4453   else
4454     {
4455       int off = val & 7;
4457       operands[1] = GEN_INT (off);
4458       operands[2] = GEN_INT (val - off);
4459     }
4462 ;; 32-bit Integer moves
4464 ;; Unlike most other insns, the move insns can't be split with
4465 ;; different predicates, because register spilling and other parts of
4466 ;; the compiler, have memoized the insn number already.
4468 (define_expand "movsi"
4469   [(set (match_operand:SI 0 "")
4470         (match_operand:SI 1 ""))]
4471   ""
4473   if (mips_legitimize_move (SImode, operands[0], operands[1]))
4474     DONE;
4477 ;; We can only store $ra directly into a small sp offset.
4479 (define_insn ""
4480   [(set (match_operand:SI 0 "stack_operand" "=m")
4481         (reg:SI 31))]
4482   "TARGET_MIPS16"
4483   "sw\t$31,%0"
4484   [(set_attr "type"     "store")
4485    (set_attr "mode"     "SI")])
4487 ;; The difference between these two is whether or not ints are allowed
4488 ;; in FP registers (off by default, use -mdebugh to enable).
4490 (define_insn "*movsi_internal"
4491   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*B*C*D,*B*C*D,*d,*m")
4492         (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*d,*m,*B*C*D,*B*C*D"))]
4493   "!TARGET_MIPS16
4494    && (register_operand (operands[0], SImode)
4495        || reg_or_0_operand (operands[1], SImode))"
4496   { return mips_output_move (operands[0], operands[1]); }
4497   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
4498    (set_attr "mode"     "SI")
4499    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
4501 (define_insn "*movsi_mips16"
4502   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4503         (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4504   "TARGET_MIPS16
4505    && (register_operand (operands[0], SImode)
4506        || register_operand (operands[1], SImode))"
4507   { return mips_output_move (operands[0], operands[1]); }
4508   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
4509    (set_attr "mode"     "SI")
4510    (set_attr_alternative "length"
4511                 [(const_int 4)
4512                  (const_int 4)
4513                  (const_int 4)
4514                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4515                                (const_int 4)
4516                                (const_int 8))
4517                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4518                                (const_int 8)
4519                                (const_int 12))
4520                  (const_string "*")
4521                  (const_string "*")
4522                  (const_string "*")])])
4524 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4525 ;; when the original load is a 4 byte instruction but the add and the
4526 ;; load are 2 2 byte instructions.
4528 (define_split
4529   [(set (match_operand:SI 0 "register_operand")
4530         (mem:SI (plus:SI (match_dup 0)
4531                          (match_operand:SI 1 "const_int_operand"))))]
4532   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4533    && GET_CODE (operands[0]) == REG
4534    && M16_REG_P (REGNO (operands[0]))
4535    && GET_CODE (operands[1]) == CONST_INT
4536    && ((INTVAL (operands[1]) < 0
4537         && INTVAL (operands[1]) >= -0x80)
4538        || (INTVAL (operands[1]) >= 32 * 4
4539            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4540        || (INTVAL (operands[1]) >= 0
4541            && INTVAL (operands[1]) < 32 * 4
4542            && (INTVAL (operands[1]) & 3) != 0))"
4543   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4544    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4546   HOST_WIDE_INT val = INTVAL (operands[1]);
4548   if (val < 0)
4549     operands[2] = const0_rtx;
4550   else if (val >= 32 * 4)
4551     {
4552       int off = val & 3;
4554       operands[1] = GEN_INT (0x7c + off);
4555       operands[2] = GEN_INT (val - off - 0x7c);
4556     }
4557   else
4558     {
4559       int off = val & 3;
4561       operands[1] = GEN_INT (off);
4562       operands[2] = GEN_INT (val - off);
4563     }
4566 ;; On the mips16, we can split a load of certain constants into a load
4567 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
4568 ;; instructions.
4570 (define_split
4571   [(set (match_operand:SI 0 "register_operand")
4572         (match_operand:SI 1 "const_int_operand"))]
4573   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4574    && GET_CODE (operands[0]) == REG
4575    && M16_REG_P (REGNO (operands[0]))
4576    && GET_CODE (operands[1]) == CONST_INT
4577    && INTVAL (operands[1]) >= 0x100
4578    && INTVAL (operands[1]) <= 0xff + 0x7f"
4579   [(set (match_dup 0) (match_dup 1))
4580    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4582   int val = INTVAL (operands[1]);
4584   operands[1] = GEN_INT (0xff);
4585   operands[2] = GEN_INT (val - 0xff);
4588 ;; On the mips16, we can split a load of a negative constant into a
4589 ;; load and a neg.  That's what mips_output_move will generate anyhow.
4591 (define_split
4592   [(set (match_operand:SI 0 "register_operand")
4593         (match_operand:SI 1 "const_int_operand"))]
4594   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4595    && GET_CODE (operands[0]) == REG
4596    && M16_REG_P (REGNO (operands[0]))
4597    && GET_CODE (operands[1]) == CONST_INT
4598    && INTVAL (operands[1]) < 0
4599    && INTVAL (operands[1]) > - 0x8000"
4600   [(set (match_dup 0) (match_dup 1))
4601    (set (match_dup 0) (neg:SI (match_dup 0)))]
4602   { operands[1] = GEN_INT (- INTVAL (operands[1])); })
4604 ;; This insn handles moving CCmode values.  It's really just a
4605 ;; slightly simplified copy of movsi_internal2, with additional cases
4606 ;; to move a condition register to a general register and to move
4607 ;; between the general registers and the floating point registers.
4609 (define_insn "movcc"
4610   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
4611         (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
4612   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4613   { return mips_output_move (operands[0], operands[1]); }
4614   [(set_attr "type"     "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
4615    (set_attr "mode"     "SI")
4616    (set_attr "length"   "8,4,*,*,4,4,4,*,*")])
4618 ;; Reload condition code registers.  reload_incc and reload_outcc
4619 ;; both handle moves from arbitrary operands into condition code
4620 ;; registers.  reload_incc handles the more common case in which
4621 ;; a source operand is constrained to be in a condition-code
4622 ;; register, but has not been allocated to one.
4624 ;; Sometimes, such as in movcc, we have a CCmode destination whose
4625 ;; constraints do not include 'z'.  reload_outcc handles the case
4626 ;; when such an operand is allocated to a condition-code register.
4628 ;; Note that reloads from a condition code register to some
4629 ;; other location can be done using ordinary moves.  Moving
4630 ;; into a GPR takes a single movcc, moving elsewhere takes
4631 ;; two.  We can leave these cases to the generic reload code.
4632 (define_expand "reload_incc"
4633   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4634         (match_operand:CC 1 "general_operand" ""))
4635    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4636   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4638   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4639   DONE;
4642 (define_expand "reload_outcc"
4643   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4644         (match_operand:CC 1 "register_operand" ""))
4645    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4646   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4648   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4649   DONE;
4652 ;; MIPS4 supports loading and storing a floating point register from
4653 ;; the sum of two general registers.  We use two versions for each of
4654 ;; these four instructions: one where the two general registers are
4655 ;; SImode, and one where they are DImode.  This is because general
4656 ;; registers will be in SImode when they hold 32 bit values, but,
4657 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
4658 ;; instructions will still work correctly.
4660 ;; ??? Perhaps it would be better to support these instructions by
4661 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
4662 ;; these instructions can only be used to load and store floating
4663 ;; point registers, that would probably cause trouble in reload.
4665 (define_insn ""
4666   [(set (match_operand:SF 0 "register_operand" "=f")
4667         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4668                          (match_operand:SI 2 "register_operand" "d"))))]
4669   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4670   "lwxc1\t%0,%1(%2)"
4671   [(set_attr "type"     "fpidxload")
4672    (set_attr "mode"     "SF")
4673    (set_attr "length"   "4")])
4675 (define_insn ""
4676   [(set (match_operand:SF 0 "register_operand" "=f")
4677         (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4678                          (match_operand:DI 2 "register_operand" "d"))))]
4679   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4680   "lwxc1\t%0,%1(%2)"
4681   [(set_attr "type"     "fpidxload")
4682    (set_attr "mode"     "SF")
4683    (set_attr "length"   "4")])
4685 (define_insn ""
4686   [(set (match_operand:DF 0 "register_operand" "=f")
4687         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4688                          (match_operand:SI 2 "register_operand" "d"))))]
4689   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4690   "ldxc1\t%0,%1(%2)"
4691   [(set_attr "type"     "fpidxload")
4692    (set_attr "mode"     "DF")
4693    (set_attr "length"   "4")])
4695 (define_insn ""
4696   [(set (match_operand:DF 0 "register_operand" "=f")
4697         (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4698                          (match_operand:DI 2 "register_operand" "d"))))]
4699   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4700   "ldxc1\t%0,%1(%2)"
4701   [(set_attr "type"     "fpidxload")
4702    (set_attr "mode"     "DF")
4703    (set_attr "length"   "4")])
4705 (define_insn ""
4706   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4707                          (match_operand:SI 2 "register_operand" "d")))
4708         (match_operand:SF 0 "register_operand" "f"))]
4709   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4710   "swxc1\t%0,%1(%2)"
4711   [(set_attr "type"     "fpidxstore")
4712    (set_attr "mode"     "SF")
4713    (set_attr "length"   "4")])
4715 (define_insn ""
4716   [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4717                          (match_operand:DI 2 "register_operand" "d")))
4718         (match_operand:SF 0 "register_operand" "f"))]
4719   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4720   "swxc1\t%0,%1(%2)"
4721   [(set_attr "type"     "fpidxstore")
4722    (set_attr "mode"     "SF")
4723    (set_attr "length"   "4")])
4725 (define_insn ""
4726   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4727                          (match_operand:SI 2 "register_operand" "d")))
4728         (match_operand:DF 0 "register_operand" "f"))]
4729   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4730   "sdxc1\t%0,%1(%2)"
4731   [(set_attr "type"     "fpidxstore")
4732    (set_attr "mode"     "DF")
4733    (set_attr "length"   "4")])
4735 (define_insn ""
4736   [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4737                          (match_operand:DI 2 "register_operand" "d")))
4738         (match_operand:DF 0 "register_operand" "f"))]
4739   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4740   "sdxc1\t%0,%1(%2)"
4741   [(set_attr "type"     "fpidxstore")
4742    (set_attr "mode"     "DF")
4743    (set_attr "length"   "4")])
4745 ;; 16-bit Integer moves
4747 ;; Unlike most other insns, the move insns can't be split with
4748 ;; different predicates, because register spilling and other parts of
4749 ;; the compiler, have memoized the insn number already.
4750 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4752 (define_expand "movhi"
4753   [(set (match_operand:HI 0 "")
4754         (match_operand:HI 1 ""))]
4755   ""
4757   if (mips_legitimize_move (HImode, operands[0], operands[1]))
4758     DONE;
4761 (define_insn "*movhi_internal"
4762   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4763         (match_operand:HI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
4764   "!TARGET_MIPS16
4765    && (register_operand (operands[0], HImode)
4766        || reg_or_0_operand (operands[1], HImode))"
4767   "@
4768     move\t%0,%1
4769     li\t%0,%1
4770     lhu\t%0,%1
4771     sh\t%z1,%0
4772     mfc1\t%0,%1
4773     mtc1\t%1,%0
4774     mov.s\t%0,%1
4775     mt%0\t%1"
4776   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4777    (set_attr "mode"     "HI")
4778    (set_attr "length"   "4,4,*,*,4,4,4,4")])
4780 (define_insn "*movhi_mips16"
4781   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4782         (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d"))]
4783   "TARGET_MIPS16
4784    && (register_operand (operands[0], HImode)
4785        || register_operand (operands[1], HImode))"
4786   "@
4787     move\t%0,%1
4788     move\t%0,%1
4789     move\t%0,%1
4790     li\t%0,%1
4791     li\t%0,%n1\;neg\t%0
4792     lhu\t%0,%1
4793     sh\t%1,%0"
4794   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
4795    (set_attr "mode"     "HI")
4796    (set_attr_alternative "length"
4797                 [(const_int 4)
4798                  (const_int 4)
4799                  (const_int 4)
4800                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4801                                (const_int 4)
4802                                (const_int 8))
4803                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4804                                (const_int 8)
4805                                (const_int 12))
4806                  (const_string "*")
4807                  (const_string "*")])])
4810 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4811 ;; when the original load is a 4 byte instruction but the add and the
4812 ;; load are 2 2 byte instructions.
4814 (define_split
4815   [(set (match_operand:HI 0 "register_operand")
4816         (mem:HI (plus:SI (match_dup 0)
4817                          (match_operand:SI 1 "const_int_operand"))))]
4818   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4819    && GET_CODE (operands[0]) == REG
4820    && M16_REG_P (REGNO (operands[0]))
4821    && GET_CODE (operands[1]) == CONST_INT
4822    && ((INTVAL (operands[1]) < 0
4823         && INTVAL (operands[1]) >= -0x80)
4824        || (INTVAL (operands[1]) >= 32 * 2
4825            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4826        || (INTVAL (operands[1]) >= 0
4827            && INTVAL (operands[1]) < 32 * 2
4828            && (INTVAL (operands[1]) & 1) != 0))"
4829   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4830    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4832   HOST_WIDE_INT val = INTVAL (operands[1]);
4834   if (val < 0)
4835     operands[2] = const0_rtx;
4836   else if (val >= 32 * 2)
4837     {
4838       int off = val & 1;
4840       operands[1] = GEN_INT (0x7e + off);
4841       operands[2] = GEN_INT (val - off - 0x7e);
4842     }
4843   else
4844     {
4845       int off = val & 1;
4847       operands[1] = GEN_INT (off);
4848       operands[2] = GEN_INT (val - off);
4849     }
4852 ;; 8-bit Integer moves
4854 ;; Unlike most other insns, the move insns can't be split with
4855 ;; different predicates, because register spilling and other parts of
4856 ;; the compiler, have memoized the insn number already.
4857 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4859 (define_expand "movqi"
4860   [(set (match_operand:QI 0 "")
4861         (match_operand:QI 1 ""))]
4862   ""
4864   if (mips_legitimize_move (QImode, operands[0], operands[1]))
4865     DONE;
4868 (define_insn "*movqi_internal"
4869   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4870         (match_operand:QI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
4871   "!TARGET_MIPS16
4872    && (register_operand (operands[0], QImode)
4873        || reg_or_0_operand (operands[1], QImode))"
4874   "@
4875     move\t%0,%1
4876     li\t%0,%1
4877     lbu\t%0,%1
4878     sb\t%z1,%0
4879     mfc1\t%0,%1
4880     mtc1\t%1,%0
4881     mov.s\t%0,%1
4882     mt%0\t%1"
4883   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4884    (set_attr "mode"     "QI")
4885    (set_attr "length"   "4,4,*,*,4,4,4,4")])
4887 (define_insn "*movqi_mips16"
4888   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4889         (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d"))]
4890   "TARGET_MIPS16
4891    && (register_operand (operands[0], QImode)
4892        || register_operand (operands[1], QImode))"
4893   "@
4894     move\t%0,%1
4895     move\t%0,%1
4896     move\t%0,%1
4897     li\t%0,%1
4898     li\t%0,%n1\;neg\t%0
4899     lbu\t%0,%1
4900     sb\t%1,%0"
4901   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
4902    (set_attr "mode"     "QI")
4903    (set_attr "length"   "4,4,4,4,8,*,*")])
4905 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4906 ;; when the original load is a 4 byte instruction but the add and the
4907 ;; load are 2 2 byte instructions.
4909 (define_split
4910   [(set (match_operand:QI 0 "register_operand")
4911         (mem:QI (plus:SI (match_dup 0)
4912                          (match_operand:SI 1 "const_int_operand"))))]
4913   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4914    && GET_CODE (operands[0]) == REG
4915    && M16_REG_P (REGNO (operands[0]))
4916    && GET_CODE (operands[1]) == CONST_INT
4917    && ((INTVAL (operands[1]) < 0
4918         && INTVAL (operands[1]) >= -0x80)
4919        || (INTVAL (operands[1]) >= 32
4920            && INTVAL (operands[1]) <= 31 + 0x7f))"
4921   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4922    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4924   HOST_WIDE_INT val = INTVAL (operands[1]);
4926   if (val < 0)
4927     operands[2] = const0_rtx;
4928   else
4929     {
4930       operands[1] = GEN_INT (0x7f);
4931       operands[2] = GEN_INT (val - 0x7f);
4932     }
4935 ;; 32-bit floating point moves
4937 (define_expand "movsf"
4938   [(set (match_operand:SF 0 "")
4939         (match_operand:SF 1 ""))]
4940   ""
4942   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4943     DONE;
4946 (define_insn "*movsf_hardfloat"
4947   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4948         (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
4949   "TARGET_HARD_FLOAT
4950    && (register_operand (operands[0], SFmode)
4951        || reg_or_0_operand (operands[1], SFmode))"
4952   { return mips_output_move (operands[0], operands[1]); }
4953   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4954    (set_attr "mode"     "SF")
4955    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
4957 (define_insn "*movsf_softfloat"
4958   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4959         (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4960   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4961    && (register_operand (operands[0], SFmode)
4962        || reg_or_0_operand (operands[1], SFmode))"
4963   { return mips_output_move (operands[0], operands[1]); }
4964   [(set_attr "type"     "arith,load,store")
4965    (set_attr "mode"     "SF")
4966    (set_attr "length"   "4,*,*")])
4968 (define_insn "*movsf_mips16"
4969   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4970         (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4971   "TARGET_MIPS16
4972    && (register_operand (operands[0], SFmode)
4973        || register_operand (operands[1], SFmode))"
4974   { return mips_output_move (operands[0], operands[1]); }
4975   [(set_attr "type"     "arith,arith,arith,load,store")
4976    (set_attr "mode"     "SF")
4977    (set_attr "length"   "4,4,4,*,*")])
4980 ;; 64-bit floating point moves
4982 (define_expand "movdf"
4983   [(set (match_operand:DF 0 "")
4984         (match_operand:DF 1 ""))]
4985   ""
4987   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4988     DONE;
4991 (define_insn "*movdf_hardfloat_64bit"
4992   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4993         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4994   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4995    && (register_operand (operands[0], DFmode)
4996        || reg_or_0_operand (operands[1], DFmode))"
4997   { return mips_output_move (operands[0], operands[1]); }
4998   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4999    (set_attr "mode"     "DF")
5000    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
5002 (define_insn "*movdf_hardfloat_32bit"
5003   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
5004         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
5005   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
5006    && (register_operand (operands[0], DFmode)
5007        || reg_or_0_operand (operands[1], DFmode))"
5008   { return mips_output_move (operands[0], operands[1]); }
5009   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
5010    (set_attr "mode"     "DF")
5011    (set_attr "length"   "4,8,*,*,8,8,8,*,*")])
5013 (define_insn "*movdf_softfloat"
5014   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
5015         (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
5016   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
5017    && (register_operand (operands[0], DFmode)
5018        || reg_or_0_operand (operands[1], DFmode))"
5019   { return mips_output_move (operands[0], operands[1]); }
5020   [(set_attr "type"     "arith,load,store,xfer,xfer,fmove")
5021    (set_attr "mode"     "DF")
5022    (set_attr "length"   "8,*,*,4,4,4")])
5024 (define_insn "*movdf_mips16"
5025   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
5026         (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
5027   "TARGET_MIPS16
5028    && (register_operand (operands[0], DFmode)
5029        || register_operand (operands[1], DFmode))"
5030   { return mips_output_move (operands[0], operands[1]); }
5031   [(set_attr "type"     "arith,arith,arith,load,store")
5032    (set_attr "mode"     "DF")
5033    (set_attr "length"   "8,8,8,*,*")])
5035 (define_split
5036   [(set (match_operand:DI 0 "nonimmediate_operand")
5037         (match_operand:DI 1 "move_operand"))]
5038   "reload_completed && !TARGET_64BIT
5039    && mips_split_64bit_move_p (operands[0], operands[1])"
5040   [(const_int 0)]
5042   mips_split_64bit_move (operands[0], operands[1]);
5043   DONE;
5046 (define_split
5047   [(set (match_operand:DF 0 "nonimmediate_operand")
5048         (match_operand:DF 1 "move_operand"))]
5049   "reload_completed && !TARGET_64BIT
5050    && mips_split_64bit_move_p (operands[0], operands[1])"
5051   [(const_int 0)]
5053   mips_split_64bit_move (operands[0], operands[1]);
5054   DONE;
5057 ;; The HI and LO registers are not truly independent.  If we move an mthi
5058 ;; instruction before an mflo instruction, it will make the result of the
5059 ;; mflo unpredictable.  The same goes for mtlo and mfhi.
5061 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
5062 ;; Operand 1 is the register we want, operand 2 is the other one.
5064 (define_insn "mfhilo_di"
5065   [(set (match_operand:DI 0 "register_operand" "=d,d")
5066         (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
5067                     (match_operand:DI 2 "register_operand" "l,h")]
5068                    UNSPEC_MFHILO))]
5069   "TARGET_64BIT"
5070   "mf%1\t%0"
5071   [(set_attr "type" "mfhilo")])
5073 (define_insn "mfhilo_si"
5074   [(set (match_operand:SI 0 "register_operand" "=d,d")
5075         (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
5076                     (match_operand:SI 2 "register_operand" "l,h")]
5077                    UNSPEC_MFHILO))]
5078   ""
5079   "mf%1\t%0"
5080   [(set_attr "type" "mfhilo")])
5082 ;; Patterns for loading or storing part of a paired floating point
5083 ;; register.  We need them because odd-numbered floating-point registers
5084 ;; are not fully independent: see mips_split_64bit_move.
5086 ;; Load the low word of operand 0 with operand 1.
5087 (define_insn "load_df_low"
5088   [(set (match_operand:DF 0 "register_operand" "=f,f")
5089         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
5090                    UNSPEC_LOAD_DF_LOW))]
5091   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5093   operands[0] = mips_subword (operands[0], 0);
5094   return mips_output_move (operands[0], operands[1]);
5096   [(set_attr "type"     "xfer,fpload")
5097    (set_attr "mode"     "SF")])
5099 ;; Load the high word of operand 0 from operand 1, preserving the value
5100 ;; in the low word.
5101 (define_insn "load_df_high"
5102   [(set (match_operand:DF 0 "register_operand" "=f,f")
5103         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
5104                     (match_operand:DF 2 "register_operand" "0,0")]
5105                    UNSPEC_LOAD_DF_HIGH))]
5106   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5108   operands[0] = mips_subword (operands[0], 1);
5109   return mips_output_move (operands[0], operands[1]);
5111   [(set_attr "type"     "xfer,fpload")
5112    (set_attr "mode"     "SF")])
5114 ;; Store the high word of operand 1 in operand 0.  The corresponding
5115 ;; low-word move is done in the normal way.
5116 (define_insn "store_df_high"
5117   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
5118         (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
5119                    UNSPEC_STORE_DF_HIGH))]
5120   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5122   operands[1] = mips_subword (operands[1], 1);
5123   return mips_output_move (operands[0], operands[1]);
5125   [(set_attr "type"     "xfer,fpstore")
5126    (set_attr "mode"     "SF")])
5128 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
5129 ;; of _gp from the start of this function.  Operand 1 is the incoming
5130 ;; function address.
5131 (define_insn_and_split "loadgp"
5132   [(unspec_volatile [(match_operand 0 "" "")
5133                      (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
5134   "TARGET_ABICALLS && TARGET_NEWABI"
5135   "#"
5136   ""
5137   [(set (match_dup 2) (match_dup 3))
5138    (set (match_dup 2) (match_dup 4))
5139    (set (match_dup 2) (match_dup 5))]
5141   operands[2] = pic_offset_table_rtx;
5142   operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
5143   operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
5144   operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
5146   [(set_attr "length" "12")])
5148 ;; The use of gp is hidden when not using explicit relocations.
5149 ;; This blockage instruction prevents the gp load from being
5150 ;; scheduled after an implicit use of gp.  It also prevents
5151 ;; the load from being deleted as dead.
5152 (define_insn "loadgp_blockage"
5153   [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
5154   ""
5155   ""
5156   [(set_attr "type"     "unknown")
5157    (set_attr "mode"     "none")
5158    (set_attr "length"   "0")])
5160 ;; Emit a .cprestore directive, which expands to a single store instruction.
5161 ;; Note that we continue to use .cprestore for explicit reloc code so that
5162 ;; jals inside inlines asms will work correctly.
5163 (define_insn "cprestore"
5164   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
5165                     UNSPEC_CPRESTORE)]
5166   ""
5167   ".cprestore\t%0"
5168   [(set_attr "type" "store")
5169    (set_attr "length" "4")])
5171 ;; Block moves, see mips.c for more details.
5172 ;; Argument 0 is the destination
5173 ;; Argument 1 is the source
5174 ;; Argument 2 is the length
5175 ;; Argument 3 is the alignment
5177 (define_expand "movstrsi"
5178   [(parallel [(set (match_operand:BLK 0 "general_operand")
5179                    (match_operand:BLK 1 "general_operand"))
5180               (use (match_operand:SI 2 ""))
5181               (use (match_operand:SI 3 "const_int_operand"))])]
5182   "!TARGET_MIPS16 && !TARGET_MEMCPY"
5184   if (mips_expand_block_move (operands[0], operands[1], operands[2]))
5185     DONE;
5186   else
5187     FAIL;
5191 ;;  ....................
5193 ;;      SHIFTS
5195 ;;  ....................
5197 ;; Many of these instructions use trivial define_expands, because we
5198 ;; want to use a different set of constraints when TARGET_MIPS16.
5200 (define_expand "ashlsi3"
5201   [(set (match_operand:SI 0 "register_operand")
5202         (ashift:SI (match_operand:SI 1 "register_operand")
5203                    (match_operand:SI 2 "arith_operand")))]
5204   ""
5206   /* On the mips16, a shift of more than 8 is a four byte instruction,
5207      so, for a shift between 8 and 16, it is just as fast to do two
5208      shifts of 8 or less.  If there is a lot of shifting going on, we
5209      may win in CSE.  Otherwise combine will put the shifts back
5210      together again.  This can be called by function_arg, so we must
5211      be careful not to allocate a new register if we've reached the
5212      reload pass.  */
5213   if (TARGET_MIPS16
5214       && optimize
5215       && GET_CODE (operands[2]) == CONST_INT
5216       && INTVAL (operands[2]) > 8
5217       && INTVAL (operands[2]) <= 16
5218       && ! reload_in_progress
5219       && ! reload_completed)
5220     {
5221       rtx temp = gen_reg_rtx (SImode);
5223       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
5224       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
5225                                         GEN_INT (INTVAL (operands[2]) - 8)));
5226       DONE;
5227     }
5230 (define_insn "ashlsi3_internal1"
5231   [(set (match_operand:SI 0 "register_operand" "=d")
5232         (ashift:SI (match_operand:SI 1 "register_operand" "d")
5233                    (match_operand:SI 2 "arith_operand" "dI")))]
5234   "!TARGET_MIPS16"
5236   if (GET_CODE (operands[2]) == CONST_INT)
5237     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5239   return "sll\t%0,%1,%2";
5241   [(set_attr "type"     "shift")
5242    (set_attr "mode"     "SI")])
5244 (define_insn "ashlsi3_internal1_extend"
5245   [(set (match_operand:DI 0 "register_operand" "=d")
5246        (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
5247                                   (match_operand:SI 2 "arith_operand" "dI"))))]
5248   "TARGET_64BIT && !TARGET_MIPS16"
5250   if (GET_CODE (operands[2]) == CONST_INT)
5251     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5253   return "sll\t%0,%1,%2";
5255   [(set_attr "type"    "shift")
5256    (set_attr "mode"    "DI")])
5259 (define_insn "ashlsi3_internal2"
5260   [(set (match_operand:SI 0 "register_operand" "=d,d")
5261         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
5262                    (match_operand:SI 2 "arith_operand" "d,I")))]
5263   "TARGET_MIPS16"
5265   if (which_alternative == 0)
5266     return "sll\t%0,%2";
5268   if (GET_CODE (operands[2]) == CONST_INT)
5269     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5271   return "sll\t%0,%1,%2";
5273   [(set_attr "type"     "shift")
5274    (set_attr "mode"     "SI")
5275    (set_attr_alternative "length"
5276                 [(const_int 4)
5277                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5278                                (const_int 4)
5279                                (const_int 8))])])
5281 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5283 (define_split
5284   [(set (match_operand:SI 0 "register_operand")
5285         (ashift:SI (match_operand:SI 1 "register_operand")
5286                    (match_operand:SI 2 "const_int_operand")))]
5287   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5288    && GET_CODE (operands[2]) == CONST_INT
5289    && INTVAL (operands[2]) > 8
5290    && INTVAL (operands[2]) <= 16"
5291   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
5292    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
5293   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5295 (define_expand "ashldi3"
5296   [(set (match_operand:DI 0 "register_operand")
5297         (ashift:DI (match_operand:DI 1 "register_operand")
5298                    (match_operand:SI 2 "arith_operand")))]
5299   "TARGET_64BIT"
5301   /* On the mips16, a shift of more than 8 is a four byte
5302      instruction, so, for a shift between 8 and 16, it is just as
5303      fast to do two shifts of 8 or less.  If there is a lot of
5304      shifting going on, we may win in CSE.  Otherwise combine will
5305      put the shifts back together again.  This can be called by
5306      function_arg, so we must be careful not to allocate a new
5307      register if we've reached the reload pass.  */
5308   if (TARGET_MIPS16
5309       && optimize
5310       && GET_CODE (operands[2]) == CONST_INT
5311       && INTVAL (operands[2]) > 8
5312       && INTVAL (operands[2]) <= 16
5313       && ! reload_in_progress
5314       && ! reload_completed)
5315     {
5316       rtx temp = gen_reg_rtx (DImode);
5318       emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
5319       emit_insn (gen_ashldi3_internal (operands[0], temp,
5320                                        GEN_INT (INTVAL (operands[2]) - 8)));
5321       DONE;
5322     }
5326 (define_insn "ashldi3_internal"
5327   [(set (match_operand:DI 0 "register_operand" "=d")
5328         (ashift:DI (match_operand:DI 1 "register_operand" "d")
5329                    (match_operand:SI 2 "arith_operand" "dI")))]
5330   "TARGET_64BIT && !TARGET_MIPS16"
5332   if (GET_CODE (operands[2]) == CONST_INT)
5333     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5335   return "dsll\t%0,%1,%2";
5337   [(set_attr "type"     "shift")
5338    (set_attr "mode"     "DI")])
5340 (define_insn ""
5341   [(set (match_operand:DI 0 "register_operand" "=d,d")
5342         (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
5343                    (match_operand:SI 2 "arith_operand" "d,I")))]
5344   "TARGET_64BIT && TARGET_MIPS16"
5346   if (which_alternative == 0)
5347     return "dsll\t%0,%2";
5349   if (GET_CODE (operands[2]) == CONST_INT)
5350     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5352   return "dsll\t%0,%1,%2";
5354   [(set_attr "type"     "shift")
5355    (set_attr "mode"     "DI")
5356    (set_attr_alternative "length"
5357                 [(const_int 4)
5358                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5359                                (const_int 4)
5360                                (const_int 8))])])
5363 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5365 (define_split
5366   [(set (match_operand:DI 0 "register_operand")
5367         (ashift:DI (match_operand:DI 1 "register_operand")
5368                    (match_operand:SI 2 "const_int_operand")))]
5369   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5370    && reload_completed
5371    && GET_CODE (operands[2]) == CONST_INT
5372    && INTVAL (operands[2]) > 8
5373    && INTVAL (operands[2]) <= 16"
5374   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
5375    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
5376   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5378 (define_expand "ashrsi3"
5379   [(set (match_operand:SI 0 "register_operand")
5380         (ashiftrt:SI (match_operand:SI 1 "register_operand")
5381                      (match_operand:SI 2 "arith_operand")))]
5382   ""
5384   /* On the mips16, a shift of more than 8 is a four byte instruction,
5385      so, for a shift between 8 and 16, it is just as fast to do two
5386      shifts of 8 or less.  If there is a lot of shifting going on, we
5387      may win in CSE.  Otherwise combine will put the shifts back
5388      together again.  */
5389   if (TARGET_MIPS16
5390       && optimize
5391       && GET_CODE (operands[2]) == CONST_INT
5392       && INTVAL (operands[2]) > 8
5393       && INTVAL (operands[2]) <= 16)
5394     {
5395       rtx temp = gen_reg_rtx (SImode);
5397       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5398       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
5399                                         GEN_INT (INTVAL (operands[2]) - 8)));
5400       DONE;
5401     }
5404 (define_insn "ashrsi3_internal1"
5405   [(set (match_operand:SI 0 "register_operand" "=d")
5406         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5407                      (match_operand:SI 2 "arith_operand" "dI")))]
5408   "!TARGET_MIPS16"
5410   if (GET_CODE (operands[2]) == CONST_INT)
5411     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5413   return "sra\t%0,%1,%2";
5415   [(set_attr "type"     "shift")
5416    (set_attr "mode"     "SI")])
5418 (define_insn "ashrsi3_internal2"
5419   [(set (match_operand:SI 0 "register_operand" "=d,d")
5420         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5421                      (match_operand:SI 2 "arith_operand" "d,I")))]
5422   "TARGET_MIPS16"
5424   if (which_alternative == 0)
5425     return "sra\t%0,%2";
5427   if (GET_CODE (operands[2]) == CONST_INT)
5428     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5430   return "sra\t%0,%1,%2";
5432   [(set_attr "type"     "shift")
5433    (set_attr "mode"     "SI")
5434    (set_attr_alternative "length"
5435                 [(const_int 4)
5436                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5437                                (const_int 4)
5438                                (const_int 8))])])
5441 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5443 (define_split
5444   [(set (match_operand:SI 0 "register_operand")
5445         (ashiftrt:SI (match_operand:SI 1 "register_operand")
5446                      (match_operand:SI 2 "const_int_operand")))]
5447   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5448    && GET_CODE (operands[2]) == CONST_INT
5449    && INTVAL (operands[2]) > 8
5450    && INTVAL (operands[2]) <= 16"
5451   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
5452    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
5453   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5455 (define_expand "ashrdi3"
5456   [(set (match_operand:DI 0 "register_operand")
5457         (ashiftrt:DI (match_operand:DI 1 "register_operand")
5458                      (match_operand:SI 2 "arith_operand")))]
5459   "TARGET_64BIT"
5461   /* On the mips16, a shift of more than 8 is a four byte
5462      instruction, so, for a shift between 8 and 16, it is just as
5463      fast to do two shifts of 8 or less.  If there is a lot of
5464      shifting going on, we may win in CSE.  Otherwise combine will
5465      put the shifts back together again.  */
5466   if (TARGET_MIPS16
5467       && optimize
5468       && GET_CODE (operands[2]) == CONST_INT
5469       && INTVAL (operands[2]) > 8
5470       && INTVAL (operands[2]) <= 16)
5471     {
5472       rtx temp = gen_reg_rtx (DImode);
5474       emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
5475       emit_insn (gen_ashrdi3_internal (operands[0], temp,
5476                                        GEN_INT (INTVAL (operands[2]) - 8)));
5477       DONE;
5478     }
5482 (define_insn "ashrdi3_internal"
5483   [(set (match_operand:DI 0 "register_operand" "=d")
5484         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5485                      (match_operand:SI 2 "arith_operand" "dI")))]
5486   "TARGET_64BIT && !TARGET_MIPS16"
5488   if (GET_CODE (operands[2]) == CONST_INT)
5489     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5491   return "dsra\t%0,%1,%2";
5493   [(set_attr "type"     "shift")
5494    (set_attr "mode"     "DI")])
5496 (define_insn ""
5497   [(set (match_operand:DI 0 "register_operand" "=d,d")
5498         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5499                      (match_operand:SI 2 "arith_operand" "d,I")))]
5500   "TARGET_64BIT && TARGET_MIPS16"
5502   if (GET_CODE (operands[2]) == CONST_INT)
5503     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5505   return "dsra\t%0,%2";
5507   [(set_attr "type"     "shift")
5508    (set_attr "mode"     "DI")
5509    (set_attr_alternative "length"
5510                 [(const_int 4)
5511                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5512                                (const_int 4)
5513                                (const_int 8))])])
5515 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5517 (define_split
5518   [(set (match_operand:DI 0 "register_operand")
5519         (ashiftrt:DI (match_operand:DI 1 "register_operand")
5520                      (match_operand:SI 2 "const_int_operand")))]
5521   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5522    && reload_completed
5523    && GET_CODE (operands[2]) == CONST_INT
5524    && INTVAL (operands[2]) > 8
5525    && INTVAL (operands[2]) <= 16"
5526   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
5527    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
5528   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5530 (define_expand "lshrsi3"
5531   [(set (match_operand:SI 0 "register_operand")
5532         (lshiftrt:SI (match_operand:SI 1 "register_operand")
5533                      (match_operand:SI 2 "arith_operand")))]
5534   ""
5536   /* On the mips16, a shift of more than 8 is a four byte instruction,
5537      so, for a shift between 8 and 16, it is just as fast to do two
5538      shifts of 8 or less.  If there is a lot of shifting going on, we
5539      may win in CSE.  Otherwise combine will put the shifts back
5540      together again.  */
5541   if (TARGET_MIPS16
5542       && optimize
5543       && GET_CODE (operands[2]) == CONST_INT
5544       && INTVAL (operands[2]) > 8
5545       && INTVAL (operands[2]) <= 16)
5546     {
5547       rtx temp = gen_reg_rtx (SImode);
5549       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5550       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
5551                                         GEN_INT (INTVAL (operands[2]) - 8)));
5552       DONE;
5553     }
5556 (define_insn "lshrsi3_internal1"
5557   [(set (match_operand:SI 0 "register_operand" "=d")
5558         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
5559                      (match_operand:SI 2 "arith_operand" "dI")))]
5560   "!TARGET_MIPS16"
5562   if (GET_CODE (operands[2]) == CONST_INT)
5563     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5565   return "srl\t%0,%1,%2";
5567   [(set_attr "type"     "shift")
5568    (set_attr "mode"     "SI")])
5570 (define_insn "lshrsi3_internal2"
5571   [(set (match_operand:SI 0 "register_operand" "=d,d")
5572         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5573                      (match_operand:SI 2 "arith_operand" "d,I")))]
5574   "TARGET_MIPS16"
5576   if (which_alternative == 0)
5577     return "srl\t%0,%2";
5579   if (GET_CODE (operands[2]) == CONST_INT)
5580     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5582   return "srl\t%0,%1,%2";
5584   [(set_attr "type"     "shift")
5585    (set_attr "mode"     "SI")
5586    (set_attr_alternative "length"
5587                 [(const_int 4)
5588                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5589                                (const_int 4)
5590                                (const_int 8))])])
5593 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5595 (define_split
5596   [(set (match_operand:SI 0 "register_operand")
5597         (lshiftrt:SI (match_operand:SI 1 "register_operand")
5598                      (match_operand:SI 2 "const_int_operand")))]
5599   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5600    && GET_CODE (operands[2]) == CONST_INT
5601    && INTVAL (operands[2]) > 8
5602    && INTVAL (operands[2]) <= 16"
5603   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
5604    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5605   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5607 ;; If we load a byte on the mips16 as a bitfield, the resulting
5608 ;; sequence of instructions is too complicated for combine, because it
5609 ;; involves four instructions: a load, a shift, a constant load into a
5610 ;; register, and an and (the key problem here is that the mips16 does
5611 ;; not have and immediate).  We recognize a shift of a load in order
5612 ;; to make it simple enough for combine to understand.
5614 ;; The length here is the worst case: the length of the split version
5615 ;; will be more accurate.
5616 (define_insn_and_split ""
5617   [(set (match_operand:SI 0 "register_operand" "=d")
5618         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5619                      (match_operand:SI 2 "immediate_operand" "I")))]
5620   "TARGET_MIPS16"
5621   "#"
5622   ""
5623   [(set (match_dup 0) (match_dup 1))
5624    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5625   ""
5626   [(set_attr "type"     "load")
5627    (set_attr "mode"     "SI")
5628    (set_attr "length"   "16")])
5630 (define_expand "lshrdi3"
5631   [(set (match_operand:DI 0 "register_operand")
5632         (lshiftrt:DI (match_operand:DI 1 "register_operand")
5633                      (match_operand:SI 2 "arith_operand")))]
5634   "TARGET_64BIT"
5636   /* On the mips16, a shift of more than 8 is a four byte
5637      instruction, so, for a shift between 8 and 16, it is just as
5638      fast to do two shifts of 8 or less.  If there is a lot of
5639      shifting going on, we may win in CSE.  Otherwise combine will
5640      put the shifts back together again.  */
5641   if (TARGET_MIPS16
5642       && optimize
5643       && GET_CODE (operands[2]) == CONST_INT
5644       && INTVAL (operands[2]) > 8
5645       && INTVAL (operands[2]) <= 16)
5646     {
5647       rtx temp = gen_reg_rtx (DImode);
5649       emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
5650       emit_insn (gen_lshrdi3_internal (operands[0], temp,
5651                                        GEN_INT (INTVAL (operands[2]) - 8)));
5652       DONE;
5653     }
5657 (define_insn "lshrdi3_internal"
5658   [(set (match_operand:DI 0 "register_operand" "=d")
5659         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5660                      (match_operand:SI 2 "arith_operand" "dI")))]
5661   "TARGET_64BIT && !TARGET_MIPS16"
5663   if (GET_CODE (operands[2]) == CONST_INT)
5664     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5666   return "dsrl\t%0,%1,%2";
5668   [(set_attr "type"     "shift")
5669    (set_attr "mode"     "DI")])
5671 (define_insn ""
5672   [(set (match_operand:DI 0 "register_operand" "=d,d")
5673         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5674                      (match_operand:SI 2 "arith_operand" "d,I")))]
5675   "TARGET_64BIT && TARGET_MIPS16"
5677   if (GET_CODE (operands[2]) == CONST_INT)
5678     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5680   return "dsrl\t%0,%2";
5682   [(set_attr "type"     "shift")
5683    (set_attr "mode"     "DI")
5684    (set_attr_alternative "length"
5685                 [(const_int 4)
5686                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5687                                (const_int 4)
5688                                (const_int 8))])])
5690 (define_insn "rotrsi3"
5691   [(set (match_operand:SI              0 "register_operand" "=d")
5692         (rotatert:SI (match_operand:SI 1 "register_operand" "d")
5693                      (match_operand:SI 2 "arith_operand"    "dn")))]
5694   "ISA_HAS_ROTR_SI"
5696   if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
5697     return "rorv\t%0,%1,%2";
5699   if ((GET_CODE (operands[2]) == CONST_INT)
5700       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
5701     abort ();
5703   return "ror\t%0,%1,%2";
5705   [(set_attr "type"     "shift")
5706    (set_attr "mode"     "SI")])
5708 (define_insn "rotrdi3"
5709   [(set (match_operand:DI              0 "register_operand" "=d")
5710         (rotatert:DI (match_operand:DI 1 "register_operand" "d")
5711                      (match_operand:DI 2 "arith_operand"    "dn")))]
5712   "ISA_HAS_ROTR_DI"
5714   if (TARGET_SR71K)
5715     {
5716       if (GET_CODE (operands[2]) != CONST_INT)
5717         return "drorv\t%0,%1,%2";
5719       if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
5720         return "dror32\t%0,%1,%2";
5721     }
5723   if ((GET_CODE (operands[2]) == CONST_INT)
5724       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
5725     abort ();
5727   return "dror\t%0,%1,%2";
5729   [(set_attr "type"     "shift")
5730    (set_attr "mode"     "DI")])
5733 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5735 (define_split
5736   [(set (match_operand:DI 0 "register_operand")
5737         (lshiftrt:DI (match_operand:DI 1 "register_operand")
5738                      (match_operand:SI 2 "const_int_operand")))]
5739   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5740    && GET_CODE (operands[2]) == CONST_INT
5741    && INTVAL (operands[2]) > 8
5742    && INTVAL (operands[2]) <= 16"
5743   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
5744    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
5745   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5748 ;;  ....................
5750 ;;      COMPARISONS
5752 ;;  ....................
5754 ;; Flow here is rather complex:
5756 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the
5757 ;;      arguments into the branch_cmp array, and the type into
5758 ;;      branch_type.  No RTL is generated.
5760 ;;  2)  The appropriate branch define_expand is called, which then
5761 ;;      creates the appropriate RTL for the comparison and branch.
5762 ;;      Different CC modes are used, based on what type of branch is
5763 ;;      done, so that we can constrain things appropriately.  There
5764 ;;      are assumptions in the rest of GCC that break if we fold the
5765 ;;      operands into the branches for integer operations, and use cc0
5766 ;;      for floating point, so we use the fp status register instead.
5767 ;;      If needed, an appropriate temporary is created to hold the
5768 ;;      of the integer compare.
5770 (define_expand "cmpsi"
5771   [(set (cc0)
5772         (compare:CC (match_operand:SI 0 "register_operand")
5773                     (match_operand:SI 1 "arith_operand")))]
5774   ""
5776   branch_cmp[0] = operands[0];
5777   branch_cmp[1] = operands[1];
5778   branch_type = CMP_SI;
5779   DONE;
5782 (define_expand "cmpdi"
5783   [(set (cc0)
5784         (compare:CC (match_operand:DI 0 "register_operand")
5785                     (match_operand:DI 1 "arith_operand")))]
5786   "TARGET_64BIT"
5788   branch_cmp[0] = operands[0];
5789   branch_cmp[1] = operands[1];
5790   branch_type = CMP_DI;
5791   DONE;
5794 (define_expand "cmpdf"
5795   [(set (cc0)
5796         (compare:CC (match_operand:DF 0 "register_operand")
5797                     (match_operand:DF 1 "register_operand")))]
5798   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5800   branch_cmp[0] = operands[0];
5801   branch_cmp[1] = operands[1];
5802   branch_type = CMP_DF;
5803   DONE;
5806 (define_expand "cmpsf"
5807   [(set (cc0)
5808         (compare:CC (match_operand:SF 0 "register_operand")
5809                     (match_operand:SF 1 "register_operand")))]
5810   "TARGET_HARD_FLOAT"
5812   branch_cmp[0] = operands[0];
5813   branch_cmp[1] = operands[1];
5814   branch_type = CMP_SF;
5815   DONE;
5819 ;;  ....................
5821 ;;      CONDITIONAL BRANCHES
5823 ;;  ....................
5825 ;; Conditional branches on floating-point equality tests.
5827 (define_insn "branch_fp"
5828   [(set (pc)
5829         (if_then_else
5830          (match_operator:CC 0 "cmp_op"
5831                             [(match_operand:CC 2 "register_operand" "z")
5832                              (const_int 0)])
5833          (label_ref (match_operand 1 "" ""))
5834          (pc)))]
5835   "TARGET_HARD_FLOAT"
5837   return mips_output_conditional_branch (insn,
5838                                          operands,
5839                                          /*two_operands_p=*/0,
5840                                          /*float_p=*/1,
5841                                          /*inverted_p=*/0,
5842                                          get_attr_length (insn));
5844   [(set_attr "type"     "branch")
5845    (set_attr "mode"     "none")])
5847 (define_insn "branch_fp_inverted"
5848   [(set (pc)
5849         (if_then_else
5850          (match_operator:CC 0 "cmp_op"
5851                             [(match_operand:CC 2 "register_operand" "z")
5852                              (const_int 0)])
5853          (pc)
5854          (label_ref (match_operand 1 "" ""))))]
5855   "TARGET_HARD_FLOAT"
5857   return mips_output_conditional_branch (insn,
5858                                          operands,
5859                                          /*two_operands_p=*/0,
5860                                          /*float_p=*/1,
5861                                          /*inverted_p=*/1,
5862                                          get_attr_length (insn));
5864   [(set_attr "type"     "branch")
5865    (set_attr "mode"     "none")])
5867 ;; Conditional branches on comparisons with zero.
5869 (define_insn "branch_zero"
5870   [(set (pc)
5871         (if_then_else
5872          (match_operator:SI 0 "cmp_op"
5873                             [(match_operand:SI 2 "register_operand" "d")
5874                              (const_int 0)])
5875         (label_ref (match_operand 1 "" ""))
5876         (pc)))]
5877   "!TARGET_MIPS16"
5879   return mips_output_conditional_branch (insn,
5880                                          operands,
5881                                          /*two_operands_p=*/0,
5882                                          /*float_p=*/0,
5883                                          /*inverted_p=*/0,
5884                                          get_attr_length (insn));
5886   [(set_attr "type"     "branch")
5887    (set_attr "mode"     "none")])
5889 (define_insn "branch_zero_inverted"
5890   [(set (pc)
5891         (if_then_else
5892          (match_operator:SI 0 "cmp_op"
5893                             [(match_operand:SI 2 "register_operand" "d")
5894                              (const_int 0)])
5895         (pc)
5896         (label_ref (match_operand 1 "" ""))))]
5897   "!TARGET_MIPS16"
5899   return mips_output_conditional_branch (insn,
5900                                          operands,
5901                                          /*two_operands_p=*/0,
5902                                          /*float_p=*/0,
5903                                          /*inverted_p=*/1,
5904                                          get_attr_length (insn));
5906   [(set_attr "type"     "branch")
5907    (set_attr "mode"     "none")])
5909 (define_insn "branch_zero_di"
5910   [(set (pc)
5911         (if_then_else
5912          (match_operator:DI 0 "cmp_op"
5913                             [(match_operand:DI 2 "register_operand" "d")
5914                              (const_int 0)])
5915         (label_ref (match_operand 1 "" ""))
5916         (pc)))]
5917   "!TARGET_MIPS16"
5919   return mips_output_conditional_branch (insn,
5920                                          operands,
5921                                          /*two_operands_p=*/0,
5922                                          /*float_p=*/0,
5923                                          /*inverted_p=*/0,
5924                                          get_attr_length (insn));
5926   [(set_attr "type"     "branch")
5927    (set_attr "mode"     "none")])
5929 (define_insn "branch_zero_di_inverted"
5930   [(set (pc)
5931         (if_then_else
5932          (match_operator:DI 0 "cmp_op"
5933                             [(match_operand:DI 2 "register_operand" "d")
5934                              (const_int 0)])
5935         (pc)
5936         (label_ref (match_operand 1 "" ""))))]
5937   "!TARGET_MIPS16"
5939   return mips_output_conditional_branch (insn,
5940                                          operands,
5941                                          /*two_operands_p=*/0,
5942                                          /*float_p=*/0,
5943                                          /*inverted_p=*/1,
5944                                          get_attr_length (insn));
5946   [(set_attr "type"     "branch")
5947    (set_attr "mode"     "none")])
5949 ;; Conditional branch on equality comparison.
5951 (define_insn "branch_equality"
5952   [(set (pc)
5953         (if_then_else
5954          (match_operator:SI 0 "equality_op"
5955                             [(match_operand:SI 2 "register_operand" "d")
5956                              (match_operand:SI 3 "register_operand" "d")])
5957          (label_ref (match_operand 1 "" ""))
5958          (pc)))]
5959   "!TARGET_MIPS16"
5961   return mips_output_conditional_branch (insn,
5962                                          operands,
5963                                          /*two_operands_p=*/1,
5964                                          /*float_p=*/0,
5965                                          /*inverted_p=*/0,
5966                                          get_attr_length (insn));
5968   [(set_attr "type"     "branch")
5969    (set_attr "mode"     "none")])
5971 (define_insn "branch_equality_di"
5972   [(set (pc)
5973         (if_then_else
5974          (match_operator:DI 0 "equality_op"
5975                             [(match_operand:DI 2 "register_operand" "d")
5976                              (match_operand:DI 3 "register_operand" "d")])
5977         (label_ref (match_operand 1 "" ""))
5978         (pc)))]
5979   "!TARGET_MIPS16"
5981   return mips_output_conditional_branch (insn,
5982                                          operands,
5983                                          /*two_operands_p=*/1,
5984                                          /*float_p=*/0,
5985                                          /*inverted_p=*/0,
5986                                          get_attr_length (insn));
5988   [(set_attr "type"     "branch")
5989    (set_attr "mode"     "none")])
5991 (define_insn "branch_equality_inverted"
5992   [(set (pc)
5993         (if_then_else
5994          (match_operator:SI 0 "equality_op"
5995                             [(match_operand:SI 2 "register_operand" "d")
5996                              (match_operand:SI 3 "register_operand" "d")])
5997          (pc)
5998          (label_ref (match_operand 1 "" ""))))]
5999   "!TARGET_MIPS16"
6001   return mips_output_conditional_branch (insn,
6002                                          operands,
6003                                          /*two_operands_p=*/1,
6004                                          /*float_p=*/0,
6005                                          /*inverted_p=*/1,
6006                                          get_attr_length (insn));
6008   [(set_attr "type"     "branch")
6009    (set_attr "mode"     "none")])
6011 (define_insn "branch_equality_di_inverted"
6012   [(set (pc)
6013         (if_then_else
6014          (match_operator:DI 0 "equality_op"
6015                             [(match_operand:DI 2 "register_operand" "d")
6016                              (match_operand:DI 3 "register_operand" "d")])
6017         (pc)
6018         (label_ref (match_operand 1 "" ""))))]
6019   "!TARGET_MIPS16"
6021   return mips_output_conditional_branch (insn,
6022                                          operands,
6023                                          /*two_operands_p=*/1,
6024                                          /*float_p=*/0,
6025                                          /*inverted_p=*/1,
6026                                          get_attr_length (insn));
6028   [(set_attr "type"     "branch")
6029    (set_attr "mode"     "none")])
6031 ;; MIPS16 branches
6033 (define_insn ""
6034   [(set (pc)
6035         (if_then_else (match_operator:SI 0 "equality_op"
6036                                          [(match_operand:SI 1 "register_operand" "d,t")
6037                                           (const_int 0)])
6038         (match_operand 2 "pc_or_label_operand" "")
6039         (match_operand 3 "pc_or_label_operand" "")))]
6040   "TARGET_MIPS16"
6042   if (operands[2] != pc_rtx)
6043     {
6044       if (which_alternative == 0)
6045         return "b%C0z\t%1,%2";
6046       else
6047         return "bt%C0z\t%2";
6048     }
6049   else
6050     {
6051       if (which_alternative == 0)
6052         return "b%N0z\t%1,%3";
6053       else
6054         return "bt%N0z\t%3";
6055     }
6057   [(set_attr "type"     "branch")
6058    (set_attr "mode"     "none")
6059    (set_attr "length"   "8")])
6061 (define_insn ""
6062   [(set (pc)
6063         (if_then_else (match_operator:DI 0 "equality_op"
6064                                          [(match_operand:DI 1 "register_operand" "d,t")
6065                                           (const_int 0)])
6066         (match_operand 2 "pc_or_label_operand" "")
6067         (match_operand 3 "pc_or_label_operand" "")))]
6068   "TARGET_MIPS16"
6070   if (operands[2] != pc_rtx)
6071     {
6072       if (which_alternative == 0)
6073         return "b%C0z\t%1,%2";
6074       else
6075         return "bt%C0z\t%2";
6076     }
6077   else
6078     {
6079       if (which_alternative == 0)
6080         return "b%N0z\t%1,%3";
6081       else
6082         return "bt%N0z\t%3";
6083     }
6085   [(set_attr "type"     "branch")
6086    (set_attr "mode"     "none")
6087    (set_attr "length"   "8")])
6089 (define_expand "bunordered"
6090   [(set (pc)
6091         (if_then_else (unordered:CC (cc0)
6092                                     (const_int 0))
6093                       (label_ref (match_operand 0 ""))
6094                       (pc)))]
6095   ""
6097   gen_conditional_branch (operands, UNORDERED);
6098   DONE;
6101 (define_expand "bordered"
6102   [(set (pc)
6103         (if_then_else (ordered:CC (cc0)
6104                                   (const_int 0))
6105                       (label_ref (match_operand 0 ""))
6106                       (pc)))]
6107   ""
6109   gen_conditional_branch (operands, ORDERED);
6110   DONE;
6113 (define_expand "bunlt"
6114   [(set (pc)
6115         (if_then_else (unlt:CC (cc0)
6116                                (const_int 0))
6117                       (label_ref (match_operand 0 ""))
6118                       (pc)))]
6119   ""
6121   gen_conditional_branch (operands, UNLT);
6122   DONE;
6125 (define_expand "bunge"
6126   [(set (pc)
6127         (if_then_else (unge:CC (cc0)
6128                                (const_int 0))
6129                       (label_ref (match_operand 0 ""))
6130                       (pc)))]
6131   ""
6133   gen_conditional_branch (operands, UNGE);
6134   DONE;
6137 (define_expand "buneq"
6138   [(set (pc)
6139         (if_then_else (uneq:CC (cc0)
6140                                (const_int 0))
6141                       (label_ref (match_operand 0 ""))
6142                       (pc)))]
6143   ""
6145   gen_conditional_branch (operands, UNEQ);
6146   DONE;
6149 (define_expand "bltgt"
6150   [(set (pc)
6151         (if_then_else (ltgt:CC (cc0)
6152                                (const_int 0))
6153                       (label_ref (match_operand 0 ""))
6154                       (pc)))]
6155   ""
6157   gen_conditional_branch (operands, LTGT);
6158   DONE;
6161 (define_expand "bunle"
6162   [(set (pc)
6163         (if_then_else (unle:CC (cc0)
6164                                (const_int 0))
6165                       (label_ref (match_operand 0 ""))
6166                       (pc)))]
6167   ""
6169   gen_conditional_branch (operands, UNLE);
6170   DONE;
6173 (define_expand "bungt"
6174   [(set (pc)
6175         (if_then_else (ungt:CC (cc0)
6176                                (const_int 0))
6177                       (label_ref (match_operand 0 ""))
6178                       (pc)))]
6179   ""
6181   gen_conditional_branch (operands, UNGT);
6182   DONE;
6185 (define_expand "beq"
6186   [(set (pc)
6187         (if_then_else (eq:CC (cc0)
6188                              (const_int 0))
6189                       (label_ref (match_operand 0 ""))
6190                       (pc)))]
6191   ""
6193   gen_conditional_branch (operands, EQ);
6194   DONE;
6197 (define_expand "bne"
6198   [(set (pc)
6199         (if_then_else (ne:CC (cc0)
6200                              (const_int 0))
6201                       (label_ref (match_operand 0 ""))
6202                       (pc)))]
6203   ""
6205   gen_conditional_branch (operands, NE);
6206   DONE;
6209 (define_expand "bgt"
6210   [(set (pc)
6211         (if_then_else (gt:CC (cc0)
6212                              (const_int 0))
6213                       (label_ref (match_operand 0 ""))
6214                       (pc)))]
6215   ""
6217   gen_conditional_branch (operands, GT);
6218   DONE;
6221 (define_expand "bge"
6222   [(set (pc)
6223         (if_then_else (ge:CC (cc0)
6224                              (const_int 0))
6225                       (label_ref (match_operand 0 ""))
6226                       (pc)))]
6227   ""
6229   gen_conditional_branch (operands, GE);
6230   DONE;
6233 (define_expand "blt"
6234   [(set (pc)
6235         (if_then_else (lt:CC (cc0)
6236                              (const_int 0))
6237                       (label_ref (match_operand 0 ""))
6238                       (pc)))]
6239   ""
6241   gen_conditional_branch (operands, LT);
6242   DONE;
6245 (define_expand "ble"
6246   [(set (pc)
6247         (if_then_else (le:CC (cc0)
6248                              (const_int 0))
6249                       (label_ref (match_operand 0 ""))
6250                       (pc)))]
6251   ""
6253   gen_conditional_branch (operands, LE);
6254   DONE;
6257 (define_expand "bgtu"
6258   [(set (pc)
6259         (if_then_else (gtu:CC (cc0)
6260                               (const_int 0))
6261                       (label_ref (match_operand 0 ""))
6262                       (pc)))]
6263   ""
6265   gen_conditional_branch (operands, GTU);
6266   DONE;
6269 (define_expand "bgeu"
6270   [(set (pc)
6271         (if_then_else (geu:CC (cc0)
6272                               (const_int 0))
6273                       (label_ref (match_operand 0 ""))
6274                       (pc)))]
6275   ""
6277   gen_conditional_branch (operands, GEU);
6278   DONE;
6281 (define_expand "bltu"
6282   [(set (pc)
6283         (if_then_else (ltu:CC (cc0)
6284                               (const_int 0))
6285                       (label_ref (match_operand 0 ""))
6286                       (pc)))]
6287   ""
6289   gen_conditional_branch (operands, LTU);
6290   DONE;
6293 (define_expand "bleu"
6294   [(set (pc)
6295         (if_then_else (leu:CC (cc0)
6296                               (const_int 0))
6297                       (label_ref (match_operand 0 ""))
6298                       (pc)))]
6299   ""
6301   gen_conditional_branch (operands, LEU);
6302   DONE;
6306 ;;  ....................
6308 ;;      SETTING A REGISTER FROM A COMPARISON
6310 ;;  ....................
6312 (define_expand "seq"
6313   [(set (match_operand:SI 0 "register_operand")
6314         (eq:SI (match_dup 1)
6315                (match_dup 2)))]
6316   ""
6318   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6319     FAIL;
6321   /* Set up operands from compare.  */
6322   operands[1] = branch_cmp[0];
6323   operands[2] = branch_cmp[1];
6325   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6326     {
6327       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
6328       DONE;
6329     }
6331   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6332     operands[2] = force_reg (SImode, operands[2]);
6334   /* Fall through and generate default code.  */
6338 (define_insn "seq_si_zero"
6339   [(set (match_operand:SI 0 "register_operand" "=d")
6340         (eq:SI (match_operand:SI 1 "register_operand" "d")
6341                (const_int 0)))]
6342   "!TARGET_MIPS16"
6343   "sltu\t%0,%1,1"
6344   [(set_attr "type"     "slt")
6345    (set_attr "mode"     "SI")])
6347 (define_insn ""
6348   [(set (match_operand:SI 0 "register_operand" "=t")
6349         (eq:SI (match_operand:SI 1 "register_operand" "d")
6350                (const_int 0)))]
6351   "TARGET_MIPS16"
6352   "sltu\t%1,1"
6353   [(set_attr "type"     "slt")
6354    (set_attr "mode"     "SI")])
6356 (define_insn "seq_di_zero"
6357   [(set (match_operand:DI 0 "register_operand" "=d")
6358         (eq:DI (match_operand:DI 1 "register_operand" "d")
6359                (const_int 0)))]
6360   "TARGET_64BIT && !TARGET_MIPS16"
6361   "sltu\t%0,%1,1"
6362   [(set_attr "type"     "slt")
6363    (set_attr "mode"     "DI")])
6365 (define_insn ""
6366   [(set (match_operand:DI 0 "register_operand" "=t")
6367         (eq:DI (match_operand:DI 1 "register_operand" "d")
6368                (const_int 0)))]
6369   "TARGET_64BIT && TARGET_MIPS16"
6370   "sltu\t%1,1"
6371   [(set_attr "type"     "slt")
6372    (set_attr "mode"     "DI")])
6374 (define_insn "seq_si"
6375   [(set (match_operand:SI 0 "register_operand" "=d,d")
6376         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
6377                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
6378   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6379   "@
6380    xor\t%0,%1,%2\;sltu\t%0,%0,1
6381    xori\t%0,%1,%2\;sltu\t%0,%0,1"
6382   [(set_attr "type"     "multi")
6383    (set_attr "mode"     "SI")
6384    (set_attr "length"   "8")])
6386 (define_split
6387   [(set (match_operand:SI 0 "register_operand")
6388         (eq:SI (match_operand:SI 1 "register_operand")
6389                (match_operand:SI 2 "uns_arith_operand")))]
6390   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
6391     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
6392   [(set (match_dup 0)
6393         (xor:SI (match_dup 1)
6394                 (match_dup 2)))
6395    (set (match_dup 0)
6396         (ltu:SI (match_dup 0)
6397                 (const_int 1)))]
6398   "")
6400 (define_insn "seq_di"
6401   [(set (match_operand:DI 0 "register_operand" "=d,d")
6402         (eq:DI (match_operand:DI 1 "register_operand" "%d,d")
6403                (match_operand:DI 2 "uns_arith_operand" "d,K")))]
6404   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6405   "@
6406    xor\t%0,%1,%2\;sltu\t%0,%0,1
6407    xori\t%0,%1,%2\;sltu\t%0,%0,1"
6408   [(set_attr "type"     "multi")
6409    (set_attr "mode"     "DI")
6410    (set_attr "length"   "8")])
6412 (define_split
6413   [(set (match_operand:DI 0 "register_operand")
6414         (eq:DI (match_operand:DI 1 "register_operand")
6415                (match_operand:DI 2 "uns_arith_operand")))]
6416   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
6417     && !TARGET_MIPS16
6418     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
6419   [(set (match_dup 0)
6420         (xor:DI (match_dup 1)
6421                 (match_dup 2)))
6422    (set (match_dup 0)
6423         (ltu:DI (match_dup 0)
6424                 (const_int 1)))]
6425   "")
6427 ;; On the mips16 the default code is better than using sltu.
6429 (define_expand "sne"
6430   [(set (match_operand:SI 0 "register_operand")
6431         (ne:SI (match_dup 1)
6432                (match_dup 2)))]
6433   "!TARGET_MIPS16"
6435   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6436     FAIL;
6438   /* Set up operands from compare.  */
6439   operands[1] = branch_cmp[0];
6440   operands[2] = branch_cmp[1];
6442   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
6443     {
6444       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
6445       DONE;
6446     }
6448   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6449     operands[2] = force_reg (SImode, operands[2]);
6451   /* Fall through and generate default code.  */
6454 (define_insn "sne_si_zero"
6455   [(set (match_operand:SI 0 "register_operand" "=d")
6456         (ne:SI (match_operand:SI 1 "register_operand" "d")
6457                (const_int 0)))]
6458   "!TARGET_MIPS16"
6459   "sltu\t%0,%.,%1"
6460   [(set_attr "type"     "slt")
6461    (set_attr "mode"     "SI")])
6463 (define_insn "sne_di_zero"
6464   [(set (match_operand:DI 0 "register_operand" "=d")
6465         (ne:DI (match_operand:DI 1 "register_operand" "d")
6466                (const_int 0)))]
6467   "TARGET_64BIT && !TARGET_MIPS16"
6468   "sltu\t%0,%.,%1"
6469   [(set_attr "type"     "slt")
6470    (set_attr "mode"     "DI")])
6472 (define_insn "sne_si"
6473   [(set (match_operand:SI 0 "register_operand" "=d,d")
6474         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
6475                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
6476   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6477   "@
6478     xor\t%0,%1,%2\;sltu\t%0,%.,%0
6479     xori\t%0,%1,%x2\;sltu\t%0,%.,%0"
6480   [(set_attr "type"     "multi")
6481    (set_attr "mode"     "SI")
6482    (set_attr "length"   "8")])
6484 (define_split
6485   [(set (match_operand:SI 0 "register_operand")
6486         (ne:SI (match_operand:SI 1 "register_operand")
6487                (match_operand:SI 2 "uns_arith_operand")))]
6488   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
6489     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
6490   [(set (match_dup 0)
6491         (xor:SI (match_dup 1)
6492                 (match_dup 2)))
6493    (set (match_dup 0)
6494         (gtu:SI (match_dup 0)
6495                 (const_int 0)))]
6496   "")
6498 (define_insn "sne_di"
6499   [(set (match_operand:DI 0 "register_operand" "=d,d")
6500         (ne:DI (match_operand:DI 1 "register_operand" "%d,d")
6501                (match_operand:DI 2 "uns_arith_operand" "d,K")))]
6502   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6503   "@
6504     xor\t%0,%1,%2\;sltu\t%0,%.,%0
6505     xori\t%0,%1,%x2\;sltu\t%0,%.,%0"
6506   [(set_attr "type"     "multi")
6507    (set_attr "mode"     "DI")
6508    (set_attr "length"   "8")])
6510 (define_split
6511   [(set (match_operand:DI 0 "register_operand")
6512         (ne:DI (match_operand:DI 1 "register_operand")
6513                (match_operand:DI 2 "uns_arith_operand")))]
6514   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
6515     && !TARGET_MIPS16
6516     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
6517   [(set (match_dup 0)
6518         (xor:DI (match_dup 1)
6519                 (match_dup 2)))
6520    (set (match_dup 0)
6521         (gtu:DI (match_dup 0)
6522                 (const_int 0)))]
6523   "")
6525 (define_expand "sgt"
6526   [(set (match_operand:SI 0 "register_operand")
6527         (gt:SI (match_dup 1)
6528                (match_dup 2)))]
6529   ""
6531   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6532     FAIL;
6534   /* Set up operands from compare.  */
6535   operands[1] = branch_cmp[0];
6536   operands[2] = branch_cmp[1];
6538   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6539     {
6540       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
6541       DONE;
6542     }
6544   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
6545     operands[2] = force_reg (SImode, operands[2]);
6547   /* Fall through and generate default code.  */
6550 (define_insn "sgt_si"
6551   [(set (match_operand:SI 0 "register_operand" "=d")
6552         (gt:SI (match_operand:SI 1 "register_operand" "d")
6553                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6554   "!TARGET_MIPS16"
6555   "slt\t%0,%z2,%1"
6556   [(set_attr "type"     "slt")
6557    (set_attr "mode"     "SI")])
6559 (define_insn ""
6560   [(set (match_operand:SI 0 "register_operand" "=t")
6561         (gt:SI (match_operand:SI 1 "register_operand" "d")
6562                (match_operand:SI 2 "register_operand" "d")))]
6563   "TARGET_MIPS16"
6564   "slt\t%2,%1"
6565   [(set_attr "type"     "slt")
6566    (set_attr "mode"     "SI")])
6568 (define_insn "sgt_di"
6569   [(set (match_operand:DI 0 "register_operand" "=d")
6570         (gt:DI (match_operand:DI 1 "register_operand" "d")
6571                (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6572   "TARGET_64BIT && !TARGET_MIPS16"
6573   "slt\t%0,%z2,%1"
6574   [(set_attr "type"     "slt")
6575    (set_attr "mode"     "DI")])
6577 (define_insn ""
6578   [(set (match_operand:DI 0 "register_operand" "=d")
6579         (gt:DI (match_operand:DI 1 "register_operand" "d")
6580                (match_operand:DI 2 "register_operand" "d")))]
6581   "TARGET_64BIT && TARGET_MIPS16"
6582   "slt\t%2,%1"
6583   [(set_attr "type"     "slt")
6584    (set_attr "mode"     "DI")])
6586 (define_expand "sge"
6587   [(set (match_operand:SI 0 "register_operand")
6588         (ge:SI (match_dup 1)
6589                (match_dup 2)))]
6590   ""
6592   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6593     FAIL;
6595   /* Set up operands from compare.  */
6596   operands[1] = branch_cmp[0];
6597   operands[2] = branch_cmp[1];
6599   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6600     {
6601       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
6602       DONE;
6603     }
6605   /* Fall through and generate default code.  */
6608 (define_insn "sge_si"
6609   [(set (match_operand:SI 0 "register_operand" "=d")
6610         (ge:SI (match_operand:SI 1 "register_operand" "d")
6611                (match_operand:SI 2 "arith_operand" "dI")))]
6612   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6613   "slt\t%0,%1,%2\;xori\t%0,%0,0x0001"
6614   [(set_attr "type"     "multi")
6615    (set_attr "mode"     "SI")
6616    (set_attr "length"   "8")])
6618 (define_split
6619   [(set (match_operand:SI 0 "register_operand")
6620         (ge:SI (match_operand:SI 1 "register_operand")
6621                (match_operand:SI 2 "arith_operand")))]
6622   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
6623   [(set (match_dup 0)
6624         (lt:SI (match_dup 1)
6625                (match_dup 2)))
6626    (set (match_dup 0)
6627         (xor:SI (match_dup 0)
6628                 (const_int 1)))]
6629   "")
6631 (define_insn "sge_di"
6632   [(set (match_operand:DI 0 "register_operand" "=d")
6633         (ge:DI (match_operand:DI 1 "register_operand" "d")
6634                (match_operand:DI 2 "arith_operand" "dI")))]
6635   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6636   "slt\t%0,%1,%2\;xori\t%0,%0,0x0001"
6637   [(set_attr "type"     "multi")
6638    (set_attr "mode"     "DI")
6639    (set_attr "length"   "8")])
6641 (define_split
6642   [(set (match_operand:DI 0 "register_operand")
6643         (ge:DI (match_operand:DI 1 "register_operand")
6644                (match_operand:DI 2 "arith_operand")))]
6645   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
6646    && !TARGET_MIPS16"
6647   [(set (match_dup 0)
6648         (lt:DI (match_dup 1)
6649                (match_dup 2)))
6650    (set (match_dup 0)
6651         (xor:DI (match_dup 0)
6652                 (const_int 1)))]
6653   "")
6655 (define_expand "slt"
6656   [(set (match_operand:SI 0 "register_operand")
6657         (lt:SI (match_dup 1)
6658                (match_dup 2)))]
6659   ""
6661   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6662     FAIL;
6664   /* Set up operands from compare.  */
6665   operands[1] = branch_cmp[0];
6666   operands[2] = branch_cmp[1];
6668   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6669     {
6670       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
6671       DONE;
6672     }
6674   /* Fall through and generate default code.  */
6677 (define_insn "slt_si"
6678   [(set (match_operand:SI 0 "register_operand" "=d")
6679         (lt:SI (match_operand:SI 1 "register_operand" "d")
6680                (match_operand:SI 2 "arith_operand" "dI")))]
6681   "!TARGET_MIPS16"
6682   "slt\t%0,%1,%2"
6683   [(set_attr "type"     "slt")
6684    (set_attr "mode"     "SI")])
6686 (define_insn ""
6687   [(set (match_operand:SI 0 "register_operand" "=t,t")
6688         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
6689                (match_operand:SI 2 "arith_operand" "d,I")))]
6690   "TARGET_MIPS16"
6691   "slt\t%1,%2"
6692   [(set_attr "type"     "slt")
6693    (set_attr "mode"     "SI")
6694    (set_attr_alternative "length"
6695                 [(const_int 4)
6696                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6697                                (const_int 4)
6698                                (const_int 8))])])
6700 (define_insn "slt_di"
6701   [(set (match_operand:DI 0 "register_operand" "=d")
6702         (lt:DI (match_operand:DI 1 "register_operand" "d")
6703                (match_operand:DI 2 "arith_operand" "dI")))]
6704   "TARGET_64BIT && !TARGET_MIPS16"
6705   "slt\t%0,%1,%2"
6706   [(set_attr "type"     "slt")
6707    (set_attr "mode"     "DI")])
6709 (define_insn ""
6710   [(set (match_operand:DI 0 "register_operand" "=t,t")
6711         (lt:DI (match_operand:DI 1 "register_operand" "d,d")
6712                (match_operand:DI 2 "arith_operand" "d,I")))]
6713   "TARGET_64BIT && TARGET_MIPS16"
6714   "slt\t%1,%2"
6715   [(set_attr "type"     "slt")
6716    (set_attr "mode"     "DI")
6717    (set_attr_alternative "length"
6718                 [(const_int 4)
6719                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6720                                (const_int 4)
6721                                (const_int 8))])])
6723 (define_expand "sle"
6724   [(set (match_operand:SI 0 "register_operand")
6725         (le:SI (match_dup 1)
6726                (match_dup 2)))]
6727   ""
6729   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6730     FAIL;
6732   /* Set up operands from compare.  */
6733   operands[1] = branch_cmp[0];
6734   operands[2] = branch_cmp[1];
6736   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6737     {
6738       gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
6739       DONE;
6740     }
6742   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
6743     operands[2] = force_reg (SImode, operands[2]);
6745   /* Fall through and generate default code.  */
6748 (define_insn "sle_si_const"
6749   [(set (match_operand:SI 0 "register_operand" "=d")
6750         (le:SI (match_operand:SI 1 "register_operand" "d")
6751                (match_operand:SI 2 "small_int" "I")))]
6752   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6754   operands[2] = GEN_INT (INTVAL (operands[2])+1);
6755   return "slt\t%0,%1,%2";
6757   [(set_attr "type"     "slt")
6758    (set_attr "mode"     "SI")])
6760 (define_insn ""
6761   [(set (match_operand:SI 0 "register_operand" "=t")
6762         (le:SI (match_operand:SI 1 "register_operand" "d")
6763                (match_operand:SI 2 "small_int" "I")))]
6764   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6766   operands[2] = GEN_INT (INTVAL (operands[2])+1);
6767   return "slt\t%1,%2";
6769   [(set_attr "type"     "slt")
6770    (set_attr "mode"     "SI")
6771    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6772                                       (const_int 4)
6773                                       (const_int 8)))])
6775 (define_insn "sle_di_const"
6776   [(set (match_operand:DI 0 "register_operand" "=d")
6777         (le:DI (match_operand:DI 1 "register_operand" "d")
6778                (match_operand:DI 2 "small_int" "I")))]
6779   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6781   operands[2] = GEN_INT (INTVAL (operands[2])+1);
6782   return "slt\t%0,%1,%2";
6784   [(set_attr "type"     "slt")
6785    (set_attr "mode"     "DI")])
6787 (define_insn ""
6788   [(set (match_operand:DI 0 "register_operand" "=t")
6789         (le:DI (match_operand:DI 1 "register_operand" "d")
6790                (match_operand:DI 2 "small_int" "I")))]
6791   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6793   operands[2] = GEN_INT (INTVAL (operands[2])+1);
6794   return "slt\t%1,%2";
6796   [(set_attr "type"     "slt")
6797    (set_attr "mode"     "DI")
6798    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6799                                       (const_int 4)
6800                                       (const_int 8)))])
6802 (define_insn "sle_si_reg"
6803   [(set (match_operand:SI 0 "register_operand" "=d")
6804         (le:SI (match_operand:SI 1 "register_operand" "d")
6805                (match_operand:SI 2 "register_operand" "d")))]
6806   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6807   "slt\t%0,%z2,%1\;xori\t%0,%0,0x0001"
6808   [(set_attr "type"     "multi")
6809    (set_attr "mode"     "SI")
6810    (set_attr "length"   "8")])
6812 (define_split
6813   [(set (match_operand:SI 0 "register_operand")
6814         (le:SI (match_operand:SI 1 "register_operand")
6815                (match_operand:SI 2 "register_operand")))]
6816   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
6817   [(set (match_dup 0)
6818         (lt:SI (match_dup 2)
6819                (match_dup 1)))
6820    (set (match_dup 0)
6821         (xor:SI (match_dup 0)
6822                 (const_int 1)))]
6823   "")
6825 (define_insn "sle_di_reg"
6826   [(set (match_operand:DI 0 "register_operand" "=d")
6827         (le:DI (match_operand:DI 1 "register_operand" "d")
6828                (match_operand:DI 2 "register_operand" "d")))]
6829   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6830   "slt\t%0,%z2,%1\;xori\t%0,%0,0x0001"
6831   [(set_attr "type"     "multi")
6832    (set_attr "mode"     "DI")
6833    (set_attr "length"   "8")])
6835 (define_split
6836   [(set (match_operand:DI 0 "register_operand")
6837         (le:DI (match_operand:DI 1 "register_operand")
6838                (match_operand:DI 2 "register_operand")))]
6839   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
6840    && !TARGET_MIPS16"
6841   [(set (match_dup 0)
6842         (lt:DI (match_dup 2)
6843                (match_dup 1)))
6844    (set (match_dup 0)
6845         (xor:DI (match_dup 0)
6846                 (const_int 1)))]
6847   "")
6849 (define_expand "sgtu"
6850   [(set (match_operand:SI 0 "register_operand")
6851         (gtu:SI (match_dup 1)
6852                 (match_dup 2)))]
6853   ""
6855   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6856     FAIL;
6858   /* Set up operands from compare.  */
6859   operands[1] = branch_cmp[0];
6860   operands[2] = branch_cmp[1];
6862   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6863     {
6864       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
6865       DONE;
6866     }
6868   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
6869     operands[2] = force_reg (SImode, operands[2]);
6871   /* Fall through and generate default code.  */
6874 (define_insn "sgtu_si"
6875   [(set (match_operand:SI 0 "register_operand" "=d")
6876         (gtu:SI (match_operand:SI 1 "register_operand" "d")
6877                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6878   "!TARGET_MIPS16"
6879   "sltu\t%0,%z2,%1"
6880   [(set_attr "type"     "slt")
6881    (set_attr "mode"     "SI")])
6883 (define_insn ""
6884   [(set (match_operand:SI 0 "register_operand" "=t")
6885         (gtu:SI (match_operand:SI 1 "register_operand" "d")
6886                 (match_operand:SI 2 "register_operand" "d")))]
6887   "TARGET_MIPS16"
6888   "sltu\t%2,%1"
6889   [(set_attr "type"     "slt")
6890    (set_attr "mode"     "SI")])
6892 (define_insn "sgtu_di"
6893   [(set (match_operand:DI 0 "register_operand" "=d")
6894         (gtu:DI (match_operand:DI 1 "register_operand" "d")
6895                 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6896   "TARGET_64BIT && !TARGET_MIPS16"
6897   "sltu\t%0,%z2,%1"
6898   [(set_attr "type"     "slt")
6899    (set_attr "mode"     "DI")])
6901 (define_insn ""
6902   [(set (match_operand:DI 0 "register_operand" "=t")
6903         (gtu:DI (match_operand:DI 1 "register_operand" "d")
6904                 (match_operand:DI 2 "register_operand" "d")))]
6905   "TARGET_64BIT && TARGET_MIPS16"
6906   "sltu\t%2,%1"
6907   [(set_attr "type"     "slt")
6908    (set_attr "mode"     "DI")])
6910 (define_expand "sgeu"
6911   [(set (match_operand:SI 0 "register_operand")
6912         (geu:SI (match_dup 1)
6913                 (match_dup 2)))]
6914   ""
6916   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6917     FAIL;
6919   /* Set up operands from compare.  */
6920   operands[1] = branch_cmp[0];
6921   operands[2] = branch_cmp[1];
6923   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6924     {
6925       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
6926       DONE;
6927     }
6929   /* Fall through and generate default code.  */
6932 (define_insn "sgeu_si"
6933   [(set (match_operand:SI 0 "register_operand" "=d")
6934         (geu:SI (match_operand:SI 1 "register_operand" "d")
6935                 (match_operand:SI 2 "arith_operand" "dI")))]
6936   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6937   "sltu\t%0,%1,%2\;xori\t%0,%0,0x0001"
6938   [(set_attr "type"     "multi")
6939    (set_attr "mode"     "SI")
6940    (set_attr "length"   "8")])
6942 (define_split
6943   [(set (match_operand:SI 0 "register_operand")
6944         (geu:SI (match_operand:SI 1 "register_operand")
6945                 (match_operand:SI 2 "arith_operand")))]
6946   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
6947   [(set (match_dup 0)
6948         (ltu:SI (match_dup 1)
6949                 (match_dup 2)))
6950    (set (match_dup 0)
6951         (xor:SI (match_dup 0)
6952                 (const_int 1)))]
6953   "")
6955 (define_insn "sgeu_di"
6956   [(set (match_operand:DI 0 "register_operand" "=d")
6957         (geu:DI (match_operand:DI 1 "register_operand" "d")
6958                 (match_operand:DI 2 "arith_operand" "dI")))]
6959   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6960   "sltu\t%0,%1,%2\;xori\t%0,%0,0x0001"
6961   [(set_attr "type"     "multi")
6962    (set_attr "mode"     "DI")
6963    (set_attr "length"   "8")])
6965 (define_split
6966   [(set (match_operand:DI 0 "register_operand")
6967         (geu:DI (match_operand:DI 1 "register_operand")
6968                 (match_operand:DI 2 "arith_operand")))]
6969   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
6970    && !TARGET_MIPS16"
6971   [(set (match_dup 0)
6972         (ltu:DI (match_dup 1)
6973                 (match_dup 2)))
6974    (set (match_dup 0)
6975         (xor:DI (match_dup 0)
6976                 (const_int 1)))]
6977   "")
6979 (define_expand "sltu"
6980   [(set (match_operand:SI 0 "register_operand")
6981         (ltu:SI (match_dup 1)
6982                 (match_dup 2)))]
6983   ""
6985   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6986     FAIL;
6988   /* Set up operands from compare.  */
6989   operands[1] = branch_cmp[0];
6990   operands[2] = branch_cmp[1];
6992   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6993     {
6994       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
6995       DONE;
6996     }
6998   /* Fall through and generate default code.  */
7001 (define_insn "sltu_si"
7002   [(set (match_operand:SI 0 "register_operand" "=d")
7003         (ltu:SI (match_operand:SI 1 "register_operand" "d")
7004                 (match_operand:SI 2 "arith_operand" "dI")))]
7005   "!TARGET_MIPS16"
7006   "sltu\t%0,%1,%2"
7007   [(set_attr "type"     "slt")
7008    (set_attr "mode"     "SI")])
7010 (define_insn ""
7011   [(set (match_operand:SI 0 "register_operand" "=t,t")
7012         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
7013                 (match_operand:SI 2 "arith_operand" "d,I")))]
7014   "TARGET_MIPS16"
7015   "sltu\t%1,%2"
7016   [(set_attr "type"     "slt")
7017    (set_attr "mode"     "SI")
7018    (set_attr_alternative "length"
7019                 [(const_int 4)
7020                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
7021                                (const_int 4)
7022                                (const_int 8))])])
7024 (define_insn "sltu_di"
7025   [(set (match_operand:DI 0 "register_operand" "=d")
7026         (ltu:DI (match_operand:DI 1 "register_operand" "d")
7027                 (match_operand:DI 2 "arith_operand" "dI")))]
7028   "TARGET_64BIT && !TARGET_MIPS16"
7029   "sltu\t%0,%1,%2"
7030   [(set_attr "type"     "slt")
7031    (set_attr "mode"     "DI")])
7033 (define_insn ""
7034   [(set (match_operand:DI 0 "register_operand" "=t,t")
7035         (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
7036                 (match_operand:DI 2 "arith_operand" "d,I")))]
7037   "TARGET_64BIT && TARGET_MIPS16"
7038   "sltu\t%1,%2"
7039   [(set_attr "type"     "slt")
7040    (set_attr "mode"     "DI")
7041    (set_attr_alternative "length"
7042                 [(const_int 4)
7043                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
7044                                (const_int 4)
7045                                (const_int 8))])])
7047 (define_expand "sleu"
7048   [(set (match_operand:SI 0 "register_operand")
7049         (leu:SI (match_dup 1)
7050                 (match_dup 2)))]
7051   ""
7053   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7054     FAIL;
7056   /* Set up operands from compare.  */
7057   operands[1] = branch_cmp[0];
7058   operands[2] = branch_cmp[1];
7060   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7061     {
7062       gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
7063       DONE;
7064     }
7066   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
7067     operands[2] = force_reg (SImode, operands[2]);
7069   /* Fall through and generate default code.  */
7072 (define_insn "sleu_si_const"
7073   [(set (match_operand:SI 0 "register_operand" "=d")
7074         (leu:SI (match_operand:SI 1 "register_operand" "d")
7075                 (match_operand:SI 2 "small_int" "I")))]
7076   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7078   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
7079   return "sltu\t%0,%1,%2";
7081   [(set_attr "type"     "slt")
7082    (set_attr "mode"     "SI")])
7084 (define_insn ""
7085   [(set (match_operand:SI 0 "register_operand" "=t")
7086         (leu:SI (match_operand:SI 1 "register_operand" "d")
7087                 (match_operand:SI 2 "small_int" "I")))]
7088   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7090   operands[2] = GEN_INT (INTVAL (operands[2])+1);
7091   return "sltu\t%1,%2";
7093   [(set_attr "type"     "slt")
7094    (set_attr "mode"     "SI")
7095    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
7096                                       (const_int 4)
7097                                       (const_int 8)))])
7099 (define_insn "sleu_di_const"
7100   [(set (match_operand:DI 0 "register_operand" "=d")
7101         (leu:DI (match_operand:DI 1 "register_operand" "d")
7102                 (match_operand:DI 2 "small_int" "I")))]
7103   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7105   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
7106   return "sltu\t%0,%1,%2";
7108   [(set_attr "type"     "slt")
7109    (set_attr "mode"     "DI")])
7111 (define_insn ""
7112   [(set (match_operand:DI 0 "register_operand" "=t")
7113         (leu:DI (match_operand:DI 1 "register_operand" "d")
7114                 (match_operand:DI 2 "small_int" "I")))]
7115   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7117   operands[2] = GEN_INT (INTVAL (operands[2])+1);
7118   return "sltu\t%1,%2";
7120   [(set_attr "type"     "slt")
7121    (set_attr "mode"     "DI")
7122    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
7123                                       (const_int 4)
7124                                       (const_int 8)))])
7126 (define_insn "sleu_si_reg"
7127   [(set (match_operand:SI 0 "register_operand" "=d")
7128         (leu:SI (match_operand:SI 1 "register_operand" "d")
7129                 (match_operand:SI 2 "register_operand" "d")))]
7130   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7131   "sltu\t%0,%z2,%1\;xori\t%0,%0,0x0001"
7132   [(set_attr "type"     "multi")
7133    (set_attr "mode"     "SI")
7134    (set_attr "length"   "8")])
7136 (define_split
7137   [(set (match_operand:SI 0 "register_operand")
7138         (leu:SI (match_operand:SI 1 "register_operand")
7139                 (match_operand:SI 2 "register_operand")))]
7140   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7141   [(set (match_dup 0)
7142         (ltu:SI (match_dup 2)
7143                 (match_dup 1)))
7144    (set (match_dup 0)
7145         (xor:SI (match_dup 0)
7146                 (const_int 1)))]
7147   "")
7149 (define_insn "sleu_di_reg"
7150   [(set (match_operand:DI 0 "register_operand" "=d")
7151         (leu:DI (match_operand:DI 1 "register_operand" "d")
7152                 (match_operand:DI 2 "register_operand" "d")))]
7153   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7154   "sltu\t%0,%z2,%1\;xori\t%0,%0,0x0001"
7155   [(set_attr "type"     "multi")
7156    (set_attr "mode"     "DI")
7157    (set_attr "length"   "8")])
7159 (define_split
7160   [(set (match_operand:DI 0 "register_operand")
7161         (leu:DI (match_operand:DI 1 "register_operand")
7162                 (match_operand:DI 2 "register_operand")))]
7163   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7164    && !TARGET_MIPS16"
7165   [(set (match_dup 0)
7166         (ltu:DI (match_dup 2)
7167                 (match_dup 1)))
7168    (set (match_dup 0)
7169         (xor:DI (match_dup 0)
7170                 (const_int 1)))]
7171   "")
7174 ;;  ....................
7176 ;;      FLOATING POINT COMPARISONS
7178 ;;  ....................
7180 (define_insn "sunordered_df"
7181   [(set (match_operand:CC 0 "register_operand" "=z")
7182         (unordered:CC (match_operand:DF 1 "register_operand" "f")
7183                       (match_operand:DF 2 "register_operand" "f")))]
7184   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7185   "c.un.d\t%Z0%1,%2"
7186   [(set_attr "type" "fcmp")
7187    (set_attr "mode" "FPSW")])
7189 (define_insn "sunlt_df"
7190   [(set (match_operand:CC 0 "register_operand" "=z")
7191         (unlt:CC (match_operand:DF 1 "register_operand" "f")
7192                  (match_operand:DF 2 "register_operand" "f")))]
7193   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7194   "c.ult.d\t%Z0%1,%2"
7195   [(set_attr "type" "fcmp")
7196    (set_attr "mode" "FPSW")])
7198 (define_insn "suneq_df"
7199   [(set (match_operand:CC 0 "register_operand" "=z")
7200         (uneq:CC (match_operand:DF 1 "register_operand" "f")
7201                  (match_operand:DF 2 "register_operand" "f")))]
7202   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7203   "c.ueq.d\t%Z0%1,%2"
7204   [(set_attr "type" "fcmp")
7205    (set_attr "mode" "FPSW")])
7207 (define_insn "sunle_df"
7208   [(set (match_operand:CC 0 "register_operand" "=z")
7209         (unle:CC (match_operand:DF 1 "register_operand" "f")
7210                  (match_operand:DF 2 "register_operand" "f")))]
7211   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7212   "c.ule.d\t%Z0%1,%2"
7213   [(set_attr "type" "fcmp")
7214    (set_attr "mode" "FPSW")])
7216 (define_insn "seq_df"
7217   [(set (match_operand:CC 0 "register_operand" "=z")
7218         (eq:CC (match_operand:DF 1 "register_operand" "f")
7219                (match_operand:DF 2 "register_operand" "f")))]
7220   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7221   "c.eq.d\t%Z0%1,%2"
7222   [(set_attr "type" "fcmp")
7223    (set_attr "mode" "FPSW")])
7225 (define_insn "slt_df"
7226   [(set (match_operand:CC 0 "register_operand" "=z")
7227         (lt:CC (match_operand:DF 1 "register_operand" "f")
7228                (match_operand:DF 2 "register_operand" "f")))]
7229   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7230   "c.lt.d\t%Z0%1,%2"
7231   [(set_attr "type" "fcmp")
7232    (set_attr "mode" "FPSW")])
7234 (define_insn "sle_df"
7235   [(set (match_operand:CC 0 "register_operand" "=z")
7236         (le:CC (match_operand:DF 1 "register_operand" "f")
7237                (match_operand:DF 2 "register_operand" "f")))]
7238   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7239   "c.le.d\t%Z0%1,%2"
7240   [(set_attr "type" "fcmp")
7241    (set_attr "mode" "FPSW")])
7243 (define_insn "sgt_df"
7244   [(set (match_operand:CC 0 "register_operand" "=z")
7245         (gt:CC (match_operand:DF 1 "register_operand" "f")
7246                (match_operand:DF 2 "register_operand" "f")))]
7247   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7248   "c.lt.d\t%Z0%2,%1"
7249   [(set_attr "type" "fcmp")
7250    (set_attr "mode" "FPSW")])
7252 (define_insn "sge_df"
7253   [(set (match_operand:CC 0 "register_operand" "=z")
7254         (ge:CC (match_operand:DF 1 "register_operand" "f")
7255                (match_operand:DF 2 "register_operand" "f")))]
7256   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7257   "c.le.d\t%Z0%2,%1"
7258   [(set_attr "type" "fcmp")
7259    (set_attr "mode" "FPSW")])
7261 (define_insn "sunordered_sf"
7262   [(set (match_operand:CC 0 "register_operand" "=z")
7263         (unordered:CC (match_operand:SF 1 "register_operand" "f")
7264                       (match_operand:SF 2 "register_operand" "f")))]
7265   "TARGET_HARD_FLOAT"
7266   "c.un.s\t%Z0%1,%2"
7267   [(set_attr "type" "fcmp")
7268    (set_attr "mode" "FPSW")])
7270 (define_insn "sunlt_sf"
7271   [(set (match_operand:CC 0 "register_operand" "=z")
7272         (unlt:CC (match_operand:SF 1 "register_operand" "f")
7273                  (match_operand:SF 2 "register_operand" "f")))]
7274   "TARGET_HARD_FLOAT"
7275   "c.ult.s\t%Z0%1,%2"
7276   [(set_attr "type" "fcmp")
7277    (set_attr "mode" "FPSW")])
7279 (define_insn "suneq_sf"
7280   [(set (match_operand:CC 0 "register_operand" "=z")
7281         (uneq:CC (match_operand:SF 1 "register_operand" "f")
7282                  (match_operand:SF 2 "register_operand" "f")))]
7283   "TARGET_HARD_FLOAT"
7284   "c.ueq.s\t%Z0%1,%2"
7285   [(set_attr "type" "fcmp")
7286    (set_attr "mode" "FPSW")])
7288 (define_insn "sunle_sf"
7289   [(set (match_operand:CC 0 "register_operand" "=z")
7290         (unle:CC (match_operand:SF 1 "register_operand" "f")
7291                  (match_operand:SF 2 "register_operand" "f")))]
7292   "TARGET_HARD_FLOAT"
7293   "c.ule.s\t%Z0%1,%2"
7294   [(set_attr "type" "fcmp")
7295    (set_attr "mode" "FPSW")])
7297 (define_insn "seq_sf"
7298   [(set (match_operand:CC 0 "register_operand" "=z")
7299         (eq:CC (match_operand:SF 1 "register_operand" "f")
7300                (match_operand:SF 2 "register_operand" "f")))]
7301   "TARGET_HARD_FLOAT"
7302   "c.eq.s\t%Z0%1,%2"
7303   [(set_attr "type" "fcmp")
7304    (set_attr "mode" "FPSW")])
7306 (define_insn "slt_sf"
7307   [(set (match_operand:CC 0 "register_operand" "=z")
7308         (lt:CC (match_operand:SF 1 "register_operand" "f")
7309                (match_operand:SF 2 "register_operand" "f")))]
7310   "TARGET_HARD_FLOAT"
7311   "c.lt.s\t%Z0%1,%2"
7312   [(set_attr "type" "fcmp")
7313    (set_attr "mode" "FPSW")])
7315 (define_insn "sle_sf"
7316   [(set (match_operand:CC 0 "register_operand" "=z")
7317         (le:CC (match_operand:SF 1 "register_operand" "f")
7318                (match_operand:SF 2 "register_operand" "f")))]
7319   "TARGET_HARD_FLOAT"
7320   "c.le.s\t%Z0%1,%2"
7321   [(set_attr "type" "fcmp")
7322    (set_attr "mode" "FPSW")])
7324 (define_insn "sgt_sf"
7325   [(set (match_operand:CC 0 "register_operand" "=z")
7326         (gt:CC (match_operand:SF 1 "register_operand" "f")
7327                (match_operand:SF 2 "register_operand" "f")))]
7328   "TARGET_HARD_FLOAT"
7329   "c.lt.s\t%Z0%2,%1"
7330   [(set_attr "type" "fcmp")
7331    (set_attr "mode" "FPSW")])
7333 (define_insn "sge_sf"
7334   [(set (match_operand:CC 0 "register_operand" "=z")
7335         (ge:CC (match_operand:SF 1 "register_operand" "f")
7336                (match_operand:SF 2 "register_operand" "f")))]
7337   "TARGET_HARD_FLOAT"
7338   "c.le.s\t%Z0%2,%1"
7339   [(set_attr "type" "fcmp")
7340    (set_attr "mode" "FPSW")])
7343 ;;  ....................
7345 ;;      UNCONDITIONAL BRANCHES
7347 ;;  ....................
7349 ;; Unconditional branches.
7351 (define_insn "jump"
7352   [(set (pc)
7353         (label_ref (match_operand 0 "" "")))]
7354   "!TARGET_MIPS16"
7356   if (flag_pic)
7357     {
7358       if (get_attr_length (insn) <= 8)
7359         return "%*b\t%l0%/";
7360       else
7361         {
7362           output_asm_insn (mips_output_load_label (), operands);
7363           return "%*jr\t%@%/%]";
7364         }
7365     }
7366   else
7367     return "%*j\t%l0%/";
7369   [(set_attr "type"     "jump")
7370    (set_attr "mode"     "none")
7371    (set (attr "length")
7372         ;; We can't use `j' when emitting PIC.  Emit a branch if it's
7373         ;; in range, otherwise load the address of the branch target into
7374         ;; $at and then jump to it.
7375         (if_then_else
7376          (ior (eq (symbol_ref "flag_pic") (const_int 0))
7377               (lt (abs (minus (match_dup 0)
7378                               (plus (pc) (const_int 4))))
7379                   (const_int 131072)))
7380          (const_int 4) (const_int 16)))])
7382 ;; We need a different insn for the mips16, because a mips16 branch
7383 ;; does not have a delay slot.
7385 (define_insn ""
7386   [(set (pc)
7387         (label_ref (match_operand 0 "" "")))]
7388   "TARGET_MIPS16"
7389   "b\t%l0"
7390   [(set_attr "type"     "branch")
7391    (set_attr "mode"     "none")
7392    (set_attr "length"   "8")])
7394 (define_expand "indirect_jump"
7395   [(set (pc) (match_operand 0 "register_operand"))]
7396   ""
7398   rtx dest;
7400   dest = operands[0];
7401   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
7402     operands[0] = copy_to_mode_reg (Pmode, dest);
7404   if (!(Pmode == DImode))
7405     emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
7406   else
7407     emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
7409   DONE;
7412 (define_insn "indirect_jump_internal1"
7413   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
7414   "!(Pmode == DImode)"
7415   "%*j\t%0%/"
7416   [(set_attr "type"     "jump")
7417    (set_attr "mode"     "none")])
7419 (define_insn "indirect_jump_internal2"
7420   [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
7421   "Pmode == DImode"
7422   "%*j\t%0%/"
7423   [(set_attr "type"     "jump")
7424    (set_attr "mode"     "none")])
7426 (define_expand "tablejump"
7427   [(set (pc)
7428         (match_operand 0 "register_operand"))
7429    (use (label_ref (match_operand 1 "")))]
7430   ""
7432   if (TARGET_MIPS16)
7433     {
7434       if (GET_MODE (operands[0]) != HImode)
7435         abort ();
7436       if (!(Pmode == DImode))
7437         emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
7438       else
7439         emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
7440       DONE;
7441     }
7443   if (GET_MODE (operands[0]) != ptr_mode)
7444     abort ();
7446   if (TARGET_GPWORD)
7447     operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
7448                                 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
7450   if (Pmode == SImode)
7451     emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
7452   else
7453     emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
7454   DONE;
7457 (define_insn "tablejump_internal1"
7458   [(set (pc)
7459         (match_operand:SI 0 "register_operand" "d"))
7460    (use (label_ref (match_operand 1 "" "")))]
7461   ""
7462   "%*j\t%0%/"
7463   [(set_attr "type"     "jump")
7464    (set_attr "mode"     "none")])
7466 (define_insn "tablejump_internal2"
7467   [(set (pc)
7468         (match_operand:DI 0 "register_operand" "d"))
7469    (use (label_ref (match_operand 1 "" "")))]
7470   "TARGET_64BIT"
7471   "%*j\t%0%/"
7472   [(set_attr "type"     "jump")
7473    (set_attr "mode"     "none")])
7475 (define_expand "tablejump_mips161"
7476   [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
7477                       (label_ref:SI (match_operand 1 ""))))]
7478   "TARGET_MIPS16 && !(Pmode == DImode)"
7480   rtx t1, t2, t3;
7482   t1 = gen_reg_rtx (SImode);
7483   t2 = gen_reg_rtx (SImode);
7484   t3 = gen_reg_rtx (SImode);
7485   emit_insn (gen_extendhisi2 (t1, operands[0]));
7486   emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
7487   emit_insn (gen_addsi3 (t3, t1, t2));
7488   emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
7489   DONE;
7492 (define_expand "tablejump_mips162"
7493   [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
7494                       (label_ref:DI (match_operand 1 ""))))]
7495   "TARGET_MIPS16 && Pmode == DImode"
7497   rtx t1, t2, t3;
7499   t1 = gen_reg_rtx (DImode);
7500   t2 = gen_reg_rtx (DImode);
7501   t3 = gen_reg_rtx (DImode);
7502   emit_insn (gen_extendhidi2 (t1, operands[0]));
7503   emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
7504   emit_insn (gen_adddi3 (t3, t1, t2));
7505   emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
7506   DONE;
7509 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
7510 ;; While it is possible to either pull it off the stack (in the
7511 ;; o32 case) or recalculate it given t9 and our target label,
7512 ;; it takes 3 or 4 insns to do so.
7514 (define_expand "builtin_setjmp_setup"
7515   [(use (match_operand 0 "register_operand"))]
7516   "TARGET_ABICALLS"
7518   rtx addr;
7520   addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
7521   emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
7522   DONE;
7525 ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
7526 ;; that older code did recalculate the gp from $25.  Continue to jump through
7527 ;; $25 for compatibility (we lose nothing by doing so).
7529 (define_expand "builtin_longjmp"
7530   [(use (match_operand 0 "register_operand"))]
7531   "TARGET_ABICALLS"
7533   /* The elements of the buffer are, in order:  */
7534   int W = GET_MODE_SIZE (Pmode);
7535   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
7536   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
7537   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
7538   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
7539   rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
7540   /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
7541      The target is bound to be using $28 as the global pointer
7542      but the current function might not be.  */
7543   rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
7545   /* This bit is similar to expand_builtin_longjmp except that it
7546      restores $gp as well.  */
7547   emit_move_insn (hard_frame_pointer_rtx, fp);
7548   emit_move_insn (pv, lab);
7549   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
7550   emit_move_insn (gp, gpv);
7551   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
7552   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7553   emit_insn (gen_rtx_USE (VOIDmode, gp));
7554   emit_indirect_jump (pv);
7555   DONE;
7559 ;;  ....................
7561 ;;      Function prologue/epilogue
7563 ;;  ....................
7566 (define_expand "prologue"
7567   [(const_int 1)]
7568   ""
7570   mips_expand_prologue ();
7571   DONE;
7574 ;; Block any insns from being moved before this point, since the
7575 ;; profiling call to mcount can use various registers that aren't
7576 ;; saved or used to pass arguments.
7578 (define_insn "blockage"
7579   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
7580   ""
7581   ""
7582   [(set_attr "type"     "unknown")
7583    (set_attr "mode"     "none")
7584    (set_attr "length"   "0")])
7586 (define_expand "epilogue"
7587   [(const_int 2)]
7588   ""
7590   mips_expand_epilogue (false);
7591   DONE;
7594 (define_expand "sibcall_epilogue"
7595   [(const_int 2)]
7596   ""
7598   mips_expand_epilogue (true);
7599   DONE;
7602 ;; Trivial return.  Make it look like a normal return insn as that
7603 ;; allows jump optimizations to work better.
7605 (define_insn "return"
7606   [(return)]
7607   "mips_can_use_return_insn ()"
7608   "%*j\t$31%/"
7609   [(set_attr "type"     "jump")
7610    (set_attr "mode"     "none")])
7612 ;; Normal return.
7614 (define_insn "return_internal"
7615   [(return)
7616    (use (match_operand 0 "pmode_register_operand" ""))]
7617   ""
7618   "%*j\t%0%/"
7619   [(set_attr "type"     "jump")
7620    (set_attr "mode"     "none")])
7622 ;; This is used in compiling the unwind routines.
7623 (define_expand "eh_return"
7624   [(use (match_operand 0 "general_operand"))]
7625   ""
7627   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
7629   if (GET_MODE (operands[0]) != gpr_mode)
7630     operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
7631   if (TARGET_64BIT)
7632     emit_insn (gen_eh_set_lr_di (operands[0]));
7633   else
7634     emit_insn (gen_eh_set_lr_si (operands[0]));
7636   DONE;
7639 ;; Clobber the return address on the stack.  We can't expand this
7640 ;; until we know where it will be put in the stack frame.
7642 (define_insn "eh_set_lr_si"
7643   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
7644    (clobber (match_scratch:SI 1 "=&d"))]
7645   "! TARGET_64BIT"
7646   "#")
7648 (define_insn "eh_set_lr_di"
7649   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
7650    (clobber (match_scratch:DI 1 "=&d"))]
7651   "TARGET_64BIT"
7652   "#")
7654 (define_split
7655   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
7656    (clobber (match_scratch 1))]
7657   "reload_completed && !TARGET_DEBUG_D_MODE"
7658   [(const_int 0)]
7660   mips_set_return_address (operands[0], operands[1]);
7661   DONE;
7664 (define_insn "exception_receiver"
7665   [(set (reg:SI 28)
7666         (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
7667   "TARGET_ABICALLS && TARGET_OLDABI"
7669   operands[0] = pic_offset_table_rtx;
7670   operands[1] = mips_gp_save_slot ();
7671   return mips_output_move (operands[0], operands[1]);
7673   [(set_attr "type"   "load")
7674    (set_attr "length" "8")])
7677 ;;  ....................
7679 ;;      FUNCTION CALLS
7681 ;;  ....................
7683 ;; Instructions to load a call address from the GOT.  The address might
7684 ;; point to a function or to a lazy binding stub.  In the latter case,
7685 ;; the stub will use the dynamic linker to resolve the function, which
7686 ;; in turn will change the GOT entry to point to the function's real
7687 ;; address.
7689 ;; This means that every call, even pure and constant ones, can
7690 ;; potentially modify the GOT entry.  And once a stub has been called,
7691 ;; we must not call it again.
7693 ;; We represent this restriction using an imaginary fixed register that
7694 ;; acts like a GOT version number.  By making the register call-clobbered,
7695 ;; we tell the target-independent code that the address could be changed
7696 ;; by any call insn.
7697 (define_insn "load_callsi"
7698   [(set (match_operand:SI 0 "register_operand" "=c")
7699         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7700                     (match_operand:SI 2 "immediate_operand" "")
7701                     (reg:SI FAKE_CALL_REGNO)]
7702                    UNSPEC_LOAD_CALL))]
7703   "TARGET_ABICALLS"
7704   "lw\t%0,%R2(%1)"
7705   [(set_attr "type" "load")
7706    (set_attr "length" "4")])
7708 (define_insn "load_calldi"
7709   [(set (match_operand:DI 0 "register_operand" "=c")
7710         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7711                     (match_operand:DI 2 "immediate_operand" "")
7712                     (reg:DI FAKE_CALL_REGNO)]
7713                    UNSPEC_LOAD_CALL))]
7714   "TARGET_ABICALLS"
7715   "ld\t%0,%R2(%1)"
7716   [(set_attr "type" "load")
7717    (set_attr "length" "4")])
7719 ;; Sibling calls.  All these patterns use jump instructions.
7721 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
7722 ;; addresses if a direct jump is acceptable.  Since the 'S' constraint
7723 ;; is defined in terms of call_insn_operand, the same is true of the
7724 ;; constraints.
7726 ;; When we use an indirect jump, we need a register that will be
7727 ;; preserved by the epilogue.  Since TARGET_ABICALLS forces us to
7728 ;; use $25 for this purpose -- and $25 is never clobbered by the
7729 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
7731 (define_expand "sibcall"
7732   [(parallel [(call (match_operand 0 "")
7733                     (match_operand 1 ""))
7734               (use (match_operand 2 ""))        ;; next_arg_reg
7735               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
7736   "TARGET_SIBCALLS"
7738   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
7739   DONE;
7742 (define_insn "sibcall_internal"
7743   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
7744          (match_operand 1 "" ""))]
7745   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7746   "@
7747     %*jr\t%0%/
7748     %*j\t%0%/"
7749   [(set_attr "type" "call")])
7751 (define_expand "sibcall_value"
7752   [(parallel [(set (match_operand 0 "")
7753                    (call (match_operand 1 "")
7754                          (match_operand 2 "")))
7755               (use (match_operand 3 ""))])]             ;; next_arg_reg
7756   "TARGET_SIBCALLS"
7758   mips_expand_call (operands[0], XEXP (operands[1], 0),
7759                     operands[2], operands[3], true);
7760   DONE;
7763 (define_insn "sibcall_value_internal"
7764   [(set (match_operand 0 "register_operand" "=df,df")
7765         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
7766               (match_operand 2 "" "")))]
7767   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7768   "@
7769     %*jr\t%1%/
7770     %*j\t%1%/"
7771   [(set_attr "type" "call")])
7773 (define_insn "sibcall_value_multiple_internal"
7774   [(set (match_operand 0 "register_operand" "=df,df")
7775         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
7776               (match_operand 2 "" "")))
7777    (set (match_operand 3 "register_operand" "=df,df")
7778         (call (mem:SI (match_dup 1))
7779               (match_dup 2)))]
7780   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7781   "@
7782     %*jr\t%1%/
7783     %*j\t%1%/"
7784   [(set_attr "type" "call")])
7786 (define_expand "call"
7787   [(parallel [(call (match_operand 0 "")
7788                     (match_operand 1 ""))
7789               (use (match_operand 2 ""))        ;; next_arg_reg
7790               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
7791   ""
7793   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
7794   DONE;
7797 ;; This instruction directly corresponds to an assembly-language "jal".
7798 ;; There are four cases:
7800 ;;    - -mno-abicalls:
7801 ;;        Both symbolic and register destinations are OK.  The pattern
7802 ;;        always expands to a single mips instruction.
7804 ;;    - -mabicalls/-mno-explicit-relocs:
7805 ;;        Again, both symbolic and register destinations are OK.
7806 ;;        The call is treated as a multi-instruction black box.
7808 ;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
7809 ;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
7810 ;;        instruction.
7812 ;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
7813 ;;        Only "jal $25" is allowed.  The call is actually two instructions:
7814 ;;        "jalr $25" followed by an insn to reload $gp.
7816 ;; In the last case, we can generate the individual instructions with
7817 ;; a define_split.  There are several things to be wary of:
7819 ;;   - We can't expose the load of $gp before reload.  If we did,
7820 ;;     it might get removed as dead, but reload can introduce new
7821 ;;     uses of $gp by rematerializing constants.
7823 ;;   - We shouldn't restore $gp after calls that never return.
7824 ;;     It isn't valid to insert instructions between a noreturn
7825 ;;     call and the following barrier.
7827 ;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
7828 ;;     instruction preserves $gp and so have no effect on its liveness.
7829 ;;     But once we generate the separate insns, it becomes obvious that
7830 ;;     $gp is not live on entry to the call.
7832 ;; ??? The operands[2] = insn check is a hack to make the original insn
7833 ;; available to the splitter.
7834 (define_insn_and_split "call_internal"
7835   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
7836          (match_operand 1 "" ""))
7837    (clobber (reg:SI 31))]
7838   ""
7839   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
7840   "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
7841   [(const_int 0)]
7843   emit_call_insn (gen_call_split (operands[0], operands[1]));
7844   if (!find_reg_note (operands[2], REG_NORETURN, 0))
7845     emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
7846   DONE;
7848   [(set_attr "jal" "indirect,direct")
7849    (set_attr "extended_mips16" "no,yes")])
7851 (define_insn "call_split"
7852   [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
7853          (match_operand 1 "" ""))
7854    (clobber (reg:SI 31))
7855    (clobber (reg:SI 28))]
7856   "TARGET_SPLIT_CALLS"
7857   "%*jalr\t%0%/"
7858   [(set_attr "type" "call")])
7860 (define_expand "call_value"
7861   [(parallel [(set (match_operand 0 "")
7862                    (call (match_operand 1 "")
7863                          (match_operand 2 "")))
7864               (use (match_operand 3 ""))])]             ;; next_arg_reg
7865   ""
7867   mips_expand_call (operands[0], XEXP (operands[1], 0),
7868                     operands[2], operands[3], false);
7869   DONE;
7872 ;; See comment for call_internal.
7873 (define_insn_and_split "call_value_internal"
7874   [(set (match_operand 0 "register_operand" "=df,df")
7875         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7876               (match_operand 2 "" "")))
7877    (clobber (reg:SI 31))]
7878   ""
7879   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7880   "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
7881   [(const_int 0)]
7883   emit_call_insn (gen_call_value_split (operands[0], operands[1],
7884                                         operands[2]));
7885   if (!find_reg_note (operands[3], REG_NORETURN, 0))
7886     emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
7887   DONE;
7889   [(set_attr "jal" "indirect,direct")
7890    (set_attr "extended_mips16" "no,yes")])
7892 (define_insn "call_value_split"
7893   [(set (match_operand 0 "register_operand" "=df")
7894         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7895               (match_operand 2 "" "")))
7896    (clobber (reg:SI 31))
7897    (clobber (reg:SI 28))]
7898   "TARGET_SPLIT_CALLS"
7899   "%*jalr\t%1%/"
7900   [(set_attr "type" "call")])
7902 ;; See comment for call_internal.
7903 (define_insn_and_split "call_value_multiple_internal"
7904   [(set (match_operand 0 "register_operand" "=df,df")
7905         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7906               (match_operand 2 "" "")))
7907    (set (match_operand 3 "register_operand" "=df,df")
7908         (call (mem:SI (match_dup 1))
7909               (match_dup 2)))
7910    (clobber (reg:SI 31))]
7911   ""
7912   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7913   "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
7914   [(const_int 0)]
7916   emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
7917                                                  operands[2], operands[3]));
7918   if (!find_reg_note (operands[4], REG_NORETURN, 0))
7919     emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
7920   DONE;
7922   [(set_attr "jal" "indirect,direct")
7923    (set_attr "extended_mips16" "no,yes")])
7925 (define_insn "call_value_multiple_split"
7926   [(set (match_operand 0 "register_operand" "=df")
7927         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7928               (match_operand 2 "" "")))
7929    (set (match_operand 3 "register_operand" "=df")
7930         (call (mem:SI (match_dup 1))
7931               (match_dup 2)))
7932    (clobber (reg:SI 31))
7933    (clobber (reg:SI 28))]
7934   "TARGET_SPLIT_CALLS"
7935   "%*jalr\t%1%/"
7936   [(set_attr "type" "call")])
7938 ;; Call subroutine returning any type.
7940 (define_expand "untyped_call"
7941   [(parallel [(call (match_operand 0 "")
7942                     (const_int 0))
7943               (match_operand 1 "")
7944               (match_operand 2 "")])]
7945   ""
7947   int i;
7949   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7951   for (i = 0; i < XVECLEN (operands[2], 0); i++)
7952     {
7953       rtx set = XVECEXP (operands[2], 0, i);
7954       emit_move_insn (SET_DEST (set), SET_SRC (set));
7955     }
7957   emit_insn (gen_blockage ());
7958   DONE;
7962 ;;  ....................
7964 ;;      MISC.
7966 ;;  ....................
7970 (define_expand "prefetch"
7971   [(prefetch (match_operand 0 "address_operand")
7972              (match_operand 1 "const_int_operand")
7973              (match_operand 2 "const_int_operand"))]
7974   "ISA_HAS_PREFETCH"
7976   if (symbolic_operand (operands[0], GET_MODE (operands[0])))
7977     operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
7980 (define_insn "prefetch_si_address"
7981   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7982                       (match_operand:SI 3 "const_int_operand" "I"))
7983              (match_operand:SI 1 "const_int_operand" "n")
7984              (match_operand:SI 2 "const_int_operand" "n"))]
7985   "ISA_HAS_PREFETCH && Pmode == SImode"
7986   { return mips_emit_prefetch (operands); }
7987   [(set_attr "type" "prefetch")])
7989 (define_insn "prefetch_indexed_si"
7990   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7991                       (match_operand:SI 3 "register_operand" "r"))
7992              (match_operand:SI 1 "const_int_operand" "n")
7993              (match_operand:SI 2 "const_int_operand" "n"))]
7994   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
7995   { return mips_emit_prefetch (operands); }
7996   [(set_attr "type" "prefetchx")])
7998 (define_insn "prefetch_si"
7999   [(prefetch (match_operand:SI 0 "register_operand" "r")
8000              (match_operand:SI 1 "const_int_operand" "n")
8001              (match_operand:SI 2 "const_int_operand" "n"))]
8002   "ISA_HAS_PREFETCH && Pmode == SImode"
8004   operands[3] = const0_rtx;
8005   return mips_emit_prefetch (operands);
8007   [(set_attr "type" "prefetch")])
8009 (define_insn "prefetch_di_address"
8010   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
8011                       (match_operand:DI 3 "const_int_operand" "I"))
8012              (match_operand:DI 1 "const_int_operand" "n")
8013              (match_operand:DI 2 "const_int_operand" "n"))]
8014   "ISA_HAS_PREFETCH && Pmode == DImode"
8015   { return mips_emit_prefetch (operands); }
8016   [(set_attr "type" "prefetch")])
8018 (define_insn "prefetch_indexed_di"
8019   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
8020                       (match_operand:DI 3 "register_operand" "r"))
8021              (match_operand:DI 1 "const_int_operand" "n")
8022              (match_operand:DI 2 "const_int_operand" "n"))]
8023   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
8024   { return mips_emit_prefetch (operands); }
8025   [(set_attr "type" "prefetchx")])
8027 (define_insn "prefetch_di"
8028   [(prefetch (match_operand:DI 0 "register_operand" "r")
8029              (match_operand:DI 1 "const_int_operand" "n")
8030              (match_operand:DI 2 "const_int_operand" "n"))]
8031   "ISA_HAS_PREFETCH && Pmode == DImode"
8033   operands[3] = const0_rtx;
8034   return mips_emit_prefetch (operands);
8036   [(set_attr "type" "prefetch")])
8038 (define_insn "nop"
8039   [(const_int 0)]
8040   ""
8041   "%(nop%)"
8042   [(set_attr "type"     "nop")
8043    (set_attr "mode"     "none")])
8045 ;; Like nop, but commented out when outside a .set noreorder block.
8046 (define_insn "hazard_nop"
8047   [(const_int 1)]
8048   ""
8049   {
8050     if (set_noreorder)
8051       return "nop";
8052     else
8053       return "#nop";
8054   }
8055   [(set_attr "type"     "nop")])
8057 ;; MIPS4 Conditional move instructions.
8059 (define_insn ""
8060   [(set (match_operand:SI 0 "register_operand" "=d,d")
8061         (if_then_else:SI
8062          (match_operator 4 "equality_op"
8063                          [(match_operand:SI 1 "register_operand" "d,d")
8064                           (const_int 0)])
8065          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
8066          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
8067   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8068   "@
8069     mov%B4\t%0,%z2,%1
8070     mov%b4\t%0,%z3,%1"
8071   [(set_attr "type" "condmove")
8072    (set_attr "mode" "SI")])
8074 (define_insn ""
8075   [(set (match_operand:SI 0 "register_operand" "=d,d")
8076         (if_then_else:SI
8077          (match_operator 4 "equality_op"
8078                          [(match_operand:DI 1 "register_operand" "d,d")
8079                           (const_int 0)])
8080          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
8081          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
8082   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8083   "@
8084     mov%B4\t%0,%z2,%1
8085     mov%b4\t%0,%z3,%1"
8086   [(set_attr "type" "condmove")
8087    (set_attr "mode" "SI")])
8089 (define_insn ""
8090   [(set (match_operand:SI 0 "register_operand" "=d,d")
8091         (if_then_else:SI
8092          (match_operator 3 "equality_op" [(match_operand:CC 4
8093                                                             "register_operand"
8094                                                             "z,z")
8095                                           (const_int 0)])
8096          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
8097          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
8098   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8099   "@
8100     mov%T3\t%0,%z1,%4
8101     mov%t3\t%0,%z2,%4"
8102   [(set_attr "type" "condmove")
8103    (set_attr "mode" "SI")])
8105 (define_insn ""
8106   [(set (match_operand:DI 0 "register_operand" "=d,d")
8107         (if_then_else:DI
8108          (match_operator 4 "equality_op"
8109                          [(match_operand:SI 1 "register_operand" "d,d")
8110                           (const_int 0)])
8111          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
8112          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
8113   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8114   "@
8115     mov%B4\t%0,%z2,%1
8116     mov%b4\t%0,%z3,%1"
8117   [(set_attr "type" "condmove")
8118    (set_attr "mode" "DI")])
8120 (define_insn ""
8121   [(set (match_operand:DI 0 "register_operand" "=d,d")
8122         (if_then_else:DI
8123          (match_operator 4 "equality_op"
8124                          [(match_operand:DI 1 "register_operand" "d,d")
8125                           (const_int 0)])
8126          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
8127          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
8128   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8129   "@
8130     mov%B4\t%0,%z2,%1
8131     mov%b4\t%0,%z3,%1"
8132   [(set_attr "type" "condmove")
8133    (set_attr "mode" "DI")])
8135 (define_insn ""
8136   [(set (match_operand:DI 0 "register_operand" "=d,d")
8137         (if_then_else:DI
8138          (match_operator 3 "equality_op" [(match_operand:CC 4
8139                                                             "register_operand"
8140                                                             "z,z")
8141                                           (const_int 0)])
8142          (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
8143          (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
8144   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
8145   "@
8146     mov%T3\t%0,%z1,%4
8147     mov%t3\t%0,%z2,%4"
8148   [(set_attr "type" "condmove")
8149    (set_attr "mode" "DI")])
8151 (define_insn ""
8152   [(set (match_operand:SF 0 "register_operand" "=f,f")
8153         (if_then_else:SF
8154          (match_operator 4 "equality_op"
8155                          [(match_operand:SI 1 "register_operand" "d,d")
8156                           (const_int 0)])
8157          (match_operand:SF 2 "register_operand" "f,0")
8158          (match_operand:SF 3 "register_operand" "0,f")))]
8159   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8160   "@
8161     mov%B4.s\t%0,%2,%1
8162     mov%b4.s\t%0,%3,%1"
8163   [(set_attr "type" "condmove")
8164    (set_attr "mode" "SF")])
8166 (define_insn ""
8167   [(set (match_operand:SF 0 "register_operand" "=f,f")
8168         (if_then_else:SF
8169          (match_operator 4 "equality_op"
8170                          [(match_operand:DI 1 "register_operand" "d,d")
8171                           (const_int 0)])
8172          (match_operand:SF 2 "register_operand" "f,0")
8173          (match_operand:SF 3 "register_operand" "0,f")))]
8174   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8175   "@
8176     mov%B4.s\t%0,%2,%1
8177     mov%b4.s\t%0,%3,%1"
8178   [(set_attr "type" "condmove")
8179    (set_attr "mode" "SF")])
8181 (define_insn ""
8182   [(set (match_operand:SF 0 "register_operand" "=f,f")
8183         (if_then_else:SF
8184          (match_operator 3 "equality_op" [(match_operand:CC 4
8185                                                             "register_operand"
8186                                                             "z,z")
8187                                           (const_int 0)])
8188          (match_operand:SF 1 "register_operand" "f,0")
8189          (match_operand:SF 2 "register_operand" "0,f")))]
8190   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8191   "@
8192     mov%T3.s\t%0,%1,%4
8193     mov%t3.s\t%0,%2,%4"
8194   [(set_attr "type" "condmove")
8195    (set_attr "mode" "SF")])
8197 (define_insn ""
8198   [(set (match_operand:DF 0 "register_operand" "=f,f")
8199         (if_then_else:DF
8200          (match_operator 4 "equality_op"
8201                          [(match_operand:SI 1 "register_operand" "d,d")
8202                           (const_int 0)])
8203          (match_operand:DF 2 "register_operand" "f,0")
8204          (match_operand:DF 3 "register_operand" "0,f")))]
8205   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8206   "@
8207     mov%B4.d\t%0,%2,%1
8208     mov%b4.d\t%0,%3,%1"
8209   [(set_attr "type" "condmove")
8210    (set_attr "mode" "DF")])
8212 (define_insn ""
8213   [(set (match_operand:DF 0 "register_operand" "=f,f")
8214         (if_then_else:DF
8215          (match_operator 4 "equality_op"
8216                          [(match_operand:DI 1 "register_operand" "d,d")
8217                           (const_int 0)])
8218          (match_operand:DF 2 "register_operand" "f,0")
8219          (match_operand:DF 3 "register_operand" "0,f")))]
8220   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8221   "@
8222     mov%B4.d\t%0,%2,%1
8223     mov%b4.d\t%0,%3,%1"
8224   [(set_attr "type" "condmove")
8225    (set_attr "mode" "DF")])
8227 (define_insn ""
8228   [(set (match_operand:DF 0 "register_operand" "=f,f")
8229         (if_then_else:DF
8230          (match_operator 3 "equality_op" [(match_operand:CC 4
8231                                                             "register_operand"
8232                                                             "z,z")
8233                                           (const_int 0)])
8234          (match_operand:DF 1 "register_operand" "f,0")
8235          (match_operand:DF 2 "register_operand" "0,f")))]
8236   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8237   "@
8238     mov%T3.d\t%0,%1,%4
8239     mov%t3.d\t%0,%2,%4"
8240   [(set_attr "type" "condmove")
8241    (set_attr "mode" "DF")])
8243 ;; These are the main define_expand's used to make conditional moves.
8245 (define_expand "movsicc"
8246   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
8247    (set (match_operand:SI 0 "register_operand")
8248         (if_then_else:SI (match_dup 5)
8249                          (match_operand:SI 2 "reg_or_0_operand")
8250                          (match_operand:SI 3 "reg_or_0_operand")))]
8251   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8253   gen_conditional_move (operands);
8254   DONE;
8257 (define_expand "movdicc"
8258   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
8259    (set (match_operand:DI 0 "register_operand")
8260         (if_then_else:DI (match_dup 5)
8261                          (match_operand:DI 2 "reg_or_0_operand")
8262                          (match_operand:DI 3 "reg_or_0_operand")))]
8263   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8265   gen_conditional_move (operands);
8266   DONE;
8269 (define_expand "movsfcc"
8270   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
8271    (set (match_operand:SF 0 "register_operand")
8272         (if_then_else:SF (match_dup 5)
8273                          (match_operand:SF 2 "register_operand")
8274                          (match_operand:SF 3 "register_operand")))]
8275   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8277   gen_conditional_move (operands);
8278   DONE;
8281 (define_expand "movdfcc"
8282   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
8283    (set (match_operand:DF 0 "register_operand")
8284         (if_then_else:DF (match_dup 5)
8285                          (match_operand:DF 2 "register_operand")
8286                          (match_operand:DF 3 "register_operand")))]
8287   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8289   gen_conditional_move (operands);
8290   DONE;
8294 ;;  ....................
8296 ;;      mips16 inline constant tables
8298 ;;  ....................
8301 (define_insn "consttable_int"
8302   [(unspec_volatile [(match_operand 0 "consttable_operand" "")
8303                      (match_operand 1 "const_int_operand" "")]
8304                     UNSPEC_CONSTTABLE_INT)]
8305   "TARGET_MIPS16"
8307   assemble_integer (operands[0], INTVAL (operands[1]),
8308                     BITS_PER_UNIT * INTVAL (operands[1]), 1);
8309   return "";
8311   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
8313 (define_insn "consttable_float"
8314   [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
8315                     UNSPEC_CONSTTABLE_FLOAT)]
8316   "TARGET_MIPS16"
8318   REAL_VALUE_TYPE d;
8320   if (GET_CODE (operands[0]) != CONST_DOUBLE)
8321     abort ();
8322   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
8323   assemble_real (d, GET_MODE (operands[0]),
8324                  GET_MODE_BITSIZE (GET_MODE (operands[0])));
8325   return "";
8327   [(set (attr "length")
8328         (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
8330 (define_insn "align"
8331   [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
8332   ""
8333   ".align\t%0"
8334   [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
8337 ;;  ....................
8339 ;;      mips16 peepholes
8341 ;;  ....................
8344 ;; On the mips16, reload will sometimes decide that a pseudo register
8345 ;; should go into $24, and then later on have to reload that register.
8346 ;; When that happens, we get a load of a general register followed by
8347 ;; a move from the general register to $24 followed by a branch.
8348 ;; These peepholes catch the common case, and fix it to just use the
8349 ;; general register for the branch.
8351 (define_peephole
8352   [(set (match_operand:SI 0 "register_operand" "=t")
8353         (match_operand:SI 1 "register_operand" "d"))
8354    (set (pc)
8355         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
8356                                                           (const_int 0)])
8357                       (match_operand 3 "pc_or_label_operand" "")
8358                       (match_operand 4 "pc_or_label_operand" "")))]
8359   "TARGET_MIPS16
8360    && GET_CODE (operands[0]) == REG
8361    && REGNO (operands[0]) == 24
8362    && dead_or_set_p (insn, operands[0])
8363    && GET_CODE (operands[1]) == REG
8364    && M16_REG_P (REGNO (operands[1]))"
8366   if (operands[3] != pc_rtx)
8367     return "b%C2z\t%1,%3";
8368   else
8369     return "b%N2z\t%1,%4";
8371   [(set_attr "type"     "branch")
8372    (set_attr "mode"     "none")
8373    (set_attr "length"   "8")])
8375 (define_peephole
8376   [(set (match_operand:DI 0 "register_operand" "=t")
8377         (match_operand:DI 1 "register_operand" "d"))
8378    (set (pc)
8379         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
8380                                                           (const_int 0)])
8381                       (match_operand 3 "pc_or_label_operand" "")
8382                       (match_operand 4 "pc_or_label_operand" "")))]
8383   "TARGET_MIPS16 && TARGET_64BIT
8384    && GET_CODE (operands[0]) == REG
8385    && REGNO (operands[0]) == 24
8386    && dead_or_set_p (insn, operands[0])
8387    && GET_CODE (operands[1]) == REG
8388    && M16_REG_P (REGNO (operands[1]))"
8390   if (operands[3] != pc_rtx)
8391     return "b%C2z\t%1,%3";
8392   else
8393     return "b%N2z\t%1,%4";
8395   [(set_attr "type"     "branch")
8396    (set_attr "mode"     "none")
8397    (set_attr "length"   "8")])
8399 ;; We can also have the reverse reload: reload will spill $24 into
8400 ;; another register, and then do a branch on that register when it
8401 ;; could have just stuck with $24.
8403 (define_peephole
8404   [(set (match_operand:SI 0 "register_operand" "=d")
8405         (match_operand:SI 1 "register_operand" "t"))
8406    (set (pc)
8407         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
8408                                                           (const_int 0)])
8409                       (match_operand 3 "pc_or_label_operand" "")
8410                       (match_operand 4 "pc_or_label_operand" "")))]
8411   "TARGET_MIPS16
8412    && GET_CODE (operands[1]) == REG
8413    && REGNO (operands[1]) == 24
8414    && GET_CODE (operands[0]) == REG
8415    && M16_REG_P (REGNO (operands[0]))
8416    && dead_or_set_p (insn, operands[0])"
8418   if (operands[3] != pc_rtx)
8419     return "bt%C2z\t%3";
8420   else
8421     return "bt%N2z\t%4";
8423   [(set_attr "type"     "branch")
8424    (set_attr "mode"     "none")
8425    (set_attr "length"   "8")])
8427 (define_peephole
8428   [(set (match_operand:DI 0 "register_operand" "=d")
8429         (match_operand:DI 1 "register_operand" "t"))
8430    (set (pc)
8431         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
8432                                                           (const_int 0)])
8433                       (match_operand 3 "pc_or_label_operand" "")
8434                       (match_operand 4 "pc_or_label_operand" "")))]
8435   "TARGET_MIPS16 && TARGET_64BIT
8436    && GET_CODE (operands[1]) == REG
8437    && REGNO (operands[1]) == 24
8438    && GET_CODE (operands[0]) == REG
8439    && M16_REG_P (REGNO (operands[0]))
8440    && dead_or_set_p (insn, operands[0])"
8442   if (operands[3] != pc_rtx)
8443     return "bt%C2z\t%3";
8444   else
8445     return "bt%N2z\t%4";
8447   [(set_attr "type"     "branch")
8448    (set_attr "mode"     "none")
8449    (set_attr "length"   "8")])
8451 (define_split
8452   [(match_operand 0 "small_data_pattern")]
8453   "reload_completed"
8454   [(match_dup 0)]
8455   { operands[0] = mips_rewrite_small_data (operands[0]); })