OSDN Git Service

* config/mips/mips.md (divide_condition): New mode attribute.
[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_LOAD_LEFT            18)
40    (UNSPEC_LOAD_RIGHT           19)
41    (UNSPEC_STORE_LEFT           20)
42    (UNSPEC_STORE_RIGHT          21)
43    (UNSPEC_LOADGP               22)
44    (UNSPEC_LOAD_CALL            23)
45    (UNSPEC_LOAD_GOT             24)
46    (UNSPEC_GP                   25)
47    (UNSPEC_MFHILO               26)
48
49    (UNSPEC_ADDRESS_FIRST        100)
50
51    (FAKE_CALL_REGNO             79)
52
53    ;; For MIPS Paired-Singled Floating Point Instructions.
54
55    (UNSPEC_C_F                  201)
56    (UNSPEC_C_UN                 202)
57    (UNSPEC_C_EQ                 203)
58    (UNSPEC_C_UEQ                204)
59    (UNSPEC_C_OLT                205)
60    (UNSPEC_C_ULT                206)
61    (UNSPEC_C_OLE                207)
62    (UNSPEC_C_ULE                208)
63    (UNSPEC_C_SF                 209)
64    (UNSPEC_C_NGLE               210)
65    (UNSPEC_C_SEQ                211)
66    (UNSPEC_C_NGL                212)
67    (UNSPEC_C_LT                 213)
68    (UNSPEC_C_NGE                214)
69    (UNSPEC_C_LE                 215)
70    (UNSPEC_C_NGT                216)
71
72    ;; MIPS64/MIPS32R2 alnv.ps
73    (UNSPEC_ALNV_PS              217)
74
75    ;; MIPS-3D instructions
76
77    (UNSPEC_CABS_F               218)
78    (UNSPEC_CABS_UN              219)
79    (UNSPEC_CABS_EQ              220)
80    (UNSPEC_CABS_UEQ             221)
81    (UNSPEC_CABS_OLT             222)
82    (UNSPEC_CABS_ULT             223)
83    (UNSPEC_CABS_OLE             224)
84    (UNSPEC_CABS_ULE             225)
85    (UNSPEC_CABS_SF              226)
86    (UNSPEC_CABS_NGLE            227)
87    (UNSPEC_CABS_SEQ             228)
88    (UNSPEC_CABS_NGL             229)
89    (UNSPEC_CABS_LT              230)
90    (UNSPEC_CABS_NGE             231)
91    (UNSPEC_CABS_LE              232)
92    (UNSPEC_CABS_NGT             233)
93
94    (UNSPEC_ADDR_PS              234)
95    (UNSPEC_CVT_PW_PS            235)
96    (UNSPEC_CVT_PS_PW            236)
97    (UNSPEC_MULR_PS              237)
98
99    (UNSPEC_RECIP1_S             238)
100    (UNSPEC_RECIP1_D             239)
101    (UNSPEC_RECIP1_PS            240)
102    (UNSPEC_RECIP2_S             241)
103    (UNSPEC_RECIP2_D             242)
104    (UNSPEC_RECIP2_PS            243)
105
106    (UNSPEC_RSQRT1_S             244)
107    (UNSPEC_RSQRT1_D             245)
108    (UNSPEC_RSQRT1_PS            246)
109    (UNSPEC_RSQRT2_S             247)
110    (UNSPEC_RSQRT2_D             248)
111    (UNSPEC_RSQRT2_PS            249)
112
113    (UNSPEC_MOVE_TF_PS           250)
114   ]
115 )
116
117 (include "predicates.md")
118 \f
119 ;; ....................
120 ;;
121 ;;      Attributes
122 ;;
123 ;; ....................
124
125 (define_attr "got" "unset,xgot_high,load"
126   (const_string "unset"))
127
128 ;; For jal instructions, this attribute is DIRECT when the target address
129 ;; is symbolic and INDIRECT when it is a register.
130 (define_attr "jal" "unset,direct,indirect"
131   (const_string "unset"))
132
133 ;; This attribute is YES if the instruction is a jal macro (not a
134 ;; real jal instruction).
135 ;;
136 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
137 ;; restore $gp.  Direct jals are also macros in NewABI PIC since they
138 ;; load the target address into $25.
139 (define_attr "jal_macro" "no,yes"
140   (cond [(eq_attr "jal" "direct")
141          (symbol_ref "TARGET_ABICALLS != 0")
142          (eq_attr "jal" "indirect")
143          (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
144         (const_string "no")))
145
146 ;; Classification of each insn.
147 ;; branch       conditional branch
148 ;; jump         unconditional jump
149 ;; call         unconditional call
150 ;; load         load instruction(s)
151 ;; fpload       floating point load
152 ;; fpidxload    floating point indexed load
153 ;; store        store instruction(s)
154 ;; fpstore      floating point store
155 ;; fpidxstore   floating point indexed store
156 ;; prefetch     memory prefetch (register + offset)
157 ;; prefetchx    memory indexed prefetch (register + register)
158 ;; condmove     conditional moves
159 ;; xfer         transfer to/from coprocessor
160 ;; mthilo       transfer to hi/lo registers
161 ;; mfhilo       transfer from hi/lo registers
162 ;; const        load constant
163 ;; arith        integer arithmetic and logical instructions
164 ;; shift        integer shift instructions
165 ;; slt          set less than instructions
166 ;; clz          the clz and clo instructions
167 ;; trap         trap if instructions
168 ;; imul         integer multiply
169 ;; imadd        integer multiply-add
170 ;; idiv         integer divide
171 ;; fmove        floating point register move
172 ;; fadd         floating point add/subtract
173 ;; fmul         floating point multiply
174 ;; fmadd        floating point multiply-add
175 ;; fdiv         floating point divide
176 ;; frdiv        floating point reciprocal divide
177 ;; fabs         floating point absolute value
178 ;; fneg         floating point negation
179 ;; fcmp         floating point compare
180 ;; fcvt         floating point convert
181 ;; fsqrt        floating point square root
182 ;; frsqrt       floating point reciprocal square root
183 ;; multi        multiword sequence (or user asm statements)
184 ;; nop          no operation
185 (define_attr "type"
186   "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"
187   (cond [(eq_attr "jal" "!unset") (const_string "call")
188          (eq_attr "got" "load") (const_string "load")]
189         (const_string "unknown")))
190
191 ;; Main data type used by the insn
192 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
193   (const_string "unknown"))
194
195 ;; Is this an extended instruction in mips16 mode?
196 (define_attr "extended_mips16" "no,yes"
197   (const_string "no"))
198
199 ;; Length of instruction in bytes.
200 (define_attr "length" ""
201    (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
202           ;; If a branch is outside this range, we have a choice of two
203           ;; sequences.  For PIC, an out-of-range branch like:
204           ;;
205           ;;    bne     r1,r2,target
206           ;;    dslot
207           ;;
208           ;; becomes the equivalent of:
209           ;;
210           ;;    beq     r1,r2,1f
211           ;;    dslot
212           ;;    la      $at,target
213           ;;    jr      $at
214           ;;    nop
215           ;; 1:
216           ;;
217           ;; where the load address can be up to three instructions long
218           ;; (lw, nop, addiu).
219           ;;
220           ;; The non-PIC case is similar except that we use a direct
221           ;; jump instead of an la/jr pair.  Since the target of this
222           ;; jump is an absolute 28-bit bit address (the other bits
223           ;; coming from the address of the delay slot) this form cannot
224           ;; cross a 256MB boundary.  We could provide the option of
225           ;; using la/jr in this case too, but we do not do so at
226           ;; present.
227           ;;
228           ;; Note that this value does not account for the delay slot
229           ;; instruction, whose length is added separately.  If the RTL
230           ;; pattern has no explicit delay slot, mips_adjust_insn_length
231           ;; will add the length of the implicit nop.  The values for
232           ;; forward and backward branches will be different as well.
233           (eq_attr "type" "branch")
234           (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
235                       (le (minus (pc) (match_dup 1)) (const_int 131068)))
236                   (const_int 4)
237                  (ne (symbol_ref "flag_pic") (const_int 0))
238                  (const_int 24)
239                  ] (const_int 12))
240
241           (eq_attr "got" "load")
242           (const_int 4)
243           (eq_attr "got" "xgot_high")
244           (const_int 8)
245
246           (eq_attr "type" "const")
247           (symbol_ref "mips_const_insns (operands[1]) * 4")
248           (eq_attr "type" "load,fpload")
249           (symbol_ref "mips_fetch_insns (operands[1]) * 4")
250           (eq_attr "type" "store,fpstore")
251           (symbol_ref "mips_fetch_insns (operands[0]) * 4")
252
253           ;; In the worst case, a call macro will take 8 instructions:
254           ;;
255           ;;     lui $25,%call_hi(FOO)
256           ;;     addu $25,$25,$28
257           ;;     lw $25,%call_lo(FOO)($25)
258           ;;     nop
259           ;;     jalr $25
260           ;;     nop
261           ;;     lw $gp,X($sp)
262           ;;     nop
263           (eq_attr "jal_macro" "yes")
264           (const_int 32)
265
266           (and (eq_attr "extended_mips16" "yes")
267                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
268           (const_int 8)
269
270           ;; Various VR4120 errata require a nop to be inserted after a macc
271           ;; instruction.  The assembler does this for us, so account for
272           ;; the worst-case length here.
273           (and (eq_attr "type" "imadd")
274                (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
275           (const_int 8)
276
277           ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
278           ;; the result of the second one is missed.  The assembler should work
279           ;; around this by inserting a nop after the first dmult.
280           (and (eq_attr "type" "imul")
281                (and (eq_attr "mode" "DI")
282                     (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
283           (const_int 8)
284
285           (eq_attr "type" "idiv")
286           (symbol_ref "mips_idiv_insns () * 4")
287           ] (const_int 4)))
288
289 ;; Attribute describing the processor.  This attribute must match exactly
290 ;; with the processor_type enumeration in mips.h.
291 (define_attr "cpu"
292   "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
293   (const (symbol_ref "mips_tune")))
294
295 ;; The type of hardware hazard associated with this instruction.
296 ;; DELAY means that the next instruction cannot read the result
297 ;; of this one.  HILO means that the next two instructions cannot
298 ;; write to HI or LO.
299 (define_attr "hazard" "none,delay,hilo"
300   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
301               (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
302          (const_string "delay")
303
304          (and (eq_attr "type" "xfer")
305               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
306          (const_string "delay")
307
308          (and (eq_attr "type" "fcmp")
309               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
310          (const_string "delay")
311
312          ;; The r4000 multiplication patterns include an mflo instruction.
313          (and (eq_attr "type" "imul")
314               (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
315          (const_string "hilo")
316
317          (and (eq_attr "type" "mfhilo")
318               (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
319          (const_string "hilo")]
320         (const_string "none")))
321
322 ;; Is it a single instruction?
323 (define_attr "single_insn" "no,yes"
324   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
325
326 ;; Can the instruction be put into a delay slot?
327 (define_attr "can_delay" "no,yes"
328   (if_then_else (and (eq_attr "type" "!branch,call,jump")
329                      (and (eq_attr "hazard" "none")
330                           (eq_attr "single_insn" "yes")))
331                 (const_string "yes")
332                 (const_string "no")))
333
334 ;; Attribute defining whether or not we can use the branch-likely instructions
335 (define_attr "branch_likely" "no,yes"
336   (const
337    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
338                  (const_string "yes")
339                  (const_string "no"))))
340
341 ;; True if an instruction might assign to hi or lo when reloaded.
342 ;; This is used by the TUNE_MACC_CHAINS code.
343 (define_attr "may_clobber_hilo" "no,yes"
344   (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
345                 (const_string "yes")
346                 (const_string "no")))
347
348 ;; Describe a user's asm statement.
349 (define_asm_attributes
350   [(set_attr "type" "multi")])
351 \f
352 ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
353 ;; from the same template.
354 (define_mode_macro GPR [SI (DI "TARGET_64BIT")])
355
356 ;; This mode macro allows :P to be used for patterns that operate on
357 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
358 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
359
360 ;; This mode macro allows :MOVECC to be used anywhere that a
361 ;; conditional-move-type condition is needed.
362 (define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
363
364 ;; This mode macro allows :ANYF to be used wherever a scalar or vector
365 ;; floating-point mode is allowed.
366 (define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT")
367                          (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
368                          (V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
369
370 ;; Like ANYF, but only applies to scalar modes.
371 (define_mode_macro SCALARF [(SF "TARGET_HARD_FLOAT")
372                             (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
373
374 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
375 ;; 32-bit version and "dsubu" in the 64-bit version.
376 (define_mode_attr d [(SI "") (DI "d")])
377
378 ;; Mode attributes for GPR loads and stores.
379 (define_mode_attr load [(SI "lw") (DI "ld")])
380 (define_mode_attr store [(SI "sw") (DI "sd")])
381
382 ;; Similarly for MIPS IV indexed FPR loads and stores.
383 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1")])
384 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1")])
385
386 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
387 ;; are different.  Some forms of unextended addiu have an 8-bit immediate
388 ;; field but the equivalent daddiu has only a 5-bit field.
389 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
390
391 ;; This attribute gives the best constraint to use for registers of
392 ;; a given mode.
393 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
394
395 ;; This attribute gives the format suffix for floating-point operations.
396 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
397
398 ;; This attribute gives the upper-case mode name for one unit of a
399 ;; floating-point mode.
400 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
401
402 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
403 ;;
404 ;; In certain cases, div.s and div.ps may have a rounding error
405 ;; and/or wrong inexact flag.
406 ;;
407 ;; Therefore, we only allow div.s if not working around SB-1 rev2
408 ;; errata or if a slight loss of precision is OK.
409 (define_mode_attr divide_condition
410   [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")])
411
412 ;; This code macro allows all branch instructions to be generated from
413 ;; a single define_expand template.
414 (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
415                              eq ne gt ge lt le gtu geu ltu leu])
416
417 ;; This code macro allows signed and unsigned widening multiplications
418 ;; to use the same template.
419 (define_code_macro any_extend [sign_extend zero_extend])
420
421 ;; This code macro allows the three shift instructions to be generated
422 ;; from the same template.
423 (define_code_macro any_shift [ashift ashiftrt lshiftrt])
424
425 ;; <u> expands to an empty string when doing a signed operation and
426 ;; "u" when doing an unsigned operation.
427 (define_code_attr u [(sign_extend "") (zero_extend "u")])
428
429 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
430 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
431
432 ;; <optab> expands to the name of the optab for a particular code.
433 (define_code_attr optab [(ashift "ashl")
434                          (ashiftrt "ashr")
435                          (lshiftrt "lshr")])
436
437 ;; <insn> expands to the name of the insn that implements a particular code.
438 (define_code_attr insn [(ashift "sll")
439                         (ashiftrt "sra")
440                         (lshiftrt "srl")])
441 \f
442 ;; .........................
443 ;;
444 ;;      Branch, call and jump delay slots
445 ;;
446 ;; .........................
447
448 (define_delay (and (eq_attr "type" "branch")
449                    (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
450   [(eq_attr "can_delay" "yes")
451    (nil)
452    (and (eq_attr "branch_likely" "yes")
453         (eq_attr "can_delay" "yes"))])
454
455 (define_delay (eq_attr "type" "jump")
456   [(eq_attr "can_delay" "yes")
457    (nil)
458    (nil)])
459
460 (define_delay (and (eq_attr "type" "call")
461                    (eq_attr "jal_macro" "no"))
462   [(eq_attr "can_delay" "yes")
463    (nil)
464    (nil)])
465 \f
466 ;; Pipeline descriptions.
467 ;;
468 ;; generic.md provides a fallback for processors without a specific
469 ;; pipeline description.  It is derived from the old define_function_unit
470 ;; version and uses the "alu" and "imuldiv" units declared below.
471 ;;
472 ;; Some of the processor-specific files are also derived from old
473 ;; define_function_unit descriptions and simply override the parts of
474 ;; generic.md that don't apply.  The other processor-specific files
475 ;; are self-contained.
476 (define_automaton "alu,imuldiv")
477
478 (define_cpu_unit "alu" "alu")
479 (define_cpu_unit "imuldiv" "imuldiv")
480
481 (include "3000.md")
482 (include "4000.md")
483 (include "4100.md")
484 (include "4130.md")
485 (include "4300.md")
486 (include "4600.md")
487 (include "5000.md")
488 (include "5400.md")
489 (include "5500.md")
490 (include "6000.md")
491 (include "7000.md")
492 (include "9000.md")
493 (include "sb1.md")
494 (include "sr71k.md")
495 (include "generic.md")
496 \f
497 ;;
498 ;;  ....................
499 ;;
500 ;;      CONDITIONAL TRAPS
501 ;;
502 ;;  ....................
503 ;;
504
505 (define_insn "trap"
506   [(trap_if (const_int 1) (const_int 0))]
507   ""
508 {
509   if (ISA_HAS_COND_TRAP)
510     return "teq\t$0,$0";
511   else if (TARGET_MIPS16)
512     return "break 0";
513   else
514     return "break";
515 }
516   [(set_attr "type" "trap")])
517
518 (define_expand "conditional_trap"
519   [(trap_if (match_operator 0 "comparison_operator"
520                             [(match_dup 2) (match_dup 3)])
521             (match_operand 1 "const_int_operand"))]
522   "ISA_HAS_COND_TRAP"
523 {
524   if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
525       && operands[1] == const0_rtx)
526     {
527       mips_gen_conditional_trap (operands);
528       DONE;
529     }
530   else
531     FAIL;
532 })
533
534 (define_insn "*conditional_trap<mode>"
535   [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
536                                 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
537                                  (match_operand:GPR 2 "arith_operand" "dI")])
538             (const_int 0))]
539   "ISA_HAS_COND_TRAP"
540   "t%C0\t%z1,%2"
541   [(set_attr "type" "trap")])
542 \f
543 ;;
544 ;;  ....................
545 ;;
546 ;;      ADDITION
547 ;;
548 ;;  ....................
549 ;;
550
551 (define_insn "add<mode>3"
552   [(set (match_operand:ANYF 0 "register_operand" "=f")
553         (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
554                    (match_operand:ANYF 2 "register_operand" "f")))]
555   ""
556   "add.<fmt>\t%0,%1,%2"
557   [(set_attr "type" "fadd")
558    (set_attr "mode" "<UNITMODE>")])
559
560 (define_expand "add<mode>3"
561   [(set (match_operand:GPR 0 "register_operand")
562         (plus:GPR (match_operand:GPR 1 "register_operand")
563                   (match_operand:GPR 2 "arith_operand")))]
564   "")
565
566 (define_insn "*add<mode>3"
567   [(set (match_operand:GPR 0 "register_operand" "=d,d")
568         (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
569                   (match_operand:GPR 2 "arith_operand" "d,Q")))]
570   "!TARGET_MIPS16"
571   "@
572     <d>addu\t%0,%1,%2
573     <d>addiu\t%0,%1,%2"
574   [(set_attr "type" "arith")
575    (set_attr "mode" "<MODE>")])
576
577 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
578 ;; we don't have a constraint for $sp.  These insns will be generated by
579 ;; the save_restore_insns functions.
580
581 (define_insn "*add<mode>3_sp1"
582   [(set (reg:GPR 29)
583         (plus:GPR (reg:GPR 29)
584                   (match_operand:GPR 0 "const_arith_operand" "")))]
585   "TARGET_MIPS16"
586   "<d>addiu\t%$,%$,%0"
587   [(set_attr "type" "arith")
588    (set_attr "mode" "<MODE>")
589    (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
590                                       (const_int 4)
591                                       (const_int 8)))])
592
593 (define_insn "*add<mode>3_sp2"
594   [(set (match_operand:GPR 0 "register_operand" "=d")
595         (plus:GPR (reg:GPR 29)
596                   (match_operand:GPR 1 "const_arith_operand" "")))]
597   "TARGET_MIPS16"
598   "<d>addiu\t%0,%$,%1"
599   [(set_attr "type" "arith")
600    (set_attr "mode" "<MODE>")
601    (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
602                                       (const_int 4)
603                                       (const_int 8)))])
604
605 (define_insn "*add<mode>3_mips16"
606   [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
607         (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
608                   (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
609   "TARGET_MIPS16"
610   "@
611     <d>addiu\t%0,%2
612     <d>addiu\t%0,%1,%2
613     <d>addu\t%0,%1,%2"
614   [(set_attr "type" "arith")
615    (set_attr "mode" "<MODE>")
616    (set_attr_alternative "length"
617                 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
618                                (const_int 4)
619                                (const_int 8))
620                  (if_then_else (match_operand 2 "m16_simm4_1")
621                                (const_int 4)
622                                (const_int 8))
623                  (const_int 4)])])
624
625
626 ;; On the mips16, we can sometimes split an add of a constant which is
627 ;; a 4 byte instruction into two adds which are both 2 byte
628 ;; instructions.  There are two cases: one where we are adding a
629 ;; constant plus a register to another register, and one where we are
630 ;; simply adding a constant to a register.
631
632 (define_split
633   [(set (match_operand:SI 0 "register_operand")
634         (plus:SI (match_dup 0)
635                  (match_operand:SI 1 "const_int_operand")))]
636   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
637    && GET_CODE (operands[0]) == REG
638    && M16_REG_P (REGNO (operands[0]))
639    && GET_CODE (operands[1]) == CONST_INT
640    && ((INTVAL (operands[1]) > 0x7f
641         && INTVAL (operands[1]) <= 0x7f + 0x7f)
642        || (INTVAL (operands[1]) < - 0x80
643            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
644   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
645    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
646 {
647   HOST_WIDE_INT val = INTVAL (operands[1]);
648
649   if (val >= 0)
650     {
651       operands[1] = GEN_INT (0x7f);
652       operands[2] = GEN_INT (val - 0x7f);
653     }
654   else
655     {
656       operands[1] = GEN_INT (- 0x80);
657       operands[2] = GEN_INT (val + 0x80);
658     }
659 })
660
661 (define_split
662   [(set (match_operand:SI 0 "register_operand")
663         (plus:SI (match_operand:SI 1 "register_operand")
664                  (match_operand:SI 2 "const_int_operand")))]
665   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
666    && GET_CODE (operands[0]) == REG
667    && M16_REG_P (REGNO (operands[0]))
668    && GET_CODE (operands[1]) == REG
669    && M16_REG_P (REGNO (operands[1]))
670    && REGNO (operands[0]) != REGNO (operands[1])
671    && GET_CODE (operands[2]) == CONST_INT
672    && ((INTVAL (operands[2]) > 0x7
673         && INTVAL (operands[2]) <= 0x7 + 0x7f)
674        || (INTVAL (operands[2]) < - 0x8
675            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
676   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
677    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
678 {
679   HOST_WIDE_INT val = INTVAL (operands[2]);
680
681   if (val >= 0)
682     {
683       operands[2] = GEN_INT (0x7);
684       operands[3] = GEN_INT (val - 0x7);
685     }
686   else
687     {
688       operands[2] = GEN_INT (- 0x8);
689       operands[3] = GEN_INT (val + 0x8);
690     }
691 })
692
693 (define_split
694   [(set (match_operand:DI 0 "register_operand")
695         (plus:DI (match_dup 0)
696                  (match_operand:DI 1 "const_int_operand")))]
697   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
698    && GET_CODE (operands[0]) == REG
699    && M16_REG_P (REGNO (operands[0]))
700    && GET_CODE (operands[1]) == CONST_INT
701    && ((INTVAL (operands[1]) > 0xf
702         && INTVAL (operands[1]) <= 0xf + 0xf)
703        || (INTVAL (operands[1]) < - 0x10
704            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
705   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
706    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
707 {
708   HOST_WIDE_INT val = INTVAL (operands[1]);
709
710   if (val >= 0)
711     {
712       operands[1] = GEN_INT (0xf);
713       operands[2] = GEN_INT (val - 0xf);
714     }
715   else
716     {
717       operands[1] = GEN_INT (- 0x10);
718       operands[2] = GEN_INT (val + 0x10);
719     }
720 })
721
722 (define_split
723   [(set (match_operand:DI 0 "register_operand")
724         (plus:DI (match_operand:DI 1 "register_operand")
725                  (match_operand:DI 2 "const_int_operand")))]
726   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
727    && GET_CODE (operands[0]) == REG
728    && M16_REG_P (REGNO (operands[0]))
729    && GET_CODE (operands[1]) == REG
730    && M16_REG_P (REGNO (operands[1]))
731    && REGNO (operands[0]) != REGNO (operands[1])
732    && GET_CODE (operands[2]) == CONST_INT
733    && ((INTVAL (operands[2]) > 0x7
734         && INTVAL (operands[2]) <= 0x7 + 0xf)
735        || (INTVAL (operands[2]) < - 0x8
736            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
737   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
738    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
739 {
740   HOST_WIDE_INT val = INTVAL (operands[2]);
741
742   if (val >= 0)
743     {
744       operands[2] = GEN_INT (0x7);
745       operands[3] = GEN_INT (val - 0x7);
746     }
747   else
748     {
749       operands[2] = GEN_INT (- 0x8);
750       operands[3] = GEN_INT (val + 0x8);
751     }
752 })
753
754 (define_insn "*addsi3_extended"
755   [(set (match_operand:DI 0 "register_operand" "=d,d")
756         (sign_extend:DI
757              (plus:SI (match_operand:SI 1 "register_operand" "d,d")
758                       (match_operand:SI 2 "arith_operand" "d,Q"))))]
759   "TARGET_64BIT && !TARGET_MIPS16"
760   "@
761     addu\t%0,%1,%2
762     addiu\t%0,%1,%2"
763   [(set_attr "type" "arith")
764    (set_attr "mode" "SI")])
765
766 ;; Split this insn so that the addiu splitters can have a crack at it.
767 ;; Use a conservative length estimate until the split.
768 (define_insn_and_split "*addsi3_extended_mips16"
769   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
770         (sign_extend:DI
771              (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
772                       (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
773   "TARGET_64BIT && TARGET_MIPS16"
774   "#"
775   "&& reload_completed"
776   [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
777   { operands[3] = gen_lowpart (SImode, operands[0]); }
778   [(set_attr "type" "arith")
779    (set_attr "mode" "SI")
780    (set_attr "extended_mips16" "yes")])
781 \f
782 ;;
783 ;;  ....................
784 ;;
785 ;;      SUBTRACTION
786 ;;
787 ;;  ....................
788 ;;
789
790 (define_insn "sub<mode>3"
791   [(set (match_operand:ANYF 0 "register_operand" "=f")
792         (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
793                     (match_operand:ANYF 2 "register_operand" "f")))]
794   ""
795   "sub.<fmt>\t%0,%1,%2"
796   [(set_attr "type" "fadd")
797    (set_attr "mode" "<UNITMODE>")])
798
799 (define_insn "sub<mode>3"
800   [(set (match_operand:GPR 0 "register_operand" "=d")
801         (minus:GPR (match_operand:GPR 1 "register_operand" "d")
802                    (match_operand:GPR 2 "register_operand" "d")))]
803   ""
804   "<d>subu\t%0,%1,%2"
805   [(set_attr "type" "arith")
806    (set_attr "mode" "<MODE>")])
807
808 (define_insn "*subsi3_extended"
809   [(set (match_operand:DI 0 "register_operand" "=d")
810         (sign_extend:DI
811             (minus:SI (match_operand:SI 1 "register_operand" "d")
812                       (match_operand:SI 2 "register_operand" "d"))))]
813   "TARGET_64BIT"
814   "subu\t%0,%1,%2"
815   [(set_attr "type" "arith")
816    (set_attr "mode" "DI")])
817 \f
818 ;;
819 ;;  ....................
820 ;;
821 ;;      MULTIPLICATION
822 ;;
823 ;;  ....................
824 ;;
825
826 (define_expand "mul<mode>3"
827   [(set (match_operand:SCALARF 0 "register_operand")
828         (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
829                       (match_operand:SCALARF 2 "register_operand")))]
830   ""
831   "")
832
833 (define_insn "*mul<mode>3"
834   [(set (match_operand:SCALARF 0 "register_operand" "=f")
835         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
836                       (match_operand:SCALARF 2 "register_operand" "f")))]
837   "!TARGET_4300_MUL_FIX"
838   "mul.<fmt>\t%0,%1,%2"
839   [(set_attr "type" "fmul")
840    (set_attr "mode" "<MODE>")])
841
842 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
843 ;; operands may corrupt immediately following multiplies. This is a
844 ;; simple fix to insert NOPs.
845
846 (define_insn "*mul<mode>3_r4300"
847   [(set (match_operand:SCALARF 0 "register_operand" "=f")
848         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
849                       (match_operand:SCALARF 2 "register_operand" "f")))]
850   "TARGET_4300_MUL_FIX"
851   "mul.<fmt>\t%0,%1,%2\;nop"
852   [(set_attr "type" "fmul")
853    (set_attr "mode" "<MODE>")
854    (set_attr "length" "8")])
855
856 (define_insn "mulv2sf3"
857   [(set (match_operand:V2SF 0 "register_operand" "=f")
858         (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
859                    (match_operand:V2SF 2 "register_operand" "f")))]
860   "TARGET_PAIRED_SINGLE_FLOAT"
861   "mul.ps\t%0,%1,%2"
862   [(set_attr "type" "fmul")
863    (set_attr "mode" "SF")])
864
865 ;; The original R4000 has a cpu bug.  If a double-word or a variable
866 ;; shift executes while an integer multiplication is in progress, the
867 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
868 ;; with the mult on the R4000.
869 ;;
870 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
871 ;; (also valid for MIPS R4000MC processors):
872 ;;
873 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
874 ;;      this errata description.
875 ;;      The following code sequence causes the R4000 to incorrectly
876 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
877 ;;      instruction.  If the dsra32 instruction is executed during an
878 ;;      integer multiply, the dsra32 will only shift by the amount in
879 ;;      specified in the instruction rather than the amount plus 32
880 ;;      bits.
881 ;;      instruction 1:          mult    rs,rt           integer multiply
882 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
883 ;;                                                      right arithmetic + 32
884 ;;      Workaround: A dsra32 instruction placed after an integer
885 ;;      multiply should not be one of the 11 instructions after the
886 ;;      multiply instruction."
887 ;;
888 ;; and:
889 ;;
890 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
891 ;;      the following description.
892 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
893 ;;      64-bit versions) may produce incorrect results under the
894 ;;      following conditions:
895 ;;      1) An integer multiply is currently executing
896 ;;      2) These types of shift instructions are executed immediately
897 ;;         following an integer divide instruction.
898 ;;      Workaround:
899 ;;      1) Make sure no integer multiply is running wihen these
900 ;;         instruction are executed.  If this cannot be predicted at
901 ;;         compile time, then insert a "mfhi" to R0 instruction
902 ;;         immediately after the integer multiply instruction.  This
903 ;;         will cause the integer multiply to complete before the shift
904 ;;         is executed.
905 ;;      2) Separate integer divide and these two classes of shift
906 ;;         instructions by another instruction or a noop."
907 ;;
908 ;; These processors have PRId values of 0x00004220 and 0x00004300,
909 ;; respectively.
910
911 (define_expand "mul<mode>3"
912   [(set (match_operand:GPR 0 "register_operand")
913         (mult:GPR (match_operand:GPR 1 "register_operand")
914                   (match_operand:GPR 2 "register_operand")))]
915   ""
916 {
917   if (GENERATE_MULT3_<MODE>)
918     emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
919   else if (!TARGET_FIX_R4000)
920     emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
921                                         operands[2]));
922   else
923     emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
924   DONE;
925 })
926
927 (define_insn "mulsi3_mult3"
928   [(set (match_operand:SI 0 "register_operand" "=d,l")
929         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
930                  (match_operand:SI 2 "register_operand" "d,d")))
931    (clobber (match_scratch:SI 3 "=h,h"))
932    (clobber (match_scratch:SI 4 "=l,X"))]
933   "GENERATE_MULT3_SI"
934 {
935   if (which_alternative == 1)
936     return "mult\t%1,%2";
937   if (TARGET_MAD
938       || TARGET_MIPS5400
939       || TARGET_MIPS5500
940       || TARGET_MIPS7000
941       || TARGET_MIPS9000
942       || ISA_MIPS32
943       || ISA_MIPS32R2
944       || ISA_MIPS64)
945     return "mul\t%0,%1,%2";
946   return "mult\t%0,%1,%2";
947 }
948   [(set_attr "type" "imul")
949    (set_attr "mode" "SI")])
950
951 (define_insn "muldi3_mult3"
952   [(set (match_operand:DI 0 "register_operand" "=d")
953         (mult:DI (match_operand:DI 1 "register_operand" "d")
954                  (match_operand:DI 2 "register_operand" "d")))
955    (clobber (match_scratch:DI 3 "=h"))
956    (clobber (match_scratch:DI 4 "=l"))]
957   "TARGET_64BIT && GENERATE_MULT3_DI"
958   "dmult\t%0,%1,%2"
959   [(set_attr "type" "imul")
960    (set_attr "mode" "DI")])
961
962 ;; If a register gets allocated to LO, and we spill to memory, the reload
963 ;; will include a move from LO to a GPR.  Merge it into the multiplication
964 ;; if it can set the GPR directly.
965 ;;
966 ;; Operand 0: LO
967 ;; Operand 1: GPR (1st multiplication operand)
968 ;; Operand 2: GPR (2nd multiplication operand)
969 ;; Operand 3: HI
970 ;; Operand 4: GPR (destination)
971 (define_peephole2
972   [(parallel
973        [(set (match_operand:SI 0 "register_operand")
974              (mult:SI (match_operand:SI 1 "register_operand")
975                       (match_operand:SI 2 "register_operand")))
976         (clobber (match_operand:SI 3 "register_operand"))
977         (clobber (scratch:SI))])
978    (set (match_operand:SI 4 "register_operand")
979         (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
980   "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
981   [(parallel
982        [(set (match_dup 4)
983              (mult:SI (match_dup 1)
984                       (match_dup 2)))
985         (clobber (match_dup 3))
986         (clobber (match_dup 0))])])
987
988 (define_insn "mul<mode>3_internal"
989   [(set (match_operand:GPR 0 "register_operand" "=l")
990         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
991                   (match_operand:GPR 2 "register_operand" "d")))
992    (clobber (match_scratch:GPR 3 "=h"))]
993   "!TARGET_FIX_R4000"
994   "<d>mult\t%1,%2"
995   [(set_attr "type" "imul")
996    (set_attr "mode" "<MODE>")])
997
998 (define_insn "mul<mode>3_r4000"
999   [(set (match_operand:GPR 0 "register_operand" "=d")
1000         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1001                   (match_operand:GPR 2 "register_operand" "d")))
1002    (clobber (match_scratch:GPR 3 "=h"))
1003    (clobber (match_scratch:GPR 4 "=l"))]
1004   "TARGET_FIX_R4000"
1005   "<d>mult\t%1,%2\;mflo\t%0"
1006   [(set_attr "type" "imul")
1007    (set_attr "mode" "<MODE>")
1008    (set_attr "length" "8")])
1009
1010 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1011 ;; of "mult; mflo".  They have the same latency, but the first form gives
1012 ;; us an extra cycle to compute the operands.
1013
1014 ;; Operand 0: LO
1015 ;; Operand 1: GPR (1st multiplication operand)
1016 ;; Operand 2: GPR (2nd multiplication operand)
1017 ;; Operand 3: HI
1018 ;; Operand 4: GPR (destination)
1019 (define_peephole2
1020   [(parallel
1021        [(set (match_operand:SI 0 "register_operand")
1022              (mult:SI (match_operand:SI 1 "register_operand")
1023                       (match_operand:SI 2 "register_operand")))
1024         (clobber (match_operand:SI 3 "register_operand"))])
1025    (set (match_operand:SI 4 "register_operand")
1026         (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1027   "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1028   [(set (match_dup 0)
1029         (const_int 0))
1030    (parallel
1031        [(set (match_dup 0)
1032              (plus:SI (mult:SI (match_dup 1)
1033                                (match_dup 2))
1034                       (match_dup 0)))
1035         (set (match_dup 4)
1036              (plus:SI (mult:SI (match_dup 1)
1037                                (match_dup 2))
1038                       (match_dup 0)))
1039         (clobber (match_dup 3))])])
1040
1041 ;; Multiply-accumulate patterns
1042
1043 ;; For processors that can copy the output to a general register:
1044 ;;
1045 ;; The all-d alternative is needed because the combiner will find this
1046 ;; pattern and then register alloc/reload will move registers around to
1047 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1048 ;;
1049 ;; The last alternative should be made slightly less desirable, but adding
1050 ;; "?" to the constraint is too strong, and causes values to be loaded into
1051 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1052 ;; trick.
1053 (define_insn "*mul_acc_si"
1054   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1055         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1056                           (match_operand:SI 2 "register_operand" "d,d,d"))
1057                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1058    (clobber (match_scratch:SI 4 "=h,h,h"))
1059    (clobber (match_scratch:SI 5 "=X,3,l"))
1060    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1061   "(TARGET_MIPS3900
1062    || ISA_HAS_MADD_MSUB)
1063    && !TARGET_MIPS16"
1064 {
1065   static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1066   if (which_alternative == 2)
1067     return "#";
1068   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1069     return "#";
1070   return madd[which_alternative];
1071 }
1072   [(set_attr "type"     "imadd,imadd,multi")
1073    (set_attr "mode"     "SI")
1074    (set_attr "length"   "4,4,8")])
1075
1076 ;; Split the above insn if we failed to get LO allocated.
1077 (define_split
1078   [(set (match_operand:SI 0 "register_operand")
1079         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1080                           (match_operand:SI 2 "register_operand"))
1081                  (match_operand:SI 3 "register_operand")))
1082    (clobber (match_scratch:SI 4))
1083    (clobber (match_scratch:SI 5))
1084    (clobber (match_scratch:SI 6))]
1085   "reload_completed && !TARGET_DEBUG_D_MODE
1086    && GP_REG_P (true_regnum (operands[0]))
1087    && GP_REG_P (true_regnum (operands[3]))"
1088   [(parallel [(set (match_dup 6)
1089                    (mult:SI (match_dup 1) (match_dup 2)))
1090               (clobber (match_dup 4))
1091               (clobber (match_dup 5))])
1092    (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1093   "")
1094
1095 ;; Splitter to copy result of MADD to a general register
1096 (define_split
1097   [(set (match_operand:SI                   0 "register_operand")
1098         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1099                           (match_operand:SI 2 "register_operand"))
1100                  (match_operand:SI          3 "register_operand")))
1101    (clobber (match_scratch:SI               4))
1102    (clobber (match_scratch:SI               5))
1103    (clobber (match_scratch:SI               6))]
1104   "reload_completed && !TARGET_DEBUG_D_MODE
1105    && GP_REG_P (true_regnum (operands[0]))
1106    && true_regnum (operands[3]) == LO_REGNUM"
1107   [(parallel [(set (match_dup 3)
1108                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1109                             (match_dup 3)))
1110               (clobber (match_dup 4))
1111               (clobber (match_dup 5))
1112               (clobber (match_dup 6))])
1113    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1114   "")
1115
1116 (define_insn "*macc"
1117   [(set (match_operand:SI 0 "register_operand" "=l,d")
1118         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1119                           (match_operand:SI 2 "register_operand" "d,d"))
1120                  (match_operand:SI 3 "register_operand" "0,l")))
1121    (clobber (match_scratch:SI 4 "=h,h"))
1122    (clobber (match_scratch:SI 5 "=X,3"))]
1123   "ISA_HAS_MACC"
1124 {
1125   if (which_alternative == 1)
1126     return "macc\t%0,%1,%2";
1127   else if (TARGET_MIPS5500)
1128     return "madd\t%1,%2";
1129   else
1130     /* The VR4130 assumes that there is a two-cycle latency between a macc
1131        that "writes" to $0 and an instruction that reads from it.  We avoid
1132        this by assigning to $1 instead.  */
1133     return "%[macc\t%@,%1,%2%]";
1134 }
1135   [(set_attr "type" "imadd")
1136    (set_attr "mode" "SI")])
1137
1138 (define_insn "*msac"
1139   [(set (match_operand:SI 0 "register_operand" "=l,d")
1140         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1141                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1142                            (match_operand:SI 3 "register_operand" "d,d"))))
1143    (clobber (match_scratch:SI 4 "=h,h"))
1144    (clobber (match_scratch:SI 5 "=X,1"))]
1145   "ISA_HAS_MSAC"
1146 {
1147   if (which_alternative == 1)
1148     return "msac\t%0,%2,%3";
1149   else if (TARGET_MIPS5500)
1150     return "msub\t%2,%3";
1151   else
1152     return "msac\t$0,%2,%3";
1153 }
1154   [(set_attr "type"     "imadd")
1155    (set_attr "mode"     "SI")])
1156
1157 ;; An msac-like instruction implemented using negation and a macc.
1158 (define_insn_and_split "*msac_using_macc"
1159   [(set (match_operand:SI 0 "register_operand" "=l,d")
1160         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1161                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1162                            (match_operand:SI 3 "register_operand" "d,d"))))
1163    (clobber (match_scratch:SI 4 "=h,h"))
1164    (clobber (match_scratch:SI 5 "=X,1"))
1165    (clobber (match_scratch:SI 6 "=d,d"))]
1166   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1167   "#"
1168   "&& reload_completed"
1169   [(set (match_dup 6)
1170         (neg:SI (match_dup 3)))
1171    (parallel
1172        [(set (match_dup 0)
1173              (plus:SI (mult:SI (match_dup 2)
1174                                (match_dup 6))
1175                       (match_dup 1)))
1176         (clobber (match_dup 4))
1177         (clobber (match_dup 5))])]
1178   ""
1179   [(set_attr "type"     "imadd")
1180    (set_attr "length"   "8")])
1181
1182 ;; Patterns generated by the define_peephole2 below.
1183
1184 (define_insn "*macc2"
1185   [(set (match_operand:SI 0 "register_operand" "=l")
1186         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1187                           (match_operand:SI 2 "register_operand" "d"))
1188                  (match_dup 0)))
1189    (set (match_operand:SI 3 "register_operand" "=d")
1190         (plus:SI (mult:SI (match_dup 1)
1191                           (match_dup 2))
1192                  (match_dup 0)))
1193    (clobber (match_scratch:SI 4 "=h"))]
1194   "ISA_HAS_MACC && reload_completed"
1195   "macc\t%3,%1,%2"
1196   [(set_attr "type"     "imadd")
1197    (set_attr "mode"     "SI")])
1198
1199 (define_insn "*msac2"
1200   [(set (match_operand:SI 0 "register_operand" "=l")
1201         (minus:SI (match_dup 0)
1202                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1203                            (match_operand:SI 2 "register_operand" "d"))))
1204    (set (match_operand:SI 3 "register_operand" "=d")
1205         (minus:SI (match_dup 0)
1206                   (mult:SI (match_dup 1)
1207                            (match_dup 2))))
1208    (clobber (match_scratch:SI 4 "=h"))]
1209   "ISA_HAS_MSAC && reload_completed"
1210   "msac\t%3,%1,%2"
1211   [(set_attr "type"     "imadd")
1212    (set_attr "mode"     "SI")])
1213
1214 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1215 ;; Similarly msac.
1216 ;;
1217 ;; Operand 0: LO
1218 ;; Operand 1: macc/msac
1219 ;; Operand 2: HI
1220 ;; Operand 3: GPR (destination)
1221 (define_peephole2
1222   [(parallel
1223        [(set (match_operand:SI 0 "register_operand")
1224              (match_operand:SI 1 "macc_msac_operand"))
1225         (clobber (match_operand:SI 2 "register_operand"))
1226         (clobber (scratch:SI))])
1227    (set (match_operand:SI 3 "register_operand")
1228         (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1229   ""
1230   [(parallel [(set (match_dup 0)
1231                    (match_dup 1))
1232               (set (match_dup 3)
1233                    (match_dup 1))
1234               (clobber (match_dup 2))])]
1235   "")
1236
1237 ;; When we have a three-address multiplication instruction, it should
1238 ;; be faster to do a separate multiply and add, rather than moving
1239 ;; something into LO in order to use a macc instruction.
1240 ;;
1241 ;; This peephole needs a scratch register to cater for the case when one
1242 ;; of the multiplication operands is the same as the destination.
1243 ;;
1244 ;; Operand 0: GPR (scratch)
1245 ;; Operand 1: LO
1246 ;; Operand 2: GPR (addend)
1247 ;; Operand 3: GPR (destination)
1248 ;; Operand 4: macc/msac
1249 ;; Operand 5: HI
1250 ;; Operand 6: new multiplication
1251 ;; Operand 7: new addition/subtraction
1252 (define_peephole2
1253   [(match_scratch:SI 0 "d")
1254    (set (match_operand:SI 1 "register_operand")
1255         (match_operand:SI 2 "register_operand"))
1256    (match_dup 0)
1257    (parallel
1258        [(set (match_operand:SI 3 "register_operand")
1259              (match_operand:SI 4 "macc_msac_operand"))
1260         (clobber (match_operand:SI 5 "register_operand"))
1261         (clobber (match_dup 1))])]
1262   "GENERATE_MULT3_SI
1263    && true_regnum (operands[1]) == LO_REGNUM
1264    && peep2_reg_dead_p (2, operands[1])
1265    && GP_REG_P (true_regnum (operands[3]))"
1266   [(parallel [(set (match_dup 0)
1267                    (match_dup 6))
1268               (clobber (match_dup 5))
1269               (clobber (match_dup 1))])
1270    (set (match_dup 3)
1271         (match_dup 7))]
1272 {
1273   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1274   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1275                                 operands[2], operands[0]);
1276 })
1277
1278 ;; Same as above, except LO is the initial target of the macc.
1279 ;;
1280 ;; Operand 0: GPR (scratch)
1281 ;; Operand 1: LO
1282 ;; Operand 2: GPR (addend)
1283 ;; Operand 3: macc/msac
1284 ;; Operand 4: HI
1285 ;; Operand 5: GPR (destination)
1286 ;; Operand 6: new multiplication
1287 ;; Operand 7: new addition/subtraction
1288 (define_peephole2
1289   [(match_scratch:SI 0 "d")
1290    (set (match_operand:SI 1 "register_operand")
1291         (match_operand:SI 2 "register_operand"))
1292    (match_dup 0)
1293    (parallel
1294        [(set (match_dup 1)
1295              (match_operand:SI 3 "macc_msac_operand"))
1296         (clobber (match_operand:SI 4 "register_operand"))
1297         (clobber (scratch:SI))])
1298    (match_dup 0)
1299    (set (match_operand:SI 5 "register_operand")
1300         (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1301   "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1302   [(parallel [(set (match_dup 0)
1303                    (match_dup 6))
1304               (clobber (match_dup 4))
1305               (clobber (match_dup 1))])
1306    (set (match_dup 5)
1307         (match_dup 7))]
1308 {
1309   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1310   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1311                                 operands[2], operands[0]);
1312 })
1313
1314 (define_insn "*mul_sub_si"
1315   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1316         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1317                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1318                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1319    (clobber (match_scratch:SI 4 "=h,h,h"))
1320    (clobber (match_scratch:SI 5 "=X,1,l"))
1321    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1322   "ISA_HAS_MADD_MSUB"
1323   "@
1324    msub\t%2,%3
1325    #
1326    #"
1327   [(set_attr "type"     "imadd,multi,multi")
1328    (set_attr "mode"     "SI")
1329    (set_attr "length"   "4,8,8")])
1330
1331 ;; Split the above insn if we failed to get LO allocated.
1332 (define_split
1333   [(set (match_operand:SI 0 "register_operand")
1334         (minus:SI (match_operand:SI 1 "register_operand")
1335                   (mult:SI (match_operand:SI 2 "register_operand")
1336                            (match_operand:SI 3 "register_operand"))))
1337    (clobber (match_scratch:SI 4))
1338    (clobber (match_scratch:SI 5))
1339    (clobber (match_scratch:SI 6))]
1340   "reload_completed && !TARGET_DEBUG_D_MODE
1341    && GP_REG_P (true_regnum (operands[0]))
1342    && GP_REG_P (true_regnum (operands[1]))"
1343   [(parallel [(set (match_dup 6)
1344                    (mult:SI (match_dup 2) (match_dup 3)))
1345               (clobber (match_dup 4))
1346               (clobber (match_dup 5))])
1347    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1348   "")
1349
1350 ;; Splitter to copy result of MSUB to a general register
1351 (define_split
1352   [(set (match_operand:SI 0 "register_operand")
1353         (minus:SI (match_operand:SI 1 "register_operand")
1354                   (mult:SI (match_operand:SI 2 "register_operand")
1355                            (match_operand:SI 3 "register_operand"))))
1356    (clobber (match_scratch:SI 4))
1357    (clobber (match_scratch:SI 5))
1358    (clobber (match_scratch:SI 6))]
1359   "reload_completed && !TARGET_DEBUG_D_MODE
1360    && GP_REG_P (true_regnum (operands[0]))
1361    && true_regnum (operands[1]) == LO_REGNUM"
1362   [(parallel [(set (match_dup 1)
1363                    (minus:SI (match_dup 1)
1364                              (mult:SI (match_dup 2) (match_dup 3))))
1365               (clobber (match_dup 4))
1366               (clobber (match_dup 5))
1367               (clobber (match_dup 6))])
1368    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1369   "")
1370
1371 (define_insn "*muls"
1372   [(set (match_operand:SI                  0 "register_operand" "=l,d")
1373         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1374                          (match_operand:SI 2 "register_operand" "d,d"))))
1375    (clobber (match_scratch:SI              3                    "=h,h"))
1376    (clobber (match_scratch:SI              4                    "=X,l"))]
1377   "ISA_HAS_MULS"
1378   "@
1379    muls\t$0,%1,%2
1380    muls\t%0,%1,%2"
1381   [(set_attr "type"     "imul")
1382    (set_attr "mode"     "SI")])
1383
1384 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1385
1386 (define_expand "<u>mulsidi3"
1387   [(parallel
1388       [(set (match_operand:DI 0 "register_operand")
1389             (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1390                      (any_extend:DI (match_operand:SI 2 "register_operand"))))
1391        (clobber (scratch:DI))
1392        (clobber (scratch:DI))
1393        (clobber (scratch:DI))])]
1394   "!TARGET_64BIT || !TARGET_FIX_R4000"
1395 {
1396   if (!TARGET_64BIT)
1397     {
1398       if (!TARGET_FIX_R4000)
1399         emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1400                                                    operands[2]));
1401       else
1402         emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1403                                                 operands[2]));
1404       DONE;
1405     }
1406 })
1407
1408 (define_insn "<u>mulsidi3_32bit_internal"
1409   [(set (match_operand:DI 0 "register_operand" "=x")
1410         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1411                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1412   "!TARGET_64BIT && !TARGET_FIX_R4000"
1413   "mult<u>\t%1,%2"
1414   [(set_attr "type" "imul")
1415    (set_attr "mode" "SI")])
1416
1417 (define_insn "<u>mulsidi3_32bit_r4000"
1418   [(set (match_operand:DI 0 "register_operand" "=d")
1419         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1420                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1421    (clobber (match_scratch:DI 3 "=x"))]
1422   "!TARGET_64BIT && TARGET_FIX_R4000"
1423   "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1424   [(set_attr "type" "imul")
1425    (set_attr "mode" "SI")
1426    (set_attr "length" "12")])
1427
1428 (define_insn_and_split "*<u>mulsidi3_64bit"
1429   [(set (match_operand:DI 0 "register_operand" "=d")
1430         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1431                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1432    (clobber (match_scratch:DI 3 "=l"))
1433    (clobber (match_scratch:DI 4 "=h"))
1434    (clobber (match_scratch:DI 5 "=d"))]
1435   "TARGET_64BIT && !TARGET_FIX_R4000"
1436   "#"
1437   "&& reload_completed"
1438   [(parallel
1439        [(set (match_dup 3)
1440              (sign_extend:DI
1441                 (mult:SI (match_dup 1)
1442                          (match_dup 2))))
1443         (set (match_dup 4)
1444              (ashiftrt:DI
1445                 (mult:DI (any_extend:DI (match_dup 1))
1446                          (any_extend:DI (match_dup 2)))
1447                 (const_int 32)))])
1448
1449    ;; OP5 <- LO, OP0 <- HI
1450    (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1451    (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1452
1453    ;; Zero-extend OP5.
1454    (set (match_dup 5)
1455         (ashift:DI (match_dup 5)
1456                    (const_int 32)))
1457    (set (match_dup 5)
1458         (lshiftrt:DI (match_dup 5)
1459                      (const_int 32)))
1460
1461    ;; Shift OP0 into place.
1462    (set (match_dup 0)
1463         (ashift:DI (match_dup 0)
1464                    (const_int 32)))
1465
1466    ;; OR the two halves together
1467    (set (match_dup 0)
1468         (ior:DI (match_dup 0)
1469                 (match_dup 5)))]
1470   ""
1471   [(set_attr "type" "imul")
1472    (set_attr "mode" "SI")
1473    (set_attr "length" "24")])
1474
1475 (define_insn "*<u>mulsidi3_64bit_parts"
1476   [(set (match_operand:DI 0 "register_operand" "=l")
1477         (sign_extend:DI
1478            (mult:SI (match_operand:SI 2 "register_operand" "d")
1479                     (match_operand:SI 3 "register_operand" "d"))))
1480    (set (match_operand:DI 1 "register_operand" "=h")
1481         (ashiftrt:DI
1482            (mult:DI (any_extend:DI (match_dup 2))
1483                     (any_extend:DI (match_dup 3)))
1484            (const_int 32)))]
1485   "TARGET_64BIT && !TARGET_FIX_R4000"
1486   "mult<u>\t%2,%3"
1487   [(set_attr "type" "imul")
1488    (set_attr "mode" "SI")])
1489
1490 ;; Widening multiply with negation.
1491 (define_insn "*muls<u>_di"
1492   [(set (match_operand:DI 0 "register_operand" "=x")
1493         (neg:DI
1494          (mult:DI
1495           (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1496           (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1497   "!TARGET_64BIT && ISA_HAS_MULS"
1498   "muls<u>\t$0,%1,%2"
1499   [(set_attr "type" "imul")
1500    (set_attr "mode" "SI")])
1501
1502 (define_insn "*msac<u>_di"
1503   [(set (match_operand:DI 0 "register_operand" "=x")
1504         (minus:DI
1505            (match_operand:DI 3 "register_operand" "0")
1506            (mult:DI
1507               (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1508               (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1509   "!TARGET_64BIT && ISA_HAS_MSAC"
1510 {
1511   if (TARGET_MIPS5500)
1512     return "msub<u>\t%1,%2";
1513   else
1514     return "msac<u>\t$0,%1,%2";
1515 }
1516   [(set_attr "type" "imadd")
1517    (set_attr "mode" "SI")])
1518
1519 ;; _highpart patterns
1520
1521 (define_expand "<su>mulsi3_highpart"
1522   [(set (match_operand:SI 0 "register_operand")
1523         (truncate:SI
1524          (lshiftrt:DI
1525           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1526                    (any_extend:DI (match_operand:SI 2 "register_operand")))
1527           (const_int 32))))]
1528   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1529 {
1530   if (ISA_HAS_MULHI)
1531     emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1532                                                        operands[1],
1533                                                        operands[2]));
1534   else
1535     emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1536                                                  operands[2]));
1537   DONE;
1538 })
1539
1540 (define_insn "<su>mulsi3_highpart_internal"
1541   [(set (match_operand:SI 0 "register_operand" "=h")
1542         (truncate:SI
1543          (lshiftrt:DI
1544           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1545                    (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1546           (const_int 32))))
1547    (clobber (match_scratch:SI 3 "=l"))]
1548   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1549   "mult<u>\t%1,%2"
1550   [(set_attr "type" "imul")
1551    (set_attr "mode" "SI")])
1552
1553 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1554   [(set (match_operand:SI 0 "register_operand" "=h,d")
1555         (truncate:SI
1556          (lshiftrt:DI
1557           (mult:DI
1558            (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1559            (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1560           (const_int 32))))
1561    (clobber (match_scratch:SI 3 "=l,l"))
1562    (clobber (match_scratch:SI 4 "=X,h"))]
1563   "ISA_HAS_MULHI"
1564   "@
1565    mult<u>\t%1,%2
1566    mulhi<u>\t%0,%1,%2"
1567   [(set_attr "type" "imul")
1568    (set_attr "mode" "SI")])
1569
1570 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1571   [(set (match_operand:SI 0 "register_operand" "=h,d")
1572         (truncate:SI
1573          (lshiftrt:DI
1574           (neg:DI
1575            (mult:DI
1576             (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1577             (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1578           (const_int 32))))
1579    (clobber (match_scratch:SI 3 "=l,l"))
1580    (clobber (match_scratch:SI 4 "=X,h"))]
1581   "ISA_HAS_MULHI"
1582   "@
1583    mulshi<u>\t%.,%1,%2
1584    mulshi<u>\t%0,%1,%2"
1585   [(set_attr "type" "imul")
1586    (set_attr "mode" "SI")])
1587
1588 ;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
1589 ;; errata MD(0), which says that dmultu does not always produce the
1590 ;; correct result.
1591 (define_insn "<su>muldi3_highpart"
1592   [(set (match_operand:DI 0 "register_operand" "=h")
1593         (truncate:DI
1594          (lshiftrt:TI
1595           (mult:TI
1596            (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1597            (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1598           (const_int 64))))
1599    (clobber (match_scratch:DI 3 "=l"))]
1600   "TARGET_64BIT && !TARGET_FIX_R4000
1601    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1602   "dmult<u>\t%1,%2"
1603   [(set_attr "type" "imul")
1604    (set_attr "mode" "DI")])
1605
1606 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1607 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
1608
1609 (define_insn "madsi"
1610   [(set (match_operand:SI 0 "register_operand" "+l")
1611         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1612                           (match_operand:SI 2 "register_operand" "d"))
1613                  (match_dup 0)))
1614    (clobber (match_scratch:SI 3 "=h"))]
1615   "TARGET_MAD"
1616   "mad\t%1,%2"
1617   [(set_attr "type"     "imadd")
1618    (set_attr "mode"     "SI")])
1619
1620 (define_insn "*<su>mul_acc_di"
1621   [(set (match_operand:DI 0 "register_operand" "=x")
1622         (plus:DI
1623          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1624                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1625          (match_operand:DI 3 "register_operand" "0")))]
1626   "(TARGET_MAD || ISA_HAS_MACC)
1627    && !TARGET_64BIT"
1628 {
1629   if (TARGET_MAD)
1630     return "mad<u>\t%1,%2";
1631   else if (TARGET_MIPS5500)
1632     return "madd<u>\t%1,%2";
1633   else
1634     /* See comment in *macc.  */
1635     return "%[macc<u>\t%@,%1,%2%]";
1636 }
1637   [(set_attr "type" "imadd")
1638    (set_attr "mode" "SI")])
1639
1640 ;; Floating point multiply accumulate instructions.
1641
1642 (define_insn "*madd<mode>"
1643   [(set (match_operand:ANYF 0 "register_operand" "=f")
1644         (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1645                               (match_operand:ANYF 2 "register_operand" "f"))
1646                    (match_operand:ANYF 3 "register_operand" "f")))]
1647   "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1648   "madd.<fmt>\t%0,%3,%1,%2"
1649   [(set_attr "type" "fmadd")
1650    (set_attr "mode" "<UNITMODE>")])
1651
1652 (define_insn "*msub<mode>"
1653   [(set (match_operand:ANYF 0 "register_operand" "=f")
1654         (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1655                                (match_operand:ANYF 2 "register_operand" "f"))
1656                     (match_operand:ANYF 3 "register_operand" "f")))]
1657   "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1658   "msub.<fmt>\t%0,%3,%1,%2"
1659   [(set_attr "type" "fmadd")
1660    (set_attr "mode" "<UNITMODE>")])
1661
1662 (define_insn "*nmadd<mode>"
1663   [(set (match_operand:ANYF 0 "register_operand" "=f")
1664         (neg:ANYF (plus:ANYF
1665                    (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1666                               (match_operand:ANYF 2 "register_operand" "f"))
1667                    (match_operand:ANYF 3 "register_operand" "f"))))]
1668   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1669    && HONOR_SIGNED_ZEROS (<MODE>mode)"
1670   "nmadd.<fmt>\t%0,%3,%1,%2"
1671   [(set_attr "type" "fmadd")
1672    (set_attr "mode" "<UNITMODE>")])
1673
1674 (define_insn "*nmadd<mode>_fastmath"
1675   [(set (match_operand:ANYF 0 "register_operand" "=f")
1676         (minus:ANYF
1677          (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1678                     (match_operand:ANYF 2 "register_operand" "f"))
1679          (match_operand:ANYF 3 "register_operand" "f")))]
1680   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1681    && !HONOR_SIGNED_ZEROS (<MODE>mode)"
1682   "nmadd.<fmt>\t%0,%3,%1,%2"
1683   [(set_attr "type" "fmadd")
1684    (set_attr "mode" "<UNITMODE>")])
1685
1686 (define_insn "*nmsub<mode>"
1687   [(set (match_operand:ANYF 0 "register_operand" "=f")
1688         (neg:ANYF (minus:ANYF
1689                    (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1690                               (match_operand:ANYF 3 "register_operand" "f"))
1691                    (match_operand:ANYF 1 "register_operand" "f"))))]
1692   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1693    && HONOR_SIGNED_ZEROS (<MODE>mode)"
1694   "nmsub.<fmt>\t%0,%1,%2,%3"
1695   [(set_attr "type" "fmadd")
1696    (set_attr "mode" "<UNITMODE>")])
1697
1698 (define_insn "*nmsub<mode>_fastmath"
1699   [(set (match_operand:ANYF 0 "register_operand" "=f")
1700         (minus:ANYF
1701          (match_operand:ANYF 1 "register_operand" "f")
1702          (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1703                     (match_operand:ANYF 3 "register_operand" "f"))))]
1704   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1705    && !HONOR_SIGNED_ZEROS (<MODE>mode)"
1706   "nmsub.<fmt>\t%0,%1,%2,%3"
1707   [(set_attr "type" "fmadd")
1708    (set_attr "mode" "<UNITMODE>")])
1709 \f
1710 ;;
1711 ;;  ....................
1712 ;;
1713 ;;      DIVISION and REMAINDER
1714 ;;
1715 ;;  ....................
1716 ;;
1717
1718 (define_expand "div<mode>3"
1719   [(set (match_operand:SCALARF 0 "register_operand")
1720         (div:SCALARF (match_operand:SCALARF 1 "reg_or_1_operand")
1721                      (match_operand:SCALARF 2 "register_operand")))]
1722   "<divide_condition>"
1723 {
1724   if (const_1_operand (operands[1], <MODE>mode))
1725     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1726       operands[1] = force_reg (<MODE>mode, operands[1]);
1727 })
1728
1729 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1730 ;;
1731 ;; If an mfc1 or dmfc1 happens to access the floating point register
1732 ;; file at the same time a long latency operation (div, sqrt, recip,
1733 ;; sqrt) iterates an intermediate result back through the floating
1734 ;; point register file bypass, then instead returning the correct
1735 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1736 ;; result of the long latency operation.
1737 ;;
1738 ;; The workaround is to insert an unconditional 'mov' from/to the
1739 ;; long latency op destination register.
1740
1741 (define_insn "*div<mode>3"
1742   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1743         (div:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1744                      (match_operand:SCALARF 2 "register_operand" "f")))]
1745   "<divide_condition>"
1746 {
1747   if (TARGET_FIX_SB1)
1748     return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1749   else
1750     return "div.<fmt>\t%0,%1,%2";
1751 }
1752   [(set_attr "type" "fdiv")
1753    (set_attr "mode" "<MODE>")
1754    (set (attr "length")
1755         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1756                       (const_int 8)
1757                       (const_int 4)))])
1758
1759 (define_insn "*recip<mode>3"
1760   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1761         (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "")
1762                      (match_operand:SCALARF 2 "register_operand" "f")))]
1763   "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
1764 {
1765   if (TARGET_FIX_SB1)
1766     return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1767   else
1768     return "recip.<fmt>\t%0,%2";
1769 }
1770   [(set_attr "type" "frdiv")
1771    (set_attr "mode" "<MODE>")
1772    (set (attr "length")
1773         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1774                       (const_int 8)
1775                       (const_int 4)))])
1776
1777 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1778 ;; with negative operands.  We use special libgcc functions instead.
1779 (define_insn "divmod<mode>4"
1780   [(set (match_operand:GPR 0 "register_operand" "=l")
1781         (div:GPR (match_operand:GPR 1 "register_operand" "d")
1782                  (match_operand:GPR 2 "register_operand" "d")))
1783    (set (match_operand:GPR 3 "register_operand" "=h")
1784         (mod:GPR (match_dup 1)
1785                  (match_dup 2)))]
1786   "!TARGET_FIX_VR4120"
1787   { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1788   [(set_attr "type" "idiv")
1789    (set_attr "mode" "<MODE>")])
1790
1791 (define_insn "udivmod<mode>4"
1792   [(set (match_operand:GPR 0 "register_operand" "=l")
1793         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1794                   (match_operand:GPR 2 "register_operand" "d")))
1795    (set (match_operand:GPR 3 "register_operand" "=h")
1796         (umod:GPR (match_dup 1)
1797                   (match_dup 2)))]
1798   ""
1799   { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1800   [(set_attr "type" "idiv")
1801    (set_attr "mode" "<MODE>")])
1802 \f
1803 ;;
1804 ;;  ....................
1805 ;;
1806 ;;      SQUARE ROOT
1807 ;;
1808 ;;  ....................
1809
1810 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1811 ;; "*div[sd]f3" comment for details).
1812
1813 (define_insn "sqrt<mode>2"
1814   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1815         (sqrt:SCALARF (match_operand:SCALARF 1 "register_operand" "f")))]
1816   "HAVE_SQRT_P()"
1817 {
1818   if (TARGET_FIX_SB1)
1819     return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
1820   else
1821     return "sqrt.<fmt>\t%0,%1";
1822 }
1823   [(set_attr "type" "fsqrt")
1824    (set_attr "mode" "<MODE>")
1825    (set (attr "length")
1826         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1827                       (const_int 8)
1828                       (const_int 4)))])
1829
1830 (define_insn "*rsqrt<mode>a"
1831   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1832         (div:SCALARF
1833          (match_operand:SCALARF 1 "const_1_operand" "")
1834          (sqrt:SCALARF (match_operand:SCALARF 2 "register_operand" "f"))))]
1835   "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
1836 {
1837   if (TARGET_FIX_SB1)
1838     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1839   else
1840     return "rsqrt.<fmt>\t%0,%2";
1841 }
1842   [(set_attr "type" "frsqrt")
1843    (set_attr "mode" "<MODE>")
1844    (set (attr "length")
1845         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1846                       (const_int 8)
1847                       (const_int 4)))])
1848
1849 (define_insn "*rsqrt<mode>b"
1850   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1851         (sqrt:SCALARF
1852          (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "")
1853                       (match_operand:SCALARF 2 "register_operand" "f"))))]
1854   "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
1855 {
1856   if (TARGET_FIX_SB1)
1857     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1858   else
1859     return "rsqrt.<fmt>\t%0,%2";
1860 }
1861   [(set_attr "type" "frsqrt")
1862    (set_attr "mode" "<MODE>")
1863    (set (attr "length")
1864         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1865                       (const_int 8)
1866                       (const_int 4)))])
1867 \f
1868 ;;
1869 ;;  ....................
1870 ;;
1871 ;;      ABSOLUTE VALUE
1872 ;;
1873 ;;  ....................
1874
1875 ;; Do not use the integer abs macro instruction, since that signals an
1876 ;; exception on -2147483648 (sigh).
1877
1878 (define_insn "abs<mode>2"
1879   [(set (match_operand:GPR 0 "register_operand" "=d")
1880         (abs:GPR (match_operand:GPR 1 "register_operand" "d")))]
1881   "!TARGET_MIPS16"
1882 {
1883   if (REGNO (operands[0]) == REGNO (operands[1]) && GENERATE_BRANCHLIKELY)
1884     return "%(bltzl\t%1,1f\;<d>subu\t%0,%.,%0\n%~1:%)";
1885   else
1886     return "%(bgez\t%1,1f\;move\t%0,%1\;<d>subu\t%0,%.,%0\n%~1:%)";
1887 }
1888   [(set_attr "type" "multi")
1889    (set_attr "mode" "<MODE>")
1890    (set_attr "length" "12")])
1891
1892 (define_insn "abs<mode>2"
1893   [(set (match_operand:ANYF 0 "register_operand" "=f")
1894         (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1895   ""
1896   "abs.<fmt>\t%0,%1"
1897   [(set_attr "type" "fabs")
1898    (set_attr "mode" "<UNITMODE>")])
1899 \f
1900 ;;
1901 ;;  ....................
1902 ;;
1903 ;;      FIND FIRST BIT INSTRUCTION
1904 ;;
1905 ;;  ....................
1906 ;;
1907
1908 (define_insn "ffs<mode>2"
1909   [(set (match_operand:GPR 0 "register_operand" "=&d")
1910         (ffs:GPR (match_operand:GPR 1 "register_operand" "d")))
1911    (clobber (match_scratch:GPR 2 "=&d"))
1912    (clobber (match_scratch:GPR 3 "=&d"))]
1913   "!TARGET_MIPS16"
1914 {
1915   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1916     return "%(\
1917 move\t%0,%.\;\
1918 beq\t%1,%.,2f\n\
1919 %~1:\tand\t%2,%1,0x0001\;\
1920 <d>addu\t%0,%0,1\;\
1921 beq\t%2,%.,1b\;\
1922 <d>srl\t%1,%1,1\n\
1923 %~2:%)";
1924
1925   return "%(\
1926 move\t%0,%.\;\
1927 move\t%3,%1\;\
1928 beq\t%3,%.,2f\n\
1929 %~1:\tand\t%2,%3,0x0001\;\
1930 <d>addu\t%0,%0,1\;\
1931 beq\t%2,%.,1b\;\
1932 <d>srl\t%3,%3,1\n\
1933 %~2:%)";
1934 }
1935   [(set_attr "type" "multi")
1936    (set_attr "mode" "<MODE>")
1937    (set_attr "length" "28")])
1938 \f
1939 ;;
1940 ;;  ...................
1941 ;;
1942 ;;  Count leading zeroes.
1943 ;;
1944 ;;  ...................
1945 ;;
1946
1947 (define_insn "clz<mode>2"
1948   [(set (match_operand:GPR 0 "register_operand" "=d")
1949         (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
1950   "ISA_HAS_CLZ_CLO"
1951   "<d>clz\t%0,%1"
1952   [(set_attr "type" "clz")
1953    (set_attr "mode" "<MODE>")])
1954 \f
1955 ;;
1956 ;;  ....................
1957 ;;
1958 ;;      NEGATION and ONE'S COMPLEMENT
1959 ;;
1960 ;;  ....................
1961
1962 (define_insn "negsi2"
1963   [(set (match_operand:SI 0 "register_operand" "=d")
1964         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1965   ""
1966 {
1967   if (TARGET_MIPS16)
1968     return "neg\t%0,%1";
1969   else
1970     return "subu\t%0,%.,%1";
1971 }
1972   [(set_attr "type"     "arith")
1973    (set_attr "mode"     "SI")])
1974
1975 (define_insn "negdi2"
1976   [(set (match_operand:DI 0 "register_operand" "=d")
1977         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
1978   "TARGET_64BIT && !TARGET_MIPS16"
1979   "dsubu\t%0,%.,%1"
1980   [(set_attr "type"     "arith")
1981    (set_attr "mode"     "DI")])
1982
1983 (define_insn "neg<mode>2"
1984   [(set (match_operand:ANYF 0 "register_operand" "=f")
1985         (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1986   ""
1987   "neg.<fmt>\t%0,%1"
1988   [(set_attr "type" "fneg")
1989    (set_attr "mode" "<UNITMODE>")])
1990
1991 (define_insn "one_cmpl<mode>2"
1992   [(set (match_operand:GPR 0 "register_operand" "=d")
1993         (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
1994   ""
1995 {
1996   if (TARGET_MIPS16)
1997     return "not\t%0,%1";
1998   else
1999     return "nor\t%0,%.,%1";
2000 }
2001   [(set_attr "type" "arith")
2002    (set_attr "mode" "<MODE>")])
2003 \f
2004 ;;
2005 ;;  ....................
2006 ;;
2007 ;;      LOGICAL
2008 ;;
2009 ;;  ....................
2010 ;;
2011
2012 ;; Many of these instructions use trivial define_expands, because we
2013 ;; want to use a different set of constraints when TARGET_MIPS16.
2014
2015 (define_expand "and<mode>3"
2016   [(set (match_operand:GPR 0 "register_operand")
2017         (and:GPR (match_operand:GPR 1 "register_operand")
2018                  (match_operand:GPR 2 "uns_arith_operand")))]
2019   ""
2020 {
2021   if (TARGET_MIPS16)
2022     operands[2] = force_reg (<MODE>mode, operands[2]);
2023 })
2024
2025 (define_insn "*and<mode>3"
2026   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2027         (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2028                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2029   "!TARGET_MIPS16"
2030   "@
2031    and\t%0,%1,%2
2032    andi\t%0,%1,%x2"
2033   [(set_attr "type" "arith")
2034    (set_attr "mode" "<MODE>")])
2035
2036 (define_insn "*and<mode>3_mips16"
2037   [(set (match_operand:GPR 0 "register_operand" "=d")
2038         (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2039                  (match_operand:GPR 2 "register_operand" "d")))]
2040   "TARGET_MIPS16"
2041   "and\t%0,%2"
2042   [(set_attr "type" "arith")
2043    (set_attr "mode" "<MODE>")])
2044
2045 (define_expand "ior<mode>3"
2046   [(set (match_operand:GPR 0 "register_operand")
2047         (ior:GPR (match_operand:GPR 1 "register_operand")
2048                  (match_operand:GPR 2 "uns_arith_operand")))]
2049   ""
2050 {
2051   if (TARGET_MIPS16)
2052     operands[2] = force_reg (<MODE>mode, operands[2]);
2053 })
2054
2055 (define_insn "*ior<mode>3"
2056   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2057         (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2058                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2059   "!TARGET_MIPS16"
2060   "@
2061    or\t%0,%1,%2
2062    ori\t%0,%1,%x2"
2063   [(set_attr "type" "arith")
2064    (set_attr "mode" "<MODE>")])
2065
2066 (define_insn "*ior<mode>3_mips16"
2067   [(set (match_operand:GPR 0 "register_operand" "=d")
2068         (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2069                  (match_operand:GPR 2 "register_operand" "d")))]
2070   "TARGET_MIPS16"
2071   "or\t%0,%2"
2072   [(set_attr "type" "arith")
2073    (set_attr "mode" "<MODE>")])
2074
2075 (define_expand "xor<mode>3"
2076   [(set (match_operand:GPR 0 "register_operand")
2077         (xor:GPR (match_operand:GPR 1 "register_operand")
2078                  (match_operand:GPR 2 "uns_arith_operand")))]
2079   ""
2080   "")
2081
2082 (define_insn ""
2083   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2084         (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2085                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2086   "!TARGET_MIPS16"
2087   "@
2088    xor\t%0,%1,%2
2089    xori\t%0,%1,%x2"
2090   [(set_attr "type" "arith")
2091    (set_attr "mode" "<MODE>")])
2092
2093 (define_insn ""
2094   [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2095         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2096                  (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2097   "TARGET_MIPS16"
2098   "@
2099    xor\t%0,%2
2100    cmpi\t%1,%2
2101    cmp\t%1,%2"
2102   [(set_attr "type" "arith")
2103    (set_attr "mode" "<MODE>")
2104    (set_attr_alternative "length"
2105                 [(const_int 4)
2106                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2107                                (const_int 4)
2108                                (const_int 8))
2109                  (const_int 4)])])
2110
2111 (define_insn "*nor<mode>3"
2112   [(set (match_operand:GPR 0 "register_operand" "=d")
2113         (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2114                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2115   "!TARGET_MIPS16"
2116   "nor\t%0,%1,%2"
2117   [(set_attr "type" "arith")
2118    (set_attr "mode" "<MODE>")])
2119 \f
2120 ;;
2121 ;;  ....................
2122 ;;
2123 ;;      TRUNCATION
2124 ;;
2125 ;;  ....................
2126
2127
2128
2129 (define_insn "truncdfsf2"
2130   [(set (match_operand:SF 0 "register_operand" "=f")
2131         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2132   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2133   "cvt.s.d\t%0,%1"
2134   [(set_attr "type"     "fcvt")
2135    (set_attr "mode"     "SF")])
2136
2137 ;; Integer truncation patterns.  Truncating SImode values to smaller
2138 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2139 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2140 ;; need to make sure that the lower 32 bits are properly sign-extended
2141 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2142 ;; smaller than SImode is equivalent to two separate truncations:
2143 ;;
2144 ;;                        A       B
2145 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2146 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2147 ;;
2148 ;; Step A needs a real instruction but step B does not.
2149
2150 (define_insn "truncdisi2"
2151   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2152         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2153   "TARGET_64BIT"
2154   "@
2155     sll\t%0,%1,0
2156     sw\t%1,%0"
2157   [(set_attr "type" "shift,store")
2158    (set_attr "mode" "SI")
2159    (set_attr "extended_mips16" "yes,*")])
2160
2161 (define_insn "truncdihi2"
2162   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2163         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2164   "TARGET_64BIT"
2165   "@
2166     sll\t%0,%1,0
2167     sh\t%1,%0"
2168   [(set_attr "type" "shift,store")
2169    (set_attr "mode" "SI")
2170    (set_attr "extended_mips16" "yes,*")])
2171
2172 (define_insn "truncdiqi2"
2173   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2174         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2175   "TARGET_64BIT"
2176   "@
2177     sll\t%0,%1,0
2178     sb\t%1,%0"
2179   [(set_attr "type" "shift,store")
2180    (set_attr "mode" "SI")
2181    (set_attr "extended_mips16" "yes,*")])
2182
2183 ;; Combiner patterns to optimize shift/truncate combinations.
2184
2185 (define_insn ""
2186   [(set (match_operand:SI 0 "register_operand" "=d")
2187         (truncate:SI
2188           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2189                        (match_operand:DI 2 "const_arith_operand" ""))))]
2190   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2191   "dsra\t%0,%1,%2"
2192   [(set_attr "type" "shift")
2193    (set_attr "mode" "SI")])
2194
2195 (define_insn ""
2196   [(set (match_operand:SI 0 "register_operand" "=d")
2197         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2198                                   (const_int 32))))]
2199   "TARGET_64BIT && !TARGET_MIPS16"
2200   "dsra\t%0,%1,32"
2201   [(set_attr "type" "shift")
2202    (set_attr "mode" "SI")])
2203
2204
2205 ;; Combiner patterns for truncate/sign_extend combinations.  They use
2206 ;; the shift/truncate patterns above.
2207
2208 (define_insn_and_split ""
2209   [(set (match_operand:SI 0 "register_operand" "=d")
2210         (sign_extend:SI
2211             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2212   "TARGET_64BIT && !TARGET_MIPS16"
2213   "#"
2214   "&& reload_completed"
2215   [(set (match_dup 2)
2216         (ashift:DI (match_dup 1)
2217                    (const_int 48)))
2218    (set (match_dup 0)
2219         (truncate:SI (ashiftrt:DI (match_dup 2)
2220                                   (const_int 48))))]
2221   { operands[2] = gen_lowpart (DImode, operands[0]); })
2222
2223 (define_insn_and_split ""
2224   [(set (match_operand:SI 0 "register_operand" "=d")
2225         (sign_extend:SI
2226             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2227   "TARGET_64BIT && !TARGET_MIPS16"
2228   "#"
2229   "&& reload_completed"
2230   [(set (match_dup 2)
2231         (ashift:DI (match_dup 1)
2232                    (const_int 56)))
2233    (set (match_dup 0)
2234         (truncate:SI (ashiftrt:DI (match_dup 2)
2235                                   (const_int 56))))]
2236   { operands[2] = gen_lowpart (DImode, operands[0]); })
2237
2238
2239 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2240
2241 (define_insn ""
2242   [(set (match_operand:SI 0 "register_operand" "=d")
2243         (zero_extend:SI (truncate:HI
2244                          (match_operand:DI 1 "register_operand" "d"))))]
2245   "TARGET_64BIT && !TARGET_MIPS16"
2246   "andi\t%0,%1,0xffff"
2247   [(set_attr "type"     "arith")
2248    (set_attr "mode"     "SI")])
2249
2250 (define_insn ""
2251   [(set (match_operand:SI 0 "register_operand" "=d")
2252         (zero_extend:SI (truncate:QI
2253                          (match_operand:DI 1 "register_operand" "d"))))]
2254   "TARGET_64BIT && !TARGET_MIPS16"
2255   "andi\t%0,%1,0xff"
2256   [(set_attr "type"     "arith")
2257    (set_attr "mode"     "SI")])
2258
2259 (define_insn ""
2260   [(set (match_operand:HI 0 "register_operand" "=d")
2261         (zero_extend:HI (truncate:QI
2262                          (match_operand:DI 1 "register_operand" "d"))))]
2263   "TARGET_64BIT && !TARGET_MIPS16"
2264   "andi\t%0,%1,0xff"
2265   [(set_attr "type"     "arith")
2266    (set_attr "mode"     "HI")])
2267 \f
2268 ;;
2269 ;;  ....................
2270 ;;
2271 ;;      ZERO EXTENSION
2272 ;;
2273 ;;  ....................
2274
2275 ;; Extension insns.
2276 ;; Those for integer source operand are ordered widest source type first.
2277
2278 (define_insn_and_split "zero_extendsidi2"
2279   [(set (match_operand:DI 0 "register_operand" "=d")
2280         (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2281   "TARGET_64BIT"
2282   "#"
2283   "&& reload_completed"
2284   [(set (match_dup 0)
2285         (ashift:DI (match_dup 1) (const_int 32)))
2286    (set (match_dup 0)
2287         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2288   "operands[1] = gen_lowpart (DImode, operands[1]);"
2289   [(set_attr "type" "multi")
2290    (set_attr "mode" "DI")
2291    (set_attr "length" "8")])
2292
2293 (define_insn "*zero_extendsidi2_mem"
2294   [(set (match_operand:DI 0 "register_operand" "=d")
2295         (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2296   "TARGET_64BIT"
2297   "lwu\t%0,%1"
2298   [(set_attr "type"     "load")
2299    (set_attr "mode"     "DI")])
2300
2301 (define_expand "zero_extendhisi2"
2302   [(set (match_operand:SI 0 "register_operand")
2303         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2304   ""
2305 {
2306   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2307     {
2308       rtx op = gen_lowpart (SImode, operands[1]);
2309       rtx temp = force_reg (SImode, GEN_INT (0xffff));
2310
2311       emit_insn (gen_andsi3 (operands[0], op, temp));
2312       DONE;
2313     }
2314 })
2315
2316 (define_insn ""
2317   [(set (match_operand:SI 0 "register_operand" "=d,d")
2318         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2319   "!TARGET_MIPS16"
2320   "@
2321    andi\t%0,%1,0xffff
2322    lhu\t%0,%1"
2323   [(set_attr "type"     "arith,load")
2324    (set_attr "mode"     "SI")
2325    (set_attr "length"   "4,*")])
2326
2327 (define_insn ""
2328   [(set (match_operand:SI 0 "register_operand" "=d")
2329         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2330   "TARGET_MIPS16"
2331   "lhu\t%0,%1"
2332   [(set_attr "type"     "load")
2333    (set_attr "mode"     "SI")])
2334
2335 (define_expand "zero_extendhidi2"
2336   [(set (match_operand:DI 0 "register_operand")
2337         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2338   "TARGET_64BIT"
2339 {
2340   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2341     {
2342       rtx op = gen_lowpart (DImode, operands[1]);
2343       rtx temp = force_reg (DImode, GEN_INT (0xffff));
2344
2345       emit_insn (gen_anddi3 (operands[0], op, temp));
2346       DONE;
2347     }
2348 })
2349
2350 (define_insn ""
2351   [(set (match_operand:DI 0 "register_operand" "=d,d")
2352         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2353   "TARGET_64BIT && !TARGET_MIPS16"
2354   "@
2355    andi\t%0,%1,0xffff
2356    lhu\t%0,%1"
2357   [(set_attr "type"     "arith,load")
2358    (set_attr "mode"     "DI")
2359    (set_attr "length"   "4,*")])
2360
2361 (define_insn ""
2362   [(set (match_operand:DI 0 "register_operand" "=d")
2363         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2364   "TARGET_64BIT && TARGET_MIPS16"
2365   "lhu\t%0,%1"
2366   [(set_attr "type"     "load")
2367    (set_attr "mode"     "DI")])
2368
2369 (define_expand "zero_extendqihi2"
2370   [(set (match_operand:HI 0 "register_operand")
2371         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2372   ""
2373 {
2374   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2375     {
2376       rtx op0 = gen_lowpart (SImode, operands[0]);
2377       rtx op1 = gen_lowpart (SImode, operands[1]);
2378       rtx temp = force_reg (SImode, GEN_INT (0xff));
2379
2380       emit_insn (gen_andsi3 (op0, op1, temp));
2381       DONE;
2382     }
2383 })
2384
2385 (define_insn ""
2386   [(set (match_operand:HI 0 "register_operand" "=d,d")
2387         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2388   "!TARGET_MIPS16"
2389   "@
2390    andi\t%0,%1,0x00ff
2391    lbu\t%0,%1"
2392   [(set_attr "type"     "arith,load")
2393    (set_attr "mode"     "HI")
2394    (set_attr "length"   "4,*")])
2395
2396 (define_insn ""
2397   [(set (match_operand:HI 0 "register_operand" "=d")
2398         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2399   "TARGET_MIPS16"
2400   "lbu\t%0,%1"
2401   [(set_attr "type"     "load")
2402    (set_attr "mode"     "HI")])
2403
2404 (define_expand "zero_extendqisi2"
2405   [(set (match_operand:SI 0 "register_operand")
2406         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2407   ""
2408 {
2409   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2410     {
2411       rtx op = gen_lowpart (SImode, operands[1]);
2412       rtx temp = force_reg (SImode, GEN_INT (0xff));
2413
2414       emit_insn (gen_andsi3 (operands[0], op, temp));
2415       DONE;
2416     }
2417 })
2418
2419 (define_insn ""
2420   [(set (match_operand:SI 0 "register_operand" "=d,d")
2421         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2422   "!TARGET_MIPS16"
2423   "@
2424    andi\t%0,%1,0x00ff
2425    lbu\t%0,%1"
2426   [(set_attr "type"     "arith,load")
2427    (set_attr "mode"     "SI")
2428    (set_attr "length"   "4,*")])
2429
2430 (define_insn ""
2431   [(set (match_operand:SI 0 "register_operand" "=d")
2432         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2433   "TARGET_MIPS16"
2434   "lbu\t%0,%1"
2435   [(set_attr "type"     "load")
2436    (set_attr "mode"     "SI")])
2437
2438 (define_expand "zero_extendqidi2"
2439   [(set (match_operand:DI 0 "register_operand")
2440         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2441   "TARGET_64BIT"
2442 {
2443   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2444     {
2445       rtx op = gen_lowpart (DImode, operands[1]);
2446       rtx temp = force_reg (DImode, GEN_INT (0xff));
2447
2448       emit_insn (gen_anddi3 (operands[0], op, temp));
2449       DONE;
2450     }
2451 })
2452
2453 (define_insn ""
2454   [(set (match_operand:DI 0 "register_operand" "=d,d")
2455         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2456   "TARGET_64BIT && !TARGET_MIPS16"
2457   "@
2458    andi\t%0,%1,0x00ff
2459    lbu\t%0,%1"
2460   [(set_attr "type"     "arith,load")
2461    (set_attr "mode"     "DI")
2462    (set_attr "length"   "4,*")])
2463
2464 (define_insn ""
2465   [(set (match_operand:DI 0 "register_operand" "=d")
2466         (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2467   "TARGET_64BIT && TARGET_MIPS16"
2468   "lbu\t%0,%1"
2469   [(set_attr "type"     "load")
2470    (set_attr "mode"     "DI")])
2471 \f
2472 ;;
2473 ;;  ....................
2474 ;;
2475 ;;      SIGN EXTENSION
2476 ;;
2477 ;;  ....................
2478
2479 ;; Extension insns.
2480 ;; Those for integer source operand are ordered widest source type first.
2481
2482 ;; When TARGET_64BIT, all SImode integer registers should already be in
2483 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
2484 ;; therefore get rid of register->register instructions if we constrain
2485 ;; the source to be in the same register as the destination.
2486 ;;
2487 ;; The register alternative has type "arith" so that the pre-reload
2488 ;; scheduler will treat it as a move.  This reflects what happens if
2489 ;; the register alternative needs a reload.
2490 (define_insn_and_split "extendsidi2"
2491   [(set (match_operand:DI 0 "register_operand" "=d,d")
2492         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2493   "TARGET_64BIT"
2494   "@
2495    #
2496    lw\t%0,%1"
2497   "&& reload_completed && register_operand (operands[1], VOIDmode)"
2498   [(const_int 0)]
2499 {
2500   emit_note (NOTE_INSN_DELETED);
2501   DONE;
2502 }
2503   [(set_attr "type" "arith,load")
2504    (set_attr "mode" "DI")])
2505
2506 ;; These patterns originally accepted general_operands, however, slightly
2507 ;; better code is generated by only accepting register_operands, and then
2508 ;; letting combine generate the lh and lb insns.
2509
2510 ;; These expanders originally put values in registers first. We split
2511 ;; all non-mem patterns after reload.
2512
2513 (define_expand "extendhidi2"
2514   [(set (match_operand:DI 0 "register_operand")
2515         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2516   "TARGET_64BIT"
2517   "")
2518
2519 (define_insn "*extendhidi2"
2520   [(set (match_operand:DI 0 "register_operand" "=d")
2521         (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
2522   "TARGET_64BIT"
2523   "#")
2524
2525 (define_split
2526   [(set (match_operand:DI 0 "register_operand")
2527         (sign_extend:DI (match_operand:HI 1 "register_operand")))]
2528   "TARGET_64BIT && reload_completed"
2529   [(set (match_dup 0)
2530         (ashift:DI (match_dup 1) (const_int 48)))
2531    (set (match_dup 0)
2532         (ashiftrt:DI (match_dup 0) (const_int 48)))]
2533   "operands[1] = gen_lowpart (DImode, operands[1]);")
2534
2535 (define_insn "*extendhidi2_mem"
2536   [(set (match_operand:DI 0 "register_operand" "=d")
2537         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2538   "TARGET_64BIT"
2539   "lh\t%0,%1"
2540   [(set_attr "type"     "load")
2541    (set_attr "mode"     "DI")])
2542
2543 (define_expand "extendhisi2"
2544   [(set (match_operand:SI 0 "register_operand")
2545         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2546   ""
2547 {
2548   if (ISA_HAS_SEB_SEH)
2549     {
2550       emit_insn (gen_extendhisi2_hw (operands[0],
2551                                      force_reg (HImode, operands[1])));
2552       DONE;
2553     }
2554 })
2555
2556 (define_insn "*extendhisi2"
2557   [(set (match_operand:SI 0 "register_operand" "=d")
2558         (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
2559   ""
2560   "#")
2561
2562 (define_split
2563   [(set (match_operand:SI 0 "register_operand")
2564         (sign_extend:SI (match_operand:HI 1 "register_operand")))]
2565   "reload_completed"
2566   [(set (match_dup 0)
2567         (ashift:SI (match_dup 1) (const_int 16)))
2568    (set (match_dup 0)
2569         (ashiftrt:SI (match_dup 0) (const_int 16)))]
2570   "operands[1] = gen_lowpart (SImode, operands[1]);")
2571
2572 (define_insn "extendhisi2_mem"
2573   [(set (match_operand:SI 0 "register_operand" "=d")
2574         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2575   ""
2576   "lh\t%0,%1"
2577   [(set_attr "type"     "load")
2578    (set_attr "mode"     "SI")])
2579
2580 (define_insn "extendhisi2_hw"
2581   [(set (match_operand:SI 0 "register_operand" "=r")
2582         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2583   "ISA_HAS_SEB_SEH"
2584   "seh\t%0,%1"
2585   [(set_attr "type" "arith")
2586    (set_attr "mode" "SI")])
2587
2588 (define_expand "extendqihi2"
2589   [(set (match_operand:HI 0 "register_operand")
2590         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2591   ""
2592   "")
2593
2594 (define_insn "*extendqihi2"
2595   [(set (match_operand:HI 0 "register_operand" "=d")
2596         (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
2597   ""
2598   "#")
2599
2600 (define_split
2601   [(set (match_operand:HI 0 "register_operand")
2602         (sign_extend:HI (match_operand:QI 1 "register_operand")))]
2603   "reload_completed"
2604   [(set (match_dup 0)
2605         (ashift:SI (match_dup 1) (const_int 24)))
2606    (set (match_dup 0)
2607         (ashiftrt:SI (match_dup 0) (const_int 24)))]
2608   "operands[0] = gen_lowpart (SImode, operands[0]);
2609    operands[1] = gen_lowpart (SImode, operands[1]);")
2610
2611 (define_insn "*extendqihi2_internal_mem"
2612   [(set (match_operand:HI 0 "register_operand" "=d")
2613         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2614   ""
2615   "lb\t%0,%1"
2616   [(set_attr "type"     "load")
2617    (set_attr "mode"     "SI")])
2618
2619
2620 (define_expand "extendqisi2"
2621   [(set (match_operand:SI 0 "register_operand")
2622         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2623   ""
2624 {
2625   if (ISA_HAS_SEB_SEH)
2626     {
2627       emit_insn (gen_extendqisi2_hw (operands[0],
2628                                      force_reg (QImode, operands[1])));
2629       DONE;
2630     }
2631 })
2632
2633 (define_insn "*extendqisi2"
2634   [(set (match_operand:SI 0 "register_operand" "=d")
2635         (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
2636   ""
2637   "#")
2638
2639 (define_split
2640   [(set (match_operand:SI 0 "register_operand")
2641         (sign_extend:SI (match_operand:QI 1 "register_operand")))]
2642   "reload_completed"
2643   [(set (match_dup 0)
2644         (ashift:SI (match_dup 1) (const_int 24)))
2645    (set (match_dup 0)
2646         (ashiftrt:SI (match_dup 0) (const_int 24)))]
2647   "operands[1] = gen_lowpart (SImode, operands[1]);")
2648
2649 (define_insn "*extendqisi2_mem"
2650   [(set (match_operand:SI 0 "register_operand" "=d")
2651         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2652   ""
2653   "lb\t%0,%1"
2654   [(set_attr "type"     "load")
2655    (set_attr "mode"     "SI")])
2656
2657 (define_insn "extendqisi2_hw"
2658   [(set (match_operand:SI 0 "register_operand" "=r")
2659         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2660   "ISA_HAS_SEB_SEH"
2661   "seb\t%0,%1"
2662   [(set_attr "type" "arith")
2663    (set_attr "mode" "SI")])
2664
2665 (define_expand "extendqidi2"
2666   [(set (match_operand:DI 0 "register_operand")
2667         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2668   "TARGET_64BIT"
2669   "")
2670
2671 (define_insn "*extendqidi2"
2672   [(set (match_operand:DI 0 "register_operand" "=d")
2673         (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
2674   "TARGET_64BIT"
2675   "#")
2676
2677 (define_split
2678   [(set (match_operand:DI 0 "register_operand")
2679         (sign_extend:DI (match_operand:QI 1 "register_operand")))]
2680   "TARGET_64BIT && reload_completed"
2681   [(set (match_dup 0)
2682         (ashift:DI (match_dup 1) (const_int 56)))
2683    (set (match_dup 0)
2684         (ashiftrt:DI (match_dup 0) (const_int 56)))]
2685   "operands[1] = gen_lowpart (DImode, operands[1]);")
2686
2687 (define_insn "*extendqidi2_mem"
2688   [(set (match_operand:DI 0 "register_operand" "=d")
2689         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2690   "TARGET_64BIT"
2691   "lb\t%0,%1"
2692   [(set_attr "type"     "load")
2693    (set_attr "mode"     "DI")])
2694
2695 (define_insn "extendsfdf2"
2696   [(set (match_operand:DF 0 "register_operand" "=f")
2697         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2698   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2699   "cvt.d.s\t%0,%1"
2700   [(set_attr "type"     "fcvt")
2701    (set_attr "mode"     "DF")])
2702 \f
2703 ;;
2704 ;;  ....................
2705 ;;
2706 ;;      CONVERSIONS
2707 ;;
2708 ;;  ....................
2709
2710 (define_expand "fix_truncdfsi2"
2711   [(set (match_operand:SI 0 "register_operand")
2712         (fix:SI (match_operand:DF 1 "register_operand")))]
2713   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2714 {
2715   if (!ISA_HAS_TRUNC_W)
2716     {
2717       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2718       DONE;
2719     }
2720 })
2721
2722 (define_insn "fix_truncdfsi2_insn"
2723   [(set (match_operand:SI 0 "register_operand" "=f")
2724         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2725   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2726   "trunc.w.d %0,%1"
2727   [(set_attr "type"     "fcvt")
2728    (set_attr "mode"     "DF")
2729    (set_attr "length"   "4")])
2730
2731 (define_insn "fix_truncdfsi2_macro"
2732   [(set (match_operand:SI 0 "register_operand" "=f")
2733         (fix:SI (match_operand:DF 1 "register_operand" "f")))
2734    (clobber (match_scratch:DF 2 "=d"))]
2735   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2736 {
2737   if (set_nomacro)
2738     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2739   else
2740     return "trunc.w.d %0,%1,%2";
2741 }
2742   [(set_attr "type"     "fcvt")
2743    (set_attr "mode"     "DF")
2744    (set_attr "length"   "36")])
2745
2746 (define_expand "fix_truncsfsi2"
2747   [(set (match_operand:SI 0 "register_operand")
2748         (fix:SI (match_operand:SF 1 "register_operand")))]
2749   "TARGET_HARD_FLOAT"
2750 {
2751   if (!ISA_HAS_TRUNC_W)
2752     {
2753       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2754       DONE;
2755     }
2756 })
2757
2758 (define_insn "fix_truncsfsi2_insn"
2759   [(set (match_operand:SI 0 "register_operand" "=f")
2760         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2761   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2762   "trunc.w.s %0,%1"
2763   [(set_attr "type"     "fcvt")
2764    (set_attr "mode"     "DF")
2765    (set_attr "length"   "4")])
2766
2767 (define_insn "fix_truncsfsi2_macro"
2768   [(set (match_operand:SI 0 "register_operand" "=f")
2769         (fix:SI (match_operand:SF 1 "register_operand" "f")))
2770    (clobber (match_scratch:SF 2 "=d"))]
2771   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2772 {
2773   if (set_nomacro)
2774     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2775   else
2776     return "trunc.w.s %0,%1,%2";
2777 }
2778   [(set_attr "type"     "fcvt")
2779    (set_attr "mode"     "DF")
2780    (set_attr "length"   "36")])
2781
2782
2783 (define_insn "fix_truncdfdi2"
2784   [(set (match_operand:DI 0 "register_operand" "=f")
2785         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2786   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2787   "trunc.l.d %0,%1"
2788   [(set_attr "type"     "fcvt")
2789    (set_attr "mode"     "DF")
2790    (set_attr "length"   "4")])
2791
2792
2793 (define_insn "fix_truncsfdi2"
2794   [(set (match_operand:DI 0 "register_operand" "=f")
2795         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2796   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2797   "trunc.l.s %0,%1"
2798   [(set_attr "type"     "fcvt")
2799    (set_attr "mode"     "SF")
2800    (set_attr "length"   "4")])
2801
2802
2803 (define_insn "floatsidf2"
2804   [(set (match_operand:DF 0 "register_operand" "=f")
2805         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2806   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2807   "cvt.d.w\t%0,%1"
2808   [(set_attr "type"     "fcvt")
2809    (set_attr "mode"     "DF")
2810    (set_attr "length"   "4")])
2811
2812
2813 (define_insn "floatdidf2"
2814   [(set (match_operand:DF 0 "register_operand" "=f")
2815         (float:DF (match_operand:DI 1 "register_operand" "f")))]
2816   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2817   "cvt.d.l\t%0,%1"
2818   [(set_attr "type"     "fcvt")
2819    (set_attr "mode"     "DF")
2820    (set_attr "length"   "4")])
2821
2822
2823 (define_insn "floatsisf2"
2824   [(set (match_operand:SF 0 "register_operand" "=f")
2825         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2826   "TARGET_HARD_FLOAT"
2827   "cvt.s.w\t%0,%1"
2828   [(set_attr "type"     "fcvt")
2829    (set_attr "mode"     "SF")
2830    (set_attr "length"   "4")])
2831
2832
2833 (define_insn "floatdisf2"
2834   [(set (match_operand:SF 0 "register_operand" "=f")
2835         (float:SF (match_operand:DI 1 "register_operand" "f")))]
2836   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2837   "cvt.s.l\t%0,%1"
2838   [(set_attr "type"     "fcvt")
2839    (set_attr "mode"     "SF")
2840    (set_attr "length"   "4")])
2841
2842
2843 (define_expand "fixuns_truncdfsi2"
2844   [(set (match_operand:SI 0 "register_operand")
2845         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2846   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2847 {
2848   rtx reg1 = gen_reg_rtx (DFmode);
2849   rtx reg2 = gen_reg_rtx (DFmode);
2850   rtx reg3 = gen_reg_rtx (SImode);
2851   rtx label1 = gen_label_rtx ();
2852   rtx label2 = gen_label_rtx ();
2853   REAL_VALUE_TYPE offset;
2854
2855   real_2expN (&offset, 31);
2856
2857   if (reg1)                     /* Turn off complaints about unreached code.  */
2858     {
2859       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2860       do_pending_stack_adjust ();
2861
2862       emit_insn (gen_cmpdf (operands[1], reg1));
2863       emit_jump_insn (gen_bge (label1));
2864
2865       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2866       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2867                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
2868       emit_barrier ();
2869
2870       emit_label (label1);
2871       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2872       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2873                                      (BITMASK_HIGH, SImode)));
2874
2875       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2876       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2877
2878       emit_label (label2);
2879
2880       /* Allow REG_NOTES to be set on last insn (labels don't have enough
2881          fields, and can't be used for REG_NOTES anyway).  */
2882       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2883       DONE;
2884     }
2885 })
2886
2887
2888 (define_expand "fixuns_truncdfdi2"
2889   [(set (match_operand:DI 0 "register_operand")
2890         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2891   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2892 {
2893   rtx reg1 = gen_reg_rtx (DFmode);
2894   rtx reg2 = gen_reg_rtx (DFmode);
2895   rtx reg3 = gen_reg_rtx (DImode);
2896   rtx label1 = gen_label_rtx ();
2897   rtx label2 = gen_label_rtx ();
2898   REAL_VALUE_TYPE offset;
2899
2900   real_2expN (&offset, 63);
2901
2902   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2903   do_pending_stack_adjust ();
2904
2905   emit_insn (gen_cmpdf (operands[1], reg1));
2906   emit_jump_insn (gen_bge (label1));
2907
2908   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2909   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2910                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2911   emit_barrier ();
2912
2913   emit_label (label1);
2914   emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2915   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2916   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2917
2918   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2919   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2920
2921   emit_label (label2);
2922
2923   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2924      fields, and can't be used for REG_NOTES anyway).  */
2925   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2926   DONE;
2927 })
2928
2929
2930 (define_expand "fixuns_truncsfsi2"
2931   [(set (match_operand:SI 0 "register_operand")
2932         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2933   "TARGET_HARD_FLOAT"
2934 {
2935   rtx reg1 = gen_reg_rtx (SFmode);
2936   rtx reg2 = gen_reg_rtx (SFmode);
2937   rtx reg3 = gen_reg_rtx (SImode);
2938   rtx label1 = gen_label_rtx ();
2939   rtx label2 = gen_label_rtx ();
2940   REAL_VALUE_TYPE offset;
2941
2942   real_2expN (&offset, 31);
2943
2944   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2945   do_pending_stack_adjust ();
2946
2947   emit_insn (gen_cmpsf (operands[1], reg1));
2948   emit_jump_insn (gen_bge (label1));
2949
2950   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2951   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2952                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2953   emit_barrier ();
2954
2955   emit_label (label1);
2956   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2957   emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2958                                  (BITMASK_HIGH, SImode)));
2959
2960   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2961   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2962
2963   emit_label (label2);
2964
2965   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2966      fields, and can't be used for REG_NOTES anyway).  */
2967   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2968   DONE;
2969 })
2970
2971
2972 (define_expand "fixuns_truncsfdi2"
2973   [(set (match_operand:DI 0 "register_operand")
2974         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2975   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2976 {
2977   rtx reg1 = gen_reg_rtx (SFmode);
2978   rtx reg2 = gen_reg_rtx (SFmode);
2979   rtx reg3 = gen_reg_rtx (DImode);
2980   rtx label1 = gen_label_rtx ();
2981   rtx label2 = gen_label_rtx ();
2982   REAL_VALUE_TYPE offset;
2983
2984   real_2expN (&offset, 63);
2985
2986   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2987   do_pending_stack_adjust ();
2988
2989   emit_insn (gen_cmpsf (operands[1], reg1));
2990   emit_jump_insn (gen_bge (label1));
2991
2992   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2993   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2994                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2995   emit_barrier ();
2996
2997   emit_label (label1);
2998   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2999   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3000   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3001
3002   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3003   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3004
3005   emit_label (label2);
3006
3007   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3008      fields, and can't be used for REG_NOTES anyway).  */
3009   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3010   DONE;
3011 })
3012 \f
3013 ;;
3014 ;;  ....................
3015 ;;
3016 ;;      DATA MOVEMENT
3017 ;;
3018 ;;  ....................
3019
3020 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3021
3022 (define_expand "extv"
3023   [(set (match_operand 0 "register_operand")
3024         (sign_extract (match_operand:QI 1 "memory_operand")
3025                       (match_operand 2 "immediate_operand")
3026                       (match_operand 3 "immediate_operand")))]
3027   "!TARGET_MIPS16"
3028 {
3029   if (mips_expand_unaligned_load (operands[0], operands[1],
3030                                   INTVAL (operands[2]),
3031                                   INTVAL (operands[3])))
3032     DONE;
3033   else
3034     FAIL;
3035 })
3036
3037 (define_expand "extzv"
3038   [(set (match_operand 0 "register_operand")
3039         (zero_extract (match_operand:QI 1 "memory_operand")
3040                       (match_operand 2 "immediate_operand")
3041                       (match_operand 3 "immediate_operand")))]
3042   "!TARGET_MIPS16"
3043 {
3044   if (mips_expand_unaligned_load (operands[0], operands[1],
3045                                   INTVAL (operands[2]),
3046                                   INTVAL (operands[3])))
3047     DONE;
3048   else
3049     FAIL;
3050 })
3051
3052 (define_expand "insv"
3053   [(set (zero_extract (match_operand:QI 0 "memory_operand")
3054                       (match_operand 1 "immediate_operand")
3055                       (match_operand 2 "immediate_operand"))
3056         (match_operand 3 "reg_or_0_operand"))]
3057   "!TARGET_MIPS16"
3058 {
3059   if (mips_expand_unaligned_store (operands[0], operands[3],
3060                                    INTVAL (operands[1]),
3061                                    INTVAL (operands[2])))
3062     DONE;
3063   else
3064     FAIL;
3065 })
3066
3067 ;; Unaligned word moves generated by the bit field patterns.
3068 ;;
3069 ;; As far as the rtl is concerned, both the left-part and right-part
3070 ;; instructions can access the whole field.  However, the real operand
3071 ;; refers to just the first or the last byte (depending on endianness).
3072 ;; We therefore use two memory operands to each instruction, one to
3073 ;; describe the rtl effect and one to use in the assembly output.
3074 ;;
3075 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3076 ;; This allows us to use the standard length calculations for the "load"
3077 ;; and "store" type attributes.
3078
3079 (define_insn "mov_<load>l"
3080   [(set (match_operand:GPR 0 "register_operand" "=d")
3081         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3082                      (match_operand:QI 2 "memory_operand" "m")]
3083                     UNSPEC_LOAD_LEFT))]
3084   "!TARGET_MIPS16"
3085   "<load>l\t%0,%2"
3086   [(set_attr "type" "load")
3087    (set_attr "mode" "<MODE>")
3088    (set_attr "hazard" "none")])
3089
3090 (define_insn "mov_<load>r"
3091   [(set (match_operand:GPR 0 "register_operand" "=d")
3092         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3093                      (match_operand:QI 2 "memory_operand" "m")
3094                      (match_operand:GPR 3 "register_operand" "0")]
3095                     UNSPEC_LOAD_RIGHT))]
3096   "!TARGET_MIPS16"
3097   "<load>r\t%0,%2"
3098   [(set_attr "type" "load")
3099    (set_attr "mode" "<MODE>")])
3100
3101 (define_insn "mov_<store>l"
3102   [(set (match_operand:BLK 0 "memory_operand" "=m")
3103         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3104                      (match_operand:QI 2 "memory_operand" "m")]
3105                     UNSPEC_STORE_LEFT))]
3106   "!TARGET_MIPS16"
3107   "<store>l\t%z1,%2"
3108   [(set_attr "type" "store")
3109    (set_attr "mode" "<MODE>")])
3110
3111 (define_insn "mov_<store>r"
3112   [(set (match_operand:BLK 0 "memory_operand" "+m")
3113         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3114                      (match_operand:QI 2 "memory_operand" "m")
3115                      (match_dup 0)]
3116                     UNSPEC_STORE_RIGHT))]
3117   "!TARGET_MIPS16"
3118   "<store>r\t%z1,%2"
3119   [(set_attr "type" "store")
3120    (set_attr "mode" "<MODE>")])
3121
3122 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3123 ;; The required value is:
3124 ;;
3125 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3126 ;;
3127 ;; which translates to:
3128 ;;
3129 ;;      lui     op0,%highest(op1)
3130 ;;      daddiu  op0,op0,%higher(op1)
3131 ;;      dsll    op0,op0,16
3132 ;;      daddiu  op0,op0,%hi(op1)
3133 ;;      dsll    op0,op0,16
3134 (define_insn_and_split "*lea_high64"
3135   [(set (match_operand:DI 0 "register_operand" "=d")
3136         (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3137   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3138   "#"
3139   "&& reload_completed"
3140   [(set (match_dup 0) (high:DI (match_dup 2)))
3141    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3142    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3143    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3144    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3145 {
3146   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3147   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3148 }
3149   [(set_attr "length" "20")])
3150
3151 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3152 ;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
3153 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3154 ;; used once.  We can then use the sequence:
3155 ;;
3156 ;;      lui     op0,%highest(op1)
3157 ;;      lui     op2,%hi(op1)
3158 ;;      daddiu  op0,op0,%higher(op1)
3159 ;;      daddiu  op2,op2,%lo(op1)
3160 ;;      dsll32  op0,op0,0
3161 ;;      daddu   op0,op0,op2
3162 ;;
3163 ;; which takes 4 cycles on most superscalar targets.
3164 (define_insn_and_split "*lea64"
3165   [(set (match_operand:DI 0 "register_operand" "=d")
3166         (match_operand:DI 1 "general_symbolic_operand" ""))
3167    (clobber (match_scratch:DI 2 "=&d"))]
3168   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3169   "#"
3170   "&& reload_completed"
3171   [(set (match_dup 0) (high:DI (match_dup 3)))
3172    (set (match_dup 2) (high:DI (match_dup 4)))
3173    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3174    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3175    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3176    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3177 {
3178   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3179   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3180 }
3181   [(set_attr "length" "24")])
3182
3183 ;; Insns to fetch a global symbol from a big GOT.
3184
3185 (define_insn_and_split "*xgot_hi<mode>"
3186   [(set (match_operand:P 0 "register_operand" "=d")
3187         (high:P (match_operand:P 1 "global_got_operand" "")))]
3188   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3189   "#"
3190   "&& reload_completed"
3191   [(set (match_dup 0) (high:P (match_dup 2)))
3192    (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3193 {
3194   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3195   operands[3] = pic_offset_table_rtx;
3196 }
3197   [(set_attr "got" "xgot_high")
3198    (set_attr "mode" "<MODE>")])
3199
3200 (define_insn_and_split "*xgot_lo<mode>"
3201   [(set (match_operand:P 0 "register_operand" "=d")
3202         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3203                   (match_operand:P 2 "global_got_operand" "")))]
3204   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3205   "#"
3206   "&& reload_completed"
3207   [(set (match_dup 0)
3208         (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3209   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3210   [(set_attr "got" "load")
3211    (set_attr "mode" "<MODE>")])
3212
3213 ;; Insns to fetch a global symbol from a normal GOT.
3214
3215 (define_insn_and_split "*got_disp<mode>"
3216   [(set (match_operand:P 0 "register_operand" "=d")
3217         (match_operand:P 1 "global_got_operand" ""))]
3218   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3219   "#"
3220   "&& reload_completed"
3221   [(set (match_dup 0)
3222         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3223 {
3224   operands[2] = pic_offset_table_rtx;
3225   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3226 }
3227   [(set_attr "got" "load")
3228    (set_attr "mode" "<MODE>")])
3229
3230 ;; Insns for loading the high part of a local symbol.
3231
3232 (define_insn_and_split "*got_page<mode>"
3233   [(set (match_operand:P 0 "register_operand" "=d")
3234         (high:P (match_operand:P 1 "local_got_operand" "")))]
3235   "TARGET_EXPLICIT_RELOCS"
3236   "#"
3237   "&& reload_completed"
3238   [(set (match_dup 0)
3239         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3240 {
3241   operands[2] = pic_offset_table_rtx;
3242   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3243 }
3244   [(set_attr "got" "load")
3245    (set_attr "mode" "<MODE>")])
3246
3247 ;; Lower-level instructions for loading an address from the GOT.
3248 ;; We could use MEMs, but an unspec gives more optimization
3249 ;; opportunities.
3250
3251 (define_insn "*load_got<mode>"
3252   [(set (match_operand:P 0 "register_operand" "=d")
3253         (unspec:P [(match_operand:P 1 "register_operand" "d")
3254                    (match_operand:P 2 "immediate_operand" "")]
3255                   UNSPEC_LOAD_GOT))]
3256   "TARGET_ABICALLS"
3257   "<load>\t%0,%R2(%1)"
3258   [(set_attr "type" "load")
3259    (set_attr "mode" "<MODE>")
3260    (set_attr "length" "4")])
3261
3262 ;; Instructions for adding the low 16 bits of an address to a register.
3263 ;; Operand 2 is the address: print_operand works out which relocation
3264 ;; should be applied.
3265
3266 (define_insn "*low<mode>"
3267   [(set (match_operand:P 0 "register_operand" "=d")
3268         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3269                   (match_operand:P 2 "immediate_operand" "")))]
3270   "!TARGET_MIPS16"
3271   "<d>addiu\t%0,%1,%R2"
3272   [(set_attr "type" "arith")
3273    (set_attr "mode" "<MODE>")])
3274
3275 (define_insn "*low<mode>_mips16"
3276   [(set (match_operand:P 0 "register_operand" "=d")
3277         (lo_sum:P (match_operand:P 1 "register_operand" "0")
3278                   (match_operand:P 2 "immediate_operand" "")))]
3279   "TARGET_MIPS16"
3280   "<d>addiu\t%0,%R2"
3281   [(set_attr "type" "arith")
3282    (set_attr "mode" "<MODE>")
3283    (set_attr "length" "8")])
3284
3285 ;; 64-bit integer moves
3286
3287 ;; Unlike most other insns, the move insns can't be split with
3288 ;; different predicates, because register spilling and other parts of
3289 ;; the compiler, have memoized the insn number already.
3290
3291 (define_expand "movdi"
3292   [(set (match_operand:DI 0 "")
3293         (match_operand:DI 1 ""))]
3294   ""
3295 {
3296   if (mips_legitimize_move (DImode, operands[0], operands[1]))
3297     DONE;
3298 })
3299
3300 ;; For mips16, we need a special case to handle storing $31 into
3301 ;; memory, since we don't have a constraint to match $31.  This
3302 ;; instruction can be generated by save_restore_insns.
3303
3304 (define_insn "*mov<mode>_ra"
3305   [(set (match_operand:GPR 0 "stack_operand" "=m")
3306         (reg:GPR 31))]
3307   "TARGET_MIPS16"
3308   "<store>\t$31,%0"
3309   [(set_attr "type" "store")
3310    (set_attr "mode" "<MODE>")])
3311
3312 (define_insn "*movdi_32bit"
3313   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
3314         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
3315   "!TARGET_64BIT && !TARGET_MIPS16
3316    && (register_operand (operands[0], DImode)
3317        || reg_or_0_operand (operands[1], DImode))"
3318   { return mips_output_move (operands[0], operands[1]); }
3319   [(set_attr "type"     "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3320    (set_attr "mode"     "DI")
3321    (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
3322
3323 (define_insn "*movdi_32bit_mips16"
3324   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3325         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3326   "!TARGET_64BIT && TARGET_MIPS16
3327    && (register_operand (operands[0], DImode)
3328        || register_operand (operands[1], DImode))"
3329   { return mips_output_move (operands[0], operands[1]); }
3330   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store,mfhilo")
3331    (set_attr "mode"     "DI")
3332    (set_attr "length"   "8,8,8,8,12,*,*,8")])
3333
3334 (define_insn "*movdi_64bit"
3335   [(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")
3336         (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"))]
3337   "TARGET_64BIT && !TARGET_MIPS16
3338    && (register_operand (operands[0], DImode)
3339        || reg_or_0_operand (operands[1], DImode))"
3340   { return mips_output_move (operands[0], operands[1]); }
3341   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3342    (set_attr "mode"     "DI")
3343    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3344
3345 (define_insn "*movdi_64bit_mips16"
3346   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3347         (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3348   "TARGET_64BIT && TARGET_MIPS16
3349    && (register_operand (operands[0], DImode)
3350        || register_operand (operands[1], DImode))"
3351   { return mips_output_move (operands[0], operands[1]); }
3352   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3353    (set_attr "mode"     "DI")
3354    (set_attr_alternative "length"
3355                 [(const_int 4)
3356                  (const_int 4)
3357                  (const_int 4)
3358                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3359                                (const_int 4)
3360                                (const_int 8))
3361                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3362                                (const_int 8)
3363                                (const_int 12))
3364                  (const_string "*")
3365                  (const_string "*")
3366                  (const_string "*")])])
3367
3368
3369 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3370 ;; when the original load is a 4 byte instruction but the add and the
3371 ;; load are 2 2 byte instructions.
3372
3373 (define_split
3374   [(set (match_operand:DI 0 "register_operand")
3375         (mem:DI (plus:DI (match_dup 0)
3376                          (match_operand:DI 1 "const_int_operand"))))]
3377   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3378    && !TARGET_DEBUG_D_MODE
3379    && GET_CODE (operands[0]) == REG
3380    && M16_REG_P (REGNO (operands[0]))
3381    && GET_CODE (operands[1]) == CONST_INT
3382    && ((INTVAL (operands[1]) < 0
3383         && INTVAL (operands[1]) >= -0x10)
3384        || (INTVAL (operands[1]) >= 32 * 8
3385            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3386        || (INTVAL (operands[1]) >= 0
3387            && INTVAL (operands[1]) < 32 * 8
3388            && (INTVAL (operands[1]) & 7) != 0))"
3389   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3390    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3391 {
3392   HOST_WIDE_INT val = INTVAL (operands[1]);
3393
3394   if (val < 0)
3395     operands[2] = const0_rtx;
3396   else if (val >= 32 * 8)
3397     {
3398       int off = val & 7;
3399
3400       operands[1] = GEN_INT (0x8 + off);
3401       operands[2] = GEN_INT (val - off - 0x8);
3402     }
3403   else
3404     {
3405       int off = val & 7;
3406
3407       operands[1] = GEN_INT (off);
3408       operands[2] = GEN_INT (val - off);
3409     }
3410 })
3411
3412 ;; 32-bit Integer moves
3413
3414 ;; Unlike most other insns, the move insns can't be split with
3415 ;; different predicates, because register spilling and other parts of
3416 ;; the compiler, have memoized the insn number already.
3417
3418 (define_expand "movsi"
3419   [(set (match_operand:SI 0 "")
3420         (match_operand:SI 1 ""))]
3421   ""
3422 {
3423   if (mips_legitimize_move (SImode, operands[0], operands[1]))
3424     DONE;
3425 })
3426
3427 ;; The difference between these two is whether or not ints are allowed
3428 ;; in FP registers (off by default, use -mdebugh to enable).
3429
3430 (define_insn "*movsi_internal"
3431   [(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")
3432         (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"))]
3433   "!TARGET_MIPS16
3434    && (register_operand (operands[0], SImode)
3435        || reg_or_0_operand (operands[1], SImode))"
3436   { return mips_output_move (operands[0], operands[1]); }
3437   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
3438    (set_attr "mode"     "SI")
3439    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
3440
3441 (define_insn "*movsi_mips16"
3442   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3443         (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3444   "TARGET_MIPS16
3445    && (register_operand (operands[0], SImode)
3446        || register_operand (operands[1], SImode))"
3447   { return mips_output_move (operands[0], operands[1]); }
3448   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3449    (set_attr "mode"     "SI")
3450    (set_attr_alternative "length"
3451                 [(const_int 4)
3452                  (const_int 4)
3453                  (const_int 4)
3454                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3455                                (const_int 4)
3456                                (const_int 8))
3457                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3458                                (const_int 8)
3459                                (const_int 12))
3460                  (const_string "*")
3461                  (const_string "*")
3462                  (const_string "*")])])
3463
3464 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3465 ;; when the original load is a 4 byte instruction but the add and the
3466 ;; load are 2 2 byte instructions.
3467
3468 (define_split
3469   [(set (match_operand:SI 0 "register_operand")
3470         (mem:SI (plus:SI (match_dup 0)
3471                          (match_operand:SI 1 "const_int_operand"))))]
3472   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3473    && GET_CODE (operands[0]) == REG
3474    && M16_REG_P (REGNO (operands[0]))
3475    && GET_CODE (operands[1]) == CONST_INT
3476    && ((INTVAL (operands[1]) < 0
3477         && INTVAL (operands[1]) >= -0x80)
3478        || (INTVAL (operands[1]) >= 32 * 4
3479            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3480        || (INTVAL (operands[1]) >= 0
3481            && INTVAL (operands[1]) < 32 * 4
3482            && (INTVAL (operands[1]) & 3) != 0))"
3483   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3484    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3485 {
3486   HOST_WIDE_INT val = INTVAL (operands[1]);
3487
3488   if (val < 0)
3489     operands[2] = const0_rtx;
3490   else if (val >= 32 * 4)
3491     {
3492       int off = val & 3;
3493
3494       operands[1] = GEN_INT (0x7c + off);
3495       operands[2] = GEN_INT (val - off - 0x7c);
3496     }
3497   else
3498     {
3499       int off = val & 3;
3500
3501       operands[1] = GEN_INT (off);
3502       operands[2] = GEN_INT (val - off);
3503     }
3504 })
3505
3506 ;; On the mips16, we can split a load of certain constants into a load
3507 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
3508 ;; instructions.
3509
3510 (define_split
3511   [(set (match_operand:SI 0 "register_operand")
3512         (match_operand:SI 1 "const_int_operand"))]
3513   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3514    && GET_CODE (operands[0]) == REG
3515    && M16_REG_P (REGNO (operands[0]))
3516    && GET_CODE (operands[1]) == CONST_INT
3517    && INTVAL (operands[1]) >= 0x100
3518    && INTVAL (operands[1]) <= 0xff + 0x7f"
3519   [(set (match_dup 0) (match_dup 1))
3520    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3521 {
3522   int val = INTVAL (operands[1]);
3523
3524   operands[1] = GEN_INT (0xff);
3525   operands[2] = GEN_INT (val - 0xff);
3526 })
3527
3528 ;; This insn handles moving CCmode values.  It's really just a
3529 ;; slightly simplified copy of movsi_internal2, with additional cases
3530 ;; to move a condition register to a general register and to move
3531 ;; between the general registers and the floating point registers.
3532
3533 (define_insn "movcc"
3534   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3535         (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3536   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3537   { return mips_output_move (operands[0], operands[1]); }
3538   [(set_attr "type"     "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
3539    (set_attr "mode"     "SI")
3540    (set_attr "length"   "8,4,*,*,4,4,4,*,*")])
3541
3542 ;; Reload condition code registers.  reload_incc and reload_outcc
3543 ;; both handle moves from arbitrary operands into condition code
3544 ;; registers.  reload_incc handles the more common case in which
3545 ;; a source operand is constrained to be in a condition-code
3546 ;; register, but has not been allocated to one.
3547 ;;
3548 ;; Sometimes, such as in movcc, we have a CCmode destination whose
3549 ;; constraints do not include 'z'.  reload_outcc handles the case
3550 ;; when such an operand is allocated to a condition-code register.
3551 ;;
3552 ;; Note that reloads from a condition code register to some
3553 ;; other location can be done using ordinary moves.  Moving
3554 ;; into a GPR takes a single movcc, moving elsewhere takes
3555 ;; two.  We can leave these cases to the generic reload code.
3556 (define_expand "reload_incc"
3557   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3558         (match_operand:CC 1 "general_operand" ""))
3559    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3560   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3561 {
3562   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3563   DONE;
3564 })
3565
3566 (define_expand "reload_outcc"
3567   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3568         (match_operand:CC 1 "register_operand" ""))
3569    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3570   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3571 {
3572   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3573   DONE;
3574 })
3575
3576 ;; MIPS4 supports loading and storing a floating point register from
3577 ;; the sum of two general registers.  We use two versions for each of
3578 ;; these four instructions: one where the two general registers are
3579 ;; SImode, and one where they are DImode.  This is because general
3580 ;; registers will be in SImode when they hold 32 bit values, but,
3581 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3582 ;; instructions will still work correctly.
3583
3584 ;; ??? Perhaps it would be better to support these instructions by
3585 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
3586 ;; these instructions can only be used to load and store floating
3587 ;; point registers, that would probably cause trouble in reload.
3588
3589 (define_insn "*<ANYF:loadx>_<P:mode>"
3590   [(set (match_operand:ANYF 0 "register_operand" "=f")
3591         (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3592                           (match_operand:P 2 "register_operand" "d"))))]
3593   "ISA_HAS_FP4"
3594   "<ANYF:loadx>\t%0,%1(%2)"
3595   [(set_attr "type" "fpidxload")
3596    (set_attr "mode" "<ANYF:UNITMODE>")])
3597
3598 (define_insn "*<ANYF:storex>_<P:mode>"
3599   [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3600                           (match_operand:P 2 "register_operand" "d")))
3601         (match_operand:ANYF 0 "register_operand" "f"))]
3602   "ISA_HAS_FP4"
3603   "<ANYF:storex>\t%0,%1(%2)"
3604   [(set_attr "type" "fpidxstore")
3605    (set_attr "mode" "<ANYF:UNITMODE>")])
3606
3607 ;; 16-bit Integer moves
3608
3609 ;; Unlike most other insns, the move insns can't be split with
3610 ;; different predicates, because register spilling and other parts of
3611 ;; the compiler, have memoized the insn number already.
3612 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3613
3614 (define_expand "movhi"
3615   [(set (match_operand:HI 0 "")
3616         (match_operand:HI 1 ""))]
3617   ""
3618 {
3619   if (mips_legitimize_move (HImode, operands[0], operands[1]))
3620     DONE;
3621 })
3622
3623 (define_insn "*movhi_internal"
3624   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3625         (match_operand:HI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3626   "!TARGET_MIPS16
3627    && (register_operand (operands[0], HImode)
3628        || reg_or_0_operand (operands[1], HImode))"
3629   "@
3630     move\t%0,%1
3631     li\t%0,%1
3632     lhu\t%0,%1
3633     sh\t%z1,%0
3634     mfc1\t%0,%1
3635     mtc1\t%1,%0
3636     mov.s\t%0,%1
3637     mt%0\t%1"
3638   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3639    (set_attr "mode"     "HI")
3640    (set_attr "length"   "4,4,*,*,4,4,4,4")])
3641
3642 (define_insn "*movhi_mips16"
3643   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3644         (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3645   "TARGET_MIPS16
3646    && (register_operand (operands[0], HImode)
3647        || register_operand (operands[1], HImode))"
3648   "@
3649     move\t%0,%1
3650     move\t%0,%1
3651     move\t%0,%1
3652     li\t%0,%1
3653     #
3654     lhu\t%0,%1
3655     sh\t%1,%0"
3656   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
3657    (set_attr "mode"     "HI")
3658    (set_attr_alternative "length"
3659                 [(const_int 4)
3660                  (const_int 4)
3661                  (const_int 4)
3662                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3663                                (const_int 4)
3664                                (const_int 8))
3665                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3666                                (const_int 8)
3667                                (const_int 12))
3668                  (const_string "*")
3669                  (const_string "*")])])
3670
3671
3672 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
3673 ;; when the original load is a 4 byte instruction but the add and the
3674 ;; load are 2 2 byte instructions.
3675
3676 (define_split
3677   [(set (match_operand:HI 0 "register_operand")
3678         (mem:HI (plus:SI (match_dup 0)
3679                          (match_operand:SI 1 "const_int_operand"))))]
3680   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3681    && GET_CODE (operands[0]) == REG
3682    && M16_REG_P (REGNO (operands[0]))
3683    && GET_CODE (operands[1]) == CONST_INT
3684    && ((INTVAL (operands[1]) < 0
3685         && INTVAL (operands[1]) >= -0x80)
3686        || (INTVAL (operands[1]) >= 32 * 2
3687            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3688        || (INTVAL (operands[1]) >= 0
3689            && INTVAL (operands[1]) < 32 * 2
3690            && (INTVAL (operands[1]) & 1) != 0))"
3691   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3692    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3693 {
3694   HOST_WIDE_INT val = INTVAL (operands[1]);
3695
3696   if (val < 0)
3697     operands[2] = const0_rtx;
3698   else if (val >= 32 * 2)
3699     {
3700       int off = val & 1;
3701
3702       operands[1] = GEN_INT (0x7e + off);
3703       operands[2] = GEN_INT (val - off - 0x7e);
3704     }
3705   else
3706     {
3707       int off = val & 1;
3708
3709       operands[1] = GEN_INT (off);
3710       operands[2] = GEN_INT (val - off);
3711     }
3712 })
3713
3714 ;; 8-bit Integer moves
3715
3716 ;; Unlike most other insns, the move insns can't be split with
3717 ;; different predicates, because register spilling and other parts of
3718 ;; the compiler, have memoized the insn number already.
3719 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3720
3721 (define_expand "movqi"
3722   [(set (match_operand:QI 0 "")
3723         (match_operand:QI 1 ""))]
3724   ""
3725 {
3726   if (mips_legitimize_move (QImode, operands[0], operands[1]))
3727     DONE;
3728 })
3729
3730 (define_insn "*movqi_internal"
3731   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3732         (match_operand:QI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3733   "!TARGET_MIPS16
3734    && (register_operand (operands[0], QImode)
3735        || reg_or_0_operand (operands[1], QImode))"
3736   "@
3737     move\t%0,%1
3738     li\t%0,%1
3739     lbu\t%0,%1
3740     sb\t%z1,%0
3741     mfc1\t%0,%1
3742     mtc1\t%1,%0
3743     mov.s\t%0,%1
3744     mt%0\t%1"
3745   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3746    (set_attr "mode"     "QI")
3747    (set_attr "length"   "4,4,*,*,4,4,4,4")])
3748
3749 (define_insn "*movqi_mips16"
3750   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3751         (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3752   "TARGET_MIPS16
3753    && (register_operand (operands[0], QImode)
3754        || register_operand (operands[1], QImode))"
3755   "@
3756     move\t%0,%1
3757     move\t%0,%1
3758     move\t%0,%1
3759     li\t%0,%1
3760     #
3761     lbu\t%0,%1
3762     sb\t%1,%0"
3763   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
3764    (set_attr "mode"     "QI")
3765    (set_attr "length"   "4,4,4,4,8,*,*")])
3766
3767 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
3768 ;; when the original load is a 4 byte instruction but the add and the
3769 ;; load are 2 2 byte instructions.
3770
3771 (define_split
3772   [(set (match_operand:QI 0 "register_operand")
3773         (mem:QI (plus:SI (match_dup 0)
3774                          (match_operand:SI 1 "const_int_operand"))))]
3775   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3776    && GET_CODE (operands[0]) == REG
3777    && M16_REG_P (REGNO (operands[0]))
3778    && GET_CODE (operands[1]) == CONST_INT
3779    && ((INTVAL (operands[1]) < 0
3780         && INTVAL (operands[1]) >= -0x80)
3781        || (INTVAL (operands[1]) >= 32
3782            && INTVAL (operands[1]) <= 31 + 0x7f))"
3783   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3784    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3785 {
3786   HOST_WIDE_INT val = INTVAL (operands[1]);
3787
3788   if (val < 0)
3789     operands[2] = const0_rtx;
3790   else
3791     {
3792       operands[1] = GEN_INT (0x7f);
3793       operands[2] = GEN_INT (val - 0x7f);
3794     }
3795 })
3796
3797 ;; 32-bit floating point moves
3798
3799 (define_expand "movsf"
3800   [(set (match_operand:SF 0 "")
3801         (match_operand:SF 1 ""))]
3802   ""
3803 {
3804   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3805     DONE;
3806 })
3807
3808 (define_insn "*movsf_hardfloat"
3809   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3810         (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
3811   "TARGET_HARD_FLOAT
3812    && (register_operand (operands[0], SFmode)
3813        || reg_or_0_operand (operands[1], SFmode))"
3814   { return mips_output_move (operands[0], operands[1]); }
3815   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
3816    (set_attr "mode"     "SF")
3817    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
3818
3819 (define_insn "*movsf_softfloat"
3820   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3821         (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3822   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3823    && (register_operand (operands[0], SFmode)
3824        || reg_or_0_operand (operands[1], SFmode))"
3825   { return mips_output_move (operands[0], operands[1]); }
3826   [(set_attr "type"     "arith,load,store")
3827    (set_attr "mode"     "SF")
3828    (set_attr "length"   "4,*,*")])
3829
3830 (define_insn "*movsf_mips16"
3831   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3832         (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3833   "TARGET_MIPS16
3834    && (register_operand (operands[0], SFmode)
3835        || register_operand (operands[1], SFmode))"
3836   { return mips_output_move (operands[0], operands[1]); }
3837   [(set_attr "type"     "arith,arith,arith,load,store")
3838    (set_attr "mode"     "SF")
3839    (set_attr "length"   "4,4,4,*,*")])
3840
3841
3842 ;; 64-bit floating point moves
3843
3844 (define_expand "movdf"
3845   [(set (match_operand:DF 0 "")
3846         (match_operand:DF 1 ""))]
3847   ""
3848 {
3849   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3850     DONE;
3851 })
3852
3853 (define_insn "*movdf_hardfloat_64bit"
3854   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3855         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
3856   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
3857    && (register_operand (operands[0], DFmode)
3858        || reg_or_0_operand (operands[1], DFmode))"
3859   { return mips_output_move (operands[0], operands[1]); }
3860   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
3861    (set_attr "mode"     "DF")
3862    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
3863
3864 (define_insn "*movdf_hardfloat_32bit"
3865   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3866         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
3867   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
3868    && (register_operand (operands[0], DFmode)
3869        || reg_or_0_operand (operands[1], DFmode))"
3870   { return mips_output_move (operands[0], operands[1]); }
3871   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
3872    (set_attr "mode"     "DF")
3873    (set_attr "length"   "4,8,*,*,8,8,8,*,*")])
3874
3875 (define_insn "*movdf_softfloat"
3876   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
3877         (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
3878   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
3879    && (register_operand (operands[0], DFmode)
3880        || reg_or_0_operand (operands[1], DFmode))"
3881   { return mips_output_move (operands[0], operands[1]); }
3882   [(set_attr "type"     "arith,load,store,xfer,xfer,fmove")
3883    (set_attr "mode"     "DF")
3884    (set_attr "length"   "8,*,*,4,4,4")])
3885
3886 (define_insn "*movdf_mips16"
3887   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
3888         (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
3889   "TARGET_MIPS16
3890    && (register_operand (operands[0], DFmode)
3891        || register_operand (operands[1], DFmode))"
3892   { return mips_output_move (operands[0], operands[1]); }
3893   [(set_attr "type"     "arith,arith,arith,load,store")
3894    (set_attr "mode"     "DF")
3895    (set_attr "length"   "8,8,8,*,*")])
3896
3897 (define_split
3898   [(set (match_operand:DI 0 "nonimmediate_operand")
3899         (match_operand:DI 1 "move_operand"))]
3900   "reload_completed && !TARGET_64BIT
3901    && mips_split_64bit_move_p (operands[0], operands[1])"
3902   [(const_int 0)]
3903 {
3904   mips_split_64bit_move (operands[0], operands[1]);
3905   DONE;
3906 })
3907
3908 (define_split
3909   [(set (match_operand:DF 0 "nonimmediate_operand")
3910         (match_operand:DF 1 "move_operand"))]
3911   "reload_completed && !TARGET_64BIT
3912    && mips_split_64bit_move_p (operands[0], operands[1])"
3913   [(const_int 0)]
3914 {
3915   mips_split_64bit_move (operands[0], operands[1]);
3916   DONE;
3917 })
3918
3919 ;; When generating mips16 code, split moves of negative constants into
3920 ;; a positive "li" followed by a negation.
3921 (define_split
3922   [(set (match_operand 0 "register_operand")
3923         (match_operand 1 "const_int_operand"))]
3924   "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
3925   [(set (match_dup 2)
3926         (match_dup 3))
3927    (set (match_dup 2)
3928         (neg:SI (match_dup 2)))]
3929 {
3930   operands[2] = gen_lowpart (SImode, operands[0]);
3931   operands[3] = GEN_INT (-INTVAL (operands[1]));
3932 })
3933
3934 ;; 64-bit paired-single floating point moves
3935
3936 (define_expand "movv2sf"
3937   [(set (match_operand:V2SF 0)
3938         (match_operand:V2SF 1))]
3939   "TARGET_PAIRED_SINGLE_FLOAT"
3940 {
3941   if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
3942     DONE;
3943 })
3944
3945 (define_insn "movv2sf_hardfloat_64bit"
3946   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3947         (match_operand:V2SF 1 "move_operand" "f,YG,m,fYG,*d,*f,*d*YG,*m,*d"))]
3948   "TARGET_PAIRED_SINGLE_FLOAT
3949    && TARGET_64BIT
3950    && (register_operand (operands[0], V2SFmode)
3951        || reg_or_0_operand (operands[1], V2SFmode))"
3952   { return mips_output_move (operands[0], operands[1]); }
3953   [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
3954    (set_attr "mode" "SF")
3955    (set_attr "length" "4,4,*,*,4,4,4,*,*")])
3956
3957 ;; The HI and LO registers are not truly independent.  If we move an mthi
3958 ;; instruction before an mflo instruction, it will make the result of the
3959 ;; mflo unpredictable.  The same goes for mtlo and mfhi.
3960 ;;
3961 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
3962 ;; Operand 1 is the register we want, operand 2 is the other one.
3963
3964 (define_insn "mfhilo_<mode>"
3965   [(set (match_operand:GPR 0 "register_operand" "=d,d")
3966         (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
3967                      (match_operand:GPR 2 "register_operand" "l,h")]
3968                     UNSPEC_MFHILO))]
3969   ""
3970   "mf%1\t%0"
3971   [(set_attr "type" "mfhilo")
3972    (set_attr "mode" "<MODE>")])
3973
3974 ;; Patterns for loading or storing part of a paired floating point
3975 ;; register.  We need them because odd-numbered floating-point registers
3976 ;; are not fully independent: see mips_split_64bit_move.
3977
3978 ;; Load the low word of operand 0 with operand 1.
3979 (define_insn "load_df_low"
3980   [(set (match_operand:DF 0 "register_operand" "=f,f")
3981         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
3982                    UNSPEC_LOAD_DF_LOW))]
3983   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3984 {
3985   operands[0] = mips_subword (operands[0], 0);
3986   return mips_output_move (operands[0], operands[1]);
3987 }
3988   [(set_attr "type"     "xfer,fpload")
3989    (set_attr "mode"     "SF")])
3990
3991 ;; Load the high word of operand 0 from operand 1, preserving the value
3992 ;; in the low word.
3993 (define_insn "load_df_high"
3994   [(set (match_operand:DF 0 "register_operand" "=f,f")
3995         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
3996                     (match_operand:DF 2 "register_operand" "0,0")]
3997                    UNSPEC_LOAD_DF_HIGH))]
3998   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3999 {
4000   operands[0] = mips_subword (operands[0], 1);
4001   return mips_output_move (operands[0], operands[1]);
4002 }
4003   [(set_attr "type"     "xfer,fpload")
4004    (set_attr "mode"     "SF")])
4005
4006 ;; Store the high word of operand 1 in operand 0.  The corresponding
4007 ;; low-word move is done in the normal way.
4008 (define_insn "store_df_high"
4009   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4010         (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4011                    UNSPEC_STORE_DF_HIGH))]
4012   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4013 {
4014   operands[1] = mips_subword (operands[1], 1);
4015   return mips_output_move (operands[0], operands[1]);
4016 }
4017   [(set_attr "type"     "xfer,fpstore")
4018    (set_attr "mode"     "SF")])
4019
4020 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
4021 ;; of _gp from the start of this function.  Operand 1 is the incoming
4022 ;; function address.
4023 (define_insn_and_split "loadgp"
4024   [(unspec_volatile [(match_operand 0 "" "")
4025                      (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4026   "TARGET_ABICALLS && TARGET_NEWABI"
4027   "#"
4028   ""
4029   [(set (match_dup 2) (match_dup 3))
4030    (set (match_dup 2) (match_dup 4))
4031    (set (match_dup 2) (match_dup 5))]
4032 {
4033   operands[2] = pic_offset_table_rtx;
4034   operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4035   operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4036   operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4037 }
4038   [(set_attr "length" "12")])
4039
4040 ;; The use of gp is hidden when not using explicit relocations.
4041 ;; This blockage instruction prevents the gp load from being
4042 ;; scheduled after an implicit use of gp.  It also prevents
4043 ;; the load from being deleted as dead.
4044 (define_insn "loadgp_blockage"
4045   [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4046   ""
4047   ""
4048   [(set_attr "type"     "unknown")
4049    (set_attr "mode"     "none")
4050    (set_attr "length"   "0")])
4051
4052 ;; Emit a .cprestore directive, which normally expands to a single store
4053 ;; instruction.  Note that we continue to use .cprestore for explicit reloc
4054 ;; code so that jals inside inline asms will work correctly.
4055 (define_insn "cprestore"
4056   [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4057                     UNSPEC_CPRESTORE)]
4058   ""
4059 {
4060   if (set_nomacro && which_alternative == 1)
4061     return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4062   else
4063     return ".cprestore\t%0";
4064 }
4065   [(set_attr "type" "store")
4066    (set_attr "length" "4,12")])
4067 \f
4068 ;; Block moves, see mips.c for more details.
4069 ;; Argument 0 is the destination
4070 ;; Argument 1 is the source
4071 ;; Argument 2 is the length
4072 ;; Argument 3 is the alignment
4073
4074 (define_expand "movmemsi"
4075   [(parallel [(set (match_operand:BLK 0 "general_operand")
4076                    (match_operand:BLK 1 "general_operand"))
4077               (use (match_operand:SI 2 ""))
4078               (use (match_operand:SI 3 "const_int_operand"))])]
4079   "!TARGET_MIPS16 && !TARGET_MEMCPY"
4080 {
4081   if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4082     DONE;
4083   else
4084     FAIL;
4085 })
4086 \f
4087 ;;
4088 ;;  ....................
4089 ;;
4090 ;;      SHIFTS
4091 ;;
4092 ;;  ....................
4093
4094 (define_expand "<optab><mode>3"
4095   [(set (match_operand:GPR 0 "register_operand")
4096         (any_shift:GPR (match_operand:GPR 1 "register_operand")
4097                        (match_operand:SI 2 "arith_operand")))]
4098   ""
4099 {
4100   /* On the mips16, a shift of more than 8 is a four byte instruction,
4101      so, for a shift between 8 and 16, it is just as fast to do two
4102      shifts of 8 or less.  If there is a lot of shifting going on, we
4103      may win in CSE.  Otherwise combine will put the shifts back
4104      together again.  This can be called by function_arg, so we must
4105      be careful not to allocate a new register if we've reached the
4106      reload pass.  */
4107   if (TARGET_MIPS16
4108       && optimize
4109       && GET_CODE (operands[2]) == CONST_INT
4110       && INTVAL (operands[2]) > 8
4111       && INTVAL (operands[2]) <= 16
4112       && !reload_in_progress
4113       && !reload_completed)
4114     {
4115       rtx temp = gen_reg_rtx (<MODE>mode);
4116
4117       emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
4118       emit_insn (gen_<optab><mode>3 (operands[0], temp,
4119                                      GEN_INT (INTVAL (operands[2]) - 8)));
4120       DONE;
4121     }
4122 })
4123
4124 (define_insn "*<optab><mode>3"
4125   [(set (match_operand:GPR 0 "register_operand" "=d")
4126         (any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
4127                        (match_operand:SI 2 "arith_operand" "dI")))]
4128   "!TARGET_MIPS16"
4129 {
4130   if (GET_CODE (operands[2]) == CONST_INT)
4131     operands[2] = GEN_INT (INTVAL (operands[2])
4132                            & (GET_MODE_BITSIZE (<MODE>mode) - 1));
4133
4134   return "<d><insn>\t%0,%1,%2";
4135 }
4136   [(set_attr "type" "shift")
4137    (set_attr "mode" "<MODE>")])
4138
4139 (define_insn "*<optab>si3_extend"
4140   [(set (match_operand:DI 0 "register_operand" "=d")
4141         (sign_extend:DI
4142            (any_shift:SI (match_operand:SI 1 "register_operand" "d")
4143                          (match_operand:SI 2 "arith_operand" "dI"))))]
4144   "TARGET_64BIT && !TARGET_MIPS16"
4145 {
4146   if (GET_CODE (operands[2]) == CONST_INT)
4147     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4148
4149   return "<insn>\t%0,%1,%2";
4150 }
4151   [(set_attr "type" "shift")
4152    (set_attr "mode" "SI")])
4153
4154 (define_insn "*<optab>si3_mips16"
4155   [(set (match_operand:SI 0 "register_operand" "=d,d")
4156         (any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
4157                       (match_operand:SI 2 "arith_operand" "d,I")))]
4158   "TARGET_MIPS16"
4159 {
4160   if (which_alternative == 0)
4161     return "<insn>\t%0,%2";
4162
4163   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4164   return "<insn>\t%0,%1,%2";
4165 }
4166   [(set_attr "type" "shift")
4167    (set_attr "mode" "SI")
4168    (set_attr_alternative "length"
4169                 [(const_int 4)
4170                  (if_then_else (match_operand 2 "m16_uimm3_b")
4171                                (const_int 4)
4172                                (const_int 8))])])
4173
4174 ;; We need separate DImode MIPS16 patterns because of the irregularity
4175 ;; of right shifts.
4176 (define_insn "*ashldi3_mips16"
4177   [(set (match_operand:DI 0 "register_operand" "=d,d")
4178         (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4179                    (match_operand:SI 2 "arith_operand" "d,I")))]
4180   "TARGET_64BIT && TARGET_MIPS16"
4181 {
4182   if (which_alternative == 0)
4183     return "dsll\t%0,%2";
4184
4185   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4186   return "dsll\t%0,%1,%2";
4187 }
4188   [(set_attr "type" "shift")
4189    (set_attr "mode" "DI")
4190    (set_attr_alternative "length"
4191                 [(const_int 4)
4192                  (if_then_else (match_operand 2 "m16_uimm3_b")
4193                                (const_int 4)
4194                                (const_int 8))])])
4195
4196 (define_insn "*ashrdi3_mips16"
4197   [(set (match_operand:DI 0 "register_operand" "=d,d")
4198         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4199                      (match_operand:SI 2 "arith_operand" "d,I")))]
4200   "TARGET_64BIT && TARGET_MIPS16"
4201 {
4202   if (GET_CODE (operands[2]) == CONST_INT)
4203     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4204
4205   return "dsra\t%0,%2";
4206 }
4207   [(set_attr "type" "shift")
4208    (set_attr "mode" "DI")
4209    (set_attr_alternative "length"
4210                 [(const_int 4)
4211                  (if_then_else (match_operand 2 "m16_uimm3_b")
4212                                (const_int 4)
4213                                (const_int 8))])])
4214
4215 (define_insn "*lshrdi3_mips16"
4216   [(set (match_operand:DI 0 "register_operand" "=d,d")
4217         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4218                      (match_operand:SI 2 "arith_operand" "d,I")))]
4219   "TARGET_64BIT && TARGET_MIPS16"
4220 {
4221   if (GET_CODE (operands[2]) == CONST_INT)
4222     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4223
4224   return "dsrl\t%0,%2";
4225 }
4226   [(set_attr "type" "shift")
4227    (set_attr "mode" "DI")
4228    (set_attr_alternative "length"
4229                 [(const_int 4)
4230                  (if_then_else (match_operand 2 "m16_uimm3_b")
4231                                (const_int 4)
4232                                (const_int 8))])])
4233
4234 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4235
4236 (define_split
4237   [(set (match_operand:GPR 0 "register_operand")
4238         (any_shift:GPR (match_operand:GPR 1 "register_operand")
4239                        (match_operand:GPR 2 "const_int_operand")))]
4240   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4241    && GET_CODE (operands[2]) == CONST_INT
4242    && INTVAL (operands[2]) > 8
4243    && INTVAL (operands[2]) <= 16"
4244   [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
4245    (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
4246   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4247
4248 ;; If we load a byte on the mips16 as a bitfield, the resulting
4249 ;; sequence of instructions is too complicated for combine, because it
4250 ;; involves four instructions: a load, a shift, a constant load into a
4251 ;; register, and an and (the key problem here is that the mips16 does
4252 ;; not have and immediate).  We recognize a shift of a load in order
4253 ;; to make it simple enough for combine to understand.
4254 ;;
4255 ;; The length here is the worst case: the length of the split version
4256 ;; will be more accurate.
4257 (define_insn_and_split ""
4258   [(set (match_operand:SI 0 "register_operand" "=d")
4259         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4260                      (match_operand:SI 2 "immediate_operand" "I")))]
4261   "TARGET_MIPS16"
4262   "#"
4263   ""
4264   [(set (match_dup 0) (match_dup 1))
4265    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4266   ""
4267   [(set_attr "type"     "load")
4268    (set_attr "mode"     "SI")
4269    (set_attr "length"   "16")])
4270
4271 (define_insn "rotr<mode>3"
4272   [(set (match_operand:GPR 0 "register_operand" "=d")
4273         (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
4274                       (match_operand:SI 2 "arith_operand" "dI")))]
4275   "ISA_HAS_ROTR_<MODE>"
4276 {
4277   if ((GET_CODE (operands[2]) == CONST_INT)
4278       && (INTVAL (operands[2]) < 0
4279           || INTVAL (operands[2]) >= GET_MODE_BITSIZE (<MODE>mode)))
4280     abort ();
4281
4282   return "<d>ror\t%0,%1,%2";
4283 }
4284   [(set_attr "type" "shift")
4285    (set_attr "mode" "<MODE>")])
4286 \f
4287 ;;
4288 ;;  ....................
4289 ;;
4290 ;;      COMPARISONS
4291 ;;
4292 ;;  ....................
4293
4294 ;; Flow here is rather complex:
4295 ;;
4296 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the arguments
4297 ;;      into cmp_operands[] but generates no RTL.
4298 ;;
4299 ;;  2)  The appropriate branch define_expand is called, which then
4300 ;;      creates the appropriate RTL for the comparison and branch.
4301 ;;      Different CC modes are used, based on what type of branch is
4302 ;;      done, so that we can constrain things appropriately.  There
4303 ;;      are assumptions in the rest of GCC that break if we fold the
4304 ;;      operands into the branches for integer operations, and use cc0
4305 ;;      for floating point, so we use the fp status register instead.
4306 ;;      If needed, an appropriate temporary is created to hold the
4307 ;;      of the integer compare.
4308
4309 (define_expand "cmp<mode>"
4310   [(set (cc0)
4311         (compare:CC (match_operand:GPR 0 "register_operand")
4312                     (match_operand:GPR 1 "nonmemory_operand")))]
4313   ""
4314 {
4315   cmp_operands[0] = operands[0];
4316   cmp_operands[1] = operands[1];
4317   DONE;
4318 })
4319
4320 (define_expand "cmpdf"
4321   [(set (cc0)
4322         (compare:CC (match_operand:DF 0 "register_operand")
4323                     (match_operand:DF 1 "register_operand")))]
4324   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4325 {
4326   cmp_operands[0] = operands[0];
4327   cmp_operands[1] = operands[1];
4328   DONE;
4329 })
4330
4331 (define_expand "cmpsf"
4332   [(set (cc0)
4333         (compare:CC (match_operand:SF 0 "register_operand")
4334                     (match_operand:SF 1 "register_operand")))]
4335   "TARGET_HARD_FLOAT"
4336 {
4337   cmp_operands[0] = operands[0];
4338   cmp_operands[1] = operands[1];
4339   DONE;
4340 })
4341 \f
4342 ;;
4343 ;;  ....................
4344 ;;
4345 ;;      CONDITIONAL BRANCHES
4346 ;;
4347 ;;  ....................
4348
4349 ;; Conditional branches on floating-point equality tests.
4350
4351 (define_insn "branch_fp"
4352   [(set (pc)
4353         (if_then_else
4354          (match_operator:CC 0 "comparison_operator"
4355                             [(match_operand:CC 2 "register_operand" "z")
4356                              (const_int 0)])
4357          (label_ref (match_operand 1 "" ""))
4358          (pc)))]
4359   "TARGET_HARD_FLOAT"
4360 {
4361   return mips_output_conditional_branch (insn,
4362                                          operands,
4363                                          /*two_operands_p=*/0,
4364                                          /*float_p=*/1,
4365                                          /*inverted_p=*/0,
4366                                          get_attr_length (insn));
4367 }
4368   [(set_attr "type"     "branch")
4369    (set_attr "mode"     "none")])
4370
4371 (define_insn "branch_fp_inverted"
4372   [(set (pc)
4373         (if_then_else
4374          (match_operator:CC 0 "comparison_operator"
4375                             [(match_operand:CC 2 "register_operand" "z")
4376                              (const_int 0)])
4377          (pc)
4378          (label_ref (match_operand 1 "" ""))))]
4379   "TARGET_HARD_FLOAT"
4380 {
4381   return mips_output_conditional_branch (insn,
4382                                          operands,
4383                                          /*two_operands_p=*/0,
4384                                          /*float_p=*/1,
4385                                          /*inverted_p=*/1,
4386                                          get_attr_length (insn));
4387 }
4388   [(set_attr "type"     "branch")
4389    (set_attr "mode"     "none")])
4390
4391 ;; Conditional branches on comparisons with zero.
4392
4393 (define_insn "*branch_zero<mode>"
4394   [(set (pc)
4395         (if_then_else
4396          (match_operator:GPR 0 "comparison_operator"
4397                              [(match_operand:GPR 2 "register_operand" "d")
4398                               (const_int 0)])
4399          (label_ref (match_operand 1 "" ""))
4400          (pc)))]
4401   "!TARGET_MIPS16"
4402 {
4403   return mips_output_conditional_branch (insn,
4404                                          operands,
4405                                          /*two_operands_p=*/0,
4406                                          /*float_p=*/0,
4407                                          /*inverted_p=*/0,
4408                                          get_attr_length (insn));
4409 }
4410   [(set_attr "type" "branch")
4411    (set_attr "mode" "none")])
4412
4413 (define_insn "*branch_zero<mode>_inverted"
4414   [(set (pc)
4415         (if_then_else
4416          (match_operator:GPR 0 "comparison_operator"
4417                              [(match_operand:GPR 2 "register_operand" "d")
4418                               (const_int 0)])
4419          (pc)
4420          (label_ref (match_operand 1 "" ""))))]
4421   "!TARGET_MIPS16"
4422 {
4423   return mips_output_conditional_branch (insn,
4424                                          operands,
4425                                          /*two_operands_p=*/0,
4426                                          /*float_p=*/0,
4427                                          /*inverted_p=*/1,
4428                                          get_attr_length (insn));
4429 }
4430   [(set_attr "type" "branch")
4431    (set_attr "mode" "none")])
4432
4433 ;; Conditional branch on equality comparison.
4434
4435 (define_insn "*branch_equality<mode>"
4436   [(set (pc)
4437         (if_then_else
4438          (match_operator:GPR 0 "equality_operator"
4439                              [(match_operand:GPR 2 "register_operand" "d")
4440                               (match_operand:GPR 3 "register_operand" "d")])
4441          (label_ref (match_operand 1 "" ""))
4442          (pc)))]
4443   "!TARGET_MIPS16"
4444 {
4445   return mips_output_conditional_branch (insn,
4446                                          operands,
4447                                          /*two_operands_p=*/1,
4448                                          /*float_p=*/0,
4449                                          /*inverted_p=*/0,
4450                                          get_attr_length (insn));
4451 }
4452   [(set_attr "type" "branch")
4453    (set_attr "mode" "none")])
4454
4455 (define_insn "*branch_equality<mode>_inverted"
4456   [(set (pc)
4457         (if_then_else
4458          (match_operator:GPR 0 "equality_operator"
4459                              [(match_operand:GPR 2 "register_operand" "d")
4460                               (match_operand:GPR 3 "register_operand" "d")])
4461          (pc)
4462          (label_ref (match_operand 1 "" ""))))]
4463   "!TARGET_MIPS16"
4464 {
4465   return mips_output_conditional_branch (insn,
4466                                          operands,
4467                                          /*two_operands_p=*/1,
4468                                          /*float_p=*/0,
4469                                          /*inverted_p=*/1,
4470                                          get_attr_length (insn));
4471 }
4472   [(set_attr "type" "branch")
4473    (set_attr "mode" "none")])
4474
4475 ;; MIPS16 branches
4476
4477 (define_insn "*branch_equality<mode>_mips16"
4478   [(set (pc)
4479         (if_then_else
4480          (match_operator:GPR 0 "equality_operator"
4481                              [(match_operand:GPR 1 "register_operand" "d,t")
4482                               (const_int 0)])
4483          (match_operand 2 "pc_or_label_operand" "")
4484          (match_operand 3 "pc_or_label_operand" "")))]
4485   "TARGET_MIPS16"
4486 {
4487   if (operands[2] != pc_rtx)
4488     {
4489       if (which_alternative == 0)
4490         return "b%C0z\t%1,%2";
4491       else
4492         return "bt%C0z\t%2";
4493     }
4494   else
4495     {
4496       if (which_alternative == 0)
4497         return "b%N0z\t%1,%3";
4498       else
4499         return "bt%N0z\t%3";
4500     }
4501 }
4502   [(set_attr "type" "branch")
4503    (set_attr "mode" "none")
4504    (set_attr "length" "8")])
4505
4506 (define_expand "b<code>"
4507   [(set (pc)
4508         (if_then_else (any_cond:CC (cc0)
4509                                    (const_int 0))
4510                       (label_ref (match_operand 0 ""))
4511                       (pc)))]
4512   ""
4513 {
4514   gen_conditional_branch (operands, <CODE>);
4515   DONE;
4516 })
4517 \f
4518 ;;
4519 ;;  ....................
4520 ;;
4521 ;;      SETTING A REGISTER FROM A COMPARISON
4522 ;;
4523 ;;  ....................
4524
4525 (define_expand "seq"
4526   [(set (match_operand:SI 0 "register_operand")
4527         (eq:SI (match_dup 1)
4528                (match_dup 2)))]
4529   ""
4530   { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
4531
4532 (define_insn "*seq_<mode>"
4533   [(set (match_operand:GPR 0 "register_operand" "=d")
4534         (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4535                 (const_int 0)))]
4536   "!TARGET_MIPS16"
4537   "sltu\t%0,%1,1"
4538   [(set_attr "type" "slt")
4539    (set_attr "mode" "<MODE>")])
4540
4541 (define_insn "*seq_<mode>_mips16"
4542   [(set (match_operand:GPR 0 "register_operand" "=t")
4543         (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4544                 (const_int 0)))]
4545   "TARGET_MIPS16"
4546   "sltu\t%1,1"
4547   [(set_attr "type" "slt")
4548    (set_attr "mode" "<MODE>")])
4549
4550 ;; "sne" uses sltu instructions in which the first operand is $0.
4551 ;; This isn't possible in mips16 code.
4552
4553 (define_expand "sne"
4554   [(set (match_operand:SI 0 "register_operand")
4555         (ne:SI (match_dup 1)
4556                (match_dup 2)))]
4557   "!TARGET_MIPS16"
4558   { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
4559
4560 (define_insn "*sne_<mode>"
4561   [(set (match_operand:GPR 0 "register_operand" "=d")
4562         (ne:GPR (match_operand:GPR 1 "register_operand" "d")
4563                 (const_int 0)))]
4564   "!TARGET_MIPS16"
4565   "sltu\t%0,%.,%1"
4566   [(set_attr "type" "slt")
4567    (set_attr "mode" "<MODE>")])
4568
4569 (define_expand "sgt"
4570   [(set (match_operand:SI 0 "register_operand")
4571         (gt:SI (match_dup 1)
4572                (match_dup 2)))]
4573   ""
4574   { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
4575
4576 (define_insn "*sgt_<mode>"
4577   [(set (match_operand:GPR 0 "register_operand" "=d")
4578         (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4579                 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4580   "!TARGET_MIPS16"
4581   "slt\t%0,%z2,%1"
4582   [(set_attr "type" "slt")
4583    (set_attr "mode" "<MODE>")])
4584
4585 (define_insn "*sgt_<mode>_mips16"
4586   [(set (match_operand:GPR 0 "register_operand" "=t")
4587         (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4588                 (match_operand:GPR 2 "register_operand" "d")))]
4589   "TARGET_MIPS16"
4590   "slt\t%2,%1"
4591   [(set_attr "type" "slt")
4592    (set_attr "mode" "<MODE>")])
4593
4594 (define_expand "sge"
4595   [(set (match_operand:SI 0 "register_operand")
4596         (ge:SI (match_dup 1)
4597                (match_dup 2)))]
4598   ""
4599   { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
4600
4601 (define_insn "*sge_<mode>"
4602   [(set (match_operand:GPR 0 "register_operand" "=d")
4603         (ge:GPR (match_operand:GPR 1 "register_operand" "d")
4604                 (const_int 1)))]
4605   "!TARGET_MIPS16"
4606   "slt\t%0,%.,%1"
4607   [(set_attr "type" "slt")
4608    (set_attr "mode" "<MODE>")])
4609
4610 (define_expand "slt"
4611   [(set (match_operand:SI 0 "register_operand")
4612         (lt:SI (match_dup 1)
4613                (match_dup 2)))]
4614   ""
4615   { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
4616
4617 (define_insn "*slt_<mode>"
4618   [(set (match_operand:GPR 0 "register_operand" "=d")
4619         (lt:GPR (match_operand:GPR 1 "register_operand" "d")
4620                 (match_operand:GPR 2 "arith_operand" "dI")))]
4621   "!TARGET_MIPS16"
4622   "slt\t%0,%1,%2"
4623   [(set_attr "type" "slt")
4624    (set_attr "mode" "<MODE>")])
4625
4626 (define_insn "*slt_<mode>_mips16"
4627   [(set (match_operand:GPR 0 "register_operand" "=t,t")
4628         (lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
4629                 (match_operand:GPR 2 "arith_operand" "d,I")))]
4630   "TARGET_MIPS16"
4631   "slt\t%1,%2"
4632   [(set_attr "type" "slt")
4633    (set_attr "mode" "<MODE>")
4634    (set_attr_alternative "length"
4635                 [(const_int 4)
4636                  (if_then_else (match_operand 2 "m16_uimm8_1")
4637                                (const_int 4)
4638                                (const_int 8))])])
4639
4640 (define_expand "sle"
4641   [(set (match_operand:SI 0 "register_operand")
4642         (le:SI (match_dup 1)
4643                (match_dup 2)))]
4644   ""
4645   { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
4646
4647 (define_insn "*sle_<mode>"
4648   [(set (match_operand:GPR 0 "register_operand" "=d")
4649         (le:GPR (match_operand:GPR 1 "register_operand" "d")
4650                 (match_operand:GPR 2 "sle_operand" "")))]
4651   "!TARGET_MIPS16"
4652 {
4653   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4654   return "slt\t%0,%1,%2";
4655 }
4656   [(set_attr "type" "slt")
4657    (set_attr "mode" "<MODE>")])
4658
4659 (define_insn "*sle_<mode>_mips16"
4660   [(set (match_operand:GPR 0 "register_operand" "=t")
4661         (le:GPR (match_operand:GPR 1 "register_operand" "d")
4662                 (match_operand:GPR 2 "sle_operand" "")))]
4663   "TARGET_MIPS16"
4664 {
4665   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4666   return "slt\t%1,%2";
4667 }
4668   [(set_attr "type" "slt")
4669    (set_attr "mode" "<MODE>")
4670    (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4671                                       (const_int 4)
4672                                       (const_int 8)))])
4673
4674 (define_expand "sgtu"
4675   [(set (match_operand:SI 0 "register_operand")
4676         (gtu:SI (match_dup 1)
4677                 (match_dup 2)))]
4678   ""
4679   { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
4680
4681 (define_insn "*sgtu_<mode>"
4682   [(set (match_operand:GPR 0 "register_operand" "=d")
4683         (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4684                  (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4685   "!TARGET_MIPS16"
4686   "sltu\t%0,%z2,%1"
4687   [(set_attr "type" "slt")
4688    (set_attr "mode" "<MODE>")])
4689
4690 (define_insn "*sgtu_<mode>_mips16"
4691   [(set (match_operand:GPR 0 "register_operand" "=t")
4692         (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4693                  (match_operand:GPR 2 "register_operand" "d")))]
4694   "TARGET_MIPS16"
4695   "sltu\t%2,%1"
4696   [(set_attr "type" "slt")
4697    (set_attr "mode" "<MODE>")])
4698
4699 (define_expand "sgeu"
4700   [(set (match_operand:SI 0 "register_operand")
4701         (geu:SI (match_dup 1)
4702                 (match_dup 2)))]
4703   ""
4704   { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
4705
4706 (define_insn "*sge_<mode>"
4707   [(set (match_operand:GPR 0 "register_operand" "=d")
4708         (geu:GPR (match_operand:GPR 1 "register_operand" "d")
4709                  (const_int 1)))]
4710   "!TARGET_MIPS16"
4711   "sltu\t%0,%.,%1"
4712   [(set_attr "type" "slt")
4713    (set_attr "mode" "<MODE>")])
4714
4715 (define_expand "sltu"
4716   [(set (match_operand:SI 0 "register_operand")
4717         (ltu:SI (match_dup 1)
4718                 (match_dup 2)))]
4719   ""
4720   { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
4721
4722 (define_insn "*sltu_<mode>"
4723   [(set (match_operand:GPR 0 "register_operand" "=d")
4724         (ltu:GPR (match_operand:GPR 1 "register_operand" "d")
4725                  (match_operand:GPR 2 "arith_operand" "dI")))]
4726   "!TARGET_MIPS16"
4727   "sltu\t%0,%1,%2"
4728   [(set_attr "type" "slt")
4729    (set_attr "mode" "<MODE>")])
4730
4731 (define_insn "*sltu_<mode>_mips16"
4732   [(set (match_operand:GPR 0 "register_operand" "=t,t")
4733         (ltu:GPR (match_operand:GPR 1 "register_operand" "d,d")
4734                  (match_operand:GPR 2 "arith_operand" "d,I")))]
4735   "TARGET_MIPS16"
4736   "sltu\t%1,%2"
4737   [(set_attr "type" "slt")
4738    (set_attr "mode" "<MODE>")
4739    (set_attr_alternative "length"
4740                 [(const_int 4)
4741                  (if_then_else (match_operand 2 "m16_uimm8_1")
4742                                (const_int 4)
4743                                (const_int 8))])])
4744
4745 (define_expand "sleu"
4746   [(set (match_operand:SI 0 "register_operand")
4747         (leu:SI (match_dup 1)
4748                 (match_dup 2)))]
4749   ""
4750   { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
4751
4752 (define_insn "*sleu_<mode>"
4753   [(set (match_operand:GPR 0 "register_operand" "=d")
4754         (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4755                  (match_operand:GPR 2 "sleu_operand" "")))]
4756   "!TARGET_MIPS16"
4757 {
4758   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4759   return "sltu\t%0,%1,%2";
4760 }
4761   [(set_attr "type" "slt")
4762    (set_attr "mode" "<MODE>")])
4763
4764 (define_insn "*sleu_<mode>_mips16"
4765   [(set (match_operand:GPR 0 "register_operand" "=t")
4766         (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4767                  (match_operand:GPR 2 "sleu_operand" "")))]
4768   "TARGET_MIPS16"
4769 {
4770   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4771   return "sltu\t%1,%2";
4772 }
4773   [(set_attr "type" "slt")
4774    (set_attr "mode" "<MODE>")
4775    (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4776                                       (const_int 4)
4777                                       (const_int 8)))])
4778 \f
4779 ;;
4780 ;;  ....................
4781 ;;
4782 ;;      FLOATING POINT COMPARISONS
4783 ;;
4784 ;;  ....................
4785
4786 (define_insn "sunordered_df"
4787   [(set (match_operand:CC 0 "register_operand" "=z")
4788         (unordered:CC (match_operand:DF 1 "register_operand" "f")
4789                       (match_operand:DF 2 "register_operand" "f")))]
4790   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4791   "c.un.d\t%Z0%1,%2"
4792   [(set_attr "type" "fcmp")
4793    (set_attr "mode" "FPSW")])
4794
4795 (define_insn "sunlt_df"
4796   [(set (match_operand:CC 0 "register_operand" "=z")
4797         (unlt:CC (match_operand:DF 1 "register_operand" "f")
4798                  (match_operand:DF 2 "register_operand" "f")))]
4799   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4800   "c.ult.d\t%Z0%1,%2"
4801   [(set_attr "type" "fcmp")
4802    (set_attr "mode" "FPSW")])
4803
4804 (define_insn "suneq_df"
4805   [(set (match_operand:CC 0 "register_operand" "=z")
4806         (uneq:CC (match_operand:DF 1 "register_operand" "f")
4807                  (match_operand:DF 2 "register_operand" "f")))]
4808   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4809   "c.ueq.d\t%Z0%1,%2"
4810   [(set_attr "type" "fcmp")
4811    (set_attr "mode" "FPSW")])
4812
4813 (define_insn "sunle_df"
4814   [(set (match_operand:CC 0 "register_operand" "=z")
4815         (unle:CC (match_operand:DF 1 "register_operand" "f")
4816                  (match_operand:DF 2 "register_operand" "f")))]
4817   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4818   "c.ule.d\t%Z0%1,%2"
4819   [(set_attr "type" "fcmp")
4820    (set_attr "mode" "FPSW")])
4821
4822 (define_insn "seq_df"
4823   [(set (match_operand:CC 0 "register_operand" "=z")
4824         (eq:CC (match_operand:DF 1 "register_operand" "f")
4825                (match_operand:DF 2 "register_operand" "f")))]
4826   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4827   "c.eq.d\t%Z0%1,%2"
4828   [(set_attr "type" "fcmp")
4829    (set_attr "mode" "FPSW")])
4830
4831 (define_insn "slt_df"
4832   [(set (match_operand:CC 0 "register_operand" "=z")
4833         (lt:CC (match_operand:DF 1 "register_operand" "f")
4834                (match_operand:DF 2 "register_operand" "f")))]
4835   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4836   "c.lt.d\t%Z0%1,%2"
4837   [(set_attr "type" "fcmp")
4838    (set_attr "mode" "FPSW")])
4839
4840 (define_insn "sle_df"
4841   [(set (match_operand:CC 0 "register_operand" "=z")
4842         (le:CC (match_operand:DF 1 "register_operand" "f")
4843                (match_operand:DF 2 "register_operand" "f")))]
4844   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4845   "c.le.d\t%Z0%1,%2"
4846   [(set_attr "type" "fcmp")
4847    (set_attr "mode" "FPSW")])
4848
4849 (define_insn "sgt_df"
4850   [(set (match_operand:CC 0 "register_operand" "=z")
4851         (gt:CC (match_operand:DF 1 "register_operand" "f")
4852                (match_operand:DF 2 "register_operand" "f")))]
4853   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4854   "c.lt.d\t%Z0%2,%1"
4855   [(set_attr "type" "fcmp")
4856    (set_attr "mode" "FPSW")])
4857
4858 (define_insn "sge_df"
4859   [(set (match_operand:CC 0 "register_operand" "=z")
4860         (ge:CC (match_operand:DF 1 "register_operand" "f")
4861                (match_operand:DF 2 "register_operand" "f")))]
4862   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4863   "c.le.d\t%Z0%2,%1"
4864   [(set_attr "type" "fcmp")
4865    (set_attr "mode" "FPSW")])
4866
4867 (define_insn "sunordered_sf"
4868   [(set (match_operand:CC 0 "register_operand" "=z")
4869         (unordered:CC (match_operand:SF 1 "register_operand" "f")
4870                       (match_operand:SF 2 "register_operand" "f")))]
4871   "TARGET_HARD_FLOAT"
4872   "c.un.s\t%Z0%1,%2"
4873   [(set_attr "type" "fcmp")
4874    (set_attr "mode" "FPSW")])
4875
4876 (define_insn "sunlt_sf"
4877   [(set (match_operand:CC 0 "register_operand" "=z")
4878         (unlt:CC (match_operand:SF 1 "register_operand" "f")
4879                  (match_operand:SF 2 "register_operand" "f")))]
4880   "TARGET_HARD_FLOAT"
4881   "c.ult.s\t%Z0%1,%2"
4882   [(set_attr "type" "fcmp")
4883    (set_attr "mode" "FPSW")])
4884
4885 (define_insn "suneq_sf"
4886   [(set (match_operand:CC 0 "register_operand" "=z")
4887         (uneq:CC (match_operand:SF 1 "register_operand" "f")
4888                  (match_operand:SF 2 "register_operand" "f")))]
4889   "TARGET_HARD_FLOAT"
4890   "c.ueq.s\t%Z0%1,%2"
4891   [(set_attr "type" "fcmp")
4892    (set_attr "mode" "FPSW")])
4893
4894 (define_insn "sunle_sf"
4895   [(set (match_operand:CC 0 "register_operand" "=z")
4896         (unle:CC (match_operand:SF 1 "register_operand" "f")
4897                  (match_operand:SF 2 "register_operand" "f")))]
4898   "TARGET_HARD_FLOAT"
4899   "c.ule.s\t%Z0%1,%2"
4900   [(set_attr "type" "fcmp")
4901    (set_attr "mode" "FPSW")])
4902
4903 (define_insn "seq_sf"
4904   [(set (match_operand:CC 0 "register_operand" "=z")
4905         (eq:CC (match_operand:SF 1 "register_operand" "f")
4906                (match_operand:SF 2 "register_operand" "f")))]
4907   "TARGET_HARD_FLOAT"
4908   "c.eq.s\t%Z0%1,%2"
4909   [(set_attr "type" "fcmp")
4910    (set_attr "mode" "FPSW")])
4911
4912 (define_insn "slt_sf"
4913   [(set (match_operand:CC 0 "register_operand" "=z")
4914         (lt:CC (match_operand:SF 1 "register_operand" "f")
4915                (match_operand:SF 2 "register_operand" "f")))]
4916   "TARGET_HARD_FLOAT"
4917   "c.lt.s\t%Z0%1,%2"
4918   [(set_attr "type" "fcmp")
4919    (set_attr "mode" "FPSW")])
4920
4921 (define_insn "sle_sf"
4922   [(set (match_operand:CC 0 "register_operand" "=z")
4923         (le:CC (match_operand:SF 1 "register_operand" "f")
4924                (match_operand:SF 2 "register_operand" "f")))]
4925   "TARGET_HARD_FLOAT"
4926   "c.le.s\t%Z0%1,%2"
4927   [(set_attr "type" "fcmp")
4928    (set_attr "mode" "FPSW")])
4929
4930 (define_insn "sgt_sf"
4931   [(set (match_operand:CC 0 "register_operand" "=z")
4932         (gt:CC (match_operand:SF 1 "register_operand" "f")
4933                (match_operand:SF 2 "register_operand" "f")))]
4934   "TARGET_HARD_FLOAT"
4935   "c.lt.s\t%Z0%2,%1"
4936   [(set_attr "type" "fcmp")
4937    (set_attr "mode" "FPSW")])
4938
4939 (define_insn "sge_sf"
4940   [(set (match_operand:CC 0 "register_operand" "=z")
4941         (ge:CC (match_operand:SF 1 "register_operand" "f")
4942                (match_operand:SF 2 "register_operand" "f")))]
4943   "TARGET_HARD_FLOAT"
4944   "c.le.s\t%Z0%2,%1"
4945   [(set_attr "type" "fcmp")
4946    (set_attr "mode" "FPSW")])
4947 \f
4948 ;;
4949 ;;  ....................
4950 ;;
4951 ;;      UNCONDITIONAL BRANCHES
4952 ;;
4953 ;;  ....................
4954
4955 ;; Unconditional branches.
4956
4957 (define_insn "jump"
4958   [(set (pc)
4959         (label_ref (match_operand 0 "" "")))]
4960   "!TARGET_MIPS16"
4961 {
4962   if (flag_pic)
4963     {
4964       if (get_attr_length (insn) <= 8)
4965         return "%*b\t%l0%/";
4966       else
4967         {
4968           output_asm_insn (mips_output_load_label (), operands);
4969           return "%*jr\t%@%/%]";
4970         }
4971     }
4972   else
4973     return "%*j\t%l0%/";
4974 }
4975   [(set_attr "type"     "jump")
4976    (set_attr "mode"     "none")
4977    (set (attr "length")
4978         ;; We can't use `j' when emitting PIC.  Emit a branch if it's
4979         ;; in range, otherwise load the address of the branch target into
4980         ;; $at and then jump to it.
4981         (if_then_else
4982          (ior (eq (symbol_ref "flag_pic") (const_int 0))
4983               (lt (abs (minus (match_dup 0)
4984                               (plus (pc) (const_int 4))))
4985                   (const_int 131072)))
4986          (const_int 4) (const_int 16)))])
4987
4988 ;; We need a different insn for the mips16, because a mips16 branch
4989 ;; does not have a delay slot.
4990
4991 (define_insn ""
4992   [(set (pc)
4993         (label_ref (match_operand 0 "" "")))]
4994   "TARGET_MIPS16"
4995   "b\t%l0"
4996   [(set_attr "type"     "branch")
4997    (set_attr "mode"     "none")
4998    (set_attr "length"   "8")])
4999
5000 (define_expand "indirect_jump"
5001   [(set (pc) (match_operand 0 "register_operand"))]
5002   ""
5003 {
5004   operands[0] = force_reg (Pmode, operands[0]);
5005   if (Pmode == SImode)
5006     emit_jump_insn (gen_indirect_jumpsi (operands[0]));
5007   else
5008     emit_jump_insn (gen_indirect_jumpdi (operands[0]));
5009   DONE;
5010 })
5011
5012 (define_insn "indirect_jump<mode>"
5013   [(set (pc) (match_operand:P 0 "register_operand" "d"))]
5014   ""
5015   "%*j\t%0%/"
5016   [(set_attr "type" "jump")
5017    (set_attr "mode" "none")])
5018
5019 (define_expand "tablejump"
5020   [(set (pc)
5021         (match_operand 0 "register_operand"))
5022    (use (label_ref (match_operand 1 "")))]
5023   ""
5024 {
5025   if (TARGET_MIPS16)
5026     operands[0] = expand_binop (Pmode, add_optab,
5027                                 convert_to_mode (Pmode, operands[0], false),
5028                                 gen_rtx_LABEL_REF (Pmode, operands[1]),
5029                                 0, 0, OPTAB_WIDEN);
5030   else if (TARGET_GPWORD)
5031     operands[0] = expand_binop (Pmode, add_optab, operands[0],
5032                                 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
5033
5034   if (Pmode == SImode)
5035     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
5036   else
5037     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
5038   DONE;
5039 })
5040
5041 (define_insn "tablejump<mode>"
5042   [(set (pc)
5043         (match_operand:P 0 "register_operand" "d"))
5044    (use (label_ref (match_operand 1 "" "")))]
5045   ""
5046   "%*j\t%0%/"
5047   [(set_attr "type" "jump")
5048    (set_attr "mode" "none")])
5049
5050 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
5051 ;; While it is possible to either pull it off the stack (in the
5052 ;; o32 case) or recalculate it given t9 and our target label,
5053 ;; it takes 3 or 4 insns to do so.
5054
5055 (define_expand "builtin_setjmp_setup"
5056   [(use (match_operand 0 "register_operand"))]
5057   "TARGET_ABICALLS"
5058 {
5059   rtx addr;
5060
5061   addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
5062   emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
5063   DONE;
5064 })
5065
5066 ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
5067 ;; that older code did recalculate the gp from $25.  Continue to jump through
5068 ;; $25 for compatibility (we lose nothing by doing so).
5069
5070 (define_expand "builtin_longjmp"
5071   [(use (match_operand 0 "register_operand"))]
5072   "TARGET_ABICALLS"
5073 {
5074   /* The elements of the buffer are, in order:  */
5075   int W = GET_MODE_SIZE (Pmode);
5076   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5077   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
5078   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
5079   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
5080   rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5081   /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
5082      The target is bound to be using $28 as the global pointer
5083      but the current function might not be.  */
5084   rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
5085
5086   /* This bit is similar to expand_builtin_longjmp except that it
5087      restores $gp as well.  */
5088   emit_move_insn (hard_frame_pointer_rtx, fp);
5089   emit_move_insn (pv, lab);
5090   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5091   emit_move_insn (gp, gpv);
5092   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5093   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5094   emit_insn (gen_rtx_USE (VOIDmode, gp));
5095   emit_indirect_jump (pv);
5096   DONE;
5097 })
5098 \f
5099 ;;
5100 ;;  ....................
5101 ;;
5102 ;;      Function prologue/epilogue
5103 ;;
5104 ;;  ....................
5105 ;;
5106
5107 (define_expand "prologue"
5108   [(const_int 1)]
5109   ""
5110 {
5111   mips_expand_prologue ();
5112   DONE;
5113 })
5114
5115 ;; Block any insns from being moved before this point, since the
5116 ;; profiling call to mcount can use various registers that aren't
5117 ;; saved or used to pass arguments.
5118
5119 (define_insn "blockage"
5120   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
5121   ""
5122   ""
5123   [(set_attr "type"     "unknown")
5124    (set_attr "mode"     "none")
5125    (set_attr "length"   "0")])
5126
5127 (define_expand "epilogue"
5128   [(const_int 2)]
5129   ""
5130 {
5131   mips_expand_epilogue (false);
5132   DONE;
5133 })
5134
5135 (define_expand "sibcall_epilogue"
5136   [(const_int 2)]
5137   ""
5138 {
5139   mips_expand_epilogue (true);
5140   DONE;
5141 })
5142
5143 ;; Trivial return.  Make it look like a normal return insn as that
5144 ;; allows jump optimizations to work better.
5145
5146 (define_insn "return"
5147   [(return)]
5148   "mips_can_use_return_insn ()"
5149   "%*j\t$31%/"
5150   [(set_attr "type"     "jump")
5151    (set_attr "mode"     "none")])
5152
5153 ;; Normal return.
5154
5155 (define_insn "return_internal"
5156   [(return)
5157    (use (match_operand 0 "pmode_register_operand" ""))]
5158   ""
5159   "%*j\t%0%/"
5160   [(set_attr "type"     "jump")
5161    (set_attr "mode"     "none")])
5162
5163 ;; This is used in compiling the unwind routines.
5164 (define_expand "eh_return"
5165   [(use (match_operand 0 "general_operand"))]
5166   ""
5167 {
5168   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
5169
5170   if (GET_MODE (operands[0]) != gpr_mode)
5171     operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
5172   if (TARGET_64BIT)
5173     emit_insn (gen_eh_set_lr_di (operands[0]));
5174   else
5175     emit_insn (gen_eh_set_lr_si (operands[0]));
5176
5177   DONE;
5178 })
5179
5180 ;; Clobber the return address on the stack.  We can't expand this
5181 ;; until we know where it will be put in the stack frame.
5182
5183 (define_insn "eh_set_lr_si"
5184   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5185    (clobber (match_scratch:SI 1 "=&d"))]
5186   "! TARGET_64BIT"
5187   "#")
5188
5189 (define_insn "eh_set_lr_di"
5190   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5191    (clobber (match_scratch:DI 1 "=&d"))]
5192   "TARGET_64BIT"
5193   "#")
5194
5195 (define_split
5196   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
5197    (clobber (match_scratch 1))]
5198   "reload_completed && !TARGET_DEBUG_D_MODE"
5199   [(const_int 0)]
5200 {
5201   mips_set_return_address (operands[0], operands[1]);
5202   DONE;
5203 })
5204
5205 (define_insn_and_split "exception_receiver"
5206   [(set (reg:SI 28)
5207         (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
5208   "TARGET_ABICALLS && TARGET_OLDABI"
5209   "#"
5210   "&& reload_completed"
5211   [(const_int 0)]
5212 {
5213   mips_restore_gp ();
5214   DONE;
5215 }
5216   [(set_attr "type"   "load")
5217    (set_attr "length" "12")])
5218 \f
5219 ;;
5220 ;;  ....................
5221 ;;
5222 ;;      FUNCTION CALLS
5223 ;;
5224 ;;  ....................
5225
5226 ;; Instructions to load a call address from the GOT.  The address might
5227 ;; point to a function or to a lazy binding stub.  In the latter case,
5228 ;; the stub will use the dynamic linker to resolve the function, which
5229 ;; in turn will change the GOT entry to point to the function's real
5230 ;; address.
5231 ;;
5232 ;; This means that every call, even pure and constant ones, can
5233 ;; potentially modify the GOT entry.  And once a stub has been called,
5234 ;; we must not call it again.
5235 ;;
5236 ;; We represent this restriction using an imaginary fixed register that
5237 ;; acts like a GOT version number.  By making the register call-clobbered,
5238 ;; we tell the target-independent code that the address could be changed
5239 ;; by any call insn.
5240 (define_insn "load_call<mode>"
5241   [(set (match_operand:P 0 "register_operand" "=c")
5242         (unspec:P [(match_operand:P 1 "register_operand" "r")
5243                    (match_operand:P 2 "immediate_operand" "")
5244                    (reg:P FAKE_CALL_REGNO)]
5245                   UNSPEC_LOAD_CALL))]
5246   "TARGET_ABICALLS"
5247   "<load>\t%0,%R2(%1)"
5248   [(set_attr "type" "load")
5249    (set_attr "mode" "<MODE>")
5250    (set_attr "length" "4")])
5251
5252 ;; Sibling calls.  All these patterns use jump instructions.
5253
5254 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
5255 ;; addresses if a direct jump is acceptable.  Since the 'S' constraint
5256 ;; is defined in terms of call_insn_operand, the same is true of the
5257 ;; constraints.
5258
5259 ;; When we use an indirect jump, we need a register that will be
5260 ;; preserved by the epilogue.  Since TARGET_ABICALLS forces us to
5261 ;; use $25 for this purpose -- and $25 is never clobbered by the
5262 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
5263
5264 (define_expand "sibcall"
5265   [(parallel [(call (match_operand 0 "")
5266                     (match_operand 1 ""))
5267               (use (match_operand 2 ""))        ;; next_arg_reg
5268               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
5269   "TARGET_SIBCALLS"
5270 {
5271   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
5272   DONE;
5273 })
5274
5275 (define_insn "sibcall_internal"
5276   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
5277          (match_operand 1 "" ""))]
5278   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5279   "@
5280     %*jr\t%0%/
5281     %*j\t%0%/"
5282   [(set_attr "type" "call")])
5283
5284 (define_expand "sibcall_value"
5285   [(parallel [(set (match_operand 0 "")
5286                    (call (match_operand 1 "")
5287                          (match_operand 2 "")))
5288               (use (match_operand 3 ""))])]             ;; next_arg_reg
5289   "TARGET_SIBCALLS"
5290 {
5291   mips_expand_call (operands[0], XEXP (operands[1], 0),
5292                     operands[2], operands[3], true);
5293   DONE;
5294 })
5295
5296 (define_insn "sibcall_value_internal"
5297   [(set (match_operand 0 "register_operand" "=df,df")
5298         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5299               (match_operand 2 "" "")))]
5300   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5301   "@
5302     %*jr\t%1%/
5303     %*j\t%1%/"
5304   [(set_attr "type" "call")])
5305
5306 (define_insn "sibcall_value_multiple_internal"
5307   [(set (match_operand 0 "register_operand" "=df,df")
5308         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5309               (match_operand 2 "" "")))
5310    (set (match_operand 3 "register_operand" "=df,df")
5311         (call (mem:SI (match_dup 1))
5312               (match_dup 2)))]
5313   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5314   "@
5315     %*jr\t%1%/
5316     %*j\t%1%/"
5317   [(set_attr "type" "call")])
5318
5319 (define_expand "call"
5320   [(parallel [(call (match_operand 0 "")
5321                     (match_operand 1 ""))
5322               (use (match_operand 2 ""))        ;; next_arg_reg
5323               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
5324   ""
5325 {
5326   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
5327   DONE;
5328 })
5329
5330 ;; This instruction directly corresponds to an assembly-language "jal".
5331 ;; There are four cases:
5332 ;;
5333 ;;    - -mno-abicalls:
5334 ;;        Both symbolic and register destinations are OK.  The pattern
5335 ;;        always expands to a single mips instruction.
5336 ;;
5337 ;;    - -mabicalls/-mno-explicit-relocs:
5338 ;;        Again, both symbolic and register destinations are OK.
5339 ;;        The call is treated as a multi-instruction black box.
5340 ;;
5341 ;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
5342 ;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
5343 ;;        instruction.
5344 ;;
5345 ;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
5346 ;;        Only "jal $25" is allowed.  The call is actually two instructions:
5347 ;;        "jalr $25" followed by an insn to reload $gp.
5348 ;;
5349 ;; In the last case, we can generate the individual instructions with
5350 ;; a define_split.  There are several things to be wary of:
5351 ;;
5352 ;;   - We can't expose the load of $gp before reload.  If we did,
5353 ;;     it might get removed as dead, but reload can introduce new
5354 ;;     uses of $gp by rematerializing constants.
5355 ;;
5356 ;;   - We shouldn't restore $gp after calls that never return.
5357 ;;     It isn't valid to insert instructions between a noreturn
5358 ;;     call and the following barrier.
5359 ;;
5360 ;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
5361 ;;     instruction preserves $gp and so have no effect on its liveness.
5362 ;;     But once we generate the separate insns, it becomes obvious that
5363 ;;     $gp is not live on entry to the call.
5364 ;;
5365 ;; ??? The operands[2] = insn check is a hack to make the original insn
5366 ;; available to the splitter.
5367 (define_insn_and_split "call_internal"
5368   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
5369          (match_operand 1 "" ""))
5370    (clobber (reg:SI 31))]
5371   ""
5372   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
5373   "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
5374   [(const_int 0)]
5375 {
5376   emit_call_insn (gen_call_split (operands[0], operands[1]));
5377   if (!find_reg_note (operands[2], REG_NORETURN, 0))
5378     mips_restore_gp ();
5379   DONE;
5380 }
5381   [(set_attr "jal" "indirect,direct")
5382    (set_attr "extended_mips16" "no,yes")])
5383
5384 (define_insn "call_split"
5385   [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
5386          (match_operand 1 "" ""))
5387    (clobber (reg:SI 31))
5388    (clobber (reg:SI 28))]
5389   "TARGET_SPLIT_CALLS"
5390   "%*jalr\t%0%/"
5391   [(set_attr "type" "call")])
5392
5393 (define_expand "call_value"
5394   [(parallel [(set (match_operand 0 "")
5395                    (call (match_operand 1 "")
5396                          (match_operand 2 "")))
5397               (use (match_operand 3 ""))])]             ;; next_arg_reg
5398   ""
5399 {
5400   mips_expand_call (operands[0], XEXP (operands[1], 0),
5401                     operands[2], operands[3], false);
5402   DONE;
5403 })
5404
5405 ;; See comment for call_internal.
5406 (define_insn_and_split "call_value_internal"
5407   [(set (match_operand 0 "register_operand" "=df,df")
5408         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5409               (match_operand 2 "" "")))
5410    (clobber (reg:SI 31))]
5411   ""
5412   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
5413   "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
5414   [(const_int 0)]
5415 {
5416   emit_call_insn (gen_call_value_split (operands[0], operands[1],
5417                                         operands[2]));
5418   if (!find_reg_note (operands[3], REG_NORETURN, 0))
5419     mips_restore_gp ();
5420   DONE;
5421 }
5422   [(set_attr "jal" "indirect,direct")
5423    (set_attr "extended_mips16" "no,yes")])
5424
5425 (define_insn "call_value_split"
5426   [(set (match_operand 0 "register_operand" "=df")
5427         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
5428               (match_operand 2 "" "")))
5429    (clobber (reg:SI 31))
5430    (clobber (reg:SI 28))]
5431   "TARGET_SPLIT_CALLS"
5432   "%*jalr\t%1%/"
5433   [(set_attr "type" "call")])
5434
5435 ;; See comment for call_internal.
5436 (define_insn_and_split "call_value_multiple_internal"
5437   [(set (match_operand 0 "register_operand" "=df,df")
5438         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5439               (match_operand 2 "" "")))
5440    (set (match_operand 3 "register_operand" "=df,df")
5441         (call (mem:SI (match_dup 1))
5442               (match_dup 2)))
5443    (clobber (reg:SI 31))]
5444   ""
5445   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
5446   "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
5447   [(const_int 0)]
5448 {
5449   emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
5450                                                  operands[2], operands[3]));
5451   if (!find_reg_note (operands[4], REG_NORETURN, 0))
5452     mips_restore_gp ();
5453   DONE;
5454 }
5455   [(set_attr "jal" "indirect,direct")
5456    (set_attr "extended_mips16" "no,yes")])
5457
5458 (define_insn "call_value_multiple_split"
5459   [(set (match_operand 0 "register_operand" "=df")
5460         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
5461               (match_operand 2 "" "")))
5462    (set (match_operand 3 "register_operand" "=df")
5463         (call (mem:SI (match_dup 1))
5464               (match_dup 2)))
5465    (clobber (reg:SI 31))
5466    (clobber (reg:SI 28))]
5467   "TARGET_SPLIT_CALLS"
5468   "%*jalr\t%1%/"
5469   [(set_attr "type" "call")])
5470
5471 ;; Call subroutine returning any type.
5472
5473 (define_expand "untyped_call"
5474   [(parallel [(call (match_operand 0 "")
5475                     (const_int 0))
5476               (match_operand 1 "")
5477               (match_operand 2 "")])]
5478   ""
5479 {
5480   int i;
5481
5482   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
5483
5484   for (i = 0; i < XVECLEN (operands[2], 0); i++)
5485     {
5486       rtx set = XVECEXP (operands[2], 0, i);
5487       emit_move_insn (SET_DEST (set), SET_SRC (set));
5488     }
5489
5490   emit_insn (gen_blockage ());
5491   DONE;
5492 })
5493 \f
5494 ;;
5495 ;;  ....................
5496 ;;
5497 ;;      MISC.
5498 ;;
5499 ;;  ....................
5500 ;;
5501
5502
5503 (define_insn "prefetch"
5504   [(prefetch (match_operand:QI 0 "address_operand" "p")
5505              (match_operand 1 "const_int_operand" "n")
5506              (match_operand 2 "const_int_operand" "n"))]
5507   "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
5508 {
5509   operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
5510   return "pref\t%1,%a0";
5511 }
5512   [(set_attr "type" "prefetch")])
5513
5514 (define_insn "*prefetch_indexed_<mode>"
5515   [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
5516                      (match_operand:P 1 "register_operand" "d"))
5517              (match_operand 2 "const_int_operand" "n")
5518              (match_operand 3 "const_int_operand" "n"))]
5519   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5520 {
5521   operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
5522   return "prefx\t%2,%1(%0)";
5523 }
5524   [(set_attr "type" "prefetchx")])
5525
5526 (define_insn "nop"
5527   [(const_int 0)]
5528   ""
5529   "%(nop%)"
5530   [(set_attr "type"     "nop")
5531    (set_attr "mode"     "none")])
5532
5533 ;; Like nop, but commented out when outside a .set noreorder block.
5534 (define_insn "hazard_nop"
5535   [(const_int 1)]
5536   ""
5537   {
5538     if (set_noreorder)
5539       return "nop";
5540     else
5541       return "#nop";
5542   }
5543   [(set_attr "type"     "nop")])
5544 \f
5545 ;; MIPS4 Conditional move instructions.
5546
5547 (define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
5548   [(set (match_operand:GPR 0 "register_operand" "=d,d")
5549         (if_then_else:GPR
5550          (match_operator:MOVECC 4 "equality_operator"
5551                 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5552                  (const_int 0)])
5553          (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
5554          (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
5555   "ISA_HAS_CONDMOVE"
5556   "@
5557     mov%T4\t%0,%z2,%1
5558     mov%t4\t%0,%z3,%1"
5559   [(set_attr "type" "condmove")
5560    (set_attr "mode" "<GPR:MODE>")])
5561
5562 (define_insn "*movsf_on_<MOVECC:mode>"
5563   [(set (match_operand:SF 0 "register_operand" "=f,f")
5564         (if_then_else:SF
5565          (match_operator:MOVECC 4 "equality_operator"
5566                 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5567                  (const_int 0)])
5568          (match_operand:SF 2 "register_operand" "f,0")
5569          (match_operand:SF 3 "register_operand" "0,f")))]
5570   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
5571   "@
5572     mov%T4.s\t%0,%2,%1
5573     mov%t4.s\t%0,%3,%1"
5574   [(set_attr "type" "condmove")
5575    (set_attr "mode" "SF")])
5576
5577 (define_insn "*movdf_on_<MOVECC:mode>"
5578   [(set (match_operand:DF 0 "register_operand" "=f,f")
5579         (if_then_else:DF
5580          (match_operator:MOVECC 4 "equality_operator"
5581                 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5582                  (const_int 0)])
5583          (match_operand:DF 2 "register_operand" "f,0")
5584          (match_operand:DF 3 "register_operand" "0,f")))]
5585   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5586   "@
5587     mov%T4.d\t%0,%2,%1
5588     mov%t4.d\t%0,%3,%1"
5589   [(set_attr "type" "condmove")
5590    (set_attr "mode" "DF")])
5591
5592 ;; These are the main define_expand's used to make conditional moves.
5593
5594 (define_expand "mov<mode>cc"
5595   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5596    (set (match_operand:GPR 0 "register_operand")
5597         (if_then_else:GPR (match_dup 5)
5598                           (match_operand:GPR 2 "reg_or_0_operand")
5599                           (match_operand:GPR 3 "reg_or_0_operand")))]
5600   "ISA_HAS_CONDMOVE"
5601 {
5602   gen_conditional_move (operands);
5603   DONE;
5604 })
5605
5606 (define_expand "movsfcc"
5607   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5608    (set (match_operand:SF 0 "register_operand")
5609         (if_then_else:SF (match_dup 5)
5610                          (match_operand:SF 2 "register_operand")
5611                          (match_operand:SF 3 "register_operand")))]
5612   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
5613 {
5614   gen_conditional_move (operands);
5615   DONE;
5616 })
5617
5618 (define_expand "movdfcc"
5619   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5620    (set (match_operand:DF 0 "register_operand")
5621         (if_then_else:DF (match_dup 5)
5622                          (match_operand:DF 2 "register_operand")
5623                          (match_operand:DF 3 "register_operand")))]
5624   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5625 {
5626   gen_conditional_move (operands);
5627   DONE;
5628 })
5629 \f
5630 ;;
5631 ;;  ....................
5632 ;;
5633 ;;      mips16 inline constant tables
5634 ;;
5635 ;;  ....................
5636 ;;
5637
5638 (define_insn "consttable_int"
5639   [(unspec_volatile [(match_operand 0 "consttable_operand" "")
5640                      (match_operand 1 "const_int_operand" "")]
5641                     UNSPEC_CONSTTABLE_INT)]
5642   "TARGET_MIPS16"
5643 {
5644   assemble_integer (operands[0], INTVAL (operands[1]),
5645                     BITS_PER_UNIT * INTVAL (operands[1]), 1);
5646   return "";
5647 }
5648   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
5649
5650 (define_insn "consttable_float"
5651   [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
5652                     UNSPEC_CONSTTABLE_FLOAT)]
5653   "TARGET_MIPS16"
5654 {
5655   REAL_VALUE_TYPE d;
5656
5657   if (GET_CODE (operands[0]) != CONST_DOUBLE)
5658     abort ();
5659   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
5660   assemble_real (d, GET_MODE (operands[0]),
5661                  GET_MODE_BITSIZE (GET_MODE (operands[0])));
5662   return "";
5663 }
5664   [(set (attr "length")
5665         (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
5666
5667 (define_insn "align"
5668   [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
5669   ""
5670   ".align\t%0"
5671   [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
5672 \f
5673 (define_split
5674   [(match_operand 0 "small_data_pattern")]
5675   "reload_completed"
5676   [(match_dup 0)]
5677   { operands[0] = mips_rewrite_small_data (operands[0]); })
5678 \f
5679 ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
5680
5681 (include "mips-ps-3d.md")