OSDN Git Service

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