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