OSDN Git Service

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