OSDN Git Service

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