OSDN Git Service

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