OSDN Git Service

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