OSDN Git Service

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