OSDN Git Service

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