OSDN Git Service

df32a546d6ccf5609e0a4d06b78adbfecf53b235
[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_MOVE_TF_PS           200)
56    (UNSPEC_C                    201)
57
58    ;; MIPS64/MIPS32R2 alnv.ps
59    (UNSPEC_ALNV_PS              202)
60
61    ;; MIPS-3D instructions
62    (UNSPEC_CABS                 203)
63
64    (UNSPEC_ADDR_PS              204)
65    (UNSPEC_CVT_PW_PS            205)
66    (UNSPEC_CVT_PS_PW            206)
67    (UNSPEC_MULR_PS              207)
68
69    (UNSPEC_RSQRT1               208)
70    (UNSPEC_RSQRT2               209)
71    (UNSPEC_RECIP1               210)
72    (UNSPEC_RECIP2               211)
73   ]
74 )
75
76 (include "predicates.md")
77 \f
78 ;; ....................
79 ;;
80 ;;      Attributes
81 ;;
82 ;; ....................
83
84 (define_attr "got" "unset,xgot_high,load"
85   (const_string "unset"))
86
87 ;; For jal instructions, this attribute is DIRECT when the target address
88 ;; is symbolic and INDIRECT when it is a register.
89 (define_attr "jal" "unset,direct,indirect"
90   (const_string "unset"))
91
92 ;; This attribute is YES if the instruction is a jal macro (not a
93 ;; real jal instruction).
94 ;;
95 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
96 ;; restore $gp.  Direct jals are also macros in NewABI PIC since they
97 ;; load the target address into $25.
98 (define_attr "jal_macro" "no,yes"
99   (cond [(eq_attr "jal" "direct")
100          (symbol_ref "TARGET_ABICALLS != 0")
101          (eq_attr "jal" "indirect")
102          (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
103         (const_string "no")))
104
105 ;; Classification of each insn.
106 ;; branch       conditional branch
107 ;; jump         unconditional jump
108 ;; call         unconditional call
109 ;; load         load instruction(s)
110 ;; fpload       floating point load
111 ;; fpidxload    floating point indexed load
112 ;; store        store instruction(s)
113 ;; fpstore      floating point store
114 ;; fpidxstore   floating point indexed store
115 ;; prefetch     memory prefetch (register + offset)
116 ;; prefetchx    memory indexed prefetch (register + register)
117 ;; condmove     conditional moves
118 ;; xfer         transfer to/from coprocessor
119 ;; mthilo       transfer to hi/lo registers
120 ;; mfhilo       transfer from hi/lo registers
121 ;; const        load constant
122 ;; arith        integer arithmetic and logical instructions
123 ;; shift        integer shift instructions
124 ;; slt          set less than instructions
125 ;; clz          the clz and clo instructions
126 ;; trap         trap if instructions
127 ;; imul         integer multiply
128 ;; imadd        integer multiply-add
129 ;; idiv         integer divide
130 ;; fmove        floating point register move
131 ;; fadd         floating point add/subtract
132 ;; fmul         floating point multiply
133 ;; fmadd        floating point multiply-add
134 ;; fdiv         floating point divide
135 ;; frdiv        floating point reciprocal divide
136 ;; fabs         floating point absolute value
137 ;; fneg         floating point negation
138 ;; fcmp         floating point compare
139 ;; fcvt         floating point convert
140 ;; fsqrt        floating point square root
141 ;; frsqrt       floating point reciprocal square root
142 ;; multi        multiword sequence (or user asm statements)
143 ;; nop          no operation
144 (define_attr "type"
145   "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"
146   (cond [(eq_attr "jal" "!unset") (const_string "call")
147          (eq_attr "got" "load") (const_string "load")]
148         (const_string "unknown")))
149
150 ;; Main data type used by the insn
151 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
152   (const_string "unknown"))
153
154 ;; Is this an extended instruction in mips16 mode?
155 (define_attr "extended_mips16" "no,yes"
156   (const_string "no"))
157
158 ;; Length of instruction in bytes.
159 (define_attr "length" ""
160    (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
161           ;; If a branch is outside this range, we have a choice of two
162           ;; sequences.  For PIC, an out-of-range branch like:
163           ;;
164           ;;    bne     r1,r2,target
165           ;;    dslot
166           ;;
167           ;; becomes the equivalent of:
168           ;;
169           ;;    beq     r1,r2,1f
170           ;;    dslot
171           ;;    la      $at,target
172           ;;    jr      $at
173           ;;    nop
174           ;; 1:
175           ;;
176           ;; where the load address can be up to three instructions long
177           ;; (lw, nop, addiu).
178           ;;
179           ;; The non-PIC case is similar except that we use a direct
180           ;; jump instead of an la/jr pair.  Since the target of this
181           ;; jump is an absolute 28-bit bit address (the other bits
182           ;; coming from the address of the delay slot) this form cannot
183           ;; cross a 256MB boundary.  We could provide the option of
184           ;; using la/jr in this case too, but we do not do so at
185           ;; present.
186           ;;
187           ;; Note that this value does not account for the delay slot
188           ;; instruction, whose length is added separately.  If the RTL
189           ;; pattern has no explicit delay slot, mips_adjust_insn_length
190           ;; will add the length of the implicit nop.  The values for
191           ;; forward and backward branches will be different as well.
192           (eq_attr "type" "branch")
193           (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
194                       (le (minus (pc) (match_dup 1)) (const_int 131068)))
195                   (const_int 4)
196                  (ne (symbol_ref "flag_pic") (const_int 0))
197                  (const_int 24)
198                  ] (const_int 12))
199
200           (eq_attr "got" "load")
201           (const_int 4)
202           (eq_attr "got" "xgot_high")
203           (const_int 8)
204
205           (eq_attr "type" "const")
206           (symbol_ref "mips_const_insns (operands[1]) * 4")
207           (eq_attr "type" "load,fpload")
208           (symbol_ref "mips_fetch_insns (operands[1]) * 4")
209           (eq_attr "type" "store,fpstore")
210           (symbol_ref "mips_fetch_insns (operands[0]) * 4")
211
212           ;; In the worst case, a call macro will take 8 instructions:
213           ;;
214           ;;     lui $25,%call_hi(FOO)
215           ;;     addu $25,$25,$28
216           ;;     lw $25,%call_lo(FOO)($25)
217           ;;     nop
218           ;;     jalr $25
219           ;;     nop
220           ;;     lw $gp,X($sp)
221           ;;     nop
222           (eq_attr "jal_macro" "yes")
223           (const_int 32)
224
225           (and (eq_attr "extended_mips16" "yes")
226                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
227           (const_int 8)
228
229           ;; Various VR4120 errata require a nop to be inserted after a macc
230           ;; instruction.  The assembler does this for us, so account for
231           ;; the worst-case length here.
232           (and (eq_attr "type" "imadd")
233                (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
234           (const_int 8)
235
236           ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
237           ;; the result of the second one is missed.  The assembler should work
238           ;; around this by inserting a nop after the first dmult.
239           (and (eq_attr "type" "imul")
240                (and (eq_attr "mode" "DI")
241                     (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
242           (const_int 8)
243
244           (eq_attr "type" "idiv")
245           (symbol_ref "mips_idiv_insns () * 4")
246           ] (const_int 4)))
247
248 ;; Attribute describing the processor.  This attribute must match exactly
249 ;; with the processor_type enumeration in mips.h.
250 (define_attr "cpu"
251   "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
252   (const (symbol_ref "mips_tune")))
253
254 ;; The type of hardware hazard associated with this instruction.
255 ;; DELAY means that the next instruction cannot read the result
256 ;; of this one.  HILO means that the next two instructions cannot
257 ;; write to HI or LO.
258 (define_attr "hazard" "none,delay,hilo"
259   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
260               (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
261          (const_string "delay")
262
263          (and (eq_attr "type" "xfer")
264               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
265          (const_string "delay")
266
267          (and (eq_attr "type" "fcmp")
268               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
269          (const_string "delay")
270
271          ;; The r4000 multiplication patterns include an mflo instruction.
272          (and (eq_attr "type" "imul")
273               (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
274          (const_string "hilo")
275
276          (and (eq_attr "type" "mfhilo")
277               (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
278          (const_string "hilo")]
279         (const_string "none")))
280
281 ;; Is it a single instruction?
282 (define_attr "single_insn" "no,yes"
283   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
284
285 ;; Can the instruction be put into a delay slot?
286 (define_attr "can_delay" "no,yes"
287   (if_then_else (and (eq_attr "type" "!branch,call,jump")
288                      (and (eq_attr "hazard" "none")
289                           (eq_attr "single_insn" "yes")))
290                 (const_string "yes")
291                 (const_string "no")))
292
293 ;; Attribute defining whether or not we can use the branch-likely instructions
294 (define_attr "branch_likely" "no,yes"
295   (const
296    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
297                  (const_string "yes")
298                  (const_string "no"))))
299
300 ;; True if an instruction might assign to hi or lo when reloaded.
301 ;; This is used by the TUNE_MACC_CHAINS code.
302 (define_attr "may_clobber_hilo" "no,yes"
303   (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
304                 (const_string "yes")
305                 (const_string "no")))
306
307 ;; Describe a user's asm statement.
308 (define_asm_attributes
309   [(set_attr "type" "multi")])
310 \f
311 ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
312 ;; from the same template.
313 (define_mode_macro GPR [SI (DI "TARGET_64BIT")])
314
315 ;; This mode macro allows :P to be used for patterns that operate on
316 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
317 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
318
319 ;; This mode macro allows :MOVECC to be used anywhere that a
320 ;; conditional-move-type condition is needed.
321 (define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
322
323 ;; This mode macro allows :ANYF to be used wherever a scalar or vector
324 ;; floating-point mode is allowed.
325 (define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT")
326                          (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
327                          (V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
328
329 ;; Like ANYF, but only applies to scalar modes.
330 (define_mode_macro SCALARF [(SF "TARGET_HARD_FLOAT")
331                             (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
332
333 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
334 ;; 32-bit version and "dsubu" in the 64-bit version.
335 (define_mode_attr d [(SI "") (DI "d")])
336
337 ;; Mode attributes for GPR loads and stores.
338 (define_mode_attr load [(SI "lw") (DI "ld")])
339 (define_mode_attr store [(SI "sw") (DI "sd")])
340
341 ;; Similarly for MIPS IV indexed FPR loads and stores.
342 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1")])
343 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1")])
344
345 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
346 ;; are different.  Some forms of unextended addiu have an 8-bit immediate
347 ;; field but the equivalent daddiu has only a 5-bit field.
348 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
349
350 ;; This attribute gives the best constraint to use for registers of
351 ;; a given mode.
352 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
353
354 ;; This attribute gives the format suffix for floating-point operations.
355 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
356
357 ;; This attribute gives the upper-case mode name for one unit of a
358 ;; floating-point mode.
359 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
360
361 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
362 ;;
363 ;; In certain cases, div.s and div.ps may have a rounding error
364 ;; and/or wrong inexact flag.
365 ;;
366 ;; Therefore, we only allow div.s if not working around SB-1 rev2
367 ;; errata or if a slight loss of precision is OK.
368 (define_mode_attr divide_condition
369   [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")])
370
371 ;; This code macro allows all branch instructions to be generated from
372 ;; a single define_expand template.
373 (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
374                              eq ne gt ge lt le gtu geu ltu leu])
375
376 ;; This code macro allows signed and unsigned widening multiplications
377 ;; to use the same template.
378 (define_code_macro any_extend [sign_extend zero_extend])
379
380 ;; This code macro allows the three shift instructions to be generated
381 ;; from the same template.
382 (define_code_macro any_shift [ashift ashiftrt lshiftrt])
383
384 ;; This code macro allows all native floating-point comparisons to be
385 ;; generated from the same template.
386 (define_code_macro fcond [unordered uneq unlt unle eq lt le])
387
388 ;; <u> expands to an empty string when doing a signed operation and
389 ;; "u" when doing an unsigned operation.
390 (define_code_attr u [(sign_extend "") (zero_extend "u")])
391
392 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
393 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
394
395 ;; <optab> expands to the name of the optab for a particular code.
396 (define_code_attr optab [(ashift "ashl")
397                          (ashiftrt "ashr")
398                          (lshiftrt "lshr")])
399
400 ;; <insn> expands to the name of the insn that implements a particular code.
401 (define_code_attr insn [(ashift "sll")
402                         (ashiftrt "sra")
403                         (lshiftrt "srl")])
404
405 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
406 (define_code_attr fcond [(unordered "un")
407                          (uneq "ueq")
408                          (unlt "ult")
409                          (unle "ule")
410                          (eq "eq")
411                          (lt "lt")
412                          (le "le")])
413 \f
414 ;; .........................
415 ;;
416 ;;      Branch, call and jump delay slots
417 ;;
418 ;; .........................
419
420 (define_delay (and (eq_attr "type" "branch")
421                    (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
422   [(eq_attr "can_delay" "yes")
423    (nil)
424    (and (eq_attr "branch_likely" "yes")
425         (eq_attr "can_delay" "yes"))])
426
427 (define_delay (eq_attr "type" "jump")
428   [(eq_attr "can_delay" "yes")
429    (nil)
430    (nil)])
431
432 (define_delay (and (eq_attr "type" "call")
433                    (eq_attr "jal_macro" "no"))
434   [(eq_attr "can_delay" "yes")
435    (nil)
436    (nil)])
437 \f
438 ;; Pipeline descriptions.
439 ;;
440 ;; generic.md provides a fallback for processors without a specific
441 ;; pipeline description.  It is derived from the old define_function_unit
442 ;; version and uses the "alu" and "imuldiv" units declared below.
443 ;;
444 ;; Some of the processor-specific files are also derived from old
445 ;; define_function_unit descriptions and simply override the parts of
446 ;; generic.md that don't apply.  The other processor-specific files
447 ;; are self-contained.
448 (define_automaton "alu,imuldiv")
449
450 (define_cpu_unit "alu" "alu")
451 (define_cpu_unit "imuldiv" "imuldiv")
452
453 (include "3000.md")
454 (include "4000.md")
455 (include "4100.md")
456 (include "4130.md")
457 (include "4300.md")
458 (include "4600.md")
459 (include "5000.md")
460 (include "5400.md")
461 (include "5500.md")
462 (include "6000.md")
463 (include "7000.md")
464 (include "9000.md")
465 (include "sb1.md")
466 (include "sr71k.md")
467 (include "generic.md")
468 \f
469 ;;
470 ;;  ....................
471 ;;
472 ;;      CONDITIONAL TRAPS
473 ;;
474 ;;  ....................
475 ;;
476
477 (define_insn "trap"
478   [(trap_if (const_int 1) (const_int 0))]
479   ""
480 {
481   if (ISA_HAS_COND_TRAP)
482     return "teq\t$0,$0";
483   else if (TARGET_MIPS16)
484     return "break 0";
485   else
486     return "break";
487 }
488   [(set_attr "type" "trap")])
489
490 (define_expand "conditional_trap"
491   [(trap_if (match_operator 0 "comparison_operator"
492                             [(match_dup 2) (match_dup 3)])
493             (match_operand 1 "const_int_operand"))]
494   "ISA_HAS_COND_TRAP"
495 {
496   if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
497       && operands[1] == const0_rtx)
498     {
499       mips_gen_conditional_trap (operands);
500       DONE;
501     }
502   else
503     FAIL;
504 })
505
506 (define_insn "*conditional_trap<mode>"
507   [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
508                                 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
509                                  (match_operand:GPR 2 "arith_operand" "dI")])
510             (const_int 0))]
511   "ISA_HAS_COND_TRAP"
512   "t%C0\t%z1,%2"
513   [(set_attr "type" "trap")])
514 \f
515 ;;
516 ;;  ....................
517 ;;
518 ;;      ADDITION
519 ;;
520 ;;  ....................
521 ;;
522
523 (define_insn "add<mode>3"
524   [(set (match_operand:ANYF 0 "register_operand" "=f")
525         (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
526                    (match_operand:ANYF 2 "register_operand" "f")))]
527   ""
528   "add.<fmt>\t%0,%1,%2"
529   [(set_attr "type" "fadd")
530    (set_attr "mode" "<UNITMODE>")])
531
532 (define_expand "add<mode>3"
533   [(set (match_operand:GPR 0 "register_operand")
534         (plus:GPR (match_operand:GPR 1 "register_operand")
535                   (match_operand:GPR 2 "arith_operand")))]
536   "")
537
538 (define_insn "*add<mode>3"
539   [(set (match_operand:GPR 0 "register_operand" "=d,d")
540         (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
541                   (match_operand:GPR 2 "arith_operand" "d,Q")))]
542   "!TARGET_MIPS16"
543   "@
544     <d>addu\t%0,%1,%2
545     <d>addiu\t%0,%1,%2"
546   [(set_attr "type" "arith")
547    (set_attr "mode" "<MODE>")])
548
549 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
550 ;; we don't have a constraint for $sp.  These insns will be generated by
551 ;; the save_restore_insns functions.
552
553 (define_insn "*add<mode>3_sp1"
554   [(set (reg:GPR 29)
555         (plus:GPR (reg:GPR 29)
556                   (match_operand:GPR 0 "const_arith_operand" "")))]
557   "TARGET_MIPS16"
558   "<d>addiu\t%$,%$,%0"
559   [(set_attr "type" "arith")
560    (set_attr "mode" "<MODE>")
561    (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
562                                       (const_int 4)
563                                       (const_int 8)))])
564
565 (define_insn "*add<mode>3_sp2"
566   [(set (match_operand:GPR 0 "register_operand" "=d")
567         (plus:GPR (reg:GPR 29)
568                   (match_operand:GPR 1 "const_arith_operand" "")))]
569   "TARGET_MIPS16"
570   "<d>addiu\t%0,%$,%1"
571   [(set_attr "type" "arith")
572    (set_attr "mode" "<MODE>")
573    (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
574                                       (const_int 4)
575                                       (const_int 8)))])
576
577 (define_insn "*add<mode>3_mips16"
578   [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
579         (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
580                   (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
581   "TARGET_MIPS16"
582   "@
583     <d>addiu\t%0,%2
584     <d>addiu\t%0,%1,%2
585     <d>addu\t%0,%1,%2"
586   [(set_attr "type" "arith")
587    (set_attr "mode" "<MODE>")
588    (set_attr_alternative "length"
589                 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
590                                (const_int 4)
591                                (const_int 8))
592                  (if_then_else (match_operand 2 "m16_simm4_1")
593                                (const_int 4)
594                                (const_int 8))
595                  (const_int 4)])])
596
597
598 ;; On the mips16, we can sometimes split an add of a constant which is
599 ;; a 4 byte instruction into two adds which are both 2 byte
600 ;; instructions.  There are two cases: one where we are adding a
601 ;; constant plus a register to another register, and one where we are
602 ;; simply adding a constant to a register.
603
604 (define_split
605   [(set (match_operand:SI 0 "register_operand")
606         (plus:SI (match_dup 0)
607                  (match_operand:SI 1 "const_int_operand")))]
608   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
609    && GET_CODE (operands[0]) == REG
610    && M16_REG_P (REGNO (operands[0]))
611    && GET_CODE (operands[1]) == CONST_INT
612    && ((INTVAL (operands[1]) > 0x7f
613         && INTVAL (operands[1]) <= 0x7f + 0x7f)
614        || (INTVAL (operands[1]) < - 0x80
615            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
616   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
617    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
618 {
619   HOST_WIDE_INT val = INTVAL (operands[1]);
620
621   if (val >= 0)
622     {
623       operands[1] = GEN_INT (0x7f);
624       operands[2] = GEN_INT (val - 0x7f);
625     }
626   else
627     {
628       operands[1] = GEN_INT (- 0x80);
629       operands[2] = GEN_INT (val + 0x80);
630     }
631 })
632
633 (define_split
634   [(set (match_operand:SI 0 "register_operand")
635         (plus:SI (match_operand:SI 1 "register_operand")
636                  (match_operand:SI 2 "const_int_operand")))]
637   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
638    && GET_CODE (operands[0]) == REG
639    && M16_REG_P (REGNO (operands[0]))
640    && GET_CODE (operands[1]) == REG
641    && M16_REG_P (REGNO (operands[1]))
642    && REGNO (operands[0]) != REGNO (operands[1])
643    && GET_CODE (operands[2]) == CONST_INT
644    && ((INTVAL (operands[2]) > 0x7
645         && INTVAL (operands[2]) <= 0x7 + 0x7f)
646        || (INTVAL (operands[2]) < - 0x8
647            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
648   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
649    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
650 {
651   HOST_WIDE_INT val = INTVAL (operands[2]);
652
653   if (val >= 0)
654     {
655       operands[2] = GEN_INT (0x7);
656       operands[3] = GEN_INT (val - 0x7);
657     }
658   else
659     {
660       operands[2] = GEN_INT (- 0x8);
661       operands[3] = GEN_INT (val + 0x8);
662     }
663 })
664
665 (define_split
666   [(set (match_operand:DI 0 "register_operand")
667         (plus:DI (match_dup 0)
668                  (match_operand:DI 1 "const_int_operand")))]
669   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
670    && GET_CODE (operands[0]) == REG
671    && M16_REG_P (REGNO (operands[0]))
672    && GET_CODE (operands[1]) == CONST_INT
673    && ((INTVAL (operands[1]) > 0xf
674         && INTVAL (operands[1]) <= 0xf + 0xf)
675        || (INTVAL (operands[1]) < - 0x10
676            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
677   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
678    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
679 {
680   HOST_WIDE_INT val = INTVAL (operands[1]);
681
682   if (val >= 0)
683     {
684       operands[1] = GEN_INT (0xf);
685       operands[2] = GEN_INT (val - 0xf);
686     }
687   else
688     {
689       operands[1] = GEN_INT (- 0x10);
690       operands[2] = GEN_INT (val + 0x10);
691     }
692 })
693
694 (define_split
695   [(set (match_operand:DI 0 "register_operand")
696         (plus:DI (match_operand:DI 1 "register_operand")
697                  (match_operand:DI 2 "const_int_operand")))]
698   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
699    && GET_CODE (operands[0]) == REG
700    && M16_REG_P (REGNO (operands[0]))
701    && GET_CODE (operands[1]) == REG
702    && M16_REG_P (REGNO (operands[1]))
703    && REGNO (operands[0]) != REGNO (operands[1])
704    && GET_CODE (operands[2]) == CONST_INT
705    && ((INTVAL (operands[2]) > 0x7
706         && INTVAL (operands[2]) <= 0x7 + 0xf)
707        || (INTVAL (operands[2]) < - 0x8
708            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
709   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
710    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
711 {
712   HOST_WIDE_INT val = INTVAL (operands[2]);
713
714   if (val >= 0)
715     {
716       operands[2] = GEN_INT (0x7);
717       operands[3] = GEN_INT (val - 0x7);
718     }
719   else
720     {
721       operands[2] = GEN_INT (- 0x8);
722       operands[3] = GEN_INT (val + 0x8);
723     }
724 })
725
726 (define_insn "*addsi3_extended"
727   [(set (match_operand:DI 0 "register_operand" "=d,d")
728         (sign_extend:DI
729              (plus:SI (match_operand:SI 1 "register_operand" "d,d")
730                       (match_operand:SI 2 "arith_operand" "d,Q"))))]
731   "TARGET_64BIT && !TARGET_MIPS16"
732   "@
733     addu\t%0,%1,%2
734     addiu\t%0,%1,%2"
735   [(set_attr "type" "arith")
736    (set_attr "mode" "SI")])
737
738 ;; Split this insn so that the addiu splitters can have a crack at it.
739 ;; Use a conservative length estimate until the split.
740 (define_insn_and_split "*addsi3_extended_mips16"
741   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
742         (sign_extend:DI
743              (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
744                       (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
745   "TARGET_64BIT && TARGET_MIPS16"
746   "#"
747   "&& reload_completed"
748   [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
749   { operands[3] = gen_lowpart (SImode, operands[0]); }
750   [(set_attr "type" "arith")
751    (set_attr "mode" "SI")
752    (set_attr "extended_mips16" "yes")])
753 \f
754 ;;
755 ;;  ....................
756 ;;
757 ;;      SUBTRACTION
758 ;;
759 ;;  ....................
760 ;;
761
762 (define_insn "sub<mode>3"
763   [(set (match_operand:ANYF 0 "register_operand" "=f")
764         (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
765                     (match_operand:ANYF 2 "register_operand" "f")))]
766   ""
767   "sub.<fmt>\t%0,%1,%2"
768   [(set_attr "type" "fadd")
769    (set_attr "mode" "<UNITMODE>")])
770
771 (define_insn "sub<mode>3"
772   [(set (match_operand:GPR 0 "register_operand" "=d")
773         (minus:GPR (match_operand:GPR 1 "register_operand" "d")
774                    (match_operand:GPR 2 "register_operand" "d")))]
775   ""
776   "<d>subu\t%0,%1,%2"
777   [(set_attr "type" "arith")
778    (set_attr "mode" "<MODE>")])
779
780 (define_insn "*subsi3_extended"
781   [(set (match_operand:DI 0 "register_operand" "=d")
782         (sign_extend:DI
783             (minus:SI (match_operand:SI 1 "register_operand" "d")
784                       (match_operand:SI 2 "register_operand" "d"))))]
785   "TARGET_64BIT"
786   "subu\t%0,%1,%2"
787   [(set_attr "type" "arith")
788    (set_attr "mode" "DI")])
789 \f
790 ;;
791 ;;  ....................
792 ;;
793 ;;      MULTIPLICATION
794 ;;
795 ;;  ....................
796 ;;
797
798 (define_expand "mul<mode>3"
799   [(set (match_operand:SCALARF 0 "register_operand")
800         (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
801                       (match_operand:SCALARF 2 "register_operand")))]
802   ""
803   "")
804
805 (define_insn "*mul<mode>3"
806   [(set (match_operand:SCALARF 0 "register_operand" "=f")
807         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
808                       (match_operand:SCALARF 2 "register_operand" "f")))]
809   "!TARGET_4300_MUL_FIX"
810   "mul.<fmt>\t%0,%1,%2"
811   [(set_attr "type" "fmul")
812    (set_attr "mode" "<MODE>")])
813
814 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
815 ;; operands may corrupt immediately following multiplies. This is a
816 ;; simple fix to insert NOPs.
817
818 (define_insn "*mul<mode>3_r4300"
819   [(set (match_operand:SCALARF 0 "register_operand" "=f")
820         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
821                       (match_operand:SCALARF 2 "register_operand" "f")))]
822   "TARGET_4300_MUL_FIX"
823   "mul.<fmt>\t%0,%1,%2\;nop"
824   [(set_attr "type" "fmul")
825    (set_attr "mode" "<MODE>")
826    (set_attr "length" "8")])
827
828 (define_insn "mulv2sf3"
829   [(set (match_operand:V2SF 0 "register_operand" "=f")
830         (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
831                    (match_operand:V2SF 2 "register_operand" "f")))]
832   "TARGET_PAIRED_SINGLE_FLOAT"
833   "mul.ps\t%0,%1,%2"
834   [(set_attr "type" "fmul")
835    (set_attr "mode" "SF")])
836
837 ;; The original R4000 has a cpu bug.  If a double-word or a variable
838 ;; shift executes while an integer multiplication is in progress, the
839 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
840 ;; with the mult on the R4000.
841 ;;
842 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
843 ;; (also valid for MIPS R4000MC processors):
844 ;;
845 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
846 ;;      this errata description.
847 ;;      The following code sequence causes the R4000 to incorrectly
848 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
849 ;;      instruction.  If the dsra32 instruction is executed during an
850 ;;      integer multiply, the dsra32 will only shift by the amount in
851 ;;      specified in the instruction rather than the amount plus 32
852 ;;      bits.
853 ;;      instruction 1:          mult    rs,rt           integer multiply
854 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
855 ;;                                                      right arithmetic + 32
856 ;;      Workaround: A dsra32 instruction placed after an integer
857 ;;      multiply should not be one of the 11 instructions after the
858 ;;      multiply instruction."
859 ;;
860 ;; and:
861 ;;
862 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
863 ;;      the following description.
864 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
865 ;;      64-bit versions) may produce incorrect results under the
866 ;;      following conditions:
867 ;;      1) An integer multiply is currently executing
868 ;;      2) These types of shift instructions are executed immediately
869 ;;         following an integer divide instruction.
870 ;;      Workaround:
871 ;;      1) Make sure no integer multiply is running wihen these
872 ;;         instruction are executed.  If this cannot be predicted at
873 ;;         compile time, then insert a "mfhi" to R0 instruction
874 ;;         immediately after the integer multiply instruction.  This
875 ;;         will cause the integer multiply to complete before the shift
876 ;;         is executed.
877 ;;      2) Separate integer divide and these two classes of shift
878 ;;         instructions by another instruction or a noop."
879 ;;
880 ;; These processors have PRId values of 0x00004220 and 0x00004300,
881 ;; respectively.
882
883 (define_expand "mul<mode>3"
884   [(set (match_operand:GPR 0 "register_operand")
885         (mult:GPR (match_operand:GPR 1 "register_operand")
886                   (match_operand:GPR 2 "register_operand")))]
887   ""
888 {
889   if (GENERATE_MULT3_<MODE>)
890     emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
891   else if (!TARGET_FIX_R4000)
892     emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
893                                         operands[2]));
894   else
895     emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
896   DONE;
897 })
898
899 (define_insn "mulsi3_mult3"
900   [(set (match_operand:SI 0 "register_operand" "=d,l")
901         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
902                  (match_operand:SI 2 "register_operand" "d,d")))
903    (clobber (match_scratch:SI 3 "=h,h"))
904    (clobber (match_scratch:SI 4 "=l,X"))]
905   "GENERATE_MULT3_SI"
906 {
907   if (which_alternative == 1)
908     return "mult\t%1,%2";
909   if (TARGET_MAD
910       || TARGET_MIPS5400
911       || TARGET_MIPS5500
912       || TARGET_MIPS7000
913       || TARGET_MIPS9000
914       || ISA_MIPS32
915       || ISA_MIPS32R2
916       || ISA_MIPS64)
917     return "mul\t%0,%1,%2";
918   return "mult\t%0,%1,%2";
919 }
920   [(set_attr "type" "imul")
921    (set_attr "mode" "SI")])
922
923 (define_insn "muldi3_mult3"
924   [(set (match_operand:DI 0 "register_operand" "=d")
925         (mult:DI (match_operand:DI 1 "register_operand" "d")
926                  (match_operand:DI 2 "register_operand" "d")))
927    (clobber (match_scratch:DI 3 "=h"))
928    (clobber (match_scratch:DI 4 "=l"))]
929   "TARGET_64BIT && GENERATE_MULT3_DI"
930   "dmult\t%0,%1,%2"
931   [(set_attr "type" "imul")
932    (set_attr "mode" "DI")])
933
934 ;; If a register gets allocated to LO, and we spill to memory, the reload
935 ;; will include a move from LO to a GPR.  Merge it into the multiplication
936 ;; if it can set the GPR directly.
937 ;;
938 ;; Operand 0: LO
939 ;; Operand 1: GPR (1st multiplication operand)
940 ;; Operand 2: GPR (2nd multiplication operand)
941 ;; Operand 3: HI
942 ;; Operand 4: GPR (destination)
943 (define_peephole2
944   [(parallel
945        [(set (match_operand:SI 0 "register_operand")
946              (mult:SI (match_operand:SI 1 "register_operand")
947                       (match_operand:SI 2 "register_operand")))
948         (clobber (match_operand:SI 3 "register_operand"))
949         (clobber (scratch:SI))])
950    (set (match_operand:SI 4 "register_operand")
951         (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
952   "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
953   [(parallel
954        [(set (match_dup 4)
955              (mult:SI (match_dup 1)
956                       (match_dup 2)))
957         (clobber (match_dup 3))
958         (clobber (match_dup 0))])])
959
960 (define_insn "mul<mode>3_internal"
961   [(set (match_operand:GPR 0 "register_operand" "=l")
962         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
963                   (match_operand:GPR 2 "register_operand" "d")))
964    (clobber (match_scratch:GPR 3 "=h"))]
965   "!TARGET_FIX_R4000"
966   "<d>mult\t%1,%2"
967   [(set_attr "type" "imul")
968    (set_attr "mode" "<MODE>")])
969
970 (define_insn "mul<mode>3_r4000"
971   [(set (match_operand:GPR 0 "register_operand" "=d")
972         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
973                   (match_operand:GPR 2 "register_operand" "d")))
974    (clobber (match_scratch:GPR 3 "=h"))
975    (clobber (match_scratch:GPR 4 "=l"))]
976   "TARGET_FIX_R4000"
977   "<d>mult\t%1,%2\;mflo\t%0"
978   [(set_attr "type" "imul")
979    (set_attr "mode" "<MODE>")
980    (set_attr "length" "8")])
981
982 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
983 ;; of "mult; mflo".  They have the same latency, but the first form gives
984 ;; us an extra cycle to compute the operands.
985
986 ;; Operand 0: LO
987 ;; Operand 1: GPR (1st multiplication operand)
988 ;; Operand 2: GPR (2nd multiplication operand)
989 ;; Operand 3: HI
990 ;; Operand 4: GPR (destination)
991 (define_peephole2
992   [(parallel
993        [(set (match_operand:SI 0 "register_operand")
994              (mult:SI (match_operand:SI 1 "register_operand")
995                       (match_operand:SI 2 "register_operand")))
996         (clobber (match_operand:SI 3 "register_operand"))])
997    (set (match_operand:SI 4 "register_operand")
998         (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
999   "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1000   [(set (match_dup 0)
1001         (const_int 0))
1002    (parallel
1003        [(set (match_dup 0)
1004              (plus:SI (mult:SI (match_dup 1)
1005                                (match_dup 2))
1006                       (match_dup 0)))
1007         (set (match_dup 4)
1008              (plus:SI (mult:SI (match_dup 1)
1009                                (match_dup 2))
1010                       (match_dup 0)))
1011         (clobber (match_dup 3))])])
1012
1013 ;; Multiply-accumulate patterns
1014
1015 ;; For processors that can copy the output to a general register:
1016 ;;
1017 ;; The all-d alternative is needed because the combiner will find this
1018 ;; pattern and then register alloc/reload will move registers around to
1019 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1020 ;;
1021 ;; The last alternative should be made slightly less desirable, but adding
1022 ;; "?" to the constraint is too strong, and causes values to be loaded into
1023 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1024 ;; trick.
1025 (define_insn "*mul_acc_si"
1026   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1027         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1028                           (match_operand:SI 2 "register_operand" "d,d,d"))
1029                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1030    (clobber (match_scratch:SI 4 "=h,h,h"))
1031    (clobber (match_scratch:SI 5 "=X,3,l"))
1032    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1033   "(TARGET_MIPS3900
1034    || ISA_HAS_MADD_MSUB)
1035    && !TARGET_MIPS16"
1036 {
1037   static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1038   if (which_alternative == 2)
1039     return "#";
1040   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1041     return "#";
1042   return madd[which_alternative];
1043 }
1044   [(set_attr "type"     "imadd,imadd,multi")
1045    (set_attr "mode"     "SI")
1046    (set_attr "length"   "4,4,8")])
1047
1048 ;; Split the above insn if we failed to get LO allocated.
1049 (define_split
1050   [(set (match_operand:SI 0 "register_operand")
1051         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1052                           (match_operand:SI 2 "register_operand"))
1053                  (match_operand:SI 3 "register_operand")))
1054    (clobber (match_scratch:SI 4))
1055    (clobber (match_scratch:SI 5))
1056    (clobber (match_scratch:SI 6))]
1057   "reload_completed && !TARGET_DEBUG_D_MODE
1058    && GP_REG_P (true_regnum (operands[0]))
1059    && GP_REG_P (true_regnum (operands[3]))"
1060   [(parallel [(set (match_dup 6)
1061                    (mult:SI (match_dup 1) (match_dup 2)))
1062               (clobber (match_dup 4))
1063               (clobber (match_dup 5))])
1064    (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1065   "")
1066
1067 ;; Splitter to copy result of MADD to a general register
1068 (define_split
1069   [(set (match_operand:SI                   0 "register_operand")
1070         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1071                           (match_operand:SI 2 "register_operand"))
1072                  (match_operand:SI          3 "register_operand")))
1073    (clobber (match_scratch:SI               4))
1074    (clobber (match_scratch:SI               5))
1075    (clobber (match_scratch:SI               6))]
1076   "reload_completed && !TARGET_DEBUG_D_MODE
1077    && GP_REG_P (true_regnum (operands[0]))
1078    && true_regnum (operands[3]) == LO_REGNUM"
1079   [(parallel [(set (match_dup 3)
1080                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1081                             (match_dup 3)))
1082               (clobber (match_dup 4))
1083               (clobber (match_dup 5))
1084               (clobber (match_dup 6))])
1085    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1086   "")
1087
1088 (define_insn "*macc"
1089   [(set (match_operand:SI 0 "register_operand" "=l,d")
1090         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1091                           (match_operand:SI 2 "register_operand" "d,d"))
1092                  (match_operand:SI 3 "register_operand" "0,l")))
1093    (clobber (match_scratch:SI 4 "=h,h"))
1094    (clobber (match_scratch:SI 5 "=X,3"))]
1095   "ISA_HAS_MACC"
1096 {
1097   if (which_alternative == 1)
1098     return "macc\t%0,%1,%2";
1099   else if (TARGET_MIPS5500)
1100     return "madd\t%1,%2";
1101   else
1102     /* The VR4130 assumes that there is a two-cycle latency between a macc
1103        that "writes" to $0 and an instruction that reads from it.  We avoid
1104        this by assigning to $1 instead.  */
1105     return "%[macc\t%@,%1,%2%]";
1106 }
1107   [(set_attr "type" "imadd")
1108    (set_attr "mode" "SI")])
1109
1110 (define_insn "*msac"
1111   [(set (match_operand:SI 0 "register_operand" "=l,d")
1112         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1113                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1114                            (match_operand:SI 3 "register_operand" "d,d"))))
1115    (clobber (match_scratch:SI 4 "=h,h"))
1116    (clobber (match_scratch:SI 5 "=X,1"))]
1117   "ISA_HAS_MSAC"
1118 {
1119   if (which_alternative == 1)
1120     return "msac\t%0,%2,%3";
1121   else if (TARGET_MIPS5500)
1122     return "msub\t%2,%3";
1123   else
1124     return "msac\t$0,%2,%3";
1125 }
1126   [(set_attr "type"     "imadd")
1127    (set_attr "mode"     "SI")])
1128
1129 ;; An msac-like instruction implemented using negation and a macc.
1130 (define_insn_and_split "*msac_using_macc"
1131   [(set (match_operand:SI 0 "register_operand" "=l,d")
1132         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1133                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1134                            (match_operand:SI 3 "register_operand" "d,d"))))
1135    (clobber (match_scratch:SI 4 "=h,h"))
1136    (clobber (match_scratch:SI 5 "=X,1"))
1137    (clobber (match_scratch:SI 6 "=d,d"))]
1138   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1139   "#"
1140   "&& reload_completed"
1141   [(set (match_dup 6)
1142         (neg:SI (match_dup 3)))
1143    (parallel
1144        [(set (match_dup 0)
1145              (plus:SI (mult:SI (match_dup 2)
1146                                (match_dup 6))
1147                       (match_dup 1)))
1148         (clobber (match_dup 4))
1149         (clobber (match_dup 5))])]
1150   ""
1151   [(set_attr "type"     "imadd")
1152    (set_attr "length"   "8")])
1153
1154 ;; Patterns generated by the define_peephole2 below.
1155
1156 (define_insn "*macc2"
1157   [(set (match_operand:SI 0 "register_operand" "=l")
1158         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1159                           (match_operand:SI 2 "register_operand" "d"))
1160                  (match_dup 0)))
1161    (set (match_operand:SI 3 "register_operand" "=d")
1162         (plus:SI (mult:SI (match_dup 1)
1163                           (match_dup 2))
1164                  (match_dup 0)))
1165    (clobber (match_scratch:SI 4 "=h"))]
1166   "ISA_HAS_MACC && reload_completed"
1167   "macc\t%3,%1,%2"
1168   [(set_attr "type"     "imadd")
1169    (set_attr "mode"     "SI")])
1170
1171 (define_insn "*msac2"
1172   [(set (match_operand:SI 0 "register_operand" "=l")
1173         (minus:SI (match_dup 0)
1174                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1175                            (match_operand:SI 2 "register_operand" "d"))))
1176    (set (match_operand:SI 3 "register_operand" "=d")
1177         (minus:SI (match_dup 0)
1178                   (mult:SI (match_dup 1)
1179                            (match_dup 2))))
1180    (clobber (match_scratch:SI 4 "=h"))]
1181   "ISA_HAS_MSAC && reload_completed"
1182   "msac\t%3,%1,%2"
1183   [(set_attr "type"     "imadd")
1184    (set_attr "mode"     "SI")])
1185
1186 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1187 ;; Similarly msac.
1188 ;;
1189 ;; Operand 0: LO
1190 ;; Operand 1: macc/msac
1191 ;; Operand 2: HI
1192 ;; Operand 3: GPR (destination)
1193 (define_peephole2
1194   [(parallel
1195        [(set (match_operand:SI 0 "register_operand")
1196              (match_operand:SI 1 "macc_msac_operand"))
1197         (clobber (match_operand:SI 2 "register_operand"))
1198         (clobber (scratch:SI))])
1199    (set (match_operand:SI 3 "register_operand")
1200         (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1201   ""
1202   [(parallel [(set (match_dup 0)
1203                    (match_dup 1))
1204               (set (match_dup 3)
1205                    (match_dup 1))
1206               (clobber (match_dup 2))])]
1207   "")
1208
1209 ;; When we have a three-address multiplication instruction, it should
1210 ;; be faster to do a separate multiply and add, rather than moving
1211 ;; something into LO in order to use a macc instruction.
1212 ;;
1213 ;; This peephole needs a scratch register to cater for the case when one
1214 ;; of the multiplication operands is the same as the destination.
1215 ;;
1216 ;; Operand 0: GPR (scratch)
1217 ;; Operand 1: LO
1218 ;; Operand 2: GPR (addend)
1219 ;; Operand 3: GPR (destination)
1220 ;; Operand 4: macc/msac
1221 ;; Operand 5: HI
1222 ;; Operand 6: new multiplication
1223 ;; Operand 7: new addition/subtraction
1224 (define_peephole2
1225   [(match_scratch:SI 0 "d")
1226    (set (match_operand:SI 1 "register_operand")
1227         (match_operand:SI 2 "register_operand"))
1228    (match_dup 0)
1229    (parallel
1230        [(set (match_operand:SI 3 "register_operand")
1231              (match_operand:SI 4 "macc_msac_operand"))
1232         (clobber (match_operand:SI 5 "register_operand"))
1233         (clobber (match_dup 1))])]
1234   "GENERATE_MULT3_SI
1235    && true_regnum (operands[1]) == LO_REGNUM
1236    && peep2_reg_dead_p (2, operands[1])
1237    && GP_REG_P (true_regnum (operands[3]))"
1238   [(parallel [(set (match_dup 0)
1239                    (match_dup 6))
1240               (clobber (match_dup 5))
1241               (clobber (match_dup 1))])
1242    (set (match_dup 3)
1243         (match_dup 7))]
1244 {
1245   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1246   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1247                                 operands[2], operands[0]);
1248 })
1249
1250 ;; Same as above, except LO is the initial target of the macc.
1251 ;;
1252 ;; Operand 0: GPR (scratch)
1253 ;; Operand 1: LO
1254 ;; Operand 2: GPR (addend)
1255 ;; Operand 3: macc/msac
1256 ;; Operand 4: HI
1257 ;; Operand 5: GPR (destination)
1258 ;; Operand 6: new multiplication
1259 ;; Operand 7: new addition/subtraction
1260 (define_peephole2
1261   [(match_scratch:SI 0 "d")
1262    (set (match_operand:SI 1 "register_operand")
1263         (match_operand:SI 2 "register_operand"))
1264    (match_dup 0)
1265    (parallel
1266        [(set (match_dup 1)
1267              (match_operand:SI 3 "macc_msac_operand"))
1268         (clobber (match_operand:SI 4 "register_operand"))
1269         (clobber (scratch:SI))])
1270    (match_dup 0)
1271    (set (match_operand:SI 5 "register_operand")
1272         (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1273   "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1274   [(parallel [(set (match_dup 0)
1275                    (match_dup 6))
1276               (clobber (match_dup 4))
1277               (clobber (match_dup 1))])
1278    (set (match_dup 5)
1279         (match_dup 7))]
1280 {
1281   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1282   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1283                                 operands[2], operands[0]);
1284 })
1285
1286 (define_insn "*mul_sub_si"
1287   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1288         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1289                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1290                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1291    (clobber (match_scratch:SI 4 "=h,h,h"))
1292    (clobber (match_scratch:SI 5 "=X,1,l"))
1293    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1294   "ISA_HAS_MADD_MSUB"
1295   "@
1296    msub\t%2,%3
1297    #
1298    #"
1299   [(set_attr "type"     "imadd,multi,multi")
1300    (set_attr "mode"     "SI")
1301    (set_attr "length"   "4,8,8")])
1302
1303 ;; Split the above insn if we failed to get LO allocated.
1304 (define_split
1305   [(set (match_operand:SI 0 "register_operand")
1306         (minus:SI (match_operand:SI 1 "register_operand")
1307                   (mult:SI (match_operand:SI 2 "register_operand")
1308                            (match_operand:SI 3 "register_operand"))))
1309    (clobber (match_scratch:SI 4))
1310    (clobber (match_scratch:SI 5))
1311    (clobber (match_scratch:SI 6))]
1312   "reload_completed && !TARGET_DEBUG_D_MODE
1313    && GP_REG_P (true_regnum (operands[0]))
1314    && GP_REG_P (true_regnum (operands[1]))"
1315   [(parallel [(set (match_dup 6)
1316                    (mult:SI (match_dup 2) (match_dup 3)))
1317               (clobber (match_dup 4))
1318               (clobber (match_dup 5))])
1319    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1320   "")
1321
1322 ;; Splitter to copy result of MSUB to a general register
1323 (define_split
1324   [(set (match_operand:SI 0 "register_operand")
1325         (minus:SI (match_operand:SI 1 "register_operand")
1326                   (mult:SI (match_operand:SI 2 "register_operand")
1327                            (match_operand:SI 3 "register_operand"))))
1328    (clobber (match_scratch:SI 4))
1329    (clobber (match_scratch:SI 5))
1330    (clobber (match_scratch:SI 6))]
1331   "reload_completed && !TARGET_DEBUG_D_MODE
1332    && GP_REG_P (true_regnum (operands[0]))
1333    && true_regnum (operands[1]) == LO_REGNUM"
1334   [(parallel [(set (match_dup 1)
1335                    (minus:SI (match_dup 1)
1336                              (mult:SI (match_dup 2) (match_dup 3))))
1337               (clobber (match_dup 4))
1338               (clobber (match_dup 5))
1339               (clobber (match_dup 6))])
1340    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1341   "")
1342
1343 (define_insn "*muls"
1344   [(set (match_operand:SI                  0 "register_operand" "=l,d")
1345         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1346                          (match_operand:SI 2 "register_operand" "d,d"))))
1347    (clobber (match_scratch:SI              3                    "=h,h"))
1348    (clobber (match_scratch:SI              4                    "=X,l"))]
1349   "ISA_HAS_MULS"
1350   "@
1351    muls\t$0,%1,%2
1352    muls\t%0,%1,%2"
1353   [(set_attr "type"     "imul")
1354    (set_attr "mode"     "SI")])
1355
1356 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1357
1358 (define_expand "<u>mulsidi3"
1359   [(parallel
1360       [(set (match_operand:DI 0 "register_operand")
1361             (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1362                      (any_extend:DI (match_operand:SI 2 "register_operand"))))
1363        (clobber (scratch:DI))
1364        (clobber (scratch:DI))
1365        (clobber (scratch:DI))])]
1366   "!TARGET_64BIT || !TARGET_FIX_R4000"
1367 {
1368   if (!TARGET_64BIT)
1369     {
1370       if (!TARGET_FIX_R4000)
1371         emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1372                                                    operands[2]));
1373       else
1374         emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1375                                                 operands[2]));
1376       DONE;
1377     }
1378 })
1379
1380 (define_insn "<u>mulsidi3_32bit_internal"
1381   [(set (match_operand:DI 0 "register_operand" "=x")
1382         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1383                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1384   "!TARGET_64BIT && !TARGET_FIX_R4000"
1385   "mult<u>\t%1,%2"
1386   [(set_attr "type" "imul")
1387    (set_attr "mode" "SI")])
1388
1389 (define_insn "<u>mulsidi3_32bit_r4000"
1390   [(set (match_operand:DI 0 "register_operand" "=d")
1391         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1392                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1393    (clobber (match_scratch:DI 3 "=x"))]
1394   "!TARGET_64BIT && TARGET_FIX_R4000"
1395   "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1396   [(set_attr "type" "imul")
1397    (set_attr "mode" "SI")
1398    (set_attr "length" "12")])
1399
1400 (define_insn_and_split "*<u>mulsidi3_64bit"
1401   [(set (match_operand:DI 0 "register_operand" "=d")
1402         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1403                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1404    (clobber (match_scratch:DI 3 "=l"))
1405    (clobber (match_scratch:DI 4 "=h"))
1406    (clobber (match_scratch:DI 5 "=d"))]
1407   "TARGET_64BIT && !TARGET_FIX_R4000"
1408   "#"
1409   "&& reload_completed"
1410   [(parallel
1411        [(set (match_dup 3)
1412              (sign_extend:DI
1413                 (mult:SI (match_dup 1)
1414                          (match_dup 2))))
1415         (set (match_dup 4)
1416              (ashiftrt:DI
1417                 (mult:DI (any_extend:DI (match_dup 1))
1418                          (any_extend:DI (match_dup 2)))
1419                 (const_int 32)))])
1420
1421    ;; OP5 <- LO, OP0 <- HI
1422    (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1423    (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1424
1425    ;; Zero-extend OP5.
1426    (set (match_dup 5)
1427         (ashift:DI (match_dup 5)
1428                    (const_int 32)))
1429    (set (match_dup 5)
1430         (lshiftrt:DI (match_dup 5)
1431                      (const_int 32)))
1432
1433    ;; Shift OP0 into place.
1434    (set (match_dup 0)
1435         (ashift:DI (match_dup 0)
1436                    (const_int 32)))
1437
1438    ;; OR the two halves together
1439    (set (match_dup 0)
1440         (ior:DI (match_dup 0)
1441                 (match_dup 5)))]
1442   ""
1443   [(set_attr "type" "imul")
1444    (set_attr "mode" "SI")
1445    (set_attr "length" "24")])
1446
1447 (define_insn "*<u>mulsidi3_64bit_parts"
1448   [(set (match_operand:DI 0 "register_operand" "=l")
1449         (sign_extend:DI
1450            (mult:SI (match_operand:SI 2 "register_operand" "d")
1451                     (match_operand:SI 3 "register_operand" "d"))))
1452    (set (match_operand:DI 1 "register_operand" "=h")
1453         (ashiftrt:DI
1454            (mult:DI (any_extend:DI (match_dup 2))
1455                     (any_extend:DI (match_dup 3)))
1456            (const_int 32)))]
1457   "TARGET_64BIT && !TARGET_FIX_R4000"
1458   "mult<u>\t%2,%3"
1459   [(set_attr "type" "imul")
1460    (set_attr "mode" "SI")])
1461
1462 ;; Widening multiply with negation.
1463 (define_insn "*muls<u>_di"
1464   [(set (match_operand:DI 0 "register_operand" "=x")
1465         (neg:DI
1466          (mult:DI
1467           (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1468           (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1469   "!TARGET_64BIT && ISA_HAS_MULS"
1470   "muls<u>\t$0,%1,%2"
1471   [(set_attr "type" "imul")
1472    (set_attr "mode" "SI")])
1473
1474 (define_insn "*msac<u>_di"
1475   [(set (match_operand:DI 0 "register_operand" "=x")
1476         (minus:DI
1477            (match_operand:DI 3 "register_operand" "0")
1478            (mult:DI
1479               (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1480               (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1481   "!TARGET_64BIT && ISA_HAS_MSAC"
1482 {
1483   if (TARGET_MIPS5500)
1484     return "msub<u>\t%1,%2";
1485   else
1486     return "msac<u>\t$0,%1,%2";
1487 }
1488   [(set_attr "type" "imadd")
1489    (set_attr "mode" "SI")])
1490
1491 ;; _highpart patterns
1492
1493 (define_expand "<su>mulsi3_highpart"
1494   [(set (match_operand:SI 0 "register_operand")
1495         (truncate:SI
1496          (lshiftrt:DI
1497           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1498                    (any_extend:DI (match_operand:SI 2 "register_operand")))
1499           (const_int 32))))]
1500   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1501 {
1502   if (ISA_HAS_MULHI)
1503     emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1504                                                        operands[1],
1505                                                        operands[2]));
1506   else
1507     emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1508                                                  operands[2]));
1509   DONE;
1510 })
1511
1512 (define_insn "<su>mulsi3_highpart_internal"
1513   [(set (match_operand:SI 0 "register_operand" "=h")
1514         (truncate:SI
1515          (lshiftrt:DI
1516           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1517                    (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1518           (const_int 32))))
1519    (clobber (match_scratch:SI 3 "=l"))]
1520   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1521   "mult<u>\t%1,%2"
1522   [(set_attr "type" "imul")
1523    (set_attr "mode" "SI")])
1524
1525 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1526   [(set (match_operand:SI 0 "register_operand" "=h,d")
1527         (truncate:SI
1528          (lshiftrt:DI
1529           (mult:DI
1530            (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1531            (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1532           (const_int 32))))
1533    (clobber (match_scratch:SI 3 "=l,l"))
1534    (clobber (match_scratch:SI 4 "=X,h"))]
1535   "ISA_HAS_MULHI"
1536   "@
1537    mult<u>\t%1,%2
1538    mulhi<u>\t%0,%1,%2"
1539   [(set_attr "type" "imul")
1540    (set_attr "mode" "SI")])
1541
1542 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1543   [(set (match_operand:SI 0 "register_operand" "=h,d")
1544         (truncate:SI
1545          (lshiftrt:DI
1546           (neg:DI
1547            (mult:DI
1548             (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1549             (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1550           (const_int 32))))
1551    (clobber (match_scratch:SI 3 "=l,l"))
1552    (clobber (match_scratch:SI 4 "=X,h"))]
1553   "ISA_HAS_MULHI"
1554   "@
1555    mulshi<u>\t%.,%1,%2
1556    mulshi<u>\t%0,%1,%2"
1557   [(set_attr "type" "imul")
1558    (set_attr "mode" "SI")])
1559
1560 ;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
1561 ;; errata MD(0), which says that dmultu does not always produce the
1562 ;; correct result.
1563 (define_insn "<su>muldi3_highpart"
1564   [(set (match_operand:DI 0 "register_operand" "=h")
1565         (truncate:DI
1566          (lshiftrt:TI
1567           (mult:TI
1568            (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1569            (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1570           (const_int 64))))
1571    (clobber (match_scratch:DI 3 "=l"))]
1572   "TARGET_64BIT && !TARGET_FIX_R4000
1573    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1574   "dmult<u>\t%1,%2"
1575   [(set_attr "type" "imul")
1576    (set_attr "mode" "DI")])
1577
1578 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1579 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
1580
1581 (define_insn "madsi"
1582   [(set (match_operand:SI 0 "register_operand" "+l")
1583         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1584                           (match_operand:SI 2 "register_operand" "d"))
1585                  (match_dup 0)))
1586    (clobber (match_scratch:SI 3 "=h"))]
1587   "TARGET_MAD"
1588   "mad\t%1,%2"
1589   [(set_attr "type"     "imadd")
1590    (set_attr "mode"     "SI")])
1591
1592 (define_insn "*<su>mul_acc_di"
1593   [(set (match_operand:DI 0 "register_operand" "=x")
1594         (plus:DI
1595          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1596                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1597          (match_operand:DI 3 "register_operand" "0")))]
1598   "(TARGET_MAD || ISA_HAS_MACC)
1599    && !TARGET_64BIT"
1600 {
1601   if (TARGET_MAD)
1602     return "mad<u>\t%1,%2";
1603   else if (TARGET_MIPS5500)
1604     return "madd<u>\t%1,%2";
1605   else
1606     /* See comment in *macc.  */
1607     return "%[macc<u>\t%@,%1,%2%]";
1608 }
1609   [(set_attr "type" "imadd")
1610    (set_attr "mode" "SI")])
1611
1612 ;; Floating point multiply accumulate instructions.
1613
1614 (define_insn "*madd<mode>"
1615   [(set (match_operand:ANYF 0 "register_operand" "=f")
1616         (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1617                               (match_operand:ANYF 2 "register_operand" "f"))
1618                    (match_operand:ANYF 3 "register_operand" "f")))]
1619   "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1620   "madd.<fmt>\t%0,%3,%1,%2"
1621   [(set_attr "type" "fmadd")
1622    (set_attr "mode" "<UNITMODE>")])
1623
1624 (define_insn "*msub<mode>"
1625   [(set (match_operand:ANYF 0 "register_operand" "=f")
1626         (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1627                                (match_operand:ANYF 2 "register_operand" "f"))
1628                     (match_operand:ANYF 3 "register_operand" "f")))]
1629   "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1630   "msub.<fmt>\t%0,%3,%1,%2"
1631   [(set_attr "type" "fmadd")
1632    (set_attr "mode" "<UNITMODE>")])
1633
1634 (define_insn "*nmadd<mode>"
1635   [(set (match_operand:ANYF 0 "register_operand" "=f")
1636         (neg:ANYF (plus:ANYF
1637                    (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1638                               (match_operand:ANYF 2 "register_operand" "f"))
1639                    (match_operand:ANYF 3 "register_operand" "f"))))]
1640   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1641    && HONOR_SIGNED_ZEROS (<MODE>mode)"
1642   "nmadd.<fmt>\t%0,%3,%1,%2"
1643   [(set_attr "type" "fmadd")
1644    (set_attr "mode" "<UNITMODE>")])
1645
1646 (define_insn "*nmadd<mode>_fastmath"
1647   [(set (match_operand:ANYF 0 "register_operand" "=f")
1648         (minus:ANYF
1649          (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1650                     (match_operand:ANYF 2 "register_operand" "f"))
1651          (match_operand:ANYF 3 "register_operand" "f")))]
1652   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1653    && !HONOR_SIGNED_ZEROS (<MODE>mode)"
1654   "nmadd.<fmt>\t%0,%3,%1,%2"
1655   [(set_attr "type" "fmadd")
1656    (set_attr "mode" "<UNITMODE>")])
1657
1658 (define_insn "*nmsub<mode>"
1659   [(set (match_operand:ANYF 0 "register_operand" "=f")
1660         (neg:ANYF (minus:ANYF
1661                    (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1662                               (match_operand:ANYF 3 "register_operand" "f"))
1663                    (match_operand:ANYF 1 "register_operand" "f"))))]
1664   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1665    && HONOR_SIGNED_ZEROS (<MODE>mode)"
1666   "nmsub.<fmt>\t%0,%1,%2,%3"
1667   [(set_attr "type" "fmadd")
1668    (set_attr "mode" "<UNITMODE>")])
1669
1670 (define_insn "*nmsub<mode>_fastmath"
1671   [(set (match_operand:ANYF 0 "register_operand" "=f")
1672         (minus:ANYF
1673          (match_operand:ANYF 1 "register_operand" "f")
1674          (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1675                     (match_operand:ANYF 3 "register_operand" "f"))))]
1676   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1677    && !HONOR_SIGNED_ZEROS (<MODE>mode)"
1678   "nmsub.<fmt>\t%0,%1,%2,%3"
1679   [(set_attr "type" "fmadd")
1680    (set_attr "mode" "<UNITMODE>")])
1681 \f
1682 ;;
1683 ;;  ....................
1684 ;;
1685 ;;      DIVISION and REMAINDER
1686 ;;
1687 ;;  ....................
1688 ;;
1689
1690 (define_expand "div<mode>3"
1691   [(set (match_operand:SCALARF 0 "register_operand")
1692         (div:SCALARF (match_operand:SCALARF 1 "reg_or_1_operand")
1693                      (match_operand:SCALARF 2 "register_operand")))]
1694   "<divide_condition>"
1695 {
1696   if (const_1_operand (operands[1], <MODE>mode))
1697     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1698       operands[1] = force_reg (<MODE>mode, operands[1]);
1699 })
1700
1701 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1702 ;;
1703 ;; If an mfc1 or dmfc1 happens to access the floating point register
1704 ;; file at the same time a long latency operation (div, sqrt, recip,
1705 ;; sqrt) iterates an intermediate result back through the floating
1706 ;; point register file bypass, then instead returning the correct
1707 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1708 ;; result of the long latency operation.
1709 ;;
1710 ;; The workaround is to insert an unconditional 'mov' from/to the
1711 ;; long latency op destination register.
1712
1713 (define_insn "*div<mode>3"
1714   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1715         (div:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1716                      (match_operand:SCALARF 2 "register_operand" "f")))]
1717   "<divide_condition>"
1718 {
1719   if (TARGET_FIX_SB1)
1720     return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1721   else
1722     return "div.<fmt>\t%0,%1,%2";
1723 }
1724   [(set_attr "type" "fdiv")
1725    (set_attr "mode" "<MODE>")
1726    (set (attr "length")
1727         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1728                       (const_int 8)
1729                       (const_int 4)))])
1730
1731 (define_insn "*recip<mode>3"
1732   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1733         (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "")
1734                      (match_operand:SCALARF 2 "register_operand" "f")))]
1735   "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
1736 {
1737   if (TARGET_FIX_SB1)
1738     return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1739   else
1740     return "recip.<fmt>\t%0,%2";
1741 }
1742   [(set_attr "type" "frdiv")
1743    (set_attr "mode" "<MODE>")
1744    (set (attr "length")
1745         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1746                       (const_int 8)
1747                       (const_int 4)))])
1748
1749 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1750 ;; with negative operands.  We use special libgcc functions instead.
1751 (define_insn "divmod<mode>4"
1752   [(set (match_operand:GPR 0 "register_operand" "=l")
1753         (div:GPR (match_operand:GPR 1 "register_operand" "d")
1754                  (match_operand:GPR 2 "register_operand" "d")))
1755    (set (match_operand:GPR 3 "register_operand" "=h")
1756         (mod:GPR (match_dup 1)
1757                  (match_dup 2)))]
1758   "!TARGET_FIX_VR4120"
1759   { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1760   [(set_attr "type" "idiv")
1761    (set_attr "mode" "<MODE>")])
1762
1763 (define_insn "udivmod<mode>4"
1764   [(set (match_operand:GPR 0 "register_operand" "=l")
1765         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1766                   (match_operand:GPR 2 "register_operand" "d")))
1767    (set (match_operand:GPR 3 "register_operand" "=h")
1768         (umod:GPR (match_dup 1)
1769                   (match_dup 2)))]
1770   ""
1771   { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1772   [(set_attr "type" "idiv")
1773    (set_attr "mode" "<MODE>")])
1774 \f
1775 ;;
1776 ;;  ....................
1777 ;;
1778 ;;      SQUARE ROOT
1779 ;;
1780 ;;  ....................
1781
1782 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1783 ;; "*div[sd]f3" comment for details).
1784
1785 (define_insn "sqrt<mode>2"
1786   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1787         (sqrt:SCALARF (match_operand:SCALARF 1 "register_operand" "f")))]
1788   "HAVE_SQRT_P()"
1789 {
1790   if (TARGET_FIX_SB1)
1791     return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
1792   else
1793     return "sqrt.<fmt>\t%0,%1";
1794 }
1795   [(set_attr "type" "fsqrt")
1796    (set_attr "mode" "<MODE>")
1797    (set (attr "length")
1798         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1799                       (const_int 8)
1800                       (const_int 4)))])
1801
1802 (define_insn "*rsqrt<mode>a"
1803   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1804         (div:SCALARF
1805          (match_operand:SCALARF 1 "const_1_operand" "")
1806          (sqrt:SCALARF (match_operand:SCALARF 2 "register_operand" "f"))))]
1807   "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
1808 {
1809   if (TARGET_FIX_SB1)
1810     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1811   else
1812     return "rsqrt.<fmt>\t%0,%2";
1813 }
1814   [(set_attr "type" "frsqrt")
1815    (set_attr "mode" "<MODE>")
1816    (set (attr "length")
1817         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1818                       (const_int 8)
1819                       (const_int 4)))])
1820
1821 (define_insn "*rsqrt<mode>b"
1822   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1823         (sqrt:SCALARF
1824          (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "")
1825                       (match_operand:SCALARF 2 "register_operand" "f"))))]
1826   "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
1827 {
1828   if (TARGET_FIX_SB1)
1829     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1830   else
1831     return "rsqrt.<fmt>\t%0,%2";
1832 }
1833   [(set_attr "type" "frsqrt")
1834    (set_attr "mode" "<MODE>")
1835    (set (attr "length")
1836         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1837                       (const_int 8)
1838                       (const_int 4)))])
1839 \f
1840 ;;
1841 ;;  ....................
1842 ;;
1843 ;;      ABSOLUTE VALUE
1844 ;;
1845 ;;  ....................
1846
1847 ;; Do not use the integer abs macro instruction, since that signals an
1848 ;; exception on -2147483648 (sigh).
1849
1850 (define_insn "abs<mode>2"
1851   [(set (match_operand:GPR 0 "register_operand" "=d")
1852         (abs:GPR (match_operand:GPR 1 "register_operand" "d")))]
1853   "!TARGET_MIPS16"
1854 {
1855   if (REGNO (operands[0]) == REGNO (operands[1]) && GENERATE_BRANCHLIKELY)
1856     return "%(bltzl\t%1,1f\;<d>subu\t%0,%.,%0\n%~1:%)";
1857   else
1858     return "%(bgez\t%1,1f\;move\t%0,%1\;<d>subu\t%0,%.,%0\n%~1:%)";
1859 }
1860   [(set_attr "type" "multi")
1861    (set_attr "mode" "<MODE>")
1862    (set_attr "length" "12")])
1863
1864 (define_insn "abs<mode>2"
1865   [(set (match_operand:ANYF 0 "register_operand" "=f")
1866         (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1867   ""
1868   "abs.<fmt>\t%0,%1"
1869   [(set_attr "type" "fabs")
1870    (set_attr "mode" "<UNITMODE>")])
1871 \f
1872 ;;
1873 ;;  ....................
1874 ;;
1875 ;;      FIND FIRST BIT INSTRUCTION
1876 ;;
1877 ;;  ....................
1878 ;;
1879
1880 (define_insn "ffs<mode>2"
1881   [(set (match_operand:GPR 0 "register_operand" "=&d")
1882         (ffs:GPR (match_operand:GPR 1 "register_operand" "d")))
1883    (clobber (match_scratch:GPR 2 "=&d"))
1884    (clobber (match_scratch:GPR 3 "=&d"))]
1885   "!TARGET_MIPS16"
1886 {
1887   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1888     return "%(\
1889 move\t%0,%.\;\
1890 beq\t%1,%.,2f\n\
1891 %~1:\tand\t%2,%1,0x0001\;\
1892 <d>addu\t%0,%0,1\;\
1893 beq\t%2,%.,1b\;\
1894 <d>srl\t%1,%1,1\n\
1895 %~2:%)";
1896
1897   return "%(\
1898 move\t%0,%.\;\
1899 move\t%3,%1\;\
1900 beq\t%3,%.,2f\n\
1901 %~1:\tand\t%2,%3,0x0001\;\
1902 <d>addu\t%0,%0,1\;\
1903 beq\t%2,%.,1b\;\
1904 <d>srl\t%3,%3,1\n\
1905 %~2:%)";
1906 }
1907   [(set_attr "type" "multi")
1908    (set_attr "mode" "<MODE>")
1909    (set_attr "length" "28")])
1910 \f
1911 ;;
1912 ;;  ...................
1913 ;;
1914 ;;  Count leading zeroes.
1915 ;;
1916 ;;  ...................
1917 ;;
1918
1919 (define_insn "clz<mode>2"
1920   [(set (match_operand:GPR 0 "register_operand" "=d")
1921         (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
1922   "ISA_HAS_CLZ_CLO"
1923   "<d>clz\t%0,%1"
1924   [(set_attr "type" "clz")
1925    (set_attr "mode" "<MODE>")])
1926 \f
1927 ;;
1928 ;;  ....................
1929 ;;
1930 ;;      NEGATION and ONE'S COMPLEMENT
1931 ;;
1932 ;;  ....................
1933
1934 (define_insn "negsi2"
1935   [(set (match_operand:SI 0 "register_operand" "=d")
1936         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1937   ""
1938 {
1939   if (TARGET_MIPS16)
1940     return "neg\t%0,%1";
1941   else
1942     return "subu\t%0,%.,%1";
1943 }
1944   [(set_attr "type"     "arith")
1945    (set_attr "mode"     "SI")])
1946
1947 (define_insn "negdi2"
1948   [(set (match_operand:DI 0 "register_operand" "=d")
1949         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
1950   "TARGET_64BIT && !TARGET_MIPS16"
1951   "dsubu\t%0,%.,%1"
1952   [(set_attr "type"     "arith")
1953    (set_attr "mode"     "DI")])
1954
1955 (define_insn "neg<mode>2"
1956   [(set (match_operand:ANYF 0 "register_operand" "=f")
1957         (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1958   ""
1959   "neg.<fmt>\t%0,%1"
1960   [(set_attr "type" "fneg")
1961    (set_attr "mode" "<UNITMODE>")])
1962
1963 (define_insn "one_cmpl<mode>2"
1964   [(set (match_operand:GPR 0 "register_operand" "=d")
1965         (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
1966   ""
1967 {
1968   if (TARGET_MIPS16)
1969     return "not\t%0,%1";
1970   else
1971     return "nor\t%0,%.,%1";
1972 }
1973   [(set_attr "type" "arith")
1974    (set_attr "mode" "<MODE>")])
1975 \f
1976 ;;
1977 ;;  ....................
1978 ;;
1979 ;;      LOGICAL
1980 ;;
1981 ;;  ....................
1982 ;;
1983
1984 ;; Many of these instructions use trivial define_expands, because we
1985 ;; want to use a different set of constraints when TARGET_MIPS16.
1986
1987 (define_expand "and<mode>3"
1988   [(set (match_operand:GPR 0 "register_operand")
1989         (and:GPR (match_operand:GPR 1 "register_operand")
1990                  (match_operand:GPR 2 "uns_arith_operand")))]
1991   ""
1992 {
1993   if (TARGET_MIPS16)
1994     operands[2] = force_reg (<MODE>mode, operands[2]);
1995 })
1996
1997 (define_insn "*and<mode>3"
1998   [(set (match_operand:GPR 0 "register_operand" "=d,d")
1999         (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2000                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2001   "!TARGET_MIPS16"
2002   "@
2003    and\t%0,%1,%2
2004    andi\t%0,%1,%x2"
2005   [(set_attr "type" "arith")
2006    (set_attr "mode" "<MODE>")])
2007
2008 (define_insn "*and<mode>3_mips16"
2009   [(set (match_operand:GPR 0 "register_operand" "=d")
2010         (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2011                  (match_operand:GPR 2 "register_operand" "d")))]
2012   "TARGET_MIPS16"
2013   "and\t%0,%2"
2014   [(set_attr "type" "arith")
2015    (set_attr "mode" "<MODE>")])
2016
2017 (define_expand "ior<mode>3"
2018   [(set (match_operand:GPR 0 "register_operand")
2019         (ior:GPR (match_operand:GPR 1 "register_operand")
2020                  (match_operand:GPR 2 "uns_arith_operand")))]
2021   ""
2022 {
2023   if (TARGET_MIPS16)
2024     operands[2] = force_reg (<MODE>mode, operands[2]);
2025 })
2026
2027 (define_insn "*ior<mode>3"
2028   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2029         (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2030                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2031   "!TARGET_MIPS16"
2032   "@
2033    or\t%0,%1,%2
2034    ori\t%0,%1,%x2"
2035   [(set_attr "type" "arith")
2036    (set_attr "mode" "<MODE>")])
2037
2038 (define_insn "*ior<mode>3_mips16"
2039   [(set (match_operand:GPR 0 "register_operand" "=d")
2040         (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2041                  (match_operand:GPR 2 "register_operand" "d")))]
2042   "TARGET_MIPS16"
2043   "or\t%0,%2"
2044   [(set_attr "type" "arith")
2045    (set_attr "mode" "<MODE>")])
2046
2047 (define_expand "xor<mode>3"
2048   [(set (match_operand:GPR 0 "register_operand")
2049         (xor:GPR (match_operand:GPR 1 "register_operand")
2050                  (match_operand:GPR 2 "uns_arith_operand")))]
2051   ""
2052   "")
2053
2054 (define_insn ""
2055   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2056         (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2057                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2058   "!TARGET_MIPS16"
2059   "@
2060    xor\t%0,%1,%2
2061    xori\t%0,%1,%x2"
2062   [(set_attr "type" "arith")
2063    (set_attr "mode" "<MODE>")])
2064
2065 (define_insn ""
2066   [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2067         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2068                  (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2069   "TARGET_MIPS16"
2070   "@
2071    xor\t%0,%2
2072    cmpi\t%1,%2
2073    cmp\t%1,%2"
2074   [(set_attr "type" "arith")
2075    (set_attr "mode" "<MODE>")
2076    (set_attr_alternative "length"
2077                 [(const_int 4)
2078                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2079                                (const_int 4)
2080                                (const_int 8))
2081                  (const_int 4)])])
2082
2083 (define_insn "*nor<mode>3"
2084   [(set (match_operand:GPR 0 "register_operand" "=d")
2085         (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2086                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2087   "!TARGET_MIPS16"
2088   "nor\t%0,%1,%2"
2089   [(set_attr "type" "arith")
2090    (set_attr "mode" "<MODE>")])
2091 \f
2092 ;;
2093 ;;  ....................
2094 ;;
2095 ;;      TRUNCATION
2096 ;;
2097 ;;  ....................
2098
2099
2100
2101 (define_insn "truncdfsf2"
2102   [(set (match_operand:SF 0 "register_operand" "=f")
2103         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2104   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2105   "cvt.s.d\t%0,%1"
2106   [(set_attr "type"     "fcvt")
2107    (set_attr "mode"     "SF")])
2108
2109 ;; Integer truncation patterns.  Truncating SImode values to smaller
2110 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2111 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2112 ;; need to make sure that the lower 32 bits are properly sign-extended
2113 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2114 ;; smaller than SImode is equivalent to two separate truncations:
2115 ;;
2116 ;;                        A       B
2117 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2118 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2119 ;;
2120 ;; Step A needs a real instruction but step B does not.
2121
2122 (define_insn "truncdisi2"
2123   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2124         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2125   "TARGET_64BIT"
2126   "@
2127     sll\t%0,%1,0
2128     sw\t%1,%0"
2129   [(set_attr "type" "shift,store")
2130    (set_attr "mode" "SI")
2131    (set_attr "extended_mips16" "yes,*")])
2132
2133 (define_insn "truncdihi2"
2134   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2135         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2136   "TARGET_64BIT"
2137   "@
2138     sll\t%0,%1,0
2139     sh\t%1,%0"
2140   [(set_attr "type" "shift,store")
2141    (set_attr "mode" "SI")
2142    (set_attr "extended_mips16" "yes,*")])
2143
2144 (define_insn "truncdiqi2"
2145   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2146         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2147   "TARGET_64BIT"
2148   "@
2149     sll\t%0,%1,0
2150     sb\t%1,%0"
2151   [(set_attr "type" "shift,store")
2152    (set_attr "mode" "SI")
2153    (set_attr "extended_mips16" "yes,*")])
2154
2155 ;; Combiner patterns to optimize shift/truncate combinations.
2156
2157 (define_insn ""
2158   [(set (match_operand:SI 0 "register_operand" "=d")
2159         (truncate:SI
2160           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2161                        (match_operand:DI 2 "const_arith_operand" ""))))]
2162   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2163   "dsra\t%0,%1,%2"
2164   [(set_attr "type" "shift")
2165    (set_attr "mode" "SI")])
2166
2167 (define_insn ""
2168   [(set (match_operand:SI 0 "register_operand" "=d")
2169         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2170                                   (const_int 32))))]
2171   "TARGET_64BIT && !TARGET_MIPS16"
2172   "dsra\t%0,%1,32"
2173   [(set_attr "type" "shift")
2174    (set_attr "mode" "SI")])
2175
2176
2177 ;; Combiner patterns for truncate/sign_extend combinations.  They use
2178 ;; the shift/truncate patterns above.
2179
2180 (define_insn_and_split ""
2181   [(set (match_operand:SI 0 "register_operand" "=d")
2182         (sign_extend:SI
2183             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2184   "TARGET_64BIT && !TARGET_MIPS16"
2185   "#"
2186   "&& reload_completed"
2187   [(set (match_dup 2)
2188         (ashift:DI (match_dup 1)
2189                    (const_int 48)))
2190    (set (match_dup 0)
2191         (truncate:SI (ashiftrt:DI (match_dup 2)
2192                                   (const_int 48))))]
2193   { operands[2] = gen_lowpart (DImode, operands[0]); })
2194
2195 (define_insn_and_split ""
2196   [(set (match_operand:SI 0 "register_operand" "=d")
2197         (sign_extend:SI
2198             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2199   "TARGET_64BIT && !TARGET_MIPS16"
2200   "#"
2201   "&& reload_completed"
2202   [(set (match_dup 2)
2203         (ashift:DI (match_dup 1)
2204                    (const_int 56)))
2205    (set (match_dup 0)
2206         (truncate:SI (ashiftrt:DI (match_dup 2)
2207                                   (const_int 56))))]
2208   { operands[2] = gen_lowpart (DImode, operands[0]); })
2209
2210
2211 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2212
2213 (define_insn ""
2214   [(set (match_operand:SI 0 "register_operand" "=d")
2215         (zero_extend:SI (truncate:HI
2216                          (match_operand:DI 1 "register_operand" "d"))))]
2217   "TARGET_64BIT && !TARGET_MIPS16"
2218   "andi\t%0,%1,0xffff"
2219   [(set_attr "type"     "arith")
2220    (set_attr "mode"     "SI")])
2221
2222 (define_insn ""
2223   [(set (match_operand:SI 0 "register_operand" "=d")
2224         (zero_extend:SI (truncate:QI
2225                          (match_operand:DI 1 "register_operand" "d"))))]
2226   "TARGET_64BIT && !TARGET_MIPS16"
2227   "andi\t%0,%1,0xff"
2228   [(set_attr "type"     "arith")
2229    (set_attr "mode"     "SI")])
2230
2231 (define_insn ""
2232   [(set (match_operand:HI 0 "register_operand" "=d")
2233         (zero_extend:HI (truncate:QI
2234                          (match_operand:DI 1 "register_operand" "d"))))]
2235   "TARGET_64BIT && !TARGET_MIPS16"
2236   "andi\t%0,%1,0xff"
2237   [(set_attr "type"     "arith")
2238    (set_attr "mode"     "HI")])
2239 \f
2240 ;;
2241 ;;  ....................
2242 ;;
2243 ;;      ZERO EXTENSION
2244 ;;
2245 ;;  ....................
2246
2247 ;; Extension insns.
2248 ;; Those for integer source operand are ordered widest source type first.
2249
2250 (define_insn_and_split "zero_extendsidi2"
2251   [(set (match_operand:DI 0 "register_operand" "=d")
2252         (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2253   "TARGET_64BIT"
2254   "#"
2255   "&& reload_completed"
2256   [(set (match_dup 0)
2257         (ashift:DI (match_dup 1) (const_int 32)))
2258    (set (match_dup 0)
2259         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2260   "operands[1] = gen_lowpart (DImode, operands[1]);"
2261   [(set_attr "type" "multi")
2262    (set_attr "mode" "DI")
2263    (set_attr "length" "8")])
2264
2265 (define_insn "*zero_extendsidi2_mem"
2266   [(set (match_operand:DI 0 "register_operand" "=d")
2267         (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2268   "TARGET_64BIT"
2269   "lwu\t%0,%1"
2270   [(set_attr "type"     "load")
2271    (set_attr "mode"     "DI")])
2272
2273 (define_expand "zero_extendhisi2"
2274   [(set (match_operand:SI 0 "register_operand")
2275         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2276   ""
2277 {
2278   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2279     {
2280       rtx op = gen_lowpart (SImode, operands[1]);
2281       rtx temp = force_reg (SImode, GEN_INT (0xffff));
2282
2283       emit_insn (gen_andsi3 (operands[0], op, temp));
2284       DONE;
2285     }
2286 })
2287
2288 (define_insn ""
2289   [(set (match_operand:SI 0 "register_operand" "=d,d")
2290         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2291   "!TARGET_MIPS16"
2292   "@
2293    andi\t%0,%1,0xffff
2294    lhu\t%0,%1"
2295   [(set_attr "type"     "arith,load")
2296    (set_attr "mode"     "SI")
2297    (set_attr "length"   "4,*")])
2298
2299 (define_insn ""
2300   [(set (match_operand:SI 0 "register_operand" "=d")
2301         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2302   "TARGET_MIPS16"
2303   "lhu\t%0,%1"
2304   [(set_attr "type"     "load")
2305    (set_attr "mode"     "SI")])
2306
2307 (define_expand "zero_extendhidi2"
2308   [(set (match_operand:DI 0 "register_operand")
2309         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2310   "TARGET_64BIT"
2311 {
2312   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2313     {
2314       rtx op = gen_lowpart (DImode, operands[1]);
2315       rtx temp = force_reg (DImode, GEN_INT (0xffff));
2316
2317       emit_insn (gen_anddi3 (operands[0], op, temp));
2318       DONE;
2319     }
2320 })
2321
2322 (define_insn ""
2323   [(set (match_operand:DI 0 "register_operand" "=d,d")
2324         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2325   "TARGET_64BIT && !TARGET_MIPS16"
2326   "@
2327    andi\t%0,%1,0xffff
2328    lhu\t%0,%1"
2329   [(set_attr "type"     "arith,load")
2330    (set_attr "mode"     "DI")
2331    (set_attr "length"   "4,*")])
2332
2333 (define_insn ""
2334   [(set (match_operand:DI 0 "register_operand" "=d")
2335         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2336   "TARGET_64BIT && TARGET_MIPS16"
2337   "lhu\t%0,%1"
2338   [(set_attr "type"     "load")
2339    (set_attr "mode"     "DI")])
2340
2341 (define_expand "zero_extendqihi2"
2342   [(set (match_operand:HI 0 "register_operand")
2343         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2344   ""
2345 {
2346   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2347     {
2348       rtx op0 = gen_lowpart (SImode, operands[0]);
2349       rtx op1 = gen_lowpart (SImode, operands[1]);
2350       rtx temp = force_reg (SImode, GEN_INT (0xff));
2351
2352       emit_insn (gen_andsi3 (op0, op1, temp));
2353       DONE;
2354     }
2355 })
2356
2357 (define_insn ""
2358   [(set (match_operand:HI 0 "register_operand" "=d,d")
2359         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2360   "!TARGET_MIPS16"
2361   "@
2362    andi\t%0,%1,0x00ff
2363    lbu\t%0,%1"
2364   [(set_attr "type"     "arith,load")
2365    (set_attr "mode"     "HI")
2366    (set_attr "length"   "4,*")])
2367
2368 (define_insn ""
2369   [(set (match_operand:HI 0 "register_operand" "=d")
2370         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2371   "TARGET_MIPS16"
2372   "lbu\t%0,%1"
2373   [(set_attr "type"     "load")
2374    (set_attr "mode"     "HI")])
2375
2376 (define_expand "zero_extendqisi2"
2377   [(set (match_operand:SI 0 "register_operand")
2378         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2379   ""
2380 {
2381   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2382     {
2383       rtx op = gen_lowpart (SImode, operands[1]);
2384       rtx temp = force_reg (SImode, GEN_INT (0xff));
2385
2386       emit_insn (gen_andsi3 (operands[0], op, temp));
2387       DONE;
2388     }
2389 })
2390
2391 (define_insn ""
2392   [(set (match_operand:SI 0 "register_operand" "=d,d")
2393         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2394   "!TARGET_MIPS16"
2395   "@
2396    andi\t%0,%1,0x00ff
2397    lbu\t%0,%1"
2398   [(set_attr "type"     "arith,load")
2399    (set_attr "mode"     "SI")
2400    (set_attr "length"   "4,*")])
2401
2402 (define_insn ""
2403   [(set (match_operand:SI 0 "register_operand" "=d")
2404         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2405   "TARGET_MIPS16"
2406   "lbu\t%0,%1"
2407   [(set_attr "type"     "load")
2408    (set_attr "mode"     "SI")])
2409
2410 (define_expand "zero_extendqidi2"
2411   [(set (match_operand:DI 0 "register_operand")
2412         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2413   "TARGET_64BIT"
2414 {
2415   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2416     {
2417       rtx op = gen_lowpart (DImode, operands[1]);
2418       rtx temp = force_reg (DImode, GEN_INT (0xff));
2419
2420       emit_insn (gen_anddi3 (operands[0], op, temp));
2421       DONE;
2422     }
2423 })
2424
2425 (define_insn ""
2426   [(set (match_operand:DI 0 "register_operand" "=d,d")
2427         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2428   "TARGET_64BIT && !TARGET_MIPS16"
2429   "@
2430    andi\t%0,%1,0x00ff
2431    lbu\t%0,%1"
2432   [(set_attr "type"     "arith,load")
2433    (set_attr "mode"     "DI")
2434    (set_attr "length"   "4,*")])
2435
2436 (define_insn ""
2437   [(set (match_operand:DI 0 "register_operand" "=d")
2438         (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2439   "TARGET_64BIT && TARGET_MIPS16"
2440   "lbu\t%0,%1"
2441   [(set_attr "type"     "load")
2442    (set_attr "mode"     "DI")])
2443 \f
2444 ;;
2445 ;;  ....................
2446 ;;
2447 ;;      SIGN EXTENSION
2448 ;;
2449 ;;  ....................
2450
2451 ;; Extension insns.
2452 ;; Those for integer source operand are ordered widest source type first.
2453
2454 ;; When TARGET_64BIT, all SImode integer registers should already be in
2455 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
2456 ;; therefore get rid of register->register instructions if we constrain
2457 ;; the source to be in the same register as the destination.
2458 ;;
2459 ;; The register alternative has type "arith" so that the pre-reload
2460 ;; scheduler will treat it as a move.  This reflects what happens if
2461 ;; the register alternative needs a reload.
2462 (define_insn_and_split "extendsidi2"
2463   [(set (match_operand:DI 0 "register_operand" "=d,d")
2464         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2465   "TARGET_64BIT"
2466   "@
2467    #
2468    lw\t%0,%1"
2469   "&& reload_completed && register_operand (operands[1], VOIDmode)"
2470   [(const_int 0)]
2471 {
2472   emit_note (NOTE_INSN_DELETED);
2473   DONE;
2474 }
2475   [(set_attr "type" "arith,load")
2476    (set_attr "mode" "DI")])
2477
2478 ;; These patterns originally accepted general_operands, however, slightly
2479 ;; better code is generated by only accepting register_operands, and then
2480 ;; letting combine generate the lh and lb insns.
2481
2482 ;; These expanders originally put values in registers first. We split
2483 ;; all non-mem patterns after reload.
2484
2485 (define_expand "extendhidi2"
2486   [(set (match_operand:DI 0 "register_operand")
2487         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2488   "TARGET_64BIT"
2489   "")
2490
2491 (define_insn "*extendhidi2"
2492   [(set (match_operand:DI 0 "register_operand" "=d")
2493         (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
2494   "TARGET_64BIT"
2495   "#")
2496
2497 (define_split
2498   [(set (match_operand:DI 0 "register_operand")
2499         (sign_extend:DI (match_operand:HI 1 "register_operand")))]
2500   "TARGET_64BIT && reload_completed"
2501   [(set (match_dup 0)
2502         (ashift:DI (match_dup 1) (const_int 48)))
2503    (set (match_dup 0)
2504         (ashiftrt:DI (match_dup 0) (const_int 48)))]
2505   "operands[1] = gen_lowpart (DImode, operands[1]);")
2506
2507 (define_insn "*extendhidi2_mem"
2508   [(set (match_operand:DI 0 "register_operand" "=d")
2509         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2510   "TARGET_64BIT"
2511   "lh\t%0,%1"
2512   [(set_attr "type"     "load")
2513    (set_attr "mode"     "DI")])
2514
2515 (define_expand "extendhisi2"
2516   [(set (match_operand:SI 0 "register_operand")
2517         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2518   ""
2519 {
2520   if (ISA_HAS_SEB_SEH)
2521     {
2522       emit_insn (gen_extendhisi2_hw (operands[0],
2523                                      force_reg (HImode, operands[1])));
2524       DONE;
2525     }
2526 })
2527
2528 (define_insn "*extendhisi2"
2529   [(set (match_operand:SI 0 "register_operand" "=d")
2530         (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
2531   ""
2532   "#")
2533
2534 (define_split
2535   [(set (match_operand:SI 0 "register_operand")
2536         (sign_extend:SI (match_operand:HI 1 "register_operand")))]
2537   "reload_completed"
2538   [(set (match_dup 0)
2539         (ashift:SI (match_dup 1) (const_int 16)))
2540    (set (match_dup 0)
2541         (ashiftrt:SI (match_dup 0) (const_int 16)))]
2542   "operands[1] = gen_lowpart (SImode, operands[1]);")
2543
2544 (define_insn "extendhisi2_mem"
2545   [(set (match_operand:SI 0 "register_operand" "=d")
2546         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2547   ""
2548   "lh\t%0,%1"
2549   [(set_attr "type"     "load")
2550    (set_attr "mode"     "SI")])
2551
2552 (define_insn "extendhisi2_hw"
2553   [(set (match_operand:SI 0 "register_operand" "=r")
2554         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2555   "ISA_HAS_SEB_SEH"
2556   "seh\t%0,%1"
2557   [(set_attr "type" "arith")
2558    (set_attr "mode" "SI")])
2559
2560 (define_expand "extendqihi2"
2561   [(set (match_operand:HI 0 "register_operand")
2562         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2563   ""
2564   "")
2565
2566 (define_insn "*extendqihi2"
2567   [(set (match_operand:HI 0 "register_operand" "=d")
2568         (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
2569   ""
2570   "#")
2571
2572 (define_split
2573   [(set (match_operand:HI 0 "register_operand")
2574         (sign_extend:HI (match_operand:QI 1 "register_operand")))]
2575   "reload_completed"
2576   [(set (match_dup 0)
2577         (ashift:SI (match_dup 1) (const_int 24)))
2578    (set (match_dup 0)
2579         (ashiftrt:SI (match_dup 0) (const_int 24)))]
2580   "operands[0] = gen_lowpart (SImode, operands[0]);
2581    operands[1] = gen_lowpart (SImode, operands[1]);")
2582
2583 (define_insn "*extendqihi2_internal_mem"
2584   [(set (match_operand:HI 0 "register_operand" "=d")
2585         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2586   ""
2587   "lb\t%0,%1"
2588   [(set_attr "type"     "load")
2589    (set_attr "mode"     "SI")])
2590
2591
2592 (define_expand "extendqisi2"
2593   [(set (match_operand:SI 0 "register_operand")
2594         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2595   ""
2596 {
2597   if (ISA_HAS_SEB_SEH)
2598     {
2599       emit_insn (gen_extendqisi2_hw (operands[0],
2600                                      force_reg (QImode, operands[1])));
2601       DONE;
2602     }
2603 })
2604
2605 (define_insn "*extendqisi2"
2606   [(set (match_operand:SI 0 "register_operand" "=d")
2607         (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
2608   ""
2609   "#")
2610
2611 (define_split
2612   [(set (match_operand:SI 0 "register_operand")
2613         (sign_extend:SI (match_operand:QI 1 "register_operand")))]
2614   "reload_completed"
2615   [(set (match_dup 0)
2616         (ashift:SI (match_dup 1) (const_int 24)))
2617    (set (match_dup 0)
2618         (ashiftrt:SI (match_dup 0) (const_int 24)))]
2619   "operands[1] = gen_lowpart (SImode, operands[1]);")
2620
2621 (define_insn "*extendqisi2_mem"
2622   [(set (match_operand:SI 0 "register_operand" "=d")
2623         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2624   ""
2625   "lb\t%0,%1"
2626   [(set_attr "type"     "load")
2627    (set_attr "mode"     "SI")])
2628
2629 (define_insn "extendqisi2_hw"
2630   [(set (match_operand:SI 0 "register_operand" "=r")
2631         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2632   "ISA_HAS_SEB_SEH"
2633   "seb\t%0,%1"
2634   [(set_attr "type" "arith")
2635    (set_attr "mode" "SI")])
2636
2637 (define_expand "extendqidi2"
2638   [(set (match_operand:DI 0 "register_operand")
2639         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2640   "TARGET_64BIT"
2641   "")
2642
2643 (define_insn "*extendqidi2"
2644   [(set (match_operand:DI 0 "register_operand" "=d")
2645         (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
2646   "TARGET_64BIT"
2647   "#")
2648
2649 (define_split
2650   [(set (match_operand:DI 0 "register_operand")
2651         (sign_extend:DI (match_operand:QI 1 "register_operand")))]
2652   "TARGET_64BIT && reload_completed"
2653   [(set (match_dup 0)
2654         (ashift:DI (match_dup 1) (const_int 56)))
2655    (set (match_dup 0)
2656         (ashiftrt:DI (match_dup 0) (const_int 56)))]
2657   "operands[1] = gen_lowpart (DImode, operands[1]);")
2658
2659 (define_insn "*extendqidi2_mem"
2660   [(set (match_operand:DI 0 "register_operand" "=d")
2661         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2662   "TARGET_64BIT"
2663   "lb\t%0,%1"
2664   [(set_attr "type"     "load")
2665    (set_attr "mode"     "DI")])
2666
2667 (define_insn "extendsfdf2"
2668   [(set (match_operand:DF 0 "register_operand" "=f")
2669         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2670   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2671   "cvt.d.s\t%0,%1"
2672   [(set_attr "type"     "fcvt")
2673    (set_attr "mode"     "DF")])
2674 \f
2675 ;;
2676 ;;  ....................
2677 ;;
2678 ;;      CONVERSIONS
2679 ;;
2680 ;;  ....................
2681
2682 (define_expand "fix_truncdfsi2"
2683   [(set (match_operand:SI 0 "register_operand")
2684         (fix:SI (match_operand:DF 1 "register_operand")))]
2685   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2686 {
2687   if (!ISA_HAS_TRUNC_W)
2688     {
2689       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2690       DONE;
2691     }
2692 })
2693
2694 (define_insn "fix_truncdfsi2_insn"
2695   [(set (match_operand:SI 0 "register_operand" "=f")
2696         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2697   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2698   "trunc.w.d %0,%1"
2699   [(set_attr "type"     "fcvt")
2700    (set_attr "mode"     "DF")
2701    (set_attr "length"   "4")])
2702
2703 (define_insn "fix_truncdfsi2_macro"
2704   [(set (match_operand:SI 0 "register_operand" "=f")
2705         (fix:SI (match_operand:DF 1 "register_operand" "f")))
2706    (clobber (match_scratch:DF 2 "=d"))]
2707   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2708 {
2709   if (set_nomacro)
2710     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2711   else
2712     return "trunc.w.d %0,%1,%2";
2713 }
2714   [(set_attr "type"     "fcvt")
2715    (set_attr "mode"     "DF")
2716    (set_attr "length"   "36")])
2717
2718 (define_expand "fix_truncsfsi2"
2719   [(set (match_operand:SI 0 "register_operand")
2720         (fix:SI (match_operand:SF 1 "register_operand")))]
2721   "TARGET_HARD_FLOAT"
2722 {
2723   if (!ISA_HAS_TRUNC_W)
2724     {
2725       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2726       DONE;
2727     }
2728 })
2729
2730 (define_insn "fix_truncsfsi2_insn"
2731   [(set (match_operand:SI 0 "register_operand" "=f")
2732         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2733   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2734   "trunc.w.s %0,%1"
2735   [(set_attr "type"     "fcvt")
2736    (set_attr "mode"     "DF")
2737    (set_attr "length"   "4")])
2738
2739 (define_insn "fix_truncsfsi2_macro"
2740   [(set (match_operand:SI 0 "register_operand" "=f")
2741         (fix:SI (match_operand:SF 1 "register_operand" "f")))
2742    (clobber (match_scratch:SF 2 "=d"))]
2743   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2744 {
2745   if (set_nomacro)
2746     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2747   else
2748     return "trunc.w.s %0,%1,%2";
2749 }
2750   [(set_attr "type"     "fcvt")
2751    (set_attr "mode"     "DF")
2752    (set_attr "length"   "36")])
2753
2754
2755 (define_insn "fix_truncdfdi2"
2756   [(set (match_operand:DI 0 "register_operand" "=f")
2757         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2758   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2759   "trunc.l.d %0,%1"
2760   [(set_attr "type"     "fcvt")
2761    (set_attr "mode"     "DF")
2762    (set_attr "length"   "4")])
2763
2764
2765 (define_insn "fix_truncsfdi2"
2766   [(set (match_operand:DI 0 "register_operand" "=f")
2767         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2768   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2769   "trunc.l.s %0,%1"
2770   [(set_attr "type"     "fcvt")
2771    (set_attr "mode"     "SF")
2772    (set_attr "length"   "4")])
2773
2774
2775 (define_insn "floatsidf2"
2776   [(set (match_operand:DF 0 "register_operand" "=f")
2777         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2778   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2779   "cvt.d.w\t%0,%1"
2780   [(set_attr "type"     "fcvt")
2781    (set_attr "mode"     "DF")
2782    (set_attr "length"   "4")])
2783
2784
2785 (define_insn "floatdidf2"
2786   [(set (match_operand:DF 0 "register_operand" "=f")
2787         (float:DF (match_operand:DI 1 "register_operand" "f")))]
2788   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2789   "cvt.d.l\t%0,%1"
2790   [(set_attr "type"     "fcvt")
2791    (set_attr "mode"     "DF")
2792    (set_attr "length"   "4")])
2793
2794
2795 (define_insn "floatsisf2"
2796   [(set (match_operand:SF 0 "register_operand" "=f")
2797         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2798   "TARGET_HARD_FLOAT"
2799   "cvt.s.w\t%0,%1"
2800   [(set_attr "type"     "fcvt")
2801    (set_attr "mode"     "SF")
2802    (set_attr "length"   "4")])
2803
2804
2805 (define_insn "floatdisf2"
2806   [(set (match_operand:SF 0 "register_operand" "=f")
2807         (float:SF (match_operand:DI 1 "register_operand" "f")))]
2808   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2809   "cvt.s.l\t%0,%1"
2810   [(set_attr "type"     "fcvt")
2811    (set_attr "mode"     "SF")
2812    (set_attr "length"   "4")])
2813
2814
2815 (define_expand "fixuns_truncdfsi2"
2816   [(set (match_operand:SI 0 "register_operand")
2817         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2818   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2819 {
2820   rtx reg1 = gen_reg_rtx (DFmode);
2821   rtx reg2 = gen_reg_rtx (DFmode);
2822   rtx reg3 = gen_reg_rtx (SImode);
2823   rtx label1 = gen_label_rtx ();
2824   rtx label2 = gen_label_rtx ();
2825   REAL_VALUE_TYPE offset;
2826
2827   real_2expN (&offset, 31);
2828
2829   if (reg1)                     /* Turn off complaints about unreached code.  */
2830     {
2831       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2832       do_pending_stack_adjust ();
2833
2834       emit_insn (gen_cmpdf (operands[1], reg1));
2835       emit_jump_insn (gen_bge (label1));
2836
2837       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2838       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2839                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
2840       emit_barrier ();
2841
2842       emit_label (label1);
2843       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2844       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2845                                      (BITMASK_HIGH, SImode)));
2846
2847       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2848       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2849
2850       emit_label (label2);
2851
2852       /* Allow REG_NOTES to be set on last insn (labels don't have enough
2853          fields, and can't be used for REG_NOTES anyway).  */
2854       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2855       DONE;
2856     }
2857 })
2858
2859
2860 (define_expand "fixuns_truncdfdi2"
2861   [(set (match_operand:DI 0 "register_operand")
2862         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2863   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2864 {
2865   rtx reg1 = gen_reg_rtx (DFmode);
2866   rtx reg2 = gen_reg_rtx (DFmode);
2867   rtx reg3 = gen_reg_rtx (DImode);
2868   rtx label1 = gen_label_rtx ();
2869   rtx label2 = gen_label_rtx ();
2870   REAL_VALUE_TYPE offset;
2871
2872   real_2expN (&offset, 63);
2873
2874   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2875   do_pending_stack_adjust ();
2876
2877   emit_insn (gen_cmpdf (operands[1], reg1));
2878   emit_jump_insn (gen_bge (label1));
2879
2880   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2881   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2882                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2883   emit_barrier ();
2884
2885   emit_label (label1);
2886   emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2887   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2888   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2889
2890   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2891   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2892
2893   emit_label (label2);
2894
2895   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2896      fields, and can't be used for REG_NOTES anyway).  */
2897   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2898   DONE;
2899 })
2900
2901
2902 (define_expand "fixuns_truncsfsi2"
2903   [(set (match_operand:SI 0 "register_operand")
2904         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2905   "TARGET_HARD_FLOAT"
2906 {
2907   rtx reg1 = gen_reg_rtx (SFmode);
2908   rtx reg2 = gen_reg_rtx (SFmode);
2909   rtx reg3 = gen_reg_rtx (SImode);
2910   rtx label1 = gen_label_rtx ();
2911   rtx label2 = gen_label_rtx ();
2912   REAL_VALUE_TYPE offset;
2913
2914   real_2expN (&offset, 31);
2915
2916   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2917   do_pending_stack_adjust ();
2918
2919   emit_insn (gen_cmpsf (operands[1], reg1));
2920   emit_jump_insn (gen_bge (label1));
2921
2922   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2923   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2924                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2925   emit_barrier ();
2926
2927   emit_label (label1);
2928   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2929   emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2930                                  (BITMASK_HIGH, SImode)));
2931
2932   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2933   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2934
2935   emit_label (label2);
2936
2937   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2938      fields, and can't be used for REG_NOTES anyway).  */
2939   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2940   DONE;
2941 })
2942
2943
2944 (define_expand "fixuns_truncsfdi2"
2945   [(set (match_operand:DI 0 "register_operand")
2946         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2947   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2948 {
2949   rtx reg1 = gen_reg_rtx (SFmode);
2950   rtx reg2 = gen_reg_rtx (SFmode);
2951   rtx reg3 = gen_reg_rtx (DImode);
2952   rtx label1 = gen_label_rtx ();
2953   rtx label2 = gen_label_rtx ();
2954   REAL_VALUE_TYPE offset;
2955
2956   real_2expN (&offset, 63);
2957
2958   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2959   do_pending_stack_adjust ();
2960
2961   emit_insn (gen_cmpsf (operands[1], reg1));
2962   emit_jump_insn (gen_bge (label1));
2963
2964   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2965   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2966                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2967   emit_barrier ();
2968
2969   emit_label (label1);
2970   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2971   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2972   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2973
2974   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2975   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2976
2977   emit_label (label2);
2978
2979   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2980      fields, and can't be used for REG_NOTES anyway).  */
2981   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2982   DONE;
2983 })
2984 \f
2985 ;;
2986 ;;  ....................
2987 ;;
2988 ;;      DATA MOVEMENT
2989 ;;
2990 ;;  ....................
2991
2992 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
2993
2994 (define_expand "extv"
2995   [(set (match_operand 0 "register_operand")
2996         (sign_extract (match_operand:QI 1 "memory_operand")
2997                       (match_operand 2 "immediate_operand")
2998                       (match_operand 3 "immediate_operand")))]
2999   "!TARGET_MIPS16"
3000 {
3001   if (mips_expand_unaligned_load (operands[0], operands[1],
3002                                   INTVAL (operands[2]),
3003                                   INTVAL (operands[3])))
3004     DONE;
3005   else
3006     FAIL;
3007 })
3008
3009 (define_expand "extzv"
3010   [(set (match_operand 0 "register_operand")
3011         (zero_extract (match_operand:QI 1 "memory_operand")
3012                       (match_operand 2 "immediate_operand")
3013                       (match_operand 3 "immediate_operand")))]
3014   "!TARGET_MIPS16"
3015 {
3016   if (mips_expand_unaligned_load (operands[0], operands[1],
3017                                   INTVAL (operands[2]),
3018                                   INTVAL (operands[3])))
3019     DONE;
3020   else
3021     FAIL;
3022 })
3023
3024 (define_expand "insv"
3025   [(set (zero_extract (match_operand:QI 0 "memory_operand")
3026                       (match_operand 1 "immediate_operand")
3027                       (match_operand 2 "immediate_operand"))
3028         (match_operand 3 "reg_or_0_operand"))]
3029   "!TARGET_MIPS16"
3030 {
3031   if (mips_expand_unaligned_store (operands[0], operands[3],
3032                                    INTVAL (operands[1]),
3033                                    INTVAL (operands[2])))
3034     DONE;
3035   else
3036     FAIL;
3037 })
3038
3039 ;; Unaligned word moves generated by the bit field patterns.
3040 ;;
3041 ;; As far as the rtl is concerned, both the left-part and right-part
3042 ;; instructions can access the whole field.  However, the real operand
3043 ;; refers to just the first or the last byte (depending on endianness).
3044 ;; We therefore use two memory operands to each instruction, one to
3045 ;; describe the rtl effect and one to use in the assembly output.
3046 ;;
3047 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3048 ;; This allows us to use the standard length calculations for the "load"
3049 ;; and "store" type attributes.
3050
3051 (define_insn "mov_<load>l"
3052   [(set (match_operand:GPR 0 "register_operand" "=d")
3053         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3054                      (match_operand:QI 2 "memory_operand" "m")]
3055                     UNSPEC_LOAD_LEFT))]
3056   "!TARGET_MIPS16"
3057   "<load>l\t%0,%2"
3058   [(set_attr "type" "load")
3059    (set_attr "mode" "<MODE>")
3060    (set_attr "hazard" "none")])
3061
3062 (define_insn "mov_<load>r"
3063   [(set (match_operand:GPR 0 "register_operand" "=d")
3064         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3065                      (match_operand:QI 2 "memory_operand" "m")
3066                      (match_operand:GPR 3 "register_operand" "0")]
3067                     UNSPEC_LOAD_RIGHT))]
3068   "!TARGET_MIPS16"
3069   "<load>r\t%0,%2"
3070   [(set_attr "type" "load")
3071    (set_attr "mode" "<MODE>")])
3072
3073 (define_insn "mov_<store>l"
3074   [(set (match_operand:BLK 0 "memory_operand" "=m")
3075         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3076                      (match_operand:QI 2 "memory_operand" "m")]
3077                     UNSPEC_STORE_LEFT))]
3078   "!TARGET_MIPS16"
3079   "<store>l\t%z1,%2"
3080   [(set_attr "type" "store")
3081    (set_attr "mode" "<MODE>")])
3082
3083 (define_insn "mov_<store>r"
3084   [(set (match_operand:BLK 0 "memory_operand" "+m")
3085         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3086                      (match_operand:QI 2 "memory_operand" "m")
3087                      (match_dup 0)]
3088                     UNSPEC_STORE_RIGHT))]
3089   "!TARGET_MIPS16"
3090   "<store>r\t%z1,%2"
3091   [(set_attr "type" "store")
3092    (set_attr "mode" "<MODE>")])
3093
3094 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3095 ;; The required value is:
3096 ;;
3097 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3098 ;;
3099 ;; which translates to:
3100 ;;
3101 ;;      lui     op0,%highest(op1)
3102 ;;      daddiu  op0,op0,%higher(op1)
3103 ;;      dsll    op0,op0,16
3104 ;;      daddiu  op0,op0,%hi(op1)
3105 ;;      dsll    op0,op0,16
3106 ;;
3107 ;; The split is deferred until after flow2 to allow the peephole2 below
3108 ;; to take effect.
3109 (define_insn_and_split "*lea_high64"
3110   [(set (match_operand:DI 0 "register_operand" "=d")
3111         (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3112   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3113   "#"
3114   "&& flow2_completed"
3115   [(set (match_dup 0) (high:DI (match_dup 2)))
3116    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3117    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3118    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3119    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3120 {
3121   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3122   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3123 }
3124   [(set_attr "length" "20")])
3125
3126 ;; Use a scratch register to reduce the latency of the above pattern
3127 ;; on superscalar machines.  The optimized sequence is:
3128 ;;
3129 ;;      lui     op1,%highest(op2)
3130 ;;      lui     op0,%hi(op2)
3131 ;;      daddiu  op1,op1,%higher(op2)
3132 ;;      dsll32  op1,op1,0
3133 ;;      daddu   op1,op1,op0
3134 (define_peephole2
3135   [(match_scratch:DI 0 "d")
3136    (set (match_operand:DI 1 "register_operand")
3137         (high:DI (match_operand:DI 2 "general_symbolic_operand")))]
3138   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3139   [(set (match_dup 1) (high:DI (match_dup 3)))
3140    (set (match_dup 0) (high:DI (match_dup 4)))
3141    (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3142    (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3143    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3144 {
3145   operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3146   operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3147 })
3148
3149 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3150 ;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
3151 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3152 ;; used once.  We can then use the sequence:
3153 ;;
3154 ;;      lui     op0,%highest(op1)
3155 ;;      lui     op2,%hi(op1)
3156 ;;      daddiu  op0,op0,%higher(op1)
3157 ;;      daddiu  op2,op2,%lo(op1)
3158 ;;      dsll32  op0,op0,0
3159 ;;      daddu   op0,op0,op2
3160 ;;
3161 ;; which takes 4 cycles on most superscalar targets.
3162 (define_insn_and_split "*lea64"
3163   [(set (match_operand:DI 0 "register_operand" "=d")
3164         (match_operand:DI 1 "general_symbolic_operand" ""))
3165    (clobber (match_scratch:DI 2 "=&d"))]
3166   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3167   "#"
3168   "&& reload_completed"
3169   [(set (match_dup 0) (high:DI (match_dup 3)))
3170    (set (match_dup 2) (high:DI (match_dup 4)))
3171    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3172    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3173    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3174    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3175 {
3176   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3177   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3178 }
3179   [(set_attr "length" "24")])
3180
3181 ;; Insns to fetch a global symbol from a big GOT.
3182
3183 (define_insn_and_split "*xgot_hi<mode>"
3184   [(set (match_operand:P 0 "register_operand" "=d")
3185         (high:P (match_operand:P 1 "global_got_operand" "")))]
3186   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3187   "#"
3188   "&& reload_completed"
3189   [(set (match_dup 0) (high:P (match_dup 2)))
3190    (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3191 {
3192   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3193   operands[3] = pic_offset_table_rtx;
3194 }
3195   [(set_attr "got" "xgot_high")
3196    (set_attr "mode" "<MODE>")])
3197
3198 (define_insn_and_split "*xgot_lo<mode>"
3199   [(set (match_operand:P 0 "register_operand" "=d")
3200         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3201                   (match_operand:P 2 "global_got_operand" "")))]
3202   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3203   "#"
3204   "&& reload_completed"
3205   [(set (match_dup 0)
3206         (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3207   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3208   [(set_attr "got" "load")
3209    (set_attr "mode" "<MODE>")])
3210
3211 ;; Insns to fetch a global symbol from a normal GOT.
3212
3213 (define_insn_and_split "*got_disp<mode>"
3214   [(set (match_operand:P 0 "register_operand" "=d")
3215         (match_operand:P 1 "global_got_operand" ""))]
3216   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3217   "#"
3218   "&& reload_completed"
3219   [(set (match_dup 0)
3220         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3221 {
3222   operands[2] = pic_offset_table_rtx;
3223   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3224 }
3225   [(set_attr "got" "load")
3226    (set_attr "mode" "<MODE>")])
3227
3228 ;; Insns for loading the high part of a local symbol.
3229
3230 (define_insn_and_split "*got_page<mode>"
3231   [(set (match_operand:P 0 "register_operand" "=d")
3232         (high:P (match_operand:P 1 "local_got_operand" "")))]
3233   "TARGET_EXPLICIT_RELOCS"
3234   "#"
3235   "&& reload_completed"
3236   [(set (match_dup 0)
3237         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3238 {
3239   operands[2] = pic_offset_table_rtx;
3240   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3241 }
3242   [(set_attr "got" "load")
3243    (set_attr "mode" "<MODE>")])
3244
3245 ;; Lower-level instructions for loading an address from the GOT.
3246 ;; We could use MEMs, but an unspec gives more optimization
3247 ;; opportunities.
3248
3249 (define_insn "*load_got<mode>"
3250   [(set (match_operand:P 0 "register_operand" "=d")
3251         (unspec:P [(match_operand:P 1 "register_operand" "d")
3252                    (match_operand:P 2 "immediate_operand" "")]
3253                   UNSPEC_LOAD_GOT))]
3254   "TARGET_ABICALLS"
3255   "<load>\t%0,%R2(%1)"
3256   [(set_attr "type" "load")
3257    (set_attr "mode" "<MODE>")
3258    (set_attr "length" "4")])
3259
3260 ;; Instructions for adding the low 16 bits of an address to a register.
3261 ;; Operand 2 is the address: print_operand works out which relocation
3262 ;; should be applied.
3263
3264 (define_insn "*low<mode>"
3265   [(set (match_operand:P 0 "register_operand" "=d")
3266         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3267                   (match_operand:P 2 "immediate_operand" "")))]
3268   "!TARGET_MIPS16"
3269   "<d>addiu\t%0,%1,%R2"
3270   [(set_attr "type" "arith")
3271    (set_attr "mode" "<MODE>")])
3272
3273 (define_insn "*low<mode>_mips16"
3274   [(set (match_operand:P 0 "register_operand" "=d")
3275         (lo_sum:P (match_operand:P 1 "register_operand" "0")
3276                   (match_operand:P 2 "immediate_operand" "")))]
3277   "TARGET_MIPS16"
3278   "<d>addiu\t%0,%R2"
3279   [(set_attr "type" "arith")
3280    (set_attr "mode" "<MODE>")
3281    (set_attr "length" "8")])
3282
3283 ;; 64-bit integer moves
3284
3285 ;; Unlike most other insns, the move insns can't be split with
3286 ;; different predicates, because register spilling and other parts of
3287 ;; the compiler, have memoized the insn number already.
3288
3289 (define_expand "movdi"
3290   [(set (match_operand:DI 0 "")
3291         (match_operand:DI 1 ""))]
3292   ""
3293 {
3294   if (mips_legitimize_move (DImode, operands[0], operands[1]))
3295     DONE;
3296 })
3297
3298 ;; For mips16, we need a special case to handle storing $31 into
3299 ;; memory, since we don't have a constraint to match $31.  This
3300 ;; instruction can be generated by save_restore_insns.
3301
3302 (define_insn "*mov<mode>_ra"
3303   [(set (match_operand:GPR 0 "stack_operand" "=m")
3304         (reg:GPR 31))]
3305   "TARGET_MIPS16"
3306   "<store>\t$31,%0"
3307   [(set_attr "type" "store")
3308    (set_attr "mode" "<MODE>")])
3309
3310 (define_insn "*movdi_32bit"
3311   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
3312         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
3313   "!TARGET_64BIT && !TARGET_MIPS16
3314    && (register_operand (operands[0], DImode)
3315        || reg_or_0_operand (operands[1], DImode))"
3316   { return mips_output_move (operands[0], operands[1]); }
3317   [(set_attr "type"     "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3318    (set_attr "mode"     "DI")
3319    (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
3320
3321 (define_insn "*movdi_32bit_mips16"
3322   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3323         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3324   "!TARGET_64BIT && TARGET_MIPS16
3325    && (register_operand (operands[0], DImode)
3326        || register_operand (operands[1], DImode))"
3327   { return mips_output_move (operands[0], operands[1]); }
3328   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store,mfhilo")
3329    (set_attr "mode"     "DI")
3330    (set_attr "length"   "8,8,8,8,12,*,*,8")])
3331
3332 (define_insn "*movdi_64bit"
3333   [(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")
3334         (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"))]
3335   "TARGET_64BIT && !TARGET_MIPS16
3336    && (register_operand (operands[0], DImode)
3337        || reg_or_0_operand (operands[1], DImode))"
3338   { return mips_output_move (operands[0], operands[1]); }
3339   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3340    (set_attr "mode"     "DI")
3341    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3342
3343 (define_insn "*movdi_64bit_mips16"
3344   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3345         (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3346   "TARGET_64BIT && TARGET_MIPS16
3347    && (register_operand (operands[0], DImode)
3348        || register_operand (operands[1], DImode))"
3349   { return mips_output_move (operands[0], operands[1]); }
3350   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3351    (set_attr "mode"     "DI")
3352    (set_attr_alternative "length"
3353                 [(const_int 4)
3354                  (const_int 4)
3355                  (const_int 4)
3356                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3357                                (const_int 4)
3358                                (const_int 8))
3359                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3360                                (const_int 8)
3361                                (const_int 12))
3362                  (const_string "*")
3363                  (const_string "*")
3364                  (const_string "*")])])
3365
3366
3367 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3368 ;; when the original load is a 4 byte instruction but the add and the
3369 ;; load are 2 2 byte instructions.
3370
3371 (define_split
3372   [(set (match_operand:DI 0 "register_operand")
3373         (mem:DI (plus:DI (match_dup 0)
3374                          (match_operand:DI 1 "const_int_operand"))))]
3375   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3376    && !TARGET_DEBUG_D_MODE
3377    && GET_CODE (operands[0]) == REG
3378    && M16_REG_P (REGNO (operands[0]))
3379    && GET_CODE (operands[1]) == CONST_INT
3380    && ((INTVAL (operands[1]) < 0
3381         && INTVAL (operands[1]) >= -0x10)
3382        || (INTVAL (operands[1]) >= 32 * 8
3383            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3384        || (INTVAL (operands[1]) >= 0
3385            && INTVAL (operands[1]) < 32 * 8
3386            && (INTVAL (operands[1]) & 7) != 0))"
3387   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3388    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3389 {
3390   HOST_WIDE_INT val = INTVAL (operands[1]);
3391
3392   if (val < 0)
3393     operands[2] = const0_rtx;
3394   else if (val >= 32 * 8)
3395     {
3396       int off = val & 7;
3397
3398       operands[1] = GEN_INT (0x8 + off);
3399       operands[2] = GEN_INT (val - off - 0x8);
3400     }
3401   else
3402     {
3403       int off = val & 7;
3404
3405       operands[1] = GEN_INT (off);
3406       operands[2] = GEN_INT (val - off);
3407     }
3408 })
3409
3410 ;; 32-bit Integer moves
3411
3412 ;; Unlike most other insns, the move insns can't be split with
3413 ;; different predicates, because register spilling and other parts of
3414 ;; the compiler, have memoized the insn number already.
3415
3416 (define_expand "movsi"
3417   [(set (match_operand:SI 0 "")
3418         (match_operand:SI 1 ""))]
3419   ""
3420 {
3421   if (mips_legitimize_move (SImode, operands[0], operands[1]))
3422     DONE;
3423 })
3424
3425 ;; The difference between these two is whether or not ints are allowed
3426 ;; in FP registers (off by default, use -mdebugh to enable).
3427
3428 (define_insn "*movsi_internal"
3429   [(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")
3430         (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"))]
3431   "!TARGET_MIPS16
3432    && (register_operand (operands[0], SImode)
3433        || reg_or_0_operand (operands[1], SImode))"
3434   { return mips_output_move (operands[0], operands[1]); }
3435   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
3436    (set_attr "mode"     "SI")
3437    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
3438
3439 (define_insn "*movsi_mips16"
3440   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3441         (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3442   "TARGET_MIPS16
3443    && (register_operand (operands[0], SImode)
3444        || register_operand (operands[1], SImode))"
3445   { return mips_output_move (operands[0], operands[1]); }
3446   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3447    (set_attr "mode"     "SI")
3448    (set_attr_alternative "length"
3449                 [(const_int 4)
3450                  (const_int 4)
3451                  (const_int 4)
3452                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3453                                (const_int 4)
3454                                (const_int 8))
3455                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3456                                (const_int 8)
3457                                (const_int 12))
3458                  (const_string "*")
3459                  (const_string "*")
3460                  (const_string "*")])])
3461
3462 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3463 ;; when the original load is a 4 byte instruction but the add and the
3464 ;; load are 2 2 byte instructions.
3465
3466 (define_split
3467   [(set (match_operand:SI 0 "register_operand")
3468         (mem:SI (plus:SI (match_dup 0)
3469                          (match_operand:SI 1 "const_int_operand"))))]
3470   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3471    && GET_CODE (operands[0]) == REG
3472    && M16_REG_P (REGNO (operands[0]))
3473    && GET_CODE (operands[1]) == CONST_INT
3474    && ((INTVAL (operands[1]) < 0
3475         && INTVAL (operands[1]) >= -0x80)
3476        || (INTVAL (operands[1]) >= 32 * 4
3477            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3478        || (INTVAL (operands[1]) >= 0
3479            && INTVAL (operands[1]) < 32 * 4
3480            && (INTVAL (operands[1]) & 3) != 0))"
3481   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3482    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3483 {
3484   HOST_WIDE_INT val = INTVAL (operands[1]);
3485
3486   if (val < 0)
3487     operands[2] = const0_rtx;
3488   else if (val >= 32 * 4)
3489     {
3490       int off = val & 3;
3491
3492       operands[1] = GEN_INT (0x7c + off);
3493       operands[2] = GEN_INT (val - off - 0x7c);
3494     }
3495   else
3496     {
3497       int off = val & 3;
3498
3499       operands[1] = GEN_INT (off);
3500       operands[2] = GEN_INT (val - off);
3501     }
3502 })
3503
3504 ;; On the mips16, we can split a load of certain constants into a load
3505 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
3506 ;; instructions.
3507
3508 (define_split
3509   [(set (match_operand:SI 0 "register_operand")
3510         (match_operand:SI 1 "const_int_operand"))]
3511   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3512    && GET_CODE (operands[0]) == REG
3513    && M16_REG_P (REGNO (operands[0]))
3514    && GET_CODE (operands[1]) == CONST_INT
3515    && INTVAL (operands[1]) >= 0x100
3516    && INTVAL (operands[1]) <= 0xff + 0x7f"
3517   [(set (match_dup 0) (match_dup 1))
3518    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3519 {
3520   int val = INTVAL (operands[1]);
3521
3522   operands[1] = GEN_INT (0xff);
3523   operands[2] = GEN_INT (val - 0xff);
3524 })
3525
3526 ;; This insn handles moving CCmode values.  It's really just a
3527 ;; slightly simplified copy of movsi_internal2, with additional cases
3528 ;; to move a condition register to a general register and to move
3529 ;; between the general registers and the floating point registers.
3530
3531 (define_insn "movcc"
3532   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3533         (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3534   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3535   { return mips_output_move (operands[0], operands[1]); }
3536   [(set_attr "type"     "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
3537    (set_attr "mode"     "SI")
3538    (set_attr "length"   "8,4,*,*,4,4,4,*,*")])
3539
3540 ;; Reload condition code registers.  reload_incc and reload_outcc
3541 ;; both handle moves from arbitrary operands into condition code
3542 ;; registers.  reload_incc handles the more common case in which
3543 ;; a source operand is constrained to be in a condition-code
3544 ;; register, but has not been allocated to one.
3545 ;;
3546 ;; Sometimes, such as in movcc, we have a CCmode destination whose
3547 ;; constraints do not include 'z'.  reload_outcc handles the case
3548 ;; when such an operand is allocated to a condition-code register.
3549 ;;
3550 ;; Note that reloads from a condition code register to some
3551 ;; other location can be done using ordinary moves.  Moving
3552 ;; into a GPR takes a single movcc, moving elsewhere takes
3553 ;; two.  We can leave these cases to the generic reload code.
3554 (define_expand "reload_incc"
3555   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3556         (match_operand:CC 1 "general_operand" ""))
3557    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3558   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3559 {
3560   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3561   DONE;
3562 })
3563
3564 (define_expand "reload_outcc"
3565   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3566         (match_operand:CC 1 "register_operand" ""))
3567    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3568   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3569 {
3570   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3571   DONE;
3572 })
3573
3574 ;; MIPS4 supports loading and storing a floating point register from
3575 ;; the sum of two general registers.  We use two versions for each of
3576 ;; these four instructions: one where the two general registers are
3577 ;; SImode, and one where they are DImode.  This is because general
3578 ;; registers will be in SImode when they hold 32 bit values, but,
3579 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3580 ;; instructions will still work correctly.
3581
3582 ;; ??? Perhaps it would be better to support these instructions by
3583 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
3584 ;; these instructions can only be used to load and store floating
3585 ;; point registers, that would probably cause trouble in reload.
3586
3587 (define_insn "*<ANYF:loadx>_<P:mode>"
3588   [(set (match_operand:ANYF 0 "register_operand" "=f")
3589         (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3590                           (match_operand:P 2 "register_operand" "d"))))]
3591   "ISA_HAS_FP4"
3592   "<ANYF:loadx>\t%0,%1(%2)"
3593   [(set_attr "type" "fpidxload")
3594    (set_attr "mode" "<ANYF:UNITMODE>")])
3595
3596 (define_insn "*<ANYF:storex>_<P:mode>"
3597   [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3598                           (match_operand:P 2 "register_operand" "d")))
3599         (match_operand:ANYF 0 "register_operand" "f"))]
3600   "ISA_HAS_FP4"
3601   "<ANYF:storex>\t%0,%1(%2)"
3602   [(set_attr "type" "fpidxstore")
3603    (set_attr "mode" "<ANYF:UNITMODE>")])
3604
3605 ;; 16-bit Integer moves
3606
3607 ;; Unlike most other insns, the move insns can't be split with
3608 ;; different predicates, because register spilling and other parts of
3609 ;; the compiler, have memoized the insn number already.
3610 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3611
3612 (define_expand "movhi"
3613   [(set (match_operand:HI 0 "")
3614         (match_operand:HI 1 ""))]
3615   ""
3616 {
3617   if (mips_legitimize_move (HImode, operands[0], operands[1]))
3618     DONE;
3619 })
3620
3621 (define_insn "*movhi_internal"
3622   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3623         (match_operand:HI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3624   "!TARGET_MIPS16
3625    && (register_operand (operands[0], HImode)
3626        || reg_or_0_operand (operands[1], HImode))"
3627   "@
3628     move\t%0,%1
3629     li\t%0,%1
3630     lhu\t%0,%1
3631     sh\t%z1,%0
3632     mfc1\t%0,%1
3633     mtc1\t%1,%0
3634     mov.s\t%0,%1
3635     mt%0\t%1"
3636   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3637    (set_attr "mode"     "HI")
3638    (set_attr "length"   "4,4,*,*,4,4,4,4")])
3639
3640 (define_insn "*movhi_mips16"
3641   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3642         (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3643   "TARGET_MIPS16
3644    && (register_operand (operands[0], HImode)
3645        || register_operand (operands[1], HImode))"
3646   "@
3647     move\t%0,%1
3648     move\t%0,%1
3649     move\t%0,%1
3650     li\t%0,%1
3651     #
3652     lhu\t%0,%1
3653     sh\t%1,%0"
3654   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
3655    (set_attr "mode"     "HI")
3656    (set_attr_alternative "length"
3657                 [(const_int 4)
3658                  (const_int 4)
3659                  (const_int 4)
3660                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3661                                (const_int 4)
3662                                (const_int 8))
3663                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3664                                (const_int 8)
3665                                (const_int 12))
3666                  (const_string "*")
3667                  (const_string "*")])])
3668
3669
3670 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
3671 ;; when the original load is a 4 byte instruction but the add and the
3672 ;; load are 2 2 byte instructions.
3673
3674 (define_split
3675   [(set (match_operand:HI 0 "register_operand")
3676         (mem:HI (plus:SI (match_dup 0)
3677                          (match_operand:SI 1 "const_int_operand"))))]
3678   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3679    && GET_CODE (operands[0]) == REG
3680    && M16_REG_P (REGNO (operands[0]))
3681    && GET_CODE (operands[1]) == CONST_INT
3682    && ((INTVAL (operands[1]) < 0
3683         && INTVAL (operands[1]) >= -0x80)
3684        || (INTVAL (operands[1]) >= 32 * 2
3685            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3686        || (INTVAL (operands[1]) >= 0
3687            && INTVAL (operands[1]) < 32 * 2
3688            && (INTVAL (operands[1]) & 1) != 0))"
3689   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3690    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3691 {
3692   HOST_WIDE_INT val = INTVAL (operands[1]);
3693
3694   if (val < 0)
3695     operands[2] = const0_rtx;
3696   else if (val >= 32 * 2)
3697     {
3698       int off = val & 1;
3699
3700       operands[1] = GEN_INT (0x7e + off);
3701       operands[2] = GEN_INT (val - off - 0x7e);
3702     }
3703   else
3704     {
3705       int off = val & 1;
3706
3707       operands[1] = GEN_INT (off);
3708       operands[2] = GEN_INT (val - off);
3709     }
3710 })
3711
3712 ;; 8-bit Integer moves
3713
3714 ;; Unlike most other insns, the move insns can't be split with
3715 ;; different predicates, because register spilling and other parts of
3716 ;; the compiler, have memoized the insn number already.
3717 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3718
3719 (define_expand "movqi"
3720   [(set (match_operand:QI 0 "")
3721         (match_operand:QI 1 ""))]
3722   ""
3723 {
3724   if (mips_legitimize_move (QImode, operands[0], operands[1]))
3725     DONE;
3726 })
3727
3728 (define_insn "*movqi_internal"
3729   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3730         (match_operand:QI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3731   "!TARGET_MIPS16
3732    && (register_operand (operands[0], QImode)
3733        || reg_or_0_operand (operands[1], QImode))"
3734   "@
3735     move\t%0,%1
3736     li\t%0,%1
3737     lbu\t%0,%1
3738     sb\t%z1,%0
3739     mfc1\t%0,%1
3740     mtc1\t%1,%0
3741     mov.s\t%0,%1
3742     mt%0\t%1"
3743   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3744    (set_attr "mode"     "QI")
3745    (set_attr "length"   "4,4,*,*,4,4,4,4")])
3746
3747 (define_insn "*movqi_mips16"
3748   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3749         (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3750   "TARGET_MIPS16
3751    && (register_operand (operands[0], QImode)
3752        || register_operand (operands[1], QImode))"
3753   "@
3754     move\t%0,%1
3755     move\t%0,%1
3756     move\t%0,%1
3757     li\t%0,%1
3758     #
3759     lbu\t%0,%1
3760     sb\t%1,%0"
3761   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
3762    (set_attr "mode"     "QI")
3763    (set_attr "length"   "4,4,4,4,8,*,*")])
3764
3765 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
3766 ;; when the original load is a 4 byte instruction but the add and the
3767 ;; load are 2 2 byte instructions.
3768
3769 (define_split
3770   [(set (match_operand:QI 0 "register_operand")
3771         (mem:QI (plus:SI (match_dup 0)
3772                          (match_operand:SI 1 "const_int_operand"))))]
3773   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3774    && GET_CODE (operands[0]) == REG
3775    && M16_REG_P (REGNO (operands[0]))
3776    && GET_CODE (operands[1]) == CONST_INT
3777    && ((INTVAL (operands[1]) < 0
3778         && INTVAL (operands[1]) >= -0x80)
3779        || (INTVAL (operands[1]) >= 32
3780            && INTVAL (operands[1]) <= 31 + 0x7f))"
3781   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3782    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3783 {
3784   HOST_WIDE_INT val = INTVAL (operands[1]);
3785
3786   if (val < 0)
3787     operands[2] = const0_rtx;
3788   else
3789     {
3790       operands[1] = GEN_INT (0x7f);
3791       operands[2] = GEN_INT (val - 0x7f);
3792     }
3793 })
3794
3795 ;; 32-bit floating point moves
3796
3797 (define_expand "movsf"
3798   [(set (match_operand:SF 0 "")
3799         (match_operand:SF 1 ""))]
3800   ""
3801 {
3802   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3803     DONE;
3804 })
3805
3806 (define_insn "*movsf_hardfloat"
3807   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3808         (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
3809   "TARGET_HARD_FLOAT
3810    && (register_operand (operands[0], SFmode)
3811        || reg_or_0_operand (operands[1], SFmode))"
3812   { return mips_output_move (operands[0], operands[1]); }
3813   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
3814    (set_attr "mode"     "SF")
3815    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
3816
3817 (define_insn "*movsf_softfloat"
3818   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3819         (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3820   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3821    && (register_operand (operands[0], SFmode)
3822        || reg_or_0_operand (operands[1], SFmode))"
3823   { return mips_output_move (operands[0], operands[1]); }
3824   [(set_attr "type"     "arith,load,store")
3825    (set_attr "mode"     "SF")
3826    (set_attr "length"   "4,*,*")])
3827
3828 (define_insn "*movsf_mips16"
3829   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3830         (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3831   "TARGET_MIPS16
3832    && (register_operand (operands[0], SFmode)
3833        || register_operand (operands[1], SFmode))"
3834   { return mips_output_move (operands[0], operands[1]); }
3835   [(set_attr "type"     "arith,arith,arith,load,store")
3836    (set_attr "mode"     "SF")
3837    (set_attr "length"   "4,4,4,*,*")])
3838
3839
3840 ;; 64-bit floating point moves
3841
3842 (define_expand "movdf"
3843   [(set (match_operand:DF 0 "")
3844         (match_operand:DF 1 ""))]
3845   ""
3846 {
3847   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3848     DONE;
3849 })
3850
3851 (define_insn "*movdf_hardfloat_64bit"
3852   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3853         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
3854   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
3855    && (register_operand (operands[0], DFmode)
3856        || reg_or_0_operand (operands[1], DFmode))"
3857   { return mips_output_move (operands[0], operands[1]); }
3858   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
3859    (set_attr "mode"     "DF")
3860    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
3861
3862 (define_insn "*movdf_hardfloat_32bit"
3863   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3864         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
3865   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
3866    && (register_operand (operands[0], DFmode)
3867        || reg_or_0_operand (operands[1], DFmode))"
3868   { return mips_output_move (operands[0], operands[1]); }
3869   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
3870    (set_attr "mode"     "DF")
3871    (set_attr "length"   "4,8,*,*,8,8,8,*,*")])
3872
3873 (define_insn "*movdf_softfloat"
3874   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
3875         (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
3876   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
3877    && (register_operand (operands[0], DFmode)
3878        || reg_or_0_operand (operands[1], DFmode))"
3879   { return mips_output_move (operands[0], operands[1]); }
3880   [(set_attr "type"     "arith,load,store,xfer,xfer,fmove")
3881    (set_attr "mode"     "DF")
3882    (set_attr "length"   "8,*,*,4,4,4")])
3883
3884 (define_insn "*movdf_mips16"
3885   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
3886         (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
3887   "TARGET_MIPS16
3888    && (register_operand (operands[0], DFmode)
3889        || register_operand (operands[1], DFmode))"
3890   { return mips_output_move (operands[0], operands[1]); }
3891   [(set_attr "type"     "arith,arith,arith,load,store")
3892    (set_attr "mode"     "DF")
3893    (set_attr "length"   "8,8,8,*,*")])
3894
3895 (define_split
3896   [(set (match_operand:DI 0 "nonimmediate_operand")
3897         (match_operand:DI 1 "move_operand"))]
3898   "reload_completed && !TARGET_64BIT
3899    && mips_split_64bit_move_p (operands[0], operands[1])"
3900   [(const_int 0)]
3901 {
3902   mips_split_64bit_move (operands[0], operands[1]);
3903   DONE;
3904 })
3905
3906 (define_split
3907   [(set (match_operand:DF 0 "nonimmediate_operand")
3908         (match_operand:DF 1 "move_operand"))]
3909   "reload_completed && !TARGET_64BIT
3910    && mips_split_64bit_move_p (operands[0], operands[1])"
3911   [(const_int 0)]
3912 {
3913   mips_split_64bit_move (operands[0], operands[1]);
3914   DONE;
3915 })
3916
3917 ;; When generating mips16 code, split moves of negative constants into
3918 ;; a positive "li" followed by a negation.
3919 (define_split
3920   [(set (match_operand 0 "register_operand")
3921         (match_operand 1 "const_int_operand"))]
3922   "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
3923   [(set (match_dup 2)
3924         (match_dup 3))
3925    (set (match_dup 2)
3926         (neg:SI (match_dup 2)))]
3927 {
3928   operands[2] = gen_lowpart (SImode, operands[0]);
3929   operands[3] = GEN_INT (-INTVAL (operands[1]));
3930 })
3931
3932 ;; 64-bit paired-single floating point moves
3933
3934 (define_expand "movv2sf"
3935   [(set (match_operand:V2SF 0)
3936         (match_operand:V2SF 1))]
3937   "TARGET_PAIRED_SINGLE_FLOAT"
3938 {
3939   if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
3940     DONE;
3941 })
3942
3943 (define_insn "movv2sf_hardfloat_64bit"
3944   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3945         (match_operand:V2SF 1 "move_operand" "f,YG,m,fYG,*d,*f,*d*YG,*m,*d"))]
3946   "TARGET_PAIRED_SINGLE_FLOAT
3947    && TARGET_64BIT
3948    && (register_operand (operands[0], V2SFmode)
3949        || reg_or_0_operand (operands[1], V2SFmode))"
3950   { return mips_output_move (operands[0], operands[1]); }
3951   [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
3952    (set_attr "mode" "SF")
3953    (set_attr "length" "4,4,*,*,4,4,4,*,*")])
3954
3955 ;; The HI and LO registers are not truly independent.  If we move an mthi
3956 ;; instruction before an mflo instruction, it will make the result of the
3957 ;; mflo unpredictable.  The same goes for mtlo and mfhi.
3958 ;;
3959 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
3960 ;; Operand 1 is the register we want, operand 2 is the other one.
3961
3962 (define_insn "mfhilo_<mode>"
3963   [(set (match_operand:GPR 0 "register_operand" "=d,d")
3964         (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
3965                      (match_operand:GPR 2 "register_operand" "l,h")]
3966                     UNSPEC_MFHILO))]
3967   ""
3968   "mf%1\t%0"
3969   [(set_attr "type" "mfhilo")
3970    (set_attr "mode" "<MODE>")])
3971
3972 ;; Patterns for loading or storing part of a paired floating point
3973 ;; register.  We need them because odd-numbered floating-point registers
3974 ;; are not fully independent: see mips_split_64bit_move.
3975
3976 ;; Load the low word of operand 0 with operand 1.
3977 (define_insn "load_df_low"
3978   [(set (match_operand:DF 0 "register_operand" "=f,f")
3979         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
3980                    UNSPEC_LOAD_DF_LOW))]
3981   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3982 {
3983   operands[0] = mips_subword (operands[0], 0);
3984   return mips_output_move (operands[0], operands[1]);
3985 }
3986   [(set_attr "type"     "xfer,fpload")
3987    (set_attr "mode"     "SF")])
3988
3989 ;; Load the high word of operand 0 from operand 1, preserving the value
3990 ;; in the low word.
3991 (define_insn "load_df_high"
3992   [(set (match_operand:DF 0 "register_operand" "=f,f")
3993         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
3994                     (match_operand:DF 2 "register_operand" "0,0")]
3995                    UNSPEC_LOAD_DF_HIGH))]
3996   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3997 {
3998   operands[0] = mips_subword (operands[0], 1);
3999   return mips_output_move (operands[0], operands[1]);
4000 }
4001   [(set_attr "type"     "xfer,fpload")
4002    (set_attr "mode"     "SF")])
4003
4004 ;; Store the high word of operand 1 in operand 0.  The corresponding
4005 ;; low-word move is done in the normal way.
4006 (define_insn "store_df_high"
4007   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4008         (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4009                    UNSPEC_STORE_DF_HIGH))]
4010   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4011 {
4012   operands[1] = mips_subword (operands[1], 1);
4013   return mips_output_move (operands[0], operands[1]);
4014 }
4015   [(set_attr "type"     "xfer,fpstore")
4016    (set_attr "mode"     "SF")])
4017
4018 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
4019 ;; of _gp from the start of this function.  Operand 1 is the incoming
4020 ;; function address.
4021 (define_insn_and_split "loadgp"
4022