* config/mips/mips.h (ISA_HAS_INT_CONDMOVE): Delete.
[official-gcc.git] / gcc / config / mips / mips.md
blobef3e69a8c02f2798d2fa30396d2f8afb1a17a2d9
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.
9 ;; This file is part of GCC.
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.
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.
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.
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)
49    (UNSPEC_ADDRESS_FIRST        100)
51    (FAKE_CALL_REGNO             79)])
53 (include "predicates.md")
55 ;; ....................
57 ;;      Attributes
59 ;; ....................
61 (define_attr "got" "unset,xgot_high,load"
62   (const_string "unset"))
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"))
69 ;; This attribute is YES if the instruction is a jal macro (not a
70 ;; real jal instruction).
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")))
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")))
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"))
131 ;; Is this an extended instruction in mips16 mode?
132 (define_attr "extended_mips16" "no,yes"
133   (const_string "no"))
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))
177           (eq_attr "got" "load")
178           (const_int 4)
179           (eq_attr "got" "xgot_high")
180           (const_int 8)
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")
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)
202           (and (eq_attr "extended_mips16" "yes")
203                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
204           (const_int 8)
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)
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)
221           (eq_attr "type" "idiv")
222           (symbol_ref "mips_idiv_insns () * 4")
223           ] (const_int 4)))
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")))
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")
240          (and (eq_attr "type" "xfer")
241               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
242          (const_string "delay")
244          (and (eq_attr "type" "fcmp")
245               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
246          (const_string "delay")
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")
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")))
258 ;; Is it a single instruction?
259 (define_attr "single_insn" "no,yes"
260   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
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")))
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"))))
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")))
284 ;; Describe a user's asm statement.
285 (define_asm_attributes
286   [(set_attr "type" "multi")])
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")])
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")])
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")])
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")])
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")])
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")])
313 ;; In MOVECC templates, this attribute gives the constraint to use
314 ;; for the condition register.
315 (define_mode_attr ccreg [(SI "d") (DI "d") (CC "z")])
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])
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])
326 ;; <u> expands to an empty string when doing a signed operation and
327 ;; "u" when doing an unsigned operation.
328 (define_code_attr u [(sign_extend "") (zero_extend "u")])
330 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
331 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
333 ;; .........................
335 ;;      Branch, call and jump delay slots
337 ;; .........................
339 (define_delay (and (eq_attr "type" "branch")
340                    (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
341   [(eq_attr "can_delay" "yes")
342    (nil)
343    (and (eq_attr "branch_likely" "yes")
344         (eq_attr "can_delay" "yes"))])
346 (define_delay (eq_attr "type" "jump")
347   [(eq_attr "can_delay" "yes")
348    (nil)
349    (nil)])
351 (define_delay (and (eq_attr "type" "call")
352                    (eq_attr "jal_macro" "no"))
353   [(eq_attr "can_delay" "yes")
354    (nil)
355    (nil)])
357 ;; Pipeline descriptions.
359 ;; generic.md provides a fallback for processors without a specific
360 ;; pipeline description.  It is derived from the old define_function_unit
361 ;; version and uses the "alu" and "imuldiv" units declared below.
363 ;; Some of the processor-specific files are also derived from old
364 ;; define_function_unit descriptions and simply override the parts of
365 ;; generic.md that don't apply.  The other processor-specific files
366 ;; are self-contained.
367 (define_automaton "alu,imuldiv")
369 (define_cpu_unit "alu" "alu")
370 (define_cpu_unit "imuldiv" "imuldiv")
372 (include "3000.md")
373 (include "4000.md")
374 (include "4100.md")
375 (include "4130.md")
376 (include "4300.md")
377 (include "4600.md")
378 (include "5000.md")
379 (include "5400.md")
380 (include "5500.md")
381 (include "6000.md")
382 (include "7000.md")
383 (include "9000.md")
384 (include "sb1.md")
385 (include "sr71k.md")
386 (include "generic.md")
389 ;;  ....................
391 ;;      CONDITIONAL TRAPS
393 ;;  ....................
396 (define_insn "trap"
397   [(trap_if (const_int 1) (const_int 0))]
398   ""
400   if (ISA_HAS_COND_TRAP)
401     return "teq\t$0,$0";
402   else if (TARGET_MIPS16)
403     return "break 0";
404   else
405     return "break";
407   [(set_attr "type" "trap")])
409 (define_expand "conditional_trap"
410   [(trap_if (match_operator 0 "comparison_operator"
411                             [(match_dup 2) (match_dup 3)])
412             (match_operand 1 "const_int_operand"))]
413   "ISA_HAS_COND_TRAP"
415   if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
416       && operands[1] == const0_rtx)
417     {
418       mips_gen_conditional_trap (operands);
419       DONE;
420     }
421   else
422     FAIL;
425 (define_insn "*conditional_trap<mode>"
426   [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
427                                 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
428                                  (match_operand:GPR 2 "arith_operand" "dI")])
429             (const_int 0))]
430   "ISA_HAS_COND_TRAP"
431   "t%C0\t%z1,%2"
432   [(set_attr "type" "trap")])
435 ;;  ....................
437 ;;      ADDITION
439 ;;  ....................
442 (define_insn "adddf3"
443   [(set (match_operand:DF 0 "register_operand" "=f")
444         (plus:DF (match_operand:DF 1 "register_operand" "f")
445                  (match_operand:DF 2 "register_operand" "f")))]
446   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
447   "add.d\t%0,%1,%2"
448   [(set_attr "type"     "fadd")
449    (set_attr "mode"     "DF")])
451 (define_insn "addsf3"
452   [(set (match_operand:SF 0 "register_operand" "=f")
453         (plus:SF (match_operand:SF 1 "register_operand" "f")
454                  (match_operand:SF 2 "register_operand" "f")))]
455   "TARGET_HARD_FLOAT"
456   "add.s\t%0,%1,%2"
457   [(set_attr "type"     "fadd")
458    (set_attr "mode"     "SF")])
460 (define_expand "add<mode>3"
461   [(set (match_operand:GPR 0 "register_operand")
462         (plus:GPR (match_operand:GPR 1 "register_operand")
463                   (match_operand:GPR 2 "arith_operand")))]
464   "")
466 (define_insn "*add<mode>3"
467   [(set (match_operand:GPR 0 "register_operand" "=d,d")
468         (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
469                   (match_operand:GPR 2 "arith_operand" "d,Q")))]
470   "!TARGET_MIPS16"
471   "@
472     <d>addu\t%0,%1,%2
473     <d>addiu\t%0,%1,%2"
474   [(set_attr "type" "arith")
475    (set_attr "mode" "<MODE>")])
477 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
478 ;; we don't have a constraint for $sp.  These insns will be generated by
479 ;; the save_restore_insns functions.
481 (define_insn "*add<mode>3_sp1"
482   [(set (reg:GPR 29)
483         (plus:GPR (reg:GPR 29)
484                   (match_operand:GPR 0 "const_arith_operand" "")))]
485   "TARGET_MIPS16"
486   "<d>addiu\t%$,%$,%0"
487   [(set_attr "type" "arith")
488    (set_attr "mode" "<MODE>")
489    (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
490                                       (const_int 4)
491                                       (const_int 8)))])
493 (define_insn "*add<mode>3_sp2"
494   [(set (match_operand:GPR 0 "register_operand" "=d")
495         (plus:GPR (reg:GPR 29)
496                   (match_operand:GPR 1 "const_arith_operand" "")))]
497   "TARGET_MIPS16"
498   "<d>addiu\t%0,%$,%1"
499   [(set_attr "type" "arith")
500    (set_attr "mode" "<MODE>")
501    (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
502                                       (const_int 4)
503                                       (const_int 8)))])
505 (define_insn "*add<mode>3_mips16"
506   [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
507         (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
508                   (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
509   "TARGET_MIPS16"
510   "@
511     <d>addiu\t%0,%2
512     <d>addiu\t%0,%1,%2
513     <d>addu\t%0,%1,%2"
514   [(set_attr "type" "arith")
515    (set_attr "mode" "<MODE>")
516    (set_attr_alternative "length"
517                 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
518                                (const_int 4)
519                                (const_int 8))
520                  (if_then_else (match_operand 2 "m16_simm4_1")
521                                (const_int 4)
522                                (const_int 8))
523                  (const_int 4)])])
526 ;; On the mips16, we can sometimes split an add of a constant which is
527 ;; a 4 byte instruction into two adds which are both 2 byte
528 ;; instructions.  There are two cases: one where we are adding a
529 ;; constant plus a register to another register, and one where we are
530 ;; simply adding a constant to a register.
532 (define_split
533   [(set (match_operand:SI 0 "register_operand")
534         (plus:SI (match_dup 0)
535                  (match_operand:SI 1 "const_int_operand")))]
536   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
537    && GET_CODE (operands[0]) == REG
538    && M16_REG_P (REGNO (operands[0]))
539    && GET_CODE (operands[1]) == CONST_INT
540    && ((INTVAL (operands[1]) > 0x7f
541         && INTVAL (operands[1]) <= 0x7f + 0x7f)
542        || (INTVAL (operands[1]) < - 0x80
543            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
544   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
545    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
547   HOST_WIDE_INT val = INTVAL (operands[1]);
549   if (val >= 0)
550     {
551       operands[1] = GEN_INT (0x7f);
552       operands[2] = GEN_INT (val - 0x7f);
553     }
554   else
555     {
556       operands[1] = GEN_INT (- 0x80);
557       operands[2] = GEN_INT (val + 0x80);
558     }
561 (define_split
562   [(set (match_operand:SI 0 "register_operand")
563         (plus:SI (match_operand:SI 1 "register_operand")
564                  (match_operand:SI 2 "const_int_operand")))]
565   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
566    && GET_CODE (operands[0]) == REG
567    && M16_REG_P (REGNO (operands[0]))
568    && GET_CODE (operands[1]) == REG
569    && M16_REG_P (REGNO (operands[1]))
570    && REGNO (operands[0]) != REGNO (operands[1])
571    && GET_CODE (operands[2]) == CONST_INT
572    && ((INTVAL (operands[2]) > 0x7
573         && INTVAL (operands[2]) <= 0x7 + 0x7f)
574        || (INTVAL (operands[2]) < - 0x8
575            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
576   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
577    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
579   HOST_WIDE_INT val = INTVAL (operands[2]);
581   if (val >= 0)
582     {
583       operands[2] = GEN_INT (0x7);
584       operands[3] = GEN_INT (val - 0x7);
585     }
586   else
587     {
588       operands[2] = GEN_INT (- 0x8);
589       operands[3] = GEN_INT (val + 0x8);
590     }
593 (define_split
594   [(set (match_operand:DI 0 "register_operand")
595         (plus:DI (match_dup 0)
596                  (match_operand:DI 1 "const_int_operand")))]
597   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
598    && GET_CODE (operands[0]) == REG
599    && M16_REG_P (REGNO (operands[0]))
600    && GET_CODE (operands[1]) == CONST_INT
601    && ((INTVAL (operands[1]) > 0xf
602         && INTVAL (operands[1]) <= 0xf + 0xf)
603        || (INTVAL (operands[1]) < - 0x10
604            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
605   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
606    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
608   HOST_WIDE_INT val = INTVAL (operands[1]);
610   if (val >= 0)
611     {
612       operands[1] = GEN_INT (0xf);
613       operands[2] = GEN_INT (val - 0xf);
614     }
615   else
616     {
617       operands[1] = GEN_INT (- 0x10);
618       operands[2] = GEN_INT (val + 0x10);
619     }
622 (define_split
623   [(set (match_operand:DI 0 "register_operand")
624         (plus:DI (match_operand:DI 1 "register_operand")
625                  (match_operand:DI 2 "const_int_operand")))]
626   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
627    && GET_CODE (operands[0]) == REG
628    && M16_REG_P (REGNO (operands[0]))
629    && GET_CODE (operands[1]) == REG
630    && M16_REG_P (REGNO (operands[1]))
631    && REGNO (operands[0]) != REGNO (operands[1])
632    && GET_CODE (operands[2]) == CONST_INT
633    && ((INTVAL (operands[2]) > 0x7
634         && INTVAL (operands[2]) <= 0x7 + 0xf)
635        || (INTVAL (operands[2]) < - 0x8
636            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
637   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
638    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
640   HOST_WIDE_INT val = INTVAL (operands[2]);
642   if (val >= 0)
643     {
644       operands[2] = GEN_INT (0x7);
645       operands[3] = GEN_INT (val - 0x7);
646     }
647   else
648     {
649       operands[2] = GEN_INT (- 0x8);
650       operands[3] = GEN_INT (val + 0x8);
651     }
654 (define_insn "*addsi3_extended"
655   [(set (match_operand:DI 0 "register_operand" "=d,d")
656         (sign_extend:DI
657              (plus:SI (match_operand:SI 1 "register_operand" "d,d")
658                       (match_operand:SI 2 "arith_operand" "d,Q"))))]
659   "TARGET_64BIT && !TARGET_MIPS16"
660   "@
661     addu\t%0,%1,%2
662     addiu\t%0,%1,%2"
663   [(set_attr "type" "arith")
664    (set_attr "mode" "SI")])
666 ;; Split this insn so that the addiu splitters can have a crack at it.
667 ;; Use a conservative length estimate until the split.
668 (define_insn_and_split "*addsi3_extended_mips16"
669   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
670         (sign_extend:DI
671              (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
672                       (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
673   "TARGET_64BIT && TARGET_MIPS16"
674   "#"
675   "&& reload_completed"
676   [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
677   { operands[3] = gen_lowpart (SImode, operands[0]); }
678   [(set_attr "type" "arith")
679    (set_attr "mode" "SI")
680    (set_attr "extended_mips16" "yes")])
683 ;;  ....................
685 ;;      SUBTRACTION
687 ;;  ....................
690 (define_insn "subdf3"
691   [(set (match_operand:DF 0 "register_operand" "=f")
692         (minus:DF (match_operand:DF 1 "register_operand" "f")
693                   (match_operand:DF 2 "register_operand" "f")))]
694   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
695   "sub.d\t%0,%1,%2"
696   [(set_attr "type"     "fadd")
697    (set_attr "mode"     "DF")])
699 (define_insn "subsf3"
700   [(set (match_operand:SF 0 "register_operand" "=f")
701         (minus:SF (match_operand:SF 1 "register_operand" "f")
702                   (match_operand:SF 2 "register_operand" "f")))]
703   "TARGET_HARD_FLOAT"
704   "sub.s\t%0,%1,%2"
705   [(set_attr "type"     "fadd")
706    (set_attr "mode"     "SF")])
708 (define_insn "sub<mode>3"
709   [(set (match_operand:GPR 0 "register_operand" "=d")
710         (minus:GPR (match_operand:GPR 1 "register_operand" "d")
711                    (match_operand:GPR 2 "register_operand" "d")))]
712   ""
713   "<d>subu\t%0,%1,%2"
714   [(set_attr "type" "arith")
715    (set_attr "mode" "<MODE>")])
717 (define_insn "*subsi3_extended"
718   [(set (match_operand:DI 0 "register_operand" "=d")
719         (sign_extend:DI
720             (minus:SI (match_operand:SI 1 "register_operand" "d")
721                       (match_operand:SI 2 "register_operand" "d"))))]
722   "TARGET_64BIT"
723   "subu\t%0,%1,%2"
724   [(set_attr "type" "arith")
725    (set_attr "mode" "DI")])
728 ;;  ....................
730 ;;      MULTIPLICATION
732 ;;  ....................
735 (define_expand "muldf3"
736   [(set (match_operand:DF 0 "register_operand")
737         (mult:DF (match_operand:DF 1 "register_operand")
738                  (match_operand:DF 2 "register_operand")))]
739   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
740   "")
742 (define_insn "muldf3_internal"
743   [(set (match_operand:DF 0 "register_operand" "=f")
744         (mult:DF (match_operand:DF 1 "register_operand" "f")
745                  (match_operand:DF 2 "register_operand" "f")))]
746   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
747   "mul.d\t%0,%1,%2"
748   [(set_attr "type"     "fmul")
749    (set_attr "mode"     "DF")])
751 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
752 ;; operands may corrupt immediately following multiplies. This is a
753 ;; simple fix to insert NOPs.
755 (define_insn "muldf3_r4300"
756   [(set (match_operand:DF 0 "register_operand" "=f")
757         (mult:DF (match_operand:DF 1 "register_operand" "f")
758                  (match_operand:DF 2 "register_operand" "f")))]
759   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
760   "mul.d\t%0,%1,%2\;nop"
761   [(set_attr "type"     "fmul")
762    (set_attr "mode"     "DF")
763    (set_attr "length"   "8")])
765 (define_expand "mulsf3"
766   [(set (match_operand:SF 0 "register_operand")
767         (mult:SF (match_operand:SF 1 "register_operand")
768                  (match_operand:SF 2 "register_operand")))]
769   "TARGET_HARD_FLOAT"
770   "")
772 (define_insn "mulsf3_internal"
773   [(set (match_operand:SF 0 "register_operand" "=f")
774         (mult:SF (match_operand:SF 1 "register_operand" "f")
775                  (match_operand:SF 2 "register_operand" "f")))]
776   "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
777   "mul.s\t%0,%1,%2"
778   [(set_attr "type"     "fmul")
779    (set_attr "mode"     "SF")])
781 ;; See muldf3_r4300.
783 (define_insn "mulsf3_r4300"
784   [(set (match_operand:SF 0 "register_operand" "=f")
785         (mult:SF (match_operand:SF 1 "register_operand" "f")
786                  (match_operand:SF 2 "register_operand" "f")))]
787   "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
788   "mul.s\t%0,%1,%2\;nop"
789   [(set_attr "type"     "fmul")
790    (set_attr "mode"     "SF")
791    (set_attr "length"   "8")])
794 ;; The original R4000 has a cpu bug.  If a double-word or a variable
795 ;; shift executes while an integer multiplication is in progress, the
796 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
797 ;; with the mult on the R4000.
799 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
800 ;; (also valid for MIPS R4000MC processors):
802 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
803 ;;      this errata description.
804 ;;      The following code sequence causes the R4000 to incorrectly
805 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
806 ;;      instruction.  If the dsra32 instruction is executed during an
807 ;;      integer multiply, the dsra32 will only shift by the amount in
808 ;;      specified in the instruction rather than the amount plus 32
809 ;;      bits.
810 ;;      instruction 1:          mult    rs,rt           integer multiply
811 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
812 ;;                                                      right arithmetic + 32
813 ;;      Workaround: A dsra32 instruction placed after an integer
814 ;;      multiply should not be one of the 11 instructions after the
815 ;;      multiply instruction."
817 ;; and:
819 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
820 ;;      the following description.
821 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
822 ;;      64-bit versions) may produce incorrect results under the
823 ;;      following conditions:
824 ;;      1) An integer multiply is currently executing
825 ;;      2) These types of shift instructions are executed immediately
826 ;;         following an integer divide instruction.
827 ;;      Workaround:
828 ;;      1) Make sure no integer multiply is running wihen these
829 ;;         instruction are executed.  If this cannot be predicted at
830 ;;         compile time, then insert a "mfhi" to R0 instruction
831 ;;         immediately after the integer multiply instruction.  This
832 ;;         will cause the integer multiply to complete before the shift
833 ;;         is executed.
834 ;;      2) Separate integer divide and these two classes of shift
835 ;;         instructions by another instruction or a noop."
837 ;; These processors have PRId values of 0x00004220 and 0x00004300,
838 ;; respectively.
840 (define_expand "mul<mode>3"
841   [(set (match_operand:GPR 0 "register_operand")
842         (mult:GPR (match_operand:GPR 1 "register_operand")
843                   (match_operand:GPR 2 "register_operand")))]
844   ""
846   if (GENERATE_MULT3_<MODE>)
847     emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
848   else if (!TARGET_FIX_R4000)
849     emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
850                                         operands[2]));
851   else
852     emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
853   DONE;
856 (define_insn "mulsi3_mult3"
857   [(set (match_operand:SI 0 "register_operand" "=d,l")
858         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
859                  (match_operand:SI 2 "register_operand" "d,d")))
860    (clobber (match_scratch:SI 3 "=h,h"))
861    (clobber (match_scratch:SI 4 "=l,X"))]
862   "GENERATE_MULT3_SI"
864   if (which_alternative == 1)
865     return "mult\t%1,%2";
866   if (TARGET_MAD
867       || TARGET_MIPS5400
868       || TARGET_MIPS5500
869       || TARGET_MIPS7000
870       || TARGET_MIPS9000
871       || ISA_MIPS32
872       || ISA_MIPS32R2
873       || ISA_MIPS64)
874     return "mul\t%0,%1,%2";
875   return "mult\t%0,%1,%2";
877   [(set_attr "type" "imul")
878    (set_attr "mode" "SI")])
880 (define_insn "muldi3_mult3"
881   [(set (match_operand:DI 0 "register_operand" "=d")
882         (mult:DI (match_operand:DI 1 "register_operand" "d")
883                  (match_operand:DI 2 "register_operand" "d")))
884    (clobber (match_scratch:DI 3 "=h"))
885    (clobber (match_scratch:DI 4 "=l"))]
886   "TARGET_64BIT && GENERATE_MULT3_DI"
887   "dmult\t%0,%1,%2"
888   [(set_attr "type" "imul")
889    (set_attr "mode" "DI")])
891 ;; If a register gets allocated to LO, and we spill to memory, the reload
892 ;; will include a move from LO to a GPR.  Merge it into the multiplication
893 ;; if it can set the GPR directly.
895 ;; Operand 0: LO
896 ;; Operand 1: GPR (1st multiplication operand)
897 ;; Operand 2: GPR (2nd multiplication operand)
898 ;; Operand 3: HI
899 ;; Operand 4: GPR (destination)
900 (define_peephole2
901   [(parallel
902        [(set (match_operand:SI 0 "register_operand")
903              (mult:SI (match_operand:SI 1 "register_operand")
904                       (match_operand:SI 2 "register_operand")))
905         (clobber (match_operand:SI 3 "register_operand"))
906         (clobber (scratch:SI))])
907    (set (match_operand:SI 4 "register_operand")
908         (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
909   "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
910   [(parallel
911        [(set (match_dup 4)
912              (mult:SI (match_dup 1)
913                       (match_dup 2)))
914         (clobber (match_dup 3))
915         (clobber (match_dup 0))])])
917 (define_insn "mul<mode>3_internal"
918   [(set (match_operand:GPR 0 "register_operand" "=l")
919         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
920                   (match_operand:GPR 2 "register_operand" "d")))
921    (clobber (match_scratch:GPR 3 "=h"))]
922   "!TARGET_FIX_R4000"
923   "<d>mult\t%1,%2"
924   [(set_attr "type" "imul")
925    (set_attr "mode" "<MODE>")])
927 (define_insn "mul<mode>3_r4000"
928   [(set (match_operand:GPR 0 "register_operand" "=d")
929         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
930                   (match_operand:GPR 2 "register_operand" "d")))
931    (clobber (match_scratch:GPR 3 "=h"))
932    (clobber (match_scratch:GPR 4 "=l"))]
933   "TARGET_FIX_R4000"
934   "<d>mult\t%1,%2\;mflo\t%0"
935   [(set_attr "type" "imul")
936    (set_attr "mode" "<MODE>")
937    (set_attr "length" "8")])
939 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
940 ;; of "mult; mflo".  They have the same latency, but the first form gives
941 ;; us an extra cycle to compute the operands.
943 ;; Operand 0: LO
944 ;; Operand 1: GPR (1st multiplication operand)
945 ;; Operand 2: GPR (2nd multiplication operand)
946 ;; Operand 3: HI
947 ;; Operand 4: GPR (destination)
948 (define_peephole2
949   [(parallel
950        [(set (match_operand:SI 0 "register_operand")
951              (mult:SI (match_operand:SI 1 "register_operand")
952                       (match_operand:SI 2 "register_operand")))
953         (clobber (match_operand:SI 3 "register_operand"))])
954    (set (match_operand:SI 4 "register_operand")
955         (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
956   "ISA_HAS_MACC && !GENERATE_MULT3_SI"
957   [(set (match_dup 0)
958         (const_int 0))
959    (parallel
960        [(set (match_dup 0)
961              (plus:SI (mult:SI (match_dup 1)
962                                (match_dup 2))
963                       (match_dup 0)))
964         (set (match_dup 4)
965              (plus:SI (mult:SI (match_dup 1)
966                                (match_dup 2))
967                       (match_dup 0)))
968         (clobber (match_dup 3))])])
970 ;; Multiply-accumulate patterns
972 ;; For processors that can copy the output to a general register:
974 ;; The all-d alternative is needed because the combiner will find this
975 ;; pattern and then register alloc/reload will move registers around to
976 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
978 ;; The last alternative should be made slightly less desirable, but adding
979 ;; "?" to the constraint is too strong, and causes values to be loaded into
980 ;; LO even when that's more costly.  For now, using "*d" mostly does the
981 ;; trick.
982 (define_insn "*mul_acc_si"
983   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
984         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
985                           (match_operand:SI 2 "register_operand" "d,d,d"))
986                  (match_operand:SI 3 "register_operand" "0,l,*d")))
987    (clobber (match_scratch:SI 4 "=h,h,h"))
988    (clobber (match_scratch:SI 5 "=X,3,l"))
989    (clobber (match_scratch:SI 6 "=X,X,&d"))]
990   "(TARGET_MIPS3900
991    || ISA_HAS_MADD_MSUB)
992    && !TARGET_MIPS16"
994   static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
995   if (which_alternative == 2)
996     return "#";
997   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
998     return "#";
999   return madd[which_alternative];
1001   [(set_attr "type"     "imadd,imadd,multi")
1002    (set_attr "mode"     "SI")
1003    (set_attr "length"   "4,4,8")])
1005 ;; Split the above insn if we failed to get LO allocated.
1006 (define_split
1007   [(set (match_operand:SI 0 "register_operand")
1008         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1009                           (match_operand:SI 2 "register_operand"))
1010                  (match_operand:SI 3 "register_operand")))
1011    (clobber (match_scratch:SI 4))
1012    (clobber (match_scratch:SI 5))
1013    (clobber (match_scratch:SI 6))]
1014   "reload_completed && !TARGET_DEBUG_D_MODE
1015    && GP_REG_P (true_regnum (operands[0]))
1016    && GP_REG_P (true_regnum (operands[3]))"
1017   [(parallel [(set (match_dup 6)
1018                    (mult:SI (match_dup 1) (match_dup 2)))
1019               (clobber (match_dup 4))
1020               (clobber (match_dup 5))])
1021    (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1022   "")
1024 ;; Splitter to copy result of MADD to a general register
1025 (define_split
1026   [(set (match_operand:SI                   0 "register_operand")
1027         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1028                           (match_operand:SI 2 "register_operand"))
1029                  (match_operand:SI          3 "register_operand")))
1030    (clobber (match_scratch:SI               4))
1031    (clobber (match_scratch:SI               5))
1032    (clobber (match_scratch:SI               6))]
1033   "reload_completed && !TARGET_DEBUG_D_MODE
1034    && GP_REG_P (true_regnum (operands[0]))
1035    && true_regnum (operands[3]) == LO_REGNUM"
1036   [(parallel [(set (match_dup 3)
1037                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1038                             (match_dup 3)))
1039               (clobber (match_dup 4))
1040               (clobber (match_dup 5))
1041               (clobber (match_dup 6))])
1042    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1043   "")
1045 (define_insn "*macc"
1046   [(set (match_operand:SI 0 "register_operand" "=l,d")
1047         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1048                           (match_operand:SI 2 "register_operand" "d,d"))
1049                  (match_operand:SI 3 "register_operand" "0,l")))
1050    (clobber (match_scratch:SI 4 "=h,h"))
1051    (clobber (match_scratch:SI 5 "=X,3"))]
1052   "ISA_HAS_MACC"
1054   if (which_alternative == 1)
1055     return "macc\t%0,%1,%2";
1056   else if (TARGET_MIPS5500)
1057     return "madd\t%1,%2";
1058   else
1059     /* The VR4130 assumes that there is a two-cycle latency between a macc
1060        that "writes" to $0 and an instruction that reads from it.  We avoid
1061        this by assigning to $1 instead.  */
1062     return "%[macc\t%@,%1,%2%]";
1064   [(set_attr "type" "imadd")
1065    (set_attr "mode" "SI")])
1067 (define_insn "*msac"
1068   [(set (match_operand:SI 0 "register_operand" "=l,d")
1069         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1070                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1071                            (match_operand:SI 3 "register_operand" "d,d"))))
1072    (clobber (match_scratch:SI 4 "=h,h"))
1073    (clobber (match_scratch:SI 5 "=X,1"))]
1074   "ISA_HAS_MSAC"
1076   if (which_alternative == 1)
1077     return "msac\t%0,%2,%3";
1078   else if (TARGET_MIPS5500)
1079     return "msub\t%2,%3";
1080   else
1081     return "msac\t$0,%2,%3";
1083   [(set_attr "type"     "imadd")
1084    (set_attr "mode"     "SI")])
1086 ;; An msac-like instruction implemented using negation and a macc.
1087 (define_insn_and_split "*msac_using_macc"
1088   [(set (match_operand:SI 0 "register_operand" "=l,d")
1089         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1090                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1091                            (match_operand:SI 3 "register_operand" "d,d"))))
1092    (clobber (match_scratch:SI 4 "=h,h"))
1093    (clobber (match_scratch:SI 5 "=X,1"))
1094    (clobber (match_scratch:SI 6 "=d,d"))]
1095   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1096   "#"
1097   "&& reload_completed"
1098   [(set (match_dup 6)
1099         (neg:SI (match_dup 3)))
1100    (parallel
1101        [(set (match_dup 0)
1102              (plus:SI (mult:SI (match_dup 2)
1103                                (match_dup 6))
1104                       (match_dup 1)))
1105         (clobber (match_dup 4))
1106         (clobber (match_dup 5))])]
1107   ""
1108   [(set_attr "type"     "imadd")
1109    (set_attr "length"   "8")])
1111 ;; Patterns generated by the define_peephole2 below.
1113 (define_insn "*macc2"
1114   [(set (match_operand:SI 0 "register_operand" "=l")
1115         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1116                           (match_operand:SI 2 "register_operand" "d"))
1117                  (match_dup 0)))
1118    (set (match_operand:SI 3 "register_operand" "=d")
1119         (plus:SI (mult:SI (match_dup 1)
1120                           (match_dup 2))
1121                  (match_dup 0)))
1122    (clobber (match_scratch:SI 4 "=h"))]
1123   "ISA_HAS_MACC && reload_completed"
1124   "macc\t%3,%1,%2"
1125   [(set_attr "type"     "imadd")
1126    (set_attr "mode"     "SI")])
1128 (define_insn "*msac2"
1129   [(set (match_operand:SI 0 "register_operand" "=l")
1130         (minus:SI (match_dup 0)
1131                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1132                            (match_operand:SI 2 "register_operand" "d"))))
1133    (set (match_operand:SI 3 "register_operand" "=d")
1134         (minus:SI (match_dup 0)
1135                   (mult:SI (match_dup 1)
1136                            (match_dup 2))))
1137    (clobber (match_scratch:SI 4 "=h"))]
1138   "ISA_HAS_MSAC && reload_completed"
1139   "msac\t%3,%1,%2"
1140   [(set_attr "type"     "imadd")
1141    (set_attr "mode"     "SI")])
1143 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1144 ;; Similarly msac.
1146 ;; Operand 0: LO
1147 ;; Operand 1: macc/msac
1148 ;; Operand 2: HI
1149 ;; Operand 3: GPR (destination)
1150 (define_peephole2
1151   [(parallel
1152        [(set (match_operand:SI 0 "register_operand")
1153              (match_operand:SI 1 "macc_msac_operand"))
1154         (clobber (match_operand:SI 2 "register_operand"))
1155         (clobber (scratch:SI))])
1156    (set (match_operand:SI 3 "register_operand")
1157         (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1158   ""
1159   [(parallel [(set (match_dup 0)
1160                    (match_dup 1))
1161               (set (match_dup 3)
1162                    (match_dup 1))
1163               (clobber (match_dup 2))])]
1164   "")
1166 ;; When we have a three-address multiplication instruction, it should
1167 ;; be faster to do a separate multiply and add, rather than moving
1168 ;; something into LO in order to use a macc instruction.
1170 ;; This peephole needs a scratch register to cater for the case when one
1171 ;; of the multiplication operands is the same as the destination.
1173 ;; Operand 0: GPR (scratch)
1174 ;; Operand 1: LO
1175 ;; Operand 2: GPR (addend)
1176 ;; Operand 3: GPR (destination)
1177 ;; Operand 4: macc/msac
1178 ;; Operand 5: HI
1179 ;; Operand 6: new multiplication
1180 ;; Operand 7: new addition/subtraction
1181 (define_peephole2
1182   [(match_scratch:SI 0 "d")
1183    (set (match_operand:SI 1 "register_operand")
1184         (match_operand:SI 2 "register_operand"))
1185    (match_dup 0)
1186    (parallel
1187        [(set (match_operand:SI 3 "register_operand")
1188              (match_operand:SI 4 "macc_msac_operand"))
1189         (clobber (match_operand:SI 5 "register_operand"))
1190         (clobber (match_dup 1))])]
1191   "GENERATE_MULT3_SI
1192    && true_regnum (operands[1]) == LO_REGNUM
1193    && peep2_reg_dead_p (2, operands[1])
1194    && GP_REG_P (true_regnum (operands[3]))"
1195   [(parallel [(set (match_dup 0)
1196                    (match_dup 6))
1197               (clobber (match_dup 5))
1198               (clobber (match_dup 1))])
1199    (set (match_dup 3)
1200         (match_dup 7))]
1202   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1203   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1204                                 operands[2], operands[0]);
1207 ;; Same as above, except LO is the initial target of the macc.
1209 ;; Operand 0: GPR (scratch)
1210 ;; Operand 1: LO
1211 ;; Operand 2: GPR (addend)
1212 ;; Operand 3: macc/msac
1213 ;; Operand 4: HI
1214 ;; Operand 5: GPR (destination)
1215 ;; Operand 6: new multiplication
1216 ;; Operand 7: new addition/subtraction
1217 (define_peephole2
1218   [(match_scratch:SI 0 "d")
1219    (set (match_operand:SI 1 "register_operand")
1220         (match_operand:SI 2 "register_operand"))
1221    (match_dup 0)
1222    (parallel
1223        [(set (match_dup 1)
1224              (match_operand:SI 3 "macc_msac_operand"))
1225         (clobber (match_operand:SI 4 "register_operand"))
1226         (clobber (scratch:SI))])
1227    (match_dup 0)
1228    (set (match_operand:SI 5 "register_operand")
1229         (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1230   "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1231   [(parallel [(set (match_dup 0)
1232                    (match_dup 6))
1233               (clobber (match_dup 4))
1234               (clobber (match_dup 1))])
1235    (set (match_dup 5)
1236         (match_dup 7))]
1238   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1239   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1240                                 operands[2], operands[0]);
1243 (define_insn "*mul_sub_si"
1244   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1245         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1246                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1247                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1248    (clobber (match_scratch:SI 4 "=h,h,h"))
1249    (clobber (match_scratch:SI 5 "=X,1,l"))
1250    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1251   "ISA_HAS_MADD_MSUB"
1252   "@
1253    msub\t%2,%3
1254    #
1255    #"
1256   [(set_attr "type"     "imadd,multi,multi")
1257    (set_attr "mode"     "SI")
1258    (set_attr "length"   "4,8,8")])
1260 ;; Split the above insn if we failed to get LO allocated.
1261 (define_split
1262   [(set (match_operand:SI 0 "register_operand")
1263         (minus:SI (match_operand:SI 1 "register_operand")
1264                   (mult:SI (match_operand:SI 2 "register_operand")
1265                            (match_operand:SI 3 "register_operand"))))
1266    (clobber (match_scratch:SI 4))
1267    (clobber (match_scratch:SI 5))
1268    (clobber (match_scratch:SI 6))]
1269   "reload_completed && !TARGET_DEBUG_D_MODE
1270    && GP_REG_P (true_regnum (operands[0]))
1271    && GP_REG_P (true_regnum (operands[1]))"
1272   [(parallel [(set (match_dup 6)
1273                    (mult:SI (match_dup 2) (match_dup 3)))
1274               (clobber (match_dup 4))
1275               (clobber (match_dup 5))])
1276    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1277   "")
1279 ;; Splitter to copy result of MSUB to a general register
1280 (define_split
1281   [(set (match_operand:SI 0 "register_operand")
1282         (minus:SI (match_operand:SI 1 "register_operand")
1283                   (mult:SI (match_operand:SI 2 "register_operand")
1284                            (match_operand:SI 3 "register_operand"))))
1285    (clobber (match_scratch:SI 4))
1286    (clobber (match_scratch:SI 5))
1287    (clobber (match_scratch:SI 6))]
1288   "reload_completed && !TARGET_DEBUG_D_MODE
1289    && GP_REG_P (true_regnum (operands[0]))
1290    && true_regnum (operands[1]) == LO_REGNUM"
1291   [(parallel [(set (match_dup 1)
1292                    (minus:SI (match_dup 1)
1293                              (mult:SI (match_dup 2) (match_dup 3))))
1294               (clobber (match_dup 4))
1295               (clobber (match_dup 5))
1296               (clobber (match_dup 6))])
1297    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1298   "")
1300 (define_insn "*muls"
1301   [(set (match_operand:SI                  0 "register_operand" "=l,d")
1302         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1303                          (match_operand:SI 2 "register_operand" "d,d"))))
1304    (clobber (match_scratch:SI              3                    "=h,h"))
1305    (clobber (match_scratch:SI              4                    "=X,l"))]
1306   "ISA_HAS_MULS"
1307   "@
1308    muls\t$0,%1,%2
1309    muls\t%0,%1,%2"
1310   [(set_attr "type"     "imul")
1311    (set_attr "mode"     "SI")])
1313 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1315 (define_expand "<u>mulsidi3"
1316   [(parallel
1317       [(set (match_operand:DI 0 "register_operand")
1318             (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1319                      (any_extend:DI (match_operand:SI 2 "register_operand"))))
1320        (clobber (scratch:DI))
1321        (clobber (scratch:DI))
1322        (clobber (scratch:DI))])]
1323   "!TARGET_64BIT || !TARGET_FIX_R4000"
1325   if (!TARGET_64BIT)
1326     {
1327       if (!TARGET_FIX_R4000)
1328         emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1329                                                    operands[2]));
1330       else
1331         emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1332                                                 operands[2]));
1333       DONE;
1334     }
1337 (define_insn "<u>mulsidi3_32bit_internal"
1338   [(set (match_operand:DI 0 "register_operand" "=x")
1339         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1340                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1341   "!TARGET_64BIT && !TARGET_FIX_R4000"
1342   "mult<u>\t%1,%2"
1343   [(set_attr "type" "imul")
1344    (set_attr "mode" "SI")])
1346 (define_insn "<u>mulsidi3_32bit_r4000"
1347   [(set (match_operand:DI 0 "register_operand" "=d")
1348         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1349                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1350    (clobber (match_scratch:DI 3 "=x"))]
1351   "!TARGET_64BIT && TARGET_FIX_R4000"
1352   "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1353   [(set_attr "type" "imul")
1354    (set_attr "mode" "SI")
1355    (set_attr "length" "12")])
1357 (define_insn_and_split "*<u>mulsidi3_64bit"
1358   [(set (match_operand:DI 0 "register_operand" "=d")
1359         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1360                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1361    (clobber (match_scratch:DI 3 "=l"))
1362    (clobber (match_scratch:DI 4 "=h"))
1363    (clobber (match_scratch:DI 5 "=d"))]
1364   "TARGET_64BIT && !TARGET_FIX_R4000"
1365   "#"
1366   "&& reload_completed"
1367   [(parallel
1368        [(set (match_dup 3)
1369              (sign_extend:DI
1370                 (mult:SI (match_dup 1)
1371                          (match_dup 2))))
1372         (set (match_dup 4)
1373              (ashiftrt:DI
1374                 (mult:DI (any_extend:DI (match_dup 1))
1375                          (any_extend:DI (match_dup 2)))
1376                 (const_int 32)))])
1378    ;; OP5 <- LO, OP0 <- HI
1379    (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1380    (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1382    ;; Zero-extend OP5.
1383    (set (match_dup 5)
1384         (ashift:DI (match_dup 5)
1385                    (const_int 32)))
1386    (set (match_dup 5)
1387         (lshiftrt:DI (match_dup 5)
1388                      (const_int 32)))
1390    ;; Shift OP0 into place.
1391    (set (match_dup 0)
1392         (ashift:DI (match_dup 0)
1393                    (const_int 32)))
1395    ;; OR the two halves together
1396    (set (match_dup 0)
1397         (ior:DI (match_dup 0)
1398                 (match_dup 5)))]
1399   ""
1400   [(set_attr "type" "imul")
1401    (set_attr "mode" "SI")
1402    (set_attr "length" "24")])
1404 (define_insn "*<u>mulsidi3_64bit_parts"
1405   [(set (match_operand:DI 0 "register_operand" "=l")
1406         (sign_extend:DI
1407            (mult:SI (match_operand:SI 2 "register_operand" "d")
1408                     (match_operand:SI 3 "register_operand" "d"))))
1409    (set (match_operand:DI 1 "register_operand" "=h")
1410         (ashiftrt:DI
1411            (mult:DI (any_extend:DI (match_dup 2))
1412                     (any_extend:DI (match_dup 3)))
1413            (const_int 32)))]
1414   "TARGET_64BIT && !TARGET_FIX_R4000"
1415   "mult<u>\t%2,%3"
1416   [(set_attr "type" "imul")
1417    (set_attr "mode" "SI")])
1419 ;; Widening multiply with negation.
1420 (define_insn "*muls<u>_di"
1421   [(set (match_operand:DI 0 "register_operand" "=x")
1422         (neg:DI
1423          (mult:DI
1424           (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1425           (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1426   "!TARGET_64BIT && ISA_HAS_MULS"
1427   "muls<u>\t$0,%1,%2"
1428   [(set_attr "type" "imul")
1429    (set_attr "mode" "SI")])
1431 (define_insn "*msac<u>_di"
1432   [(set (match_operand:DI 0 "register_operand" "=x")
1433         (minus:DI
1434            (match_operand:DI 3 "register_operand" "0")
1435            (mult:DI
1436               (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1437               (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1438   "!TARGET_64BIT && ISA_HAS_MSAC"
1440   if (TARGET_MIPS5500)
1441     return "msub<u>\t%1,%2";
1442   else
1443     return "msac<u>\t$0,%1,%2";
1445   [(set_attr "type" "imadd")
1446    (set_attr "mode" "SI")])
1448 ;; _highpart patterns
1450 (define_expand "<su>mulsi3_highpart"
1451   [(set (match_operand:SI 0 "register_operand")
1452         (truncate:SI
1453          (lshiftrt:DI
1454           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1455                    (any_extend:DI (match_operand:SI 2 "register_operand")))
1456           (const_int 32))))]
1457   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1459   if (ISA_HAS_MULHI)
1460     emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1461                                                        operands[1],
1462                                                        operands[2]));
1463   else
1464     emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1465                                                  operands[2]));
1466   DONE;
1469 (define_insn "<su>mulsi3_highpart_internal"
1470   [(set (match_operand:SI 0 "register_operand" "=h")
1471         (truncate:SI
1472          (lshiftrt:DI
1473           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1474                    (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1475           (const_int 32))))
1476    (clobber (match_scratch:SI 3 "=l"))]
1477   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1478   "mult<u>\t%1,%2"
1479   [(set_attr "type" "imul")
1480    (set_attr "mode" "SI")])
1482 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1483   [(set (match_operand:SI 0 "register_operand" "=h,d")
1484         (truncate:SI
1485          (lshiftrt:DI
1486           (mult:DI
1487            (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1488            (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1489           (const_int 32))))
1490    (clobber (match_scratch:SI 3 "=l,l"))
1491    (clobber (match_scratch:SI 4 "=X,h"))]
1492   "ISA_HAS_MULHI"
1493   "@
1494    mult<u>\t%1,%2
1495    mulhi<u>\t%0,%1,%2"
1496   [(set_attr "type" "imul")
1497    (set_attr "mode" "SI")])
1499 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1500   [(set (match_operand:SI 0 "register_operand" "=h,d")
1501         (truncate:SI
1502          (lshiftrt:DI
1503           (neg:DI
1504            (mult:DI
1505             (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1506             (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1507           (const_int 32))))
1508    (clobber (match_scratch:SI 3 "=l,l"))
1509    (clobber (match_scratch:SI 4 "=X,h"))]
1510   "ISA_HAS_MULHI"
1511   "@
1512    mulshi<u>\t%.,%1,%2
1513    mulshi<u>\t%0,%1,%2"
1514   [(set_attr "type" "imul")
1515    (set_attr "mode" "SI")])
1517 ;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
1518 ;; errata MD(0), which says that dmultu does not always produce the
1519 ;; correct result.
1520 (define_insn "<su>muldi3_highpart"
1521   [(set (match_operand:DI 0 "register_operand" "=h")
1522         (truncate:DI
1523          (lshiftrt:TI
1524           (mult:TI
1525            (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1526            (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1527           (const_int 64))))
1528    (clobber (match_scratch:DI 3 "=l"))]
1529   "TARGET_64BIT && !TARGET_FIX_R4000
1530    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1531   "dmult<u>\t%1,%2"
1532   [(set_attr "type" "imul")
1533    (set_attr "mode" "DI")])
1535 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1536 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
1538 (define_insn "madsi"
1539   [(set (match_operand:SI 0 "register_operand" "+l")
1540         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1541                           (match_operand:SI 2 "register_operand" "d"))
1542                  (match_dup 0)))
1543    (clobber (match_scratch:SI 3 "=h"))]
1544   "TARGET_MAD"
1545   "mad\t%1,%2"
1546   [(set_attr "type"     "imadd")
1547    (set_attr "mode"     "SI")])
1549 (define_insn "*<su>mul_acc_di"
1550   [(set (match_operand:DI 0 "register_operand" "=x")
1551         (plus:DI
1552          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1553                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1554          (match_operand:DI 3 "register_operand" "0")))]
1555   "(TARGET_MAD || ISA_HAS_MACC)
1556    && !TARGET_64BIT"
1558   if (TARGET_MAD)
1559     return "mad<u>\t%1,%2";
1560   else if (TARGET_MIPS5500)
1561     return "madd<u>\t%1,%2";
1562   else
1563     /* See comment in *macc.  */
1564     return "%[macc<u>\t%@,%1,%2%]";
1566   [(set_attr "type" "imadd")
1567    (set_attr "mode" "SI")])
1569 ;; Floating point multiply accumulate instructions.
1571 (define_insn ""
1572   [(set (match_operand:DF 0 "register_operand" "=f")
1573         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1574                           (match_operand:DF 2 "register_operand" "f"))
1575                  (match_operand:DF 3 "register_operand" "f")))]
1576   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1577   "madd.d\t%0,%3,%1,%2"
1578   [(set_attr "type"     "fmadd")
1579    (set_attr "mode"     "DF")])
1581 (define_insn ""
1582   [(set (match_operand:SF 0 "register_operand" "=f")
1583         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1584                           (match_operand:SF 2 "register_operand" "f"))
1585                  (match_operand:SF 3 "register_operand" "f")))]
1586   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1587   "madd.s\t%0,%3,%1,%2"
1588   [(set_attr "type"     "fmadd")
1589    (set_attr "mode"     "SF")])
1591 (define_insn ""
1592   [(set (match_operand:DF 0 "register_operand" "=f")
1593         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1594                            (match_operand:DF 2 "register_operand" "f"))
1595                   (match_operand:DF 3 "register_operand" "f")))]
1596   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1597   "msub.d\t%0,%3,%1,%2"
1598   [(set_attr "type"     "fmadd")
1599    (set_attr "mode"     "DF")])
1601 (define_insn ""
1602   [(set (match_operand:SF 0 "register_operand" "=f")
1603         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1604                            (match_operand:SF 2 "register_operand" "f"))
1605                   (match_operand:SF 3 "register_operand" "f")))]
1607   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1608   "msub.s\t%0,%3,%1,%2"
1609   [(set_attr "type"     "fmadd")
1610    (set_attr "mode"     "SF")])
1612 (define_insn ""
1613   [(set (match_operand:DF 0 "register_operand" "=f")
1614         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1615                                   (match_operand:DF 2 "register_operand" "f"))
1616                          (match_operand:DF 3 "register_operand" "f"))))]
1617   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1618    && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1619   "nmadd.d\t%0,%3,%1,%2"
1620   [(set_attr "type"     "fmadd")
1621    (set_attr "mode"     "DF")])
1623 (define_insn ""
1624   [(set (match_operand:DF 0 "register_operand" "=f")
1625         (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
1626                                    (match_operand:DF 2 "register_operand" "f"))
1627                   (match_operand:DF 3 "register_operand" "f")))]
1628   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1629    && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1630   "nmadd.d\t%0,%3,%1,%2"
1631   [(set_attr "type"     "fmadd")
1632    (set_attr "mode"     "DF")])
1634 (define_insn ""
1635   [(set (match_operand:SF 0 "register_operand" "=f")
1636         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1637                                   (match_operand:SF 2 "register_operand" "f"))
1638                          (match_operand:SF 3 "register_operand" "f"))))]
1639   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1640    && HONOR_SIGNED_ZEROS (SFmode)"
1641   "nmadd.s\t%0,%3,%1,%2"
1642   [(set_attr "type"     "fmadd")
1643    (set_attr "mode"     "SF")])
1645 (define_insn ""
1646   [(set (match_operand:SF 0 "register_operand" "=f")
1647         (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
1648                            (match_operand:SF 2 "register_operand" "f"))
1649                   (match_operand:SF 3 "register_operand" "f")))]
1650   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1651    && !HONOR_SIGNED_ZEROS (SFmode)"
1652   "nmadd.s\t%0,%3,%1,%2"
1653   [(set_attr "type"     "fmadd")
1654    (set_attr "mode"     "SF")])
1656 (define_insn ""
1657   [(set (match_operand:DF 0 "register_operand" "=f")
1658         (neg:DF (minus:DF (mult:DF (match_operand:DF 2 "register_operand" "f")
1659                                    (match_operand:DF 3 "register_operand" "f"))
1660                           (match_operand:DF 1 "register_operand" "f"))))]
1661   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1662    && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1663   "nmsub.d\t%0,%1,%2,%3"
1664   [(set_attr "type"     "fmadd")
1665    (set_attr "mode"     "DF")])
1667 (define_insn ""
1668   [(set (match_operand:DF 0 "register_operand" "=f")
1669         (minus:DF (match_operand:DF 1 "register_operand" "f")
1670                   (mult:DF (match_operand:DF 2 "register_operand" "f")
1671                            (match_operand:DF 3 "register_operand" "f"))))]
1672   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1673    && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1674   "nmsub.d\t%0,%1,%2,%3"
1675   [(set_attr "type"     "fmadd")
1676    (set_attr "mode"     "DF")])
1678 (define_insn ""
1679   [(set (match_operand:SF 0 "register_operand" "=f")
1680         (neg:SF (minus:SF (mult:SF (match_operand:SF 2 "register_operand" "f")
1681                                    (match_operand:SF 3 "register_operand" "f"))
1682                           (match_operand:SF 1 "register_operand" "f"))))]
1683   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1684    && HONOR_SIGNED_ZEROS (SFmode)"
1685   "nmsub.s\t%0,%1,%2,%3"
1686   [(set_attr "type"     "fmadd")
1687    (set_attr "mode"     "SF")])
1689 (define_insn ""
1690   [(set (match_operand:SF 0 "register_operand" "=f")
1691         (minus:SF (match_operand:SF 1 "register_operand" "f")
1692                   (mult:SF (match_operand:SF 2 "register_operand" "f")
1693                            (match_operand:SF 3 "register_operand" "f"))))]
1694   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1695    && !HONOR_SIGNED_ZEROS (SFmode)"
1696   "nmsub.s\t%0,%1,%2,%3"
1697   [(set_attr "type"     "fmadd")
1698    (set_attr "mode"     "SF")])
1701 ;;  ....................
1703 ;;      DIVISION and REMAINDER
1705 ;;  ....................
1708 (define_expand "divdf3"
1709   [(set (match_operand:DF 0 "register_operand")
1710         (div:DF (match_operand:DF 1 "reg_or_1_operand")
1711                 (match_operand:DF 2 "register_operand")))]
1712   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1714   if (const_1_operand (operands[1], DFmode))
1715     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1716       operands[1] = force_reg (DFmode, operands[1]);
1719 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
1721 ;; If an mfc1 or dmfc1 happens to access the floating point register
1722 ;; file at the same time a long latency operation (div, sqrt, recip,
1723 ;; sqrt) iterates an intermediate result back through the floating
1724 ;; point register file bypass, then instead returning the correct
1725 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1726 ;; result of the long latency operation.
1728 ;; The workaround is to insert an unconditional 'mov' from/to the
1729 ;; long latency op destination register.
1731 (define_insn "*divdf3"
1732   [(set (match_operand:DF 0 "register_operand" "=f")
1733         (div:DF (match_operand:DF 1 "register_operand" "f")
1734                 (match_operand:DF 2 "register_operand" "f")))]
1735   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1737   if (TARGET_FIX_SB1)
1738     return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
1739   else
1740     return "div.d\t%0,%1,%2";
1742   [(set_attr "type"     "fdiv")
1743    (set_attr "mode"     "DF")
1744    (set (attr "length")
1745         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1746                       (const_int 8)
1747                       (const_int 4)))])
1750 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
1752 ;; In certain cases, div.s and div.ps may have a rounding error
1753 ;; and/or wrong inexact flag.
1755 ;; Therefore, we only allow div.s if not working around SB-1 rev2
1756 ;; errata, or if working around those errata and a slight loss of
1757 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
1758 (define_expand "divsf3"
1759   [(set (match_operand:SF 0 "register_operand")
1760         (div:SF (match_operand:SF 1 "reg_or_1_operand")
1761                 (match_operand:SF 2 "register_operand")))]
1762   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
1764   if (const_1_operand (operands[1], SFmode))
1765     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1766       operands[1] = force_reg (SFmode, operands[1]);
1769 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1770 ;; "divdf3" comment for details).
1772 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
1773 ;; "divsf3" comment for details).
1774 (define_insn "*divsf3"
1775   [(set (match_operand:SF 0 "register_operand" "=f")
1776         (div:SF (match_operand:SF 1 "register_operand" "f")
1777                 (match_operand:SF 2 "register_operand" "f")))]
1778   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
1780   if (TARGET_FIX_SB1)
1781     return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
1782   else
1783     return "div.s\t%0,%1,%2";
1785   [(set_attr "type"     "fdiv")
1786    (set_attr "mode"     "SF")
1787    (set (attr "length")
1788         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1789                       (const_int 8)
1790                       (const_int 4)))])
1792 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1793 ;; "divdf3" comment for details).
1794 (define_insn ""
1795   [(set (match_operand:DF 0 "register_operand" "=f")
1796         (div:DF (match_operand:DF 1 "const_1_operand" "")
1797                 (match_operand:DF 2 "register_operand" "f")))]
1798   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1800   if (TARGET_FIX_SB1)
1801     return "recip.d\t%0,%2\;mov.d\t%0,%0";
1802   else
1803     return "recip.d\t%0,%2";
1805   [(set_attr "type"     "frdiv")
1806    (set_attr "mode"     "DF")
1807    (set (attr "length")
1808         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1809                       (const_int 8)
1810                       (const_int 4)))])
1812 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1813 ;; "divdf3" comment for details).
1814 (define_insn ""
1815   [(set (match_operand:SF 0 "register_operand" "=f")
1816         (div:SF (match_operand:SF 1 "const_1_operand" "")
1817                 (match_operand:SF 2 "register_operand" "f")))]
1818   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1820   if (TARGET_FIX_SB1)
1821     return "recip.s\t%0,%2\;mov.s\t%0,%0";
1822   else
1823     return "recip.s\t%0,%2";
1825   [(set_attr "type"     "frdiv")
1826    (set_attr "mode"     "SF")
1827    (set (attr "length")
1828         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1829                       (const_int 8)
1830                       (const_int 4)))])
1832 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1833 ;; with negative operands.  We use special libgcc functions instead.
1834 (define_insn "divmod<mode>4"
1835   [(set (match_operand:GPR 0 "register_operand" "=l")
1836         (div:GPR (match_operand:GPR 1 "register_operand" "d")
1837                  (match_operand:GPR 2 "register_operand" "d")))
1838    (set (match_operand:GPR 3 "register_operand" "=h")
1839         (mod:GPR (match_dup 1)
1840                  (match_dup 2)))]
1841   "!TARGET_FIX_VR4120"
1842   { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1843   [(set_attr "type" "idiv")
1844    (set_attr "mode" "<MODE>")])
1846 (define_insn "udivmod<mode>4"
1847   [(set (match_operand:GPR 0 "register_operand" "=l")
1848         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1849                   (match_operand:GPR 2 "register_operand" "d")))
1850    (set (match_operand:GPR 3 "register_operand" "=h")
1851         (umod:GPR (match_dup 1)
1852                   (match_dup 2)))]
1853   ""
1854   { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1855   [(set_attr "type" "idiv")
1856    (set_attr "mode" "<MODE>")])
1859 ;;  ....................
1861 ;;      SQUARE ROOT
1863 ;;  ....................
1865 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1866 ;; "divdf3" comment for details).
1867 (define_insn "sqrtdf2"
1868   [(set (match_operand:DF 0 "register_operand" "=f")
1869         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
1870   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
1872   if (TARGET_FIX_SB1)
1873     return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
1874   else
1875     return "sqrt.d\t%0,%1";
1877   [(set_attr "type"     "fsqrt")
1878    (set_attr "mode"     "DF")
1879    (set (attr "length")
1880         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1881                       (const_int 8)
1882                       (const_int 4)))])
1884 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1885 ;; "divdf3" comment for details).
1886 (define_insn "sqrtsf2"
1887   [(set (match_operand:SF 0 "register_operand" "=f")
1888         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
1889   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
1891   if (TARGET_FIX_SB1)
1892     return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
1893   else
1894     return "sqrt.s\t%0,%1";
1896   [(set_attr "type"     "fsqrt")
1897    (set_attr "mode"     "SF")
1898    (set (attr "length")
1899         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1900                       (const_int 8)
1901                       (const_int 4)))])
1903 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1904 ;; "divdf3" comment for details).
1905 (define_insn ""
1906   [(set (match_operand:DF 0 "register_operand" "=f")
1907         (div:DF (match_operand:DF 1 "const_1_operand" "")
1908                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
1909   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1911   if (TARGET_FIX_SB1)
1912     return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
1913   else
1914     return "rsqrt.d\t%0,%2";
1916   [(set_attr "type"     "frsqrt")
1917    (set_attr "mode"     "DF")
1918    (set (attr "length")
1919         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1920                       (const_int 8)
1921                       (const_int 4)))])
1923 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1924 ;; "divdf3" comment for details).
1925 (define_insn ""
1926   [(set (match_operand:SF 0 "register_operand" "=f")
1927         (div:SF (match_operand:SF 1 "const_1_operand" "")
1928                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
1929   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1931   if (TARGET_FIX_SB1)
1932     return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
1933   else
1934     return "rsqrt.s\t%0,%2";
1936   [(set_attr "type"     "frsqrt")
1937    (set_attr "mode"     "SF")
1938    (set (attr "length")
1939         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1940                       (const_int 8)
1941                       (const_int 4)))])
1943 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1944 ;; "divdf3" comment for details).
1945 (define_insn ""
1946   [(set (match_operand:DF 0 "register_operand" "=f")
1947         (sqrt:DF (div:DF (match_operand:DF 1 "const_1_operand" "")
1948                          (match_operand:DF 2 "register_operand" "f"))))]
1949   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1951   if (TARGET_FIX_SB1)
1952     return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
1953   else
1954     return "rsqrt.d\t%0,%2";
1956   [(set_attr "type"     "frsqrt")
1957    (set_attr "mode"     "DF")
1958    (set (attr "length")
1959         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1960                       (const_int 8)
1961                       (const_int 4)))])
1963 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1964 ;; "divdf3" comment for details).
1965 (define_insn ""
1966   [(set (match_operand:SF 0 "register_operand" "=f")
1967         (sqrt:SF (div:SF (match_operand:SF 1 "const_1_operand" "")
1968                          (match_operand:SF 2 "register_operand" "f"))))]
1969   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1971   if (TARGET_FIX_SB1)
1972     return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
1973   else
1974     return "rsqrt.s\t%0,%2";
1976   [(set_attr "type"     "frsqrt")
1977    (set_attr "mode"     "SF")
1978    (set (attr "length")
1979         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1980                       (const_int 8)
1981                       (const_int 4)))])
1984 ;;  ....................
1986 ;;      ABSOLUTE VALUE
1988 ;;  ....................
1990 ;; Do not use the integer abs macro instruction, since that signals an
1991 ;; exception on -2147483648 (sigh).
1993 (define_insn "abs<mode>2"
1994   [(set (match_operand:GPR 0 "register_operand" "=d")
1995         (abs:GPR (match_operand:GPR 1 "register_operand" "d")))]
1996   "!TARGET_MIPS16"
1998   if (REGNO (operands[0]) == REGNO (operands[1]) && GENERATE_BRANCHLIKELY)
1999     return "%(bltzl\t%1,1f\;<d>subu\t%0,%.,%0\n%~1:%)";
2000   else
2001     return "%(bgez\t%1,1f\;move\t%0,%1\;<d>subu\t%0,%.,%0\n%~1:%)";
2003   [(set_attr "type" "multi")
2004    (set_attr "mode" "<MODE>")
2005    (set_attr "length" "12")])
2007 (define_insn "absdf2"
2008   [(set (match_operand:DF 0 "register_operand" "=f")
2009         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2010   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2011   "abs.d\t%0,%1"
2012   [(set_attr "type"     "fabs")
2013    (set_attr "mode"     "DF")])
2015 (define_insn "abssf2"
2016   [(set (match_operand:SF 0 "register_operand" "=f")
2017         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2018   "TARGET_HARD_FLOAT"
2019   "abs.s\t%0,%1"
2020   [(set_attr "type"     "fabs")
2021    (set_attr "mode"     "SF")])
2024 ;;  ....................
2026 ;;      FIND FIRST BIT INSTRUCTION
2028 ;;  ....................
2031 (define_insn "ffs<mode>2"
2032   [(set (match_operand:GPR 0 "register_operand" "=&d")
2033         (ffs:GPR (match_operand:GPR 1 "register_operand" "d")))
2034    (clobber (match_scratch:GPR 2 "=&d"))
2035    (clobber (match_scratch:GPR 3 "=&d"))]
2036   "!TARGET_MIPS16"
2038   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2039     return "%(\
2040 move\t%0,%.\;\
2041 beq\t%1,%.,2f\n\
2042 %~1:\tand\t%2,%1,0x0001\;\
2043 <d>addu\t%0,%0,1\;\
2044 beq\t%2,%.,1b\;\
2045 <d>srl\t%1,%1,1\n\
2046 %~2:%)";
2048   return "%(\
2049 move\t%0,%.\;\
2050 move\t%3,%1\;\
2051 beq\t%3,%.,2f\n\
2052 %~1:\tand\t%2,%3,0x0001\;\
2053 <d>addu\t%0,%0,1\;\
2054 beq\t%2,%.,1b\;\
2055 <d>srl\t%3,%3,1\n\
2056 %~2:%)";
2058   [(set_attr "type" "multi")
2059    (set_attr "mode" "<MODE>")
2060    (set_attr "length" "28")])
2063 ;;  ...................
2065 ;;  Count leading zeroes.
2067 ;;  ...................
2070 (define_insn "clz<mode>2"
2071   [(set (match_operand:GPR 0 "register_operand" "=d")
2072         (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2073   "ISA_HAS_CLZ_CLO"
2074   "<d>clz\t%0,%1"
2075   [(set_attr "type" "clz")
2076    (set_attr "mode" "<MODE>")])
2079 ;;  ....................
2081 ;;      NEGATION and ONE'S COMPLEMENT
2083 ;;  ....................
2085 (define_insn "negsi2"
2086   [(set (match_operand:SI 0 "register_operand" "=d")
2087         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2088   ""
2090   if (TARGET_MIPS16)
2091     return "neg\t%0,%1";
2092   else
2093     return "subu\t%0,%.,%1";
2095   [(set_attr "type"     "arith")
2096    (set_attr "mode"     "SI")])
2098 (define_insn "negdi2"
2099   [(set (match_operand:DI 0 "register_operand" "=d")
2100         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2101   "TARGET_64BIT && !TARGET_MIPS16"
2102   "dsubu\t%0,%.,%1"
2103   [(set_attr "type"     "arith")
2104    (set_attr "mode"     "DI")])
2106 (define_insn "negdf2"
2107   [(set (match_operand:DF 0 "register_operand" "=f")
2108         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2109   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2110   "neg.d\t%0,%1"
2111   [(set_attr "type"     "fneg")
2112    (set_attr "mode"     "DF")])
2114 (define_insn "negsf2"
2115   [(set (match_operand:SF 0 "register_operand" "=f")
2116         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2117   "TARGET_HARD_FLOAT"
2118   "neg.s\t%0,%1"
2119   [(set_attr "type"     "fneg")
2120    (set_attr "mode"     "SF")])
2122 (define_insn "one_cmpl<mode>2"
2123   [(set (match_operand:GPR 0 "register_operand" "=d")
2124         (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2125   ""
2127   if (TARGET_MIPS16)
2128     return "not\t%0,%1";
2129   else
2130     return "nor\t%0,%.,%1";
2132   [(set_attr "type" "arith")
2133    (set_attr "mode" "<MODE>")])
2136 ;;  ....................
2138 ;;      LOGICAL
2140 ;;  ....................
2143 ;; Many of these instructions use trivial define_expands, because we
2144 ;; want to use a different set of constraints when TARGET_MIPS16.
2146 (define_expand "and<mode>3"
2147   [(set (match_operand:GPR 0 "register_operand")
2148         (and:GPR (match_operand:GPR 1 "register_operand")
2149                  (match_operand:GPR 2 "uns_arith_operand")))]
2150   ""
2152   if (TARGET_MIPS16)
2153     operands[2] = force_reg (<MODE>mode, operands[2]);
2156 (define_insn "*and<mode>3"
2157   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2158         (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2159                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2160   "!TARGET_MIPS16"
2161   "@
2162    and\t%0,%1,%2
2163    andi\t%0,%1,%x2"
2164   [(set_attr "type" "arith")
2165    (set_attr "mode" "<MODE>")])
2167 (define_insn "*and<mode>3_mips16"
2168   [(set (match_operand:GPR 0 "register_operand" "=d")
2169         (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2170                  (match_operand:GPR 2 "register_operand" "d")))]
2171   "TARGET_MIPS16"
2172   "and\t%0,%2"
2173   [(set_attr "type" "arith")
2174    (set_attr "mode" "<MODE>")])
2176 (define_expand "ior<mode>3"
2177   [(set (match_operand:GPR 0 "register_operand")
2178         (ior:GPR (match_operand:GPR 1 "register_operand")
2179                  (match_operand:GPR 2 "uns_arith_operand")))]
2180   ""
2182   if (TARGET_MIPS16)
2183     operands[2] = force_reg (<MODE>mode, operands[2]);
2186 (define_insn "*ior<mode>3"
2187   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2188         (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2189                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2190   "!TARGET_MIPS16"
2191   "@
2192    or\t%0,%1,%2
2193    ori\t%0,%1,%x2"
2194   [(set_attr "type" "arith")
2195    (set_attr "mode" "<MODE>")])
2197 (define_insn "*ior<mode>3_mips16"
2198   [(set (match_operand:GPR 0 "register_operand" "=d")
2199         (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2200                  (match_operand:GPR 2 "register_operand" "d")))]
2201   "TARGET_MIPS16"
2202   "or\t%0,%2"
2203   [(set_attr "type" "arith")
2204    (set_attr "mode" "<MODE>")])
2206 (define_expand "xor<mode>3"
2207   [(set (match_operand:GPR 0 "register_operand")
2208         (xor:GPR (match_operand:GPR 1 "register_operand")
2209                  (match_operand:GPR 2 "uns_arith_operand")))]
2210   ""
2211   "")
2213 (define_insn ""
2214   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2215         (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2216                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2217   "!TARGET_MIPS16"
2218   "@
2219    xor\t%0,%1,%2
2220    xori\t%0,%1,%x2"
2221   [(set_attr "type" "arith")
2222    (set_attr "mode" "<MODE>")])
2224 (define_insn ""
2225   [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2226         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2227                  (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2228   "TARGET_MIPS16"
2229   "@
2230    xor\t%0,%2
2231    cmpi\t%1,%2
2232    cmp\t%1,%2"
2233   [(set_attr "type" "arith")
2234    (set_attr "mode" "<MODE>")
2235    (set_attr_alternative "length"
2236                 [(const_int 4)
2237                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2238                                (const_int 4)
2239                                (const_int 8))
2240                  (const_int 4)])])
2242 (define_insn "*nor<mode>3"
2243   [(set (match_operand:GPR 0 "register_operand" "=d")
2244         (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2245                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2246   "!TARGET_MIPS16"
2247   "nor\t%0,%1,%2"
2248   [(set_attr "type" "arith")
2249    (set_attr "mode" "<MODE>")])
2252 ;;  ....................
2254 ;;      TRUNCATION
2256 ;;  ....................
2260 (define_insn "truncdfsf2"
2261   [(set (match_operand:SF 0 "register_operand" "=f")
2262         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2263   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2264   "cvt.s.d\t%0,%1"
2265   [(set_attr "type"     "fcvt")
2266    (set_attr "mode"     "SF")])
2268 ;; Integer truncation patterns.  Truncating SImode values to smaller
2269 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2270 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2271 ;; need to make sure that the lower 32 bits are properly sign-extended
2272 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2273 ;; smaller than SImode is equivalent to two separate truncations:
2275 ;;                        A       B
2276 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2277 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2279 ;; Step A needs a real instruction but step B does not.
2281 (define_insn "truncdisi2"
2282   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2283         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2284   "TARGET_64BIT"
2285   "@
2286     sll\t%0,%1,0
2287     sw\t%1,%0"
2288   [(set_attr "type" "shift,store")
2289    (set_attr "mode" "SI")
2290    (set_attr "extended_mips16" "yes,*")])
2292 (define_insn "truncdihi2"
2293   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2294         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2295   "TARGET_64BIT"
2296   "@
2297     sll\t%0,%1,0
2298     sh\t%1,%0"
2299   [(set_attr "type" "shift,store")
2300    (set_attr "mode" "SI")
2301    (set_attr "extended_mips16" "yes,*")])
2303 (define_insn "truncdiqi2"
2304   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2305         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2306   "TARGET_64BIT"
2307   "@
2308     sll\t%0,%1,0
2309     sb\t%1,%0"
2310   [(set_attr "type" "shift,store")
2311    (set_attr "mode" "SI")
2312    (set_attr "extended_mips16" "yes,*")])
2314 ;; Combiner patterns to optimize shift/truncate combinations.
2316 (define_insn ""
2317   [(set (match_operand:SI 0 "register_operand" "=d")
2318         (truncate:SI
2319           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2320                        (match_operand:DI 2 "const_arith_operand" ""))))]
2321   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2322   "dsra\t%0,%1,%2"
2323   [(set_attr "type" "shift")
2324    (set_attr "mode" "SI")])
2326 (define_insn ""
2327   [(set (match_operand:SI 0 "register_operand" "=d")
2328         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2329                                   (const_int 32))))]
2330   "TARGET_64BIT && !TARGET_MIPS16"
2331   "dsra\t%0,%1,32"
2332   [(set_attr "type" "shift")
2333    (set_attr "mode" "SI")])
2336 ;; Combiner patterns for truncate/sign_extend combinations.  They use
2337 ;; the shift/truncate patterns above.
2339 (define_insn_and_split ""
2340   [(set (match_operand:SI 0 "register_operand" "=d")
2341         (sign_extend:SI
2342             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2343   "TARGET_64BIT && !TARGET_MIPS16"
2344   "#"
2345   "&& reload_completed"
2346   [(set (match_dup 2)
2347         (ashift:DI (match_dup 1)
2348                    (const_int 48)))
2349    (set (match_dup 0)
2350         (truncate:SI (ashiftrt:DI (match_dup 2)
2351                                   (const_int 48))))]
2352   { operands[2] = gen_lowpart (DImode, operands[0]); })
2354 (define_insn_and_split ""
2355   [(set (match_operand:SI 0 "register_operand" "=d")
2356         (sign_extend:SI
2357             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2358   "TARGET_64BIT && !TARGET_MIPS16"
2359   "#"
2360   "&& reload_completed"
2361   [(set (match_dup 2)
2362         (ashift:DI (match_dup 1)
2363                    (const_int 56)))
2364    (set (match_dup 0)
2365         (truncate:SI (ashiftrt:DI (match_dup 2)
2366                                   (const_int 56))))]
2367   { operands[2] = gen_lowpart (DImode, operands[0]); })
2370 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2372 (define_insn ""
2373   [(set (match_operand:SI 0 "register_operand" "=d")
2374         (zero_extend:SI (truncate:HI
2375                          (match_operand:DI 1 "register_operand" "d"))))]
2376   "TARGET_64BIT && !TARGET_MIPS16"
2377   "andi\t%0,%1,0xffff"
2378   [(set_attr "type"     "arith")
2379    (set_attr "mode"     "SI")])
2381 (define_insn ""
2382   [(set (match_operand:SI 0 "register_operand" "=d")
2383         (zero_extend:SI (truncate:QI
2384                          (match_operand:DI 1 "register_operand" "d"))))]
2385   "TARGET_64BIT && !TARGET_MIPS16"
2386   "andi\t%0,%1,0xff"
2387   [(set_attr "type"     "arith")
2388    (set_attr "mode"     "SI")])
2390 (define_insn ""
2391   [(set (match_operand:HI 0 "register_operand" "=d")
2392         (zero_extend:HI (truncate:QI
2393                          (match_operand:DI 1 "register_operand" "d"))))]
2394   "TARGET_64BIT && !TARGET_MIPS16"
2395   "andi\t%0,%1,0xff"
2396   [(set_attr "type"     "arith")
2397    (set_attr "mode"     "HI")])
2400 ;;  ....................
2402 ;;      ZERO EXTENSION
2404 ;;  ....................
2406 ;; Extension insns.
2407 ;; Those for integer source operand are ordered widest source type first.
2409 (define_insn_and_split "zero_extendsidi2"
2410   [(set (match_operand:DI 0 "register_operand" "=d")
2411         (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2412   "TARGET_64BIT"
2413   "#"
2414   "&& reload_completed"
2415   [(set (match_dup 0)
2416         (ashift:DI (match_dup 1) (const_int 32)))
2417    (set (match_dup 0)
2418         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2419   "operands[1] = gen_lowpart (DImode, operands[1]);"
2420   [(set_attr "type" "multi")
2421    (set_attr "mode" "DI")
2422    (set_attr "length" "8")])
2424 (define_insn "*zero_extendsidi2_mem"
2425   [(set (match_operand:DI 0 "register_operand" "=d")
2426         (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2427   "TARGET_64BIT"
2428   "lwu\t%0,%1"
2429   [(set_attr "type"     "load")
2430    (set_attr "mode"     "DI")])
2432 (define_expand "zero_extendhisi2"
2433   [(set (match_operand:SI 0 "register_operand")
2434         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2435   ""
2437   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2438     {
2439       rtx op = gen_lowpart (SImode, operands[1]);
2440       rtx temp = force_reg (SImode, GEN_INT (0xffff));
2442       emit_insn (gen_andsi3 (operands[0], op, temp));
2443       DONE;
2444     }
2447 (define_insn ""
2448   [(set (match_operand:SI 0 "register_operand" "=d,d")
2449         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2450   "!TARGET_MIPS16"
2451   "@
2452    andi\t%0,%1,0xffff
2453    lhu\t%0,%1"
2454   [(set_attr "type"     "arith,load")
2455    (set_attr "mode"     "SI")
2456    (set_attr "length"   "4,*")])
2458 (define_insn ""
2459   [(set (match_operand:SI 0 "register_operand" "=d")
2460         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2461   "TARGET_MIPS16"
2462   "lhu\t%0,%1"
2463   [(set_attr "type"     "load")
2464    (set_attr "mode"     "SI")])
2466 (define_expand "zero_extendhidi2"
2467   [(set (match_operand:DI 0 "register_operand")
2468         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2469   "TARGET_64BIT"
2471   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2472     {
2473       rtx op = gen_lowpart (DImode, operands[1]);
2474       rtx temp = force_reg (DImode, GEN_INT (0xffff));
2476       emit_insn (gen_anddi3 (operands[0], op, temp));
2477       DONE;
2478     }
2481 (define_insn ""
2482   [(set (match_operand:DI 0 "register_operand" "=d,d")
2483         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2484   "TARGET_64BIT && !TARGET_MIPS16"
2485   "@
2486    andi\t%0,%1,0xffff
2487    lhu\t%0,%1"
2488   [(set_attr "type"     "arith,load")
2489    (set_attr "mode"     "DI")
2490    (set_attr "length"   "4,*")])
2492 (define_insn ""
2493   [(set (match_operand:DI 0 "register_operand" "=d")
2494         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2495   "TARGET_64BIT && TARGET_MIPS16"
2496   "lhu\t%0,%1"
2497   [(set_attr "type"     "load")
2498    (set_attr "mode"     "DI")])
2500 (define_expand "zero_extendqihi2"
2501   [(set (match_operand:HI 0 "register_operand")
2502         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2503   ""
2505   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2506     {
2507       rtx op0 = gen_lowpart (SImode, operands[0]);
2508       rtx op1 = gen_lowpart (SImode, operands[1]);
2509       rtx temp = force_reg (SImode, GEN_INT (0xff));
2511       emit_insn (gen_andsi3 (op0, op1, temp));
2512       DONE;
2513     }
2516 (define_insn ""
2517   [(set (match_operand:HI 0 "register_operand" "=d,d")
2518         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2519   "!TARGET_MIPS16"
2520   "@
2521    andi\t%0,%1,0x00ff
2522    lbu\t%0,%1"
2523   [(set_attr "type"     "arith,load")
2524    (set_attr "mode"     "HI")
2525    (set_attr "length"   "4,*")])
2527 (define_insn ""
2528   [(set (match_operand:HI 0 "register_operand" "=d")
2529         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2530   "TARGET_MIPS16"
2531   "lbu\t%0,%1"
2532   [(set_attr "type"     "load")
2533    (set_attr "mode"     "HI")])
2535 (define_expand "zero_extendqisi2"
2536   [(set (match_operand:SI 0 "register_operand")
2537         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2538   ""
2540   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2541     {
2542       rtx op = gen_lowpart (SImode, operands[1]);
2543       rtx temp = force_reg (SImode, GEN_INT (0xff));
2545       emit_insn (gen_andsi3 (operands[0], op, temp));
2546       DONE;
2547     }
2550 (define_insn ""
2551   [(set (match_operand:SI 0 "register_operand" "=d,d")
2552         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2553   "!TARGET_MIPS16"
2554   "@
2555    andi\t%0,%1,0x00ff
2556    lbu\t%0,%1"
2557   [(set_attr "type"     "arith,load")
2558    (set_attr "mode"     "SI")
2559    (set_attr "length"   "4,*")])
2561 (define_insn ""
2562   [(set (match_operand:SI 0 "register_operand" "=d")
2563         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2564   "TARGET_MIPS16"
2565   "lbu\t%0,%1"
2566   [(set_attr "type"     "load")
2567    (set_attr "mode"     "SI")])
2569 (define_expand "zero_extendqidi2"
2570   [(set (match_operand:DI 0 "register_operand")
2571         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2572   "TARGET_64BIT"
2574   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2575     {
2576       rtx op = gen_lowpart (DImode, operands[1]);
2577       rtx temp = force_reg (DImode, GEN_INT (0xff));
2579       emit_insn (gen_anddi3 (operands[0], op, temp));
2580       DONE;
2581     }
2584 (define_insn ""
2585   [(set (match_operand:DI 0 "register_operand" "=d,d")
2586         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2587   "TARGET_64BIT && !TARGET_MIPS16"
2588   "@
2589    andi\t%0,%1,0x00ff
2590    lbu\t%0,%1"
2591   [(set_attr "type"     "arith,load")
2592    (set_attr "mode"     "DI")
2593    (set_attr "length"   "4,*")])
2595 (define_insn ""
2596   [(set (match_operand:DI 0 "register_operand" "=d")
2597         (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2598   "TARGET_64BIT && TARGET_MIPS16"
2599   "lbu\t%0,%1"
2600   [(set_attr "type"     "load")
2601    (set_attr "mode"     "DI")])
2604 ;;  ....................
2606 ;;      SIGN EXTENSION
2608 ;;  ....................
2610 ;; Extension insns.
2611 ;; Those for integer source operand are ordered widest source type first.
2613 ;; When TARGET_64BIT, all SImode integer registers should already be in
2614 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
2615 ;; therefore get rid of register->register instructions if we constrain
2616 ;; the source to be in the same register as the destination.
2618 ;; The register alternative has type "arith" so that the pre-reload
2619 ;; scheduler will treat it as a move.  This reflects what happens if
2620 ;; the register alternative needs a reload.
2621 (define_insn_and_split "extendsidi2"
2622   [(set (match_operand:DI 0 "register_operand" "=d,d")
2623         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2624   "TARGET_64BIT"
2625   "@
2626    #
2627    lw\t%0,%1"
2628   "&& reload_completed && register_operand (operands[1], VOIDmode)"
2629   [(const_int 0)]
2631   emit_note (NOTE_INSN_DELETED);
2632   DONE;
2634   [(set_attr "type" "arith,load")
2635    (set_attr "mode" "DI")])
2637 ;; These patterns originally accepted general_operands, however, slightly
2638 ;; better code is generated by only accepting register_operands, and then
2639 ;; letting combine generate the lh and lb insns.
2641 ;; These expanders originally put values in registers first. We split
2642 ;; all non-mem patterns after reload.
2644 (define_expand "extendhidi2"
2645   [(set (match_operand:DI 0 "register_operand")
2646         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2647   "TARGET_64BIT"
2648   "")
2650 (define_insn "*extendhidi2"
2651   [(set (match_operand:DI 0 "register_operand" "=d")
2652         (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
2653   "TARGET_64BIT"
2654   "#")
2656 (define_split
2657   [(set (match_operand:DI 0 "register_operand")
2658         (sign_extend:DI (match_operand:HI 1 "register_operand")))]
2659   "TARGET_64BIT && reload_completed"
2660   [(set (match_dup 0)
2661         (ashift:DI (match_dup 1) (const_int 48)))
2662    (set (match_dup 0)
2663         (ashiftrt:DI (match_dup 0) (const_int 48)))]
2664   "operands[1] = gen_lowpart (DImode, operands[1]);")
2666 (define_insn "*extendhidi2_mem"
2667   [(set (match_operand:DI 0 "register_operand" "=d")
2668         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2669   "TARGET_64BIT"
2670   "lh\t%0,%1"
2671   [(set_attr "type"     "load")
2672    (set_attr "mode"     "DI")])
2674 (define_expand "extendhisi2"
2675   [(set (match_operand:SI 0 "register_operand")
2676         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2677   ""
2679   if (ISA_HAS_SEB_SEH)
2680     {
2681       emit_insn (gen_extendhisi2_hw (operands[0],
2682                                      force_reg (HImode, operands[1])));
2683       DONE;
2684     }
2687 (define_insn "*extendhisi2"
2688   [(set (match_operand:SI 0 "register_operand" "=d")
2689         (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
2690   ""
2691   "#")
2693 (define_split
2694   [(set (match_operand:SI 0 "register_operand")
2695         (sign_extend:SI (match_operand:HI 1 "register_operand")))]
2696   "reload_completed"
2697   [(set (match_dup 0)
2698         (ashift:SI (match_dup 1) (const_int 16)))
2699    (set (match_dup 0)
2700         (ashiftrt:SI (match_dup 0) (const_int 16)))]
2701   "operands[1] = gen_lowpart (SImode, operands[1]);")
2703 (define_insn "extendhisi2_mem"
2704   [(set (match_operand:SI 0 "register_operand" "=d")
2705         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2706   ""
2707   "lh\t%0,%1"
2708   [(set_attr "type"     "load")
2709    (set_attr "mode"     "SI")])
2711 (define_insn "extendhisi2_hw"
2712   [(set (match_operand:SI 0 "register_operand" "=r")
2713         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2714   "ISA_HAS_SEB_SEH"
2715   "seh\t%0,%1"
2716   [(set_attr "type" "arith")
2717    (set_attr "mode" "SI")])
2719 (define_expand "extendqihi2"
2720   [(set (match_operand:HI 0 "register_operand")
2721         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2722   ""
2723   "")
2725 (define_insn "*extendqihi2"
2726   [(set (match_operand:HI 0 "register_operand" "=d")
2727         (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
2728   ""
2729   "#")
2731 (define_split
2732   [(set (match_operand:HI 0 "register_operand")
2733         (sign_extend:HI (match_operand:QI 1 "register_operand")))]
2734   "reload_completed"
2735   [(set (match_dup 0)
2736         (ashift:SI (match_dup 1) (const_int 24)))
2737    (set (match_dup 0)
2738         (ashiftrt:SI (match_dup 0) (const_int 24)))]
2739   "operands[0] = gen_lowpart (SImode, operands[0]);
2740    operands[1] = gen_lowpart (SImode, operands[1]);")
2742 (define_insn "*extendqihi2_internal_mem"
2743   [(set (match_operand:HI 0 "register_operand" "=d")
2744         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2745   ""
2746   "lb\t%0,%1"
2747   [(set_attr "type"     "load")
2748    (set_attr "mode"     "SI")])
2751 (define_expand "extendqisi2"
2752   [(set (match_operand:SI 0 "register_operand")
2753         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2754   ""
2756   if (ISA_HAS_SEB_SEH)
2757     {
2758       emit_insn (gen_extendqisi2_hw (operands[0],
2759                                      force_reg (QImode, operands[1])));
2760       DONE;
2761     }
2764 (define_insn "*extendqisi2"
2765   [(set (match_operand:SI 0 "register_operand" "=d")
2766         (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
2767   ""
2768   "#")
2770 (define_split
2771   [(set (match_operand:SI 0 "register_operand")
2772         (sign_extend:SI (match_operand:QI 1 "register_operand")))]
2773   "reload_completed"
2774   [(set (match_dup 0)
2775         (ashift:SI (match_dup 1) (const_int 24)))
2776    (set (match_dup 0)
2777         (ashiftrt:SI (match_dup 0) (const_int 24)))]
2778   "operands[1] = gen_lowpart (SImode, operands[1]);")
2780 (define_insn "*extendqisi2_mem"
2781   [(set (match_operand:SI 0 "register_operand" "=d")
2782         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2783   ""
2784   "lb\t%0,%1"
2785   [(set_attr "type"     "load")
2786    (set_attr "mode"     "SI")])
2788 (define_insn "extendqisi2_hw"
2789   [(set (match_operand:SI 0 "register_operand" "=r")
2790         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2791   "ISA_HAS_SEB_SEH"
2792   "seb\t%0,%1"
2793   [(set_attr "type" "arith")
2794    (set_attr "mode" "SI")])
2796 (define_expand "extendqidi2"
2797   [(set (match_operand:DI 0 "register_operand")
2798         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2799   "TARGET_64BIT"
2800   "")
2802 (define_insn "*extendqidi2"
2803   [(set (match_operand:DI 0 "register_operand" "=d")
2804         (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
2805   "TARGET_64BIT"
2806   "#")
2808 (define_split
2809   [(set (match_operand:DI 0 "register_operand")
2810         (sign_extend:DI (match_operand:QI 1 "register_operand")))]
2811   "TARGET_64BIT && reload_completed"
2812   [(set (match_dup 0)
2813         (ashift:DI (match_dup 1) (const_int 56)))
2814    (set (match_dup 0)
2815         (ashiftrt:DI (match_dup 0) (const_int 56)))]
2816   "operands[1] = gen_lowpart (DImode, operands[1]);")
2818 (define_insn "*extendqidi2_mem"
2819   [(set (match_operand:DI 0 "register_operand" "=d")
2820         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2821   "TARGET_64BIT"
2822   "lb\t%0,%1"
2823   [(set_attr "type"     "load")
2824    (set_attr "mode"     "DI")])
2826 (define_insn "extendsfdf2"
2827   [(set (match_operand:DF 0 "register_operand" "=f")
2828         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2829   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2830   "cvt.d.s\t%0,%1"
2831   [(set_attr "type"     "fcvt")
2832    (set_attr "mode"     "DF")])
2835 ;;  ....................
2837 ;;      CONVERSIONS
2839 ;;  ....................
2841 (define_expand "fix_truncdfsi2"
2842   [(set (match_operand:SI 0 "register_operand")
2843         (fix:SI (match_operand:DF 1 "register_operand")))]
2844   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2846   if (!ISA_HAS_TRUNC_W)
2847     {
2848       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2849       DONE;
2850     }
2853 (define_insn "fix_truncdfsi2_insn"
2854   [(set (match_operand:SI 0 "register_operand" "=f")
2855         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2856   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2857   "trunc.w.d %0,%1"
2858   [(set_attr "type"     "fcvt")
2859    (set_attr "mode"     "DF")
2860    (set_attr "length"   "4")])
2862 (define_insn "fix_truncdfsi2_macro"
2863   [(set (match_operand:SI 0 "register_operand" "=f")
2864         (fix:SI (match_operand:DF 1 "register_operand" "f")))
2865    (clobber (match_scratch:DF 2 "=d"))]
2866   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2868   if (set_nomacro)
2869     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2870   else
2871     return "trunc.w.d %0,%1,%2";
2873   [(set_attr "type"     "fcvt")
2874    (set_attr "mode"     "DF")
2875    (set_attr "length"   "36")])
2877 (define_expand "fix_truncsfsi2"
2878   [(set (match_operand:SI 0 "register_operand")
2879         (fix:SI (match_operand:SF 1 "register_operand")))]
2880   "TARGET_HARD_FLOAT"
2882   if (!ISA_HAS_TRUNC_W)
2883     {
2884       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2885       DONE;
2886     }
2889 (define_insn "fix_truncsfsi2_insn"
2890   [(set (match_operand:SI 0 "register_operand" "=f")
2891         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2892   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2893   "trunc.w.s %0,%1"
2894   [(set_attr "type"     "fcvt")
2895    (set_attr "mode"     "DF")
2896    (set_attr "length"   "4")])
2898 (define_insn "fix_truncsfsi2_macro"
2899   [(set (match_operand:SI 0 "register_operand" "=f")
2900         (fix:SI (match_operand:SF 1 "register_operand" "f")))
2901    (clobber (match_scratch:SF 2 "=d"))]
2902   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2904   if (set_nomacro)
2905     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2906   else
2907     return "trunc.w.s %0,%1,%2";
2909   [(set_attr "type"     "fcvt")
2910    (set_attr "mode"     "DF")
2911    (set_attr "length"   "36")])
2914 (define_insn "fix_truncdfdi2"
2915   [(set (match_operand:DI 0 "register_operand" "=f")
2916         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2917   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2918   "trunc.l.d %0,%1"
2919   [(set_attr "type"     "fcvt")
2920    (set_attr "mode"     "DF")
2921    (set_attr "length"   "4")])
2924 (define_insn "fix_truncsfdi2"
2925   [(set (match_operand:DI 0 "register_operand" "=f")
2926         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2927   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2928   "trunc.l.s %0,%1"
2929   [(set_attr "type"     "fcvt")
2930    (set_attr "mode"     "SF")
2931    (set_attr "length"   "4")])
2934 (define_insn "floatsidf2"
2935   [(set (match_operand:DF 0 "register_operand" "=f")
2936         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2937   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2938   "cvt.d.w\t%0,%1"
2939   [(set_attr "type"     "fcvt")
2940    (set_attr "mode"     "DF")
2941    (set_attr "length"   "4")])
2944 (define_insn "floatdidf2"
2945   [(set (match_operand:DF 0 "register_operand" "=f")
2946         (float:DF (match_operand:DI 1 "register_operand" "f")))]
2947   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2948   "cvt.d.l\t%0,%1"
2949   [(set_attr "type"     "fcvt")
2950    (set_attr "mode"     "DF")
2951    (set_attr "length"   "4")])
2954 (define_insn "floatsisf2"
2955   [(set (match_operand:SF 0 "register_operand" "=f")
2956         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2957   "TARGET_HARD_FLOAT"
2958   "cvt.s.w\t%0,%1"
2959   [(set_attr "type"     "fcvt")
2960    (set_attr "mode"     "SF")
2961    (set_attr "length"   "4")])
2964 (define_insn "floatdisf2"
2965   [(set (match_operand:SF 0 "register_operand" "=f")
2966         (float:SF (match_operand:DI 1 "register_operand" "f")))]
2967   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2968   "cvt.s.l\t%0,%1"
2969   [(set_attr "type"     "fcvt")
2970    (set_attr "mode"     "SF")
2971    (set_attr "length"   "4")])
2974 (define_expand "fixuns_truncdfsi2"
2975   [(set (match_operand:SI 0 "register_operand")
2976         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2977   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2979   rtx reg1 = gen_reg_rtx (DFmode);
2980   rtx reg2 = gen_reg_rtx (DFmode);
2981   rtx reg3 = gen_reg_rtx (SImode);
2982   rtx label1 = gen_label_rtx ();
2983   rtx label2 = gen_label_rtx ();
2984   REAL_VALUE_TYPE offset;
2986   real_2expN (&offset, 31);
2988   if (reg1)                     /* Turn off complaints about unreached code.  */
2989     {
2990       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2991       do_pending_stack_adjust ();
2993       emit_insn (gen_cmpdf (operands[1], reg1));
2994       emit_jump_insn (gen_bge (label1));
2996       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2997       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2998                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
2999       emit_barrier ();
3001       emit_label (label1);
3002       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3003       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3004                                      (BITMASK_HIGH, SImode)));
3006       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3007       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3009       emit_label (label2);
3011       /* Allow REG_NOTES to be set on last insn (labels don't have enough
3012          fields, and can't be used for REG_NOTES anyway).  */
3013       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3014       DONE;
3015     }
3019 (define_expand "fixuns_truncdfdi2"
3020   [(set (match_operand:DI 0 "register_operand")
3021         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3022   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3024   rtx reg1 = gen_reg_rtx (DFmode);
3025   rtx reg2 = gen_reg_rtx (DFmode);
3026   rtx reg3 = gen_reg_rtx (DImode);
3027   rtx label1 = gen_label_rtx ();
3028   rtx label2 = gen_label_rtx ();
3029   REAL_VALUE_TYPE offset;
3031   real_2expN (&offset, 63);
3033   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3034   do_pending_stack_adjust ();
3036   emit_insn (gen_cmpdf (operands[1], reg1));
3037   emit_jump_insn (gen_bge (label1));
3039   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3040   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3041                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3042   emit_barrier ();
3044   emit_label (label1);
3045   emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3046   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3047   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3049   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3050   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3052   emit_label (label2);
3054   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3055      fields, and can't be used for REG_NOTES anyway).  */
3056   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3057   DONE;
3061 (define_expand "fixuns_truncsfsi2"
3062   [(set (match_operand:SI 0 "register_operand")
3063         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3064   "TARGET_HARD_FLOAT"
3066   rtx reg1 = gen_reg_rtx (SFmode);
3067   rtx reg2 = gen_reg_rtx (SFmode);
3068   rtx reg3 = gen_reg_rtx (SImode);
3069   rtx label1 = gen_label_rtx ();
3070   rtx label2 = gen_label_rtx ();
3071   REAL_VALUE_TYPE offset;
3073   real_2expN (&offset, 31);
3075   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3076   do_pending_stack_adjust ();
3078   emit_insn (gen_cmpsf (operands[1], reg1));
3079   emit_jump_insn (gen_bge (label1));
3081   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3082   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3083                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3084   emit_barrier ();
3086   emit_label (label1);
3087   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3088   emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3089                                  (BITMASK_HIGH, SImode)));
3091   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3092   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3094   emit_label (label2);
3096   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3097      fields, and can't be used for REG_NOTES anyway).  */
3098   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3099   DONE;
3103 (define_expand "fixuns_truncsfdi2"
3104   [(set (match_operand:DI 0 "register_operand")
3105         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3106   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3108   rtx reg1 = gen_reg_rtx (SFmode);
3109   rtx reg2 = gen_reg_rtx (SFmode);
3110   rtx reg3 = gen_reg_rtx (DImode);
3111   rtx label1 = gen_label_rtx ();
3112   rtx label2 = gen_label_rtx ();
3113   REAL_VALUE_TYPE offset;
3115   real_2expN (&offset, 63);
3117   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3118   do_pending_stack_adjust ();
3120   emit_insn (gen_cmpsf (operands[1], reg1));
3121   emit_jump_insn (gen_bge (label1));
3123   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3124   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3125                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3126   emit_barrier ();
3128   emit_label (label1);
3129   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3130   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3131   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3133   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3134   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3136   emit_label (label2);
3138   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3139      fields, and can't be used for REG_NOTES anyway).  */
3140   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3141   DONE;
3145 ;;  ....................
3147 ;;      DATA MOVEMENT
3149 ;;  ....................
3151 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3153 (define_expand "extv"
3154   [(set (match_operand 0 "register_operand")
3155         (sign_extract (match_operand:QI 1 "memory_operand")
3156                       (match_operand 2 "immediate_operand")
3157                       (match_operand 3 "immediate_operand")))]
3158   "!TARGET_MIPS16"
3160   if (mips_expand_unaligned_load (operands[0], operands[1],
3161                                   INTVAL (operands[2]),
3162                                   INTVAL (operands[3])))
3163     DONE;
3164   else
3165     FAIL;
3168 (define_expand "extzv"
3169   [(set (match_operand 0 "register_operand")
3170         (zero_extract (match_operand:QI 1 "memory_operand")
3171                       (match_operand 2 "immediate_operand")
3172                       (match_operand 3 "immediate_operand")))]
3173   "!TARGET_MIPS16"
3175   if (mips_expand_unaligned_load (operands[0], operands[1],
3176                                   INTVAL (operands[2]),
3177                                   INTVAL (operands[3])))
3178     DONE;
3179   else
3180     FAIL;
3183 (define_expand "insv"
3184   [(set (zero_extract (match_operand:QI 0 "memory_operand")
3185                       (match_operand 1 "immediate_operand")
3186                       (match_operand 2 "immediate_operand"))
3187         (match_operand 3 "reg_or_0_operand"))]
3188   "!TARGET_MIPS16"
3190   if (mips_expand_unaligned_store (operands[0], operands[3],
3191                                    INTVAL (operands[1]),
3192                                    INTVAL (operands[2])))
3193     DONE;
3194   else
3195     FAIL;
3198 ;; Unaligned word moves generated by the bit field patterns.
3200 ;; As far as the rtl is concerned, both the left-part and right-part
3201 ;; instructions can access the whole field.  However, the real operand
3202 ;; refers to just the first or the last byte (depending on endianness).
3203 ;; We therefore use two memory operands to each instruction, one to
3204 ;; describe the rtl effect and one to use in the assembly output.
3206 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3207 ;; This allows us to use the standard length calculations for the "load"
3208 ;; and "store" type attributes.
3210 (define_insn "mov_<load>l"
3211   [(set (match_operand:GPR 0 "register_operand" "=d")
3212         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3213                      (match_operand:QI 2 "memory_operand" "m")]
3214                     UNSPEC_LOAD_LEFT))]
3215   "!TARGET_MIPS16"
3216   "<load>l\t%0,%2"
3217   [(set_attr "type" "load")
3218    (set_attr "mode" "<MODE>")
3219    (set_attr "hazard" "none")])
3221 (define_insn "mov_<load>r"
3222   [(set (match_operand:GPR 0 "register_operand" "=d")
3223         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3224                      (match_operand:QI 2 "memory_operand" "m")
3225                      (match_operand:GPR 3 "register_operand" "0")]
3226                     UNSPEC_LOAD_RIGHT))]
3227   "!TARGET_MIPS16"
3228   "<load>r\t%0,%2"
3229   [(set_attr "type" "load")
3230    (set_attr "mode" "<MODE>")])
3232 (define_insn "mov_<store>l"
3233   [(set (match_operand:BLK 0 "memory_operand" "=m")
3234         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3235                      (match_operand:QI 2 "memory_operand" "m")]
3236                     UNSPEC_STORE_LEFT))]
3237   "!TARGET_MIPS16"
3238   "<store>l\t%z1,%2"
3239   [(set_attr "type" "store")
3240    (set_attr "mode" "<MODE>")])
3242 (define_insn "mov_<store>r"
3243   [(set (match_operand:BLK 0 "memory_operand" "+m")
3244         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3245                      (match_operand:QI 2 "memory_operand" "m")
3246                      (match_dup 0)]
3247                     UNSPEC_STORE_RIGHT))]
3248   "!TARGET_MIPS16"
3249   "<store>r\t%z1,%2"
3250   [(set_attr "type" "store")
3251    (set_attr "mode" "<MODE>")])
3253 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3254 ;; The required value is:
3256 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3258 ;; which translates to:
3260 ;;      lui     op0,%highest(op1)
3261 ;;      daddiu  op0,op0,%higher(op1)
3262 ;;      dsll    op0,op0,16
3263 ;;      daddiu  op0,op0,%hi(op1)
3264 ;;      dsll    op0,op0,16
3265 (define_insn_and_split "*lea_high64"
3266   [(set (match_operand:DI 0 "register_operand" "=d")
3267         (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3268   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3269   "#"
3270   "&& reload_completed"
3271   [(set (match_dup 0) (high:DI (match_dup 2)))
3272    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3273    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3274    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3275    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3277   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3278   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3280   [(set_attr "length" "20")])
3282 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3283 ;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
3284 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3285 ;; used once.  We can then use the sequence:
3287 ;;      lui     op0,%highest(op1)
3288 ;;      lui     op2,%hi(op1)
3289 ;;      daddiu  op0,op0,%higher(op1)
3290 ;;      daddiu  op2,op2,%lo(op1)
3291 ;;      dsll32  op0,op0,0
3292 ;;      daddu   op0,op0,op2
3294 ;; which takes 4 cycles on most superscalar targets.
3295 (define_insn_and_split "*lea64"
3296   [(set (match_operand:DI 0 "register_operand" "=d")
3297         (match_operand:DI 1 "general_symbolic_operand" ""))
3298    (clobber (match_scratch:DI 2 "=&d"))]
3299   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3300   "#"
3301   "&& reload_completed"
3302   [(set (match_dup 0) (high:DI (match_dup 3)))
3303    (set (match_dup 2) (high:DI (match_dup 4)))
3304    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3305    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3306    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3307    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3309   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3310   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3312   [(set_attr "length" "24")])
3314 ;; Insns to fetch a global symbol from a big GOT.
3316 (define_insn_and_split "*xgot_hi<mode>"
3317   [(set (match_operand:P 0 "register_operand" "=d")
3318         (high:P (match_operand:P 1 "global_got_operand" "")))]
3319   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3320   "#"
3321   "&& reload_completed"
3322   [(set (match_dup 0) (high:P (match_dup 2)))
3323    (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3325   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3326   operands[3] = pic_offset_table_rtx;
3328   [(set_attr "got" "xgot_high")
3329    (set_attr "mode" "<MODE>")])
3331 (define_insn_and_split "*xgot_lo<mode>"
3332   [(set (match_operand:P 0 "register_operand" "=d")
3333         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3334                   (match_operand:P 2 "global_got_operand" "")))]
3335   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3336   "#"
3337   "&& reload_completed"
3338   [(set (match_dup 0)
3339         (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3340   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3341   [(set_attr "got" "load")
3342    (set_attr "mode" "<MODE>")])
3344 ;; Insns to fetch a global symbol from a normal GOT.
3346 (define_insn_and_split "*got_disp<mode>"
3347   [(set (match_operand:P 0 "register_operand" "=d")
3348         (match_operand:P 1 "global_got_operand" ""))]
3349   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3350   "#"
3351   "&& reload_completed"
3352   [(set (match_dup 0)
3353         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3355   operands[2] = pic_offset_table_rtx;
3356   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3358   [(set_attr "got" "load")
3359    (set_attr "mode" "<MODE>")])
3361 ;; Insns for loading the high part of a local symbol.
3363 (define_insn_and_split "*got_page<mode>"
3364   [(set (match_operand:P 0 "register_operand" "=d")
3365         (high:P (match_operand:P 1 "local_got_operand" "")))]
3366   "TARGET_EXPLICIT_RELOCS"
3367   "#"
3368   "&& reload_completed"
3369   [(set (match_dup 0)
3370         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3372   operands[2] = pic_offset_table_rtx;
3373   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3375   [(set_attr "got" "load")
3376    (set_attr "mode" "<MODE>")])
3378 ;; Lower-level instructions for loading an address from the GOT.
3379 ;; We could use MEMs, but an unspec gives more optimization
3380 ;; opportunities.
3382 (define_insn "*load_got<mode>"
3383   [(set (match_operand:P 0 "register_operand" "=d")
3384         (unspec:P [(match_operand:P 1 "register_operand" "d")
3385                    (match_operand:P 2 "immediate_operand" "")]
3386                   UNSPEC_LOAD_GOT))]
3387   "TARGET_ABICALLS"
3388   "<load>\t%0,%R2(%1)"
3389   [(set_attr "type" "load")
3390    (set_attr "mode" "<MODE>")
3391    (set_attr "length" "4")])
3393 ;; Instructions for adding the low 16 bits of an address to a register.
3394 ;; Operand 2 is the address: print_operand works out which relocation
3395 ;; should be applied.
3397 (define_insn "*low<mode>"
3398   [(set (match_operand:P 0 "register_operand" "=d")
3399         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3400                   (match_operand:P 2 "immediate_operand" "")))]
3401   "!TARGET_MIPS16"
3402   "<d>addiu\t%0,%1,%R2"
3403   [(set_attr "type" "arith")
3404    (set_attr "mode" "<MODE>")])
3406 (define_insn "*low<mode>_mips16"
3407   [(set (match_operand:P 0 "register_operand" "=d")
3408         (lo_sum:P (match_operand:P 1 "register_operand" "0")
3409                   (match_operand:P 2 "immediate_operand" "")))]
3410   "TARGET_MIPS16"
3411   "<d>addiu\t%0,%R2"
3412   [(set_attr "type" "arith")
3413    (set_attr "mode" "<MODE>")
3414    (set_attr "length" "8")])
3416 ;; 64-bit integer moves
3418 ;; Unlike most other insns, the move insns can't be split with
3419 ;; different predicates, because register spilling and other parts of
3420 ;; the compiler, have memoized the insn number already.
3422 (define_expand "movdi"
3423   [(set (match_operand:DI 0 "")
3424         (match_operand:DI 1 ""))]
3425   ""
3427   if (mips_legitimize_move (DImode, operands[0], operands[1]))
3428     DONE;
3431 ;; For mips16, we need a special case to handle storing $31 into
3432 ;; memory, since we don't have a constraint to match $31.  This
3433 ;; instruction can be generated by save_restore_insns.
3435 (define_insn "*mov<mode>_ra"
3436   [(set (match_operand:GPR 0 "stack_operand" "=m")
3437         (reg:GPR 31))]
3438   "TARGET_MIPS16"
3439   "<store>\t$31,%0"
3440   [(set_attr "type" "store")
3441    (set_attr "mode" "<MODE>")])
3443 (define_insn "*movdi_32bit"
3444   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
3445         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
3446   "!TARGET_64BIT && !TARGET_MIPS16
3447    && (register_operand (operands[0], DImode)
3448        || reg_or_0_operand (operands[1], DImode))"
3449   { return mips_output_move (operands[0], operands[1]); }
3450   [(set_attr "type"     "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3451    (set_attr "mode"     "DI")
3452    (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
3454 (define_insn "*movdi_32bit_mips16"
3455   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3456         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3457   "!TARGET_64BIT && TARGET_MIPS16
3458    && (register_operand (operands[0], DImode)
3459        || register_operand (operands[1], DImode))"
3460   { return mips_output_move (operands[0], operands[1]); }
3461   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store,mfhilo")
3462    (set_attr "mode"     "DI")
3463    (set_attr "length"   "8,8,8,8,12,*,*,8")])
3465 (define_insn "*movdi_64bit"
3466   [(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")
3467         (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"))]
3468   "TARGET_64BIT && !TARGET_MIPS16
3469    && (register_operand (operands[0], DImode)
3470        || reg_or_0_operand (operands[1], DImode))"
3471   { return mips_output_move (operands[0], operands[1]); }
3472   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3473    (set_attr "mode"     "DI")
3474    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3476 (define_insn "*movdi_64bit_mips16"
3477   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3478         (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3479   "TARGET_64BIT && TARGET_MIPS16
3480    && (register_operand (operands[0], DImode)
3481        || register_operand (operands[1], DImode))"
3482   { return mips_output_move (operands[0], operands[1]); }
3483   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3484    (set_attr "mode"     "DI")
3485    (set_attr_alternative "length"
3486                 [(const_int 4)
3487                  (const_int 4)
3488                  (const_int 4)
3489                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3490                                (const_int 4)
3491                                (const_int 8))
3492                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3493                                (const_int 8)
3494                                (const_int 12))
3495                  (const_string "*")
3496                  (const_string "*")
3497                  (const_string "*")])])
3500 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3501 ;; when the original load is a 4 byte instruction but the add and the
3502 ;; load are 2 2 byte instructions.
3504 (define_split
3505   [(set (match_operand:DI 0 "register_operand")
3506         (mem:DI (plus:DI (match_dup 0)
3507                          (match_operand:DI 1 "const_int_operand"))))]
3508   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3509    && !TARGET_DEBUG_D_MODE
3510    && GET_CODE (operands[0]) == REG
3511    && M16_REG_P (REGNO (operands[0]))
3512    && GET_CODE (operands[1]) == CONST_INT
3513    && ((INTVAL (operands[1]) < 0
3514         && INTVAL (operands[1]) >= -0x10)
3515        || (INTVAL (operands[1]) >= 32 * 8
3516            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3517        || (INTVAL (operands[1]) >= 0
3518            && INTVAL (operands[1]) < 32 * 8
3519            && (INTVAL (operands[1]) & 7) != 0))"
3520   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3521    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3523   HOST_WIDE_INT val = INTVAL (operands[1]);
3525   if (val < 0)
3526     operands[2] = const0_rtx;
3527   else if (val >= 32 * 8)
3528     {
3529       int off = val & 7;
3531       operands[1] = GEN_INT (0x8 + off);
3532       operands[2] = GEN_INT (val - off - 0x8);
3533     }
3534   else
3535     {
3536       int off = val & 7;
3538       operands[1] = GEN_INT (off);
3539       operands[2] = GEN_INT (val - off);
3540     }
3543 ;; 32-bit Integer moves
3545 ;; Unlike most other insns, the move insns can't be split with
3546 ;; different predicates, because register spilling and other parts of
3547 ;; the compiler, have memoized the insn number already.
3549 (define_expand "movsi"
3550   [(set (match_operand:SI 0 "")
3551         (match_operand:SI 1 ""))]
3552   ""
3554   if (mips_legitimize_move (SImode, operands[0], operands[1]))
3555     DONE;
3558 ;; The difference between these two is whether or not ints are allowed
3559 ;; in FP registers (off by default, use -mdebugh to enable).
3561 (define_insn "*movsi_internal"
3562   [(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")
3563         (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"))]
3564   "!TARGET_MIPS16
3565    && (register_operand (operands[0], SImode)
3566        || reg_or_0_operand (operands[1], SImode))"
3567   { return mips_output_move (operands[0], operands[1]); }
3568   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
3569    (set_attr "mode"     "SI")
3570    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
3572 (define_insn "*movsi_mips16"
3573   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3574         (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3575   "TARGET_MIPS16
3576    && (register_operand (operands[0], SImode)
3577        || register_operand (operands[1], SImode))"
3578   { return mips_output_move (operands[0], operands[1]); }
3579   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3580    (set_attr "mode"     "SI")
3581    (set_attr_alternative "length"
3582                 [(const_int 4)
3583                  (const_int 4)
3584                  (const_int 4)
3585                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3586                                (const_int 4)
3587                                (const_int 8))
3588                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3589                                (const_int 8)
3590                                (const_int 12))
3591                  (const_string "*")
3592                  (const_string "*")
3593                  (const_string "*")])])
3595 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3596 ;; when the original load is a 4 byte instruction but the add and the
3597 ;; load are 2 2 byte instructions.
3599 (define_split
3600   [(set (match_operand:SI 0 "register_operand")
3601         (mem:SI (plus:SI (match_dup 0)
3602                          (match_operand:SI 1 "const_int_operand"))))]
3603   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3604    && GET_CODE (operands[0]) == REG
3605    && M16_REG_P (REGNO (operands[0]))
3606    && GET_CODE (operands[1]) == CONST_INT
3607    && ((INTVAL (operands[1]) < 0
3608         && INTVAL (operands[1]) >= -0x80)
3609        || (INTVAL (operands[1]) >= 32 * 4
3610            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3611        || (INTVAL (operands[1]) >= 0
3612            && INTVAL (operands[1]) < 32 * 4
3613            && (INTVAL (operands[1]) & 3) != 0))"
3614   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3615    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3617   HOST_WIDE_INT val = INTVAL (operands[1]);
3619   if (val < 0)
3620     operands[2] = const0_rtx;
3621   else if (val >= 32 * 4)
3622     {
3623       int off = val & 3;
3625       operands[1] = GEN_INT (0x7c + off);
3626       operands[2] = GEN_INT (val - off - 0x7c);
3627     }
3628   else
3629     {
3630       int off = val & 3;
3632       operands[1] = GEN_INT (off);
3633       operands[2] = GEN_INT (val - off);
3634     }
3637 ;; On the mips16, we can split a load of certain constants into a load
3638 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
3639 ;; instructions.
3641 (define_split
3642   [(set (match_operand:SI 0 "register_operand")
3643         (match_operand:SI 1 "const_int_operand"))]
3644   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3645    && GET_CODE (operands[0]) == REG
3646    && M16_REG_P (REGNO (operands[0]))
3647    && GET_CODE (operands[1]) == CONST_INT
3648    && INTVAL (operands[1]) >= 0x100
3649    && INTVAL (operands[1]) <= 0xff + 0x7f"
3650   [(set (match_dup 0) (match_dup 1))
3651    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3653   int val = INTVAL (operands[1]);
3655   operands[1] = GEN_INT (0xff);
3656   operands[2] = GEN_INT (val - 0xff);
3659 ;; This insn handles moving CCmode values.  It's really just a
3660 ;; slightly simplified copy of movsi_internal2, with additional cases
3661 ;; to move a condition register to a general register and to move
3662 ;; between the general registers and the floating point registers.
3664 (define_insn "movcc"
3665   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3666         (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3667   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3668   { return mips_output_move (operands[0], operands[1]); }
3669   [(set_attr "type"     "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
3670    (set_attr "mode"     "SI")
3671    (set_attr "length"   "8,4,*,*,4,4,4,*,*")])
3673 ;; Reload condition code registers.  reload_incc and reload_outcc
3674 ;; both handle moves from arbitrary operands into condition code
3675 ;; registers.  reload_incc handles the more common case in which
3676 ;; a source operand is constrained to be in a condition-code
3677 ;; register, but has not been allocated to one.
3679 ;; Sometimes, such as in movcc, we have a CCmode destination whose
3680 ;; constraints do not include 'z'.  reload_outcc handles the case
3681 ;; when such an operand is allocated to a condition-code register.
3683 ;; Note that reloads from a condition code register to some
3684 ;; other location can be done using ordinary moves.  Moving
3685 ;; into a GPR takes a single movcc, moving elsewhere takes
3686 ;; two.  We can leave these cases to the generic reload code.
3687 (define_expand "reload_incc"
3688   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3689         (match_operand:CC 1 "general_operand" ""))
3690    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3691   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3693   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3694   DONE;
3697 (define_expand "reload_outcc"
3698   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3699         (match_operand:CC 1 "register_operand" ""))
3700    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3701   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3703   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3704   DONE;
3707 ;; MIPS4 supports loading and storing a floating point register from
3708 ;; the sum of two general registers.  We use two versions for each of
3709 ;; these four instructions: one where the two general registers are
3710 ;; SImode, and one where they are DImode.  This is because general
3711 ;; registers will be in SImode when they hold 32 bit values, but,
3712 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3713 ;; instructions will still work correctly.
3715 ;; ??? Perhaps it would be better to support these instructions by
3716 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
3717 ;; these instructions can only be used to load and store floating
3718 ;; point registers, that would probably cause trouble in reload.
3720 (define_insn "*lwxc1_<mode>"
3721   [(set (match_operand:SF 0 "register_operand" "=f")
3722         (mem:SF (plus:P (match_operand:P 1 "register_operand" "d")
3723                         (match_operand:P 2 "register_operand" "d"))))]
3724   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
3725   "lwxc1\t%0,%1(%2)"
3726   [(set_attr "type" "fpidxload")
3727    (set_attr "mode" "SF")])
3729 (define_insn "*ldxc1_<mode>"
3730   [(set (match_operand:DF 0 "register_operand" "=f")
3731         (mem:DF (plus:P (match_operand:P 1 "register_operand" "d")
3732                         (match_operand:P 2 "register_operand" "d"))))]
3733   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3734   "ldxc1\t%0,%1(%2)"
3735   [(set_attr "type" "fpidxload")
3736    (set_attr "mode" "DF")])
3738 (define_insn "*swxc1_<mode>"
3739   [(set (mem:SF (plus:P (match_operand:P 1 "register_operand" "d")
3740                         (match_operand:P 2 "register_operand" "d")))
3741         (match_operand:SF 0 "register_operand" "f"))]
3742   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
3743   "swxc1\t%0,%1(%2)"
3744   [(set_attr "type" "fpidxstore")
3745    (set_attr "mode" "SF")])
3747 (define_insn "*sdxc1_<mode>"
3748   [(set (mem:DF (plus:P (match_operand:P 1 "register_operand" "d")
3749                         (match_operand:P 2 "register_operand" "d")))
3750         (match_operand:DF 0 "register_operand" "f"))]
3751   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3752   "sdxc1\t%0,%1(%2)"
3753   [(set_attr "type" "fpidxstore")
3754    (set_attr "mode" "DF")])
3756 ;; 16-bit Integer moves
3758 ;; Unlike most other insns, the move insns can't be split with
3759 ;; different predicates, because register spilling and other parts of
3760 ;; the compiler, have memoized the insn number already.
3761 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3763 (define_expand "movhi"
3764   [(set (match_operand:HI 0 "")
3765         (match_operand:HI 1 ""))]
3766   ""
3768   if (mips_legitimize_move (HImode, operands[0], operands[1]))
3769     DONE;
3772 (define_insn "*movhi_internal"
3773   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3774         (match_operand:HI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3775   "!TARGET_MIPS16
3776    && (register_operand (operands[0], HImode)
3777        || reg_or_0_operand (operands[1], HImode))"
3778   "@
3779     move\t%0,%1
3780     li\t%0,%1
3781     lhu\t%0,%1
3782     sh\t%z1,%0
3783     mfc1\t%0,%1
3784     mtc1\t%1,%0
3785     mov.s\t%0,%1
3786     mt%0\t%1"
3787   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3788    (set_attr "mode"     "HI")
3789    (set_attr "length"   "4,4,*,*,4,4,4,4")])
3791 (define_insn "*movhi_mips16"
3792   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3793         (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3794   "TARGET_MIPS16
3795    && (register_operand (operands[0], HImode)
3796        || register_operand (operands[1], HImode))"
3797   "@
3798     move\t%0,%1
3799     move\t%0,%1
3800     move\t%0,%1
3801     li\t%0,%1
3802     #
3803     lhu\t%0,%1
3804     sh\t%1,%0"
3805   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
3806    (set_attr "mode"     "HI")
3807    (set_attr_alternative "length"
3808                 [(const_int 4)
3809                  (const_int 4)
3810                  (const_int 4)
3811                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3812                                (const_int 4)
3813                                (const_int 8))
3814                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3815                                (const_int 8)
3816                                (const_int 12))
3817                  (const_string "*")
3818                  (const_string "*")])])
3821 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
3822 ;; when the original load is a 4 byte instruction but the add and the
3823 ;; load are 2 2 byte instructions.
3825 (define_split
3826   [(set (match_operand:HI 0 "register_operand")
3827         (mem:HI (plus:SI (match_dup 0)
3828                          (match_operand:SI 1 "const_int_operand"))))]
3829   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3830    && GET_CODE (operands[0]) == REG
3831    && M16_REG_P (REGNO (operands[0]))
3832    && GET_CODE (operands[1]) == CONST_INT
3833    && ((INTVAL (operands[1]) < 0
3834         && INTVAL (operands[1]) >= -0x80)
3835        || (INTVAL (operands[1]) >= 32 * 2
3836            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3837        || (INTVAL (operands[1]) >= 0
3838            && INTVAL (operands[1]) < 32 * 2
3839            && (INTVAL (operands[1]) & 1) != 0))"
3840   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3841    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3843   HOST_WIDE_INT val = INTVAL (operands[1]);
3845   if (val < 0)
3846     operands[2] = const0_rtx;
3847   else if (val >= 32 * 2)
3848     {
3849       int off = val & 1;
3851       operands[1] = GEN_INT (0x7e + off);
3852       operands[2] = GEN_INT (val - off - 0x7e);
3853     }
3854   else
3855     {
3856       int off = val & 1;
3858       operands[1] = GEN_INT (off);
3859       operands[2] = GEN_INT (val - off);
3860     }
3863 ;; 8-bit Integer moves
3865 ;; Unlike most other insns, the move insns can't be split with
3866 ;; different predicates, because register spilling and other parts of
3867 ;; the compiler, have memoized the insn number already.
3868 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3870 (define_expand "movqi"
3871   [(set (match_operand:QI 0 "")
3872         (match_operand:QI 1 ""))]
3873   ""
3875   if (mips_legitimize_move (QImode, operands[0], operands[1]))
3876     DONE;
3879 (define_insn "*movqi_internal"
3880   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3881         (match_operand:QI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3882   "!TARGET_MIPS16
3883    && (register_operand (operands[0], QImode)
3884        || reg_or_0_operand (operands[1], QImode))"
3885   "@
3886     move\t%0,%1
3887     li\t%0,%1
3888     lbu\t%0,%1
3889     sb\t%z1,%0
3890     mfc1\t%0,%1
3891     mtc1\t%1,%0
3892     mov.s\t%0,%1
3893     mt%0\t%1"
3894   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3895    (set_attr "mode"     "QI")
3896    (set_attr "length"   "4,4,*,*,4,4,4,4")])
3898 (define_insn "*movqi_mips16"
3899   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3900         (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3901   "TARGET_MIPS16
3902    && (register_operand (operands[0], QImode)
3903        || register_operand (operands[1], QImode))"
3904   "@
3905     move\t%0,%1
3906     move\t%0,%1
3907     move\t%0,%1
3908     li\t%0,%1
3909     #
3910     lbu\t%0,%1
3911     sb\t%1,%0"
3912   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
3913    (set_attr "mode"     "QI")
3914    (set_attr "length"   "4,4,4,4,8,*,*")])
3916 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
3917 ;; when the original load is a 4 byte instruction but the add and the
3918 ;; load are 2 2 byte instructions.
3920 (define_split
3921   [(set (match_operand:QI 0 "register_operand")
3922         (mem:QI (plus:SI (match_dup 0)
3923                          (match_operand:SI 1 "const_int_operand"))))]
3924   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3925    && GET_CODE (operands[0]) == REG
3926    && M16_REG_P (REGNO (operands[0]))
3927    && GET_CODE (operands[1]) == CONST_INT
3928    && ((INTVAL (operands[1]) < 0
3929         && INTVAL (operands[1]) >= -0x80)
3930        || (INTVAL (operands[1]) >= 32
3931            && INTVAL (operands[1]) <= 31 + 0x7f))"
3932   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3933    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3935   HOST_WIDE_INT val = INTVAL (operands[1]);
3937   if (val < 0)
3938     operands[2] = const0_rtx;
3939   else
3940     {
3941       operands[1] = GEN_INT (0x7f);
3942       operands[2] = GEN_INT (val - 0x7f);
3943     }
3946 ;; 32-bit floating point moves
3948 (define_expand "movsf"
3949   [(set (match_operand:SF 0 "")
3950         (match_operand:SF 1 ""))]
3951   ""
3953   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3954     DONE;
3957 (define_insn "*movsf_hardfloat"
3958   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3959         (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
3960   "TARGET_HARD_FLOAT
3961    && (register_operand (operands[0], SFmode)
3962        || reg_or_0_operand (operands[1], SFmode))"
3963   { return mips_output_move (operands[0], operands[1]); }
3964   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
3965    (set_attr "mode"     "SF")
3966    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
3968 (define_insn "*movsf_softfloat"
3969   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3970         (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3971   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3972    && (register_operand (operands[0], SFmode)
3973        || reg_or_0_operand (operands[1], SFmode))"
3974   { return mips_output_move (operands[0], operands[1]); }
3975   [(set_attr "type"     "arith,load,store")
3976    (set_attr "mode"     "SF")
3977    (set_attr "length"   "4,*,*")])
3979 (define_insn "*movsf_mips16"
3980   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3981         (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3982   "TARGET_MIPS16
3983    && (register_operand (operands[0], SFmode)
3984        || register_operand (operands[1], SFmode))"
3985   { return mips_output_move (operands[0], operands[1]); }
3986   [(set_attr "type"     "arith,arith,arith,load,store")
3987    (set_attr "mode"     "SF")
3988    (set_attr "length"   "4,4,4,*,*")])
3991 ;; 64-bit floating point moves
3993 (define_expand "movdf"
3994   [(set (match_operand:DF 0 "")
3995         (match_operand:DF 1 ""))]
3996   ""
3998   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3999     DONE;
4002 (define_insn "*movdf_hardfloat_64bit"
4003   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4004         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4005   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4006    && (register_operand (operands[0], DFmode)
4007        || reg_or_0_operand (operands[1], DFmode))"
4008   { return mips_output_move (operands[0], operands[1]); }
4009   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4010    (set_attr "mode"     "DF")
4011    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
4013 (define_insn "*movdf_hardfloat_32bit"
4014   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4015         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4016   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4017    && (register_operand (operands[0], DFmode)
4018        || reg_or_0_operand (operands[1], DFmode))"
4019   { return mips_output_move (operands[0], operands[1]); }
4020   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4021    (set_attr "mode"     "DF")
4022    (set_attr "length"   "4,8,*,*,8,8,8,*,*")])
4024 (define_insn "*movdf_softfloat"
4025   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4026         (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4027   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4028    && (register_operand (operands[0], DFmode)
4029        || reg_or_0_operand (operands[1], DFmode))"
4030   { return mips_output_move (operands[0], operands[1]); }
4031   [(set_attr "type"     "arith,load,store,xfer,xfer,fmove")
4032    (set_attr "mode"     "DF")
4033    (set_attr "length"   "8,*,*,4,4,4")])
4035 (define_insn "*movdf_mips16"
4036   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4037         (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4038   "TARGET_MIPS16
4039    && (register_operand (operands[0], DFmode)
4040        || register_operand (operands[1], DFmode))"
4041   { return mips_output_move (operands[0], operands[1]); }
4042   [(set_attr "type"     "arith,arith,arith,load,store")
4043    (set_attr "mode"     "DF")
4044    (set_attr "length"   "8,8,8,*,*")])
4046 (define_split
4047   [(set (match_operand:DI 0 "nonimmediate_operand")
4048         (match_operand:DI 1 "move_operand"))]
4049   "reload_completed && !TARGET_64BIT
4050    && mips_split_64bit_move_p (operands[0], operands[1])"
4051   [(const_int 0)]
4053   mips_split_64bit_move (operands[0], operands[1]);
4054   DONE;
4057 (define_split
4058   [(set (match_operand:DF 0 "nonimmediate_operand")
4059         (match_operand:DF 1 "move_operand"))]
4060   "reload_completed && !TARGET_64BIT
4061    && mips_split_64bit_move_p (operands[0], operands[1])"
4062   [(const_int 0)]
4064   mips_split_64bit_move (operands[0], operands[1]);
4065   DONE;
4068 ;; When generating mips16 code, split moves of negative constants into
4069 ;; a positive "li" followed by a negation.
4070 (define_split
4071   [(set (match_operand 0 "register_operand")
4072         (match_operand 1 "const_int_operand"))]
4073   "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4074   [(set (match_dup 2)
4075         (match_dup 3))
4076    (set (match_dup 2)
4077         (neg:SI (match_dup 2)))]
4079   operands[2] = gen_lowpart (SImode, operands[0]);
4080   operands[3] = GEN_INT (-INTVAL (operands[1]));
4083 ;; The HI and LO registers are not truly independent.  If we move an mthi
4084 ;; instruction before an mflo instruction, it will make the result of the
4085 ;; mflo unpredictable.  The same goes for mtlo and mfhi.
4087 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4088 ;; Operand 1 is the register we want, operand 2 is the other one.
4090 (define_insn "mfhilo_<mode>"
4091   [(set (match_operand:GPR 0 "register_operand" "=d,d")
4092         (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
4093                      (match_operand:GPR 2 "register_operand" "l,h")]
4094                     UNSPEC_MFHILO))]
4095   ""
4096   "mf%1\t%0"
4097   [(set_attr "type" "mfhilo")
4098    (set_attr "mode" "<MODE>")])
4100 ;; Patterns for loading or storing part of a paired floating point
4101 ;; register.  We need them because odd-numbered floating-point registers
4102 ;; are not fully independent: see mips_split_64bit_move.
4104 ;; Load the low word of operand 0 with operand 1.
4105 (define_insn "load_df_low"
4106   [(set (match_operand:DF 0 "register_operand" "=f,f")
4107         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4108                    UNSPEC_LOAD_DF_LOW))]
4109   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4111   operands[0] = mips_subword (operands[0], 0);
4112   return mips_output_move (operands[0], operands[1]);
4114   [(set_attr "type"     "xfer,fpload")
4115    (set_attr "mode"     "SF")])
4117 ;; Load the high word of operand 0 from operand 1, preserving the value
4118 ;; in the low word.
4119 (define_insn "load_df_high"
4120   [(set (match_operand:DF 0 "register_operand" "=f,f")
4121         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4122                     (match_operand:DF 2 "register_operand" "0,0")]
4123                    UNSPEC_LOAD_DF_HIGH))]
4124   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4126   operands[0] = mips_subword (operands[0], 1);
4127   return mips_output_move (operands[0], operands[1]);
4129   [(set_attr "type"     "xfer,fpload")
4130    (set_attr "mode"     "SF")])
4132 ;; Store the high word of operand 1 in operand 0.  The corresponding
4133 ;; low-word move is done in the normal way.
4134 (define_insn "store_df_high"
4135   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4136         (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4137                    UNSPEC_STORE_DF_HIGH))]
4138   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4140   operands[1] = mips_subword (operands[1], 1);
4141   return mips_output_move (operands[0], operands[1]);
4143   [(set_attr "type"     "xfer,fpstore")
4144    (set_attr "mode"     "SF")])
4146 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
4147 ;; of _gp from the start of this function.  Operand 1 is the incoming
4148 ;; function address.
4149 (define_insn_and_split "loadgp"
4150   [(unspec_volatile [(match_operand 0 "" "")
4151                      (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4152   "TARGET_ABICALLS && TARGET_NEWABI"
4153   "#"
4154   ""
4155   [(set (match_dup 2) (match_dup 3))
4156    (set (match_dup 2) (match_dup 4))
4157    (set (match_dup 2) (match_dup 5))]
4159   operands[2] = pic_offset_table_rtx;
4160   operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4161   operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4162   operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4164   [(set_attr "length" "12")])
4166 ;; The use of gp is hidden when not using explicit relocations.
4167 ;; This blockage instruction prevents the gp load from being
4168 ;; scheduled after an implicit use of gp.  It also prevents
4169 ;; the load from being deleted as dead.
4170 (define_insn "loadgp_blockage"
4171   [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4172   ""
4173   ""
4174   [(set_attr "type"     "unknown")
4175    (set_attr "mode"     "none")
4176    (set_attr "length"   "0")])
4178 ;; Emit a .cprestore directive, which normally expands to a single store
4179 ;; instruction.  Note that we continue to use .cprestore for explicit reloc
4180 ;; code so that jals inside inline asms will work correctly.
4181 (define_insn "cprestore"
4182   [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4183                     UNSPEC_CPRESTORE)]
4184   ""
4186   if (set_nomacro && which_alternative == 1)
4187     return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4188   else
4189     return ".cprestore\t%0";
4191   [(set_attr "type" "store")
4192    (set_attr "length" "4,12")])
4194 ;; Block moves, see mips.c for more details.
4195 ;; Argument 0 is the destination
4196 ;; Argument 1 is the source
4197 ;; Argument 2 is the length
4198 ;; Argument 3 is the alignment
4200 (define_expand "movmemsi"
4201   [(parallel [(set (match_operand:BLK 0 "general_operand")
4202                    (match_operand:BLK 1 "general_operand"))
4203               (use (match_operand:SI 2 ""))
4204               (use (match_operand:SI 3 "const_int_operand"))])]
4205   "!TARGET_MIPS16 && !TARGET_MEMCPY"
4207   if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4208     DONE;
4209   else
4210     FAIL;
4214 ;;  ....................
4216 ;;      SHIFTS
4218 ;;  ....................
4220 ;; Many of these instructions use trivial define_expands, because we
4221 ;; want to use a different set of constraints when TARGET_MIPS16.
4223 (define_expand "ashlsi3"
4224   [(set (match_operand:SI 0 "register_operand")
4225         (ashift:SI (match_operand:SI 1 "register_operand")
4226                    (match_operand:SI 2 "arith_operand")))]
4227   ""
4229   /* On the mips16, a shift of more than 8 is a four byte instruction,
4230      so, for a shift between 8 and 16, it is just as fast to do two
4231      shifts of 8 or less.  If there is a lot of shifting going on, we
4232      may win in CSE.  Otherwise combine will put the shifts back
4233      together again.  This can be called by function_arg, so we must
4234      be careful not to allocate a new register if we've reached the
4235      reload pass.  */
4236   if (TARGET_MIPS16
4237       && optimize
4238       && GET_CODE (operands[2]) == CONST_INT
4239       && INTVAL (operands[2]) > 8
4240       && INTVAL (operands[2]) <= 16
4241       && ! reload_in_progress
4242       && ! reload_completed)
4243     {
4244       rtx temp = gen_reg_rtx (SImode);
4246       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4247       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4248                                         GEN_INT (INTVAL (operands[2]) - 8)));
4249       DONE;
4250     }
4253 (define_insn "ashlsi3_internal1"
4254   [(set (match_operand:SI 0 "register_operand" "=d")
4255         (ashift:SI (match_operand:SI 1 "register_operand" "d")
4256                    (match_operand:SI 2 "arith_operand" "dI")))]
4257   "!TARGET_MIPS16"
4259   if (GET_CODE (operands[2]) == CONST_INT)
4260     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4262   return "sll\t%0,%1,%2";
4264   [(set_attr "type"     "shift")
4265    (set_attr "mode"     "SI")])
4267 (define_insn "ashlsi3_internal1_extend"
4268   [(set (match_operand:DI 0 "register_operand" "=d")
4269        (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4270                                   (match_operand:SI 2 "arith_operand" "dI"))))]
4271   "TARGET_64BIT && !TARGET_MIPS16"
4273   if (GET_CODE (operands[2]) == CONST_INT)
4274     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4276   return "sll\t%0,%1,%2";
4278   [(set_attr "type"    "shift")
4279    (set_attr "mode"    "DI")])
4282 (define_insn "ashlsi3_internal2"
4283   [(set (match_operand:SI 0 "register_operand" "=d,d")
4284         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4285                    (match_operand:SI 2 "arith_operand" "d,I")))]
4286   "TARGET_MIPS16"
4288   if (which_alternative == 0)
4289     return "sll\t%0,%2";
4291   if (GET_CODE (operands[2]) == CONST_INT)
4292     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4294   return "sll\t%0,%1,%2";
4296   [(set_attr "type"     "shift")
4297    (set_attr "mode"     "SI")
4298    (set_attr_alternative "length"
4299                 [(const_int 4)
4300                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4301                                (const_int 4)
4302                                (const_int 8))])])
4304 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4306 (define_split
4307   [(set (match_operand:SI 0 "register_operand")
4308         (ashift:SI (match_operand:SI 1 "register_operand")
4309                    (match_operand:SI 2 "const_int_operand")))]
4310   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4311    && GET_CODE (operands[2]) == CONST_INT
4312    && INTVAL (operands[2]) > 8
4313    && INTVAL (operands[2]) <= 16"
4314   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
4315    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4316   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4318 (define_expand "ashldi3"
4319   [(set (match_operand:DI 0 "register_operand")
4320         (ashift:DI (match_operand:DI 1 "register_operand")
4321                    (match_operand:SI 2 "arith_operand")))]
4322   "TARGET_64BIT"
4324   /* On the mips16, a shift of more than 8 is a four byte
4325      instruction, so, for a shift between 8 and 16, it is just as
4326      fast to do two shifts of 8 or less.  If there is a lot of
4327      shifting going on, we may win in CSE.  Otherwise combine will
4328      put the shifts back together again.  This can be called by
4329      function_arg, so we must be careful not to allocate a new
4330      register if we've reached the reload pass.  */
4331   if (TARGET_MIPS16
4332       && optimize
4333       && GET_CODE (operands[2]) == CONST_INT
4334       && INTVAL (operands[2]) > 8
4335       && INTVAL (operands[2]) <= 16
4336       && ! reload_in_progress
4337       && ! reload_completed)
4338     {
4339       rtx temp = gen_reg_rtx (DImode);
4341       emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
4342       emit_insn (gen_ashldi3_internal (operands[0], temp,
4343                                        GEN_INT (INTVAL (operands[2]) - 8)));
4344       DONE;
4345     }
4349 (define_insn "ashldi3_internal"
4350   [(set (match_operand:DI 0 "register_operand" "=d")
4351         (ashift:DI (match_operand:DI 1 "register_operand" "d")
4352                    (match_operand:SI 2 "arith_operand" "dI")))]
4353   "TARGET_64BIT && !TARGET_MIPS16"
4355   if (GET_CODE (operands[2]) == CONST_INT)
4356     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4358   return "dsll\t%0,%1,%2";
4360   [(set_attr "type"     "shift")
4361    (set_attr "mode"     "DI")])
4363 (define_insn ""
4364   [(set (match_operand:DI 0 "register_operand" "=d,d")
4365         (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4366                    (match_operand:SI 2 "arith_operand" "d,I")))]
4367   "TARGET_64BIT && TARGET_MIPS16"
4369   if (which_alternative == 0)
4370     return "dsll\t%0,%2";
4372   if (GET_CODE (operands[2]) == CONST_INT)
4373     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4375   return "dsll\t%0,%1,%2";
4377   [(set_attr "type"     "shift")
4378    (set_attr "mode"     "DI")
4379    (set_attr_alternative "length"
4380                 [(const_int 4)
4381                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4382                                (const_int 4)
4383                                (const_int 8))])])
4386 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4388 (define_split
4389   [(set (match_operand:DI 0 "register_operand")
4390         (ashift:DI (match_operand:DI 1 "register_operand")
4391                    (match_operand:SI 2 "const_int_operand")))]
4392   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
4393    && reload_completed
4394    && GET_CODE (operands[2]) == CONST_INT
4395    && INTVAL (operands[2]) > 8
4396    && INTVAL (operands[2]) <= 16"
4397   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
4398    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
4399   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4401 (define_expand "ashrsi3"
4402   [(set (match_operand:SI 0 "register_operand")
4403         (ashiftrt:SI (match_operand:SI 1 "register_operand")
4404                      (match_operand:SI 2 "arith_operand")))]
4405   ""
4407   /* On the mips16, a shift of more than 8 is a four byte instruction,
4408      so, for a shift between 8 and 16, it is just as fast to do two
4409      shifts of 8 or less.  If there is a lot of shifting going on, we
4410      may win in CSE.  Otherwise combine will put the shifts back
4411      together again.  */
4412   if (TARGET_MIPS16
4413       && optimize
4414       && GET_CODE (operands[2]) == CONST_INT
4415       && INTVAL (operands[2]) > 8
4416       && INTVAL (operands[2]) <= 16)
4417     {
4418       rtx temp = gen_reg_rtx (SImode);
4420       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
4421       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
4422                                         GEN_INT (INTVAL (operands[2]) - 8)));
4423       DONE;
4424     }
4427 (define_insn "ashrsi3_internal1"
4428   [(set (match_operand:SI 0 "register_operand" "=d")
4429         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
4430                      (match_operand:SI 2 "arith_operand" "dI")))]
4431   "!TARGET_MIPS16"
4433   if (GET_CODE (operands[2]) == CONST_INT)
4434     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4436   return "sra\t%0,%1,%2";
4438   [(set_attr "type"     "shift")
4439    (set_attr "mode"     "SI")])
4441 (define_insn "ashrsi3_internal2"
4442   [(set (match_operand:SI 0 "register_operand" "=d,d")
4443         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
4444                      (match_operand:SI 2 "arith_operand" "d,I")))]
4445   "TARGET_MIPS16"
4447   if (which_alternative == 0)
4448     return "sra\t%0,%2";
4450   if (GET_CODE (operands[2]) == CONST_INT)
4451     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4453   return "sra\t%0,%1,%2";
4455   [(set_attr "type"     "shift")
4456    (set_attr "mode"     "SI")
4457    (set_attr_alternative "length"
4458                 [(const_int 4)
4459                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4460                                (const_int 4)
4461                                (const_int 8))])])
4464 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4466 (define_split
4467   [(set (match_operand:SI 0 "register_operand")
4468         (ashiftrt:SI (match_operand:SI 1 "register_operand")
4469                      (match_operand:SI 2 "const_int_operand")))]
4470   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4471    && GET_CODE (operands[2]) == CONST_INT
4472    && INTVAL (operands[2]) > 8
4473    && INTVAL (operands[2]) <= 16"
4474   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
4475    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
4476   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4478 (define_expand "ashrdi3"
4479   [(set (match_operand:DI 0 "register_operand")
4480         (ashiftrt:DI (match_operand:DI 1 "register_operand")
4481                      (match_operand:SI 2 "arith_operand")))]
4482   "TARGET_64BIT"
4484   /* On the mips16, a shift of more than 8 is a four byte
4485      instruction, so, for a shift between 8 and 16, it is just as
4486      fast to do two shifts of 8 or less.  If there is a lot of
4487      shifting going on, we may win in CSE.  Otherwise combine will
4488      put the shifts back together again.  */
4489   if (TARGET_MIPS16
4490       && optimize
4491       && GET_CODE (operands[2]) == CONST_INT
4492       && INTVAL (operands[2]) > 8
4493       && INTVAL (operands[2]) <= 16)
4494     {
4495       rtx temp = gen_reg_rtx (DImode);
4497       emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
4498       emit_insn (gen_ashrdi3_internal (operands[0], temp,
4499                                        GEN_INT (INTVAL (operands[2]) - 8)));
4500       DONE;
4501     }
4505 (define_insn "ashrdi3_internal"
4506   [(set (match_operand:DI 0 "register_operand" "=d")
4507         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4508                      (match_operand:SI 2 "arith_operand" "dI")))]
4509   "TARGET_64BIT && !TARGET_MIPS16"
4511   if (GET_CODE (operands[2]) == CONST_INT)
4512     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4514   return "dsra\t%0,%1,%2";
4516   [(set_attr "type"     "shift")
4517    (set_attr "mode"     "DI")])
4519 (define_insn ""
4520   [(set (match_operand:DI 0 "register_operand" "=d,d")
4521         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4522                      (match_operand:SI 2 "arith_operand" "d,I")))]
4523   "TARGET_64BIT && TARGET_MIPS16"
4525   if (GET_CODE (operands[2]) == CONST_INT)
4526     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4528   return "dsra\t%0,%2";
4530   [(set_attr "type"     "shift")
4531    (set_attr "mode"     "DI")
4532    (set_attr_alternative "length"
4533                 [(const_int 4)
4534                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4535                                (const_int 4)
4536                                (const_int 8))])])
4538 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4540 (define_split
4541   [(set (match_operand:DI 0 "register_operand")
4542         (ashiftrt:DI (match_operand:DI 1 "register_operand")
4543                      (match_operand:SI 2 "const_int_operand")))]
4544   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
4545    && reload_completed
4546    && GET_CODE (operands[2]) == CONST_INT
4547    && INTVAL (operands[2]) > 8
4548    && INTVAL (operands[2]) <= 16"
4549   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
4550    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
4551   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4553 (define_expand "lshrsi3"
4554   [(set (match_operand:SI 0 "register_operand")
4555         (lshiftrt:SI (match_operand:SI 1 "register_operand")
4556                      (match_operand:SI 2 "arith_operand")))]
4557   ""
4559   /* On the mips16, a shift of more than 8 is a four byte instruction,
4560      so, for a shift between 8 and 16, it is just as fast to do two
4561      shifts of 8 or less.  If there is a lot of shifting going on, we
4562      may win in CSE.  Otherwise combine will put the shifts back
4563      together again.  */
4564   if (TARGET_MIPS16
4565       && optimize
4566       && GET_CODE (operands[2]) == CONST_INT
4567       && INTVAL (operands[2]) > 8
4568       && INTVAL (operands[2]) <= 16)
4569     {
4570       rtx temp = gen_reg_rtx (SImode);
4572       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
4573       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
4574                                         GEN_INT (INTVAL (operands[2]) - 8)));
4575       DONE;
4576     }
4579 (define_insn "lshrsi3_internal1"
4580   [(set (match_operand:SI 0 "register_operand" "=d")
4581         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
4582                      (match_operand:SI 2 "arith_operand" "dI")))]
4583   "!TARGET_MIPS16"
4585   if (GET_CODE (operands[2]) == CONST_INT)
4586     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4588   return "srl\t%0,%1,%2";
4590   [(set_attr "type"     "shift")
4591    (set_attr "mode"     "SI")])
4593 (define_insn "lshrsi3_internal2"
4594   [(set (match_operand:SI 0 "register_operand" "=d,d")
4595         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
4596                      (match_operand:SI 2 "arith_operand" "d,I")))]
4597   "TARGET_MIPS16"
4599   if (which_alternative == 0)
4600     return "srl\t%0,%2";
4602   if (GET_CODE (operands[2]) == CONST_INT)
4603     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4605   return "srl\t%0,%1,%2";
4607   [(set_attr "type"     "shift")
4608    (set_attr "mode"     "SI")
4609    (set_attr_alternative "length"
4610                 [(const_int 4)
4611                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4612                                (const_int 4)
4613                                (const_int 8))])])
4616 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4618 (define_split
4619   [(set (match_operand:SI 0 "register_operand")
4620         (lshiftrt:SI (match_operand:SI 1 "register_operand")
4621                      (match_operand:SI 2 "const_int_operand")))]
4622   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4623    && GET_CODE (operands[2]) == CONST_INT
4624    && INTVAL (operands[2]) > 8
4625    && INTVAL (operands[2]) <= 16"
4626   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
4627    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4628   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4630 ;; If we load a byte on the mips16 as a bitfield, the resulting
4631 ;; sequence of instructions is too complicated for combine, because it
4632 ;; involves four instructions: a load, a shift, a constant load into a
4633 ;; register, and an and (the key problem here is that the mips16 does
4634 ;; not have and immediate).  We recognize a shift of a load in order
4635 ;; to make it simple enough for combine to understand.
4637 ;; The length here is the worst case: the length of the split version
4638 ;; will be more accurate.
4639 (define_insn_and_split ""
4640   [(set (match_operand:SI 0 "register_operand" "=d")
4641         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4642                      (match_operand:SI 2 "immediate_operand" "I")))]
4643   "TARGET_MIPS16"
4644   "#"
4645   ""
4646   [(set (match_dup 0) (match_dup 1))
4647    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4648   ""
4649   [(set_attr "type"     "load")
4650    (set_attr "mode"     "SI")
4651    (set_attr "length"   "16")])
4653 (define_expand "lshrdi3"
4654   [(set (match_operand:DI 0 "register_operand")
4655         (lshiftrt:DI (match_operand:DI 1 "register_operand")
4656                      (match_operand:SI 2 "arith_operand")))]
4657   "TARGET_64BIT"
4659   /* On the mips16, a shift of more than 8 is a four byte
4660      instruction, so, for a shift between 8 and 16, it is just as
4661      fast to do two shifts of 8 or less.  If there is a lot of
4662      shifting going on, we may win in CSE.  Otherwise combine will
4663      put the shifts back together again.  */
4664   if (TARGET_MIPS16
4665       && optimize
4666       && GET_CODE (operands[2]) == CONST_INT
4667       && INTVAL (operands[2]) > 8
4668       && INTVAL (operands[2]) <= 16)
4669     {
4670       rtx temp = gen_reg_rtx (DImode);
4672       emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
4673       emit_insn (gen_lshrdi3_internal (operands[0], temp,
4674                                        GEN_INT (INTVAL (operands[2]) - 8)));
4675       DONE;
4676     }
4680 (define_insn "lshrdi3_internal"
4681   [(set (match_operand:DI 0 "register_operand" "=d")
4682         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4683                      (match_operand:SI 2 "arith_operand" "dI")))]
4684   "TARGET_64BIT && !TARGET_MIPS16"
4686   if (GET_CODE (operands[2]) == CONST_INT)
4687     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4689   return "dsrl\t%0,%1,%2";
4691   [(set_attr "type"     "shift")
4692    (set_attr "mode"     "DI")])
4694 (define_insn ""
4695   [(set (match_operand:DI 0 "register_operand" "=d,d")
4696         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4697                      (match_operand:SI 2 "arith_operand" "d,I")))]
4698   "TARGET_64BIT && TARGET_MIPS16"
4700   if (GET_CODE (operands[2]) == CONST_INT)
4701     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4703   return "dsrl\t%0,%2";
4705   [(set_attr "type"     "shift")
4706    (set_attr "mode"     "DI")
4707    (set_attr_alternative "length"
4708                 [(const_int 4)
4709                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4710                                (const_int 4)
4711                                (const_int 8))])])
4713 (define_insn "rotrsi3"
4714   [(set (match_operand:SI              0 "register_operand" "=d")
4715         (rotatert:SI (match_operand:SI 1 "register_operand" "d")
4716                      (match_operand:SI 2 "arith_operand"    "dn")))]
4717   "ISA_HAS_ROTR_SI"
4719   if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
4720     return "rorv\t%0,%1,%2";
4722   if ((GET_CODE (operands[2]) == CONST_INT)
4723       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
4724     abort ();
4726   return "ror\t%0,%1,%2";
4728   [(set_attr "type"     "shift")
4729    (set_attr "mode"     "SI")])
4731 (define_insn "rotrdi3"
4732   [(set (match_operand:DI              0 "register_operand" "=d")
4733         (rotatert:DI (match_operand:DI 1 "register_operand" "d")
4734                      (match_operand:DI 2 "arith_operand"    "dn")))]
4735   "ISA_HAS_ROTR_DI"
4737   if (TARGET_SR71K)
4738     {
4739       if (GET_CODE (operands[2]) != CONST_INT)
4740         return "drorv\t%0,%1,%2";
4742       if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
4743         return "dror32\t%0,%1,%2";
4744     }
4746   if ((GET_CODE (operands[2]) == CONST_INT)
4747       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
4748     abort ();
4750   return "dror\t%0,%1,%2";
4752   [(set_attr "type"     "shift")
4753    (set_attr "mode"     "DI")])
4756 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4758 (define_split
4759   [(set (match_operand:DI 0 "register_operand")
4760         (lshiftrt:DI (match_operand:DI 1 "register_operand")
4761                      (match_operand:SI 2 "const_int_operand")))]
4762   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4763    && GET_CODE (operands[2]) == CONST_INT
4764    && INTVAL (operands[2]) > 8
4765    && INTVAL (operands[2]) <= 16"
4766   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
4767    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
4768   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4771 ;;  ....................
4773 ;;      COMPARISONS
4775 ;;  ....................
4777 ;; Flow here is rather complex:
4779 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the arguments
4780 ;;      into cmp_operands[] but generates no RTL.
4782 ;;  2)  The appropriate branch define_expand is called, which then
4783 ;;      creates the appropriate RTL for the comparison and branch.
4784 ;;      Different CC modes are used, based on what type of branch is
4785 ;;      done, so that we can constrain things appropriately.  There
4786 ;;      are assumptions in the rest of GCC that break if we fold the
4787 ;;      operands into the branches for integer operations, and use cc0
4788 ;;      for floating point, so we use the fp status register instead.
4789 ;;      If needed, an appropriate temporary is created to hold the
4790 ;;      of the integer compare.
4792 (define_expand "cmp<mode>"
4793   [(set (cc0)
4794         (compare:CC (match_operand:GPR 0 "register_operand")
4795                     (match_operand:GPR 1 "nonmemory_operand")))]
4796   ""
4798   cmp_operands[0] = operands[0];
4799   cmp_operands[1] = operands[1];
4800   DONE;
4803 (define_expand "cmpdf"
4804   [(set (cc0)
4805         (compare:CC (match_operand:DF 0 "register_operand")
4806                     (match_operand:DF 1 "register_operand")))]
4807   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4809   cmp_operands[0] = operands[0];
4810   cmp_operands[1] = operands[1];
4811   DONE;
4814 (define_expand "cmpsf"
4815   [(set (cc0)
4816         (compare:CC (match_operand:SF 0 "register_operand")
4817                     (match_operand:SF 1 "register_operand")))]
4818   "TARGET_HARD_FLOAT"
4820   cmp_operands[0] = operands[0];
4821   cmp_operands[1] = operands[1];
4822   DONE;
4826 ;;  ....................
4828 ;;      CONDITIONAL BRANCHES
4830 ;;  ....................
4832 ;; Conditional branches on floating-point equality tests.
4834 (define_insn "branch_fp"
4835   [(set (pc)
4836         (if_then_else
4837          (match_operator:CC 0 "comparison_operator"
4838                             [(match_operand:CC 2 "register_operand" "z")
4839                              (const_int 0)])
4840          (label_ref (match_operand 1 "" ""))
4841          (pc)))]
4842   "TARGET_HARD_FLOAT"
4844   return mips_output_conditional_branch (insn,
4845                                          operands,
4846                                          /*two_operands_p=*/0,
4847                                          /*float_p=*/1,
4848                                          /*inverted_p=*/0,
4849                                          get_attr_length (insn));
4851   [(set_attr "type"     "branch")
4852    (set_attr "mode"     "none")])
4854 (define_insn "branch_fp_inverted"
4855   [(set (pc)
4856         (if_then_else
4857          (match_operator:CC 0 "comparison_operator"
4858                             [(match_operand:CC 2 "register_operand" "z")
4859                              (const_int 0)])
4860          (pc)
4861          (label_ref (match_operand 1 "" ""))))]
4862   "TARGET_HARD_FLOAT"
4864   return mips_output_conditional_branch (insn,
4865                                          operands,
4866                                          /*two_operands_p=*/0,
4867                                          /*float_p=*/1,
4868                                          /*inverted_p=*/1,
4869                                          get_attr_length (insn));
4871   [(set_attr "type"     "branch")
4872    (set_attr "mode"     "none")])
4874 ;; Conditional branches on comparisons with zero.
4876 (define_insn "*branch_zero<mode>"
4877   [(set (pc)
4878         (if_then_else
4879          (match_operator:GPR 0 "comparison_operator"
4880                              [(match_operand:GPR 2 "register_operand" "d")
4881                               (const_int 0)])
4882          (label_ref (match_operand 1 "" ""))
4883          (pc)))]
4884   "!TARGET_MIPS16"
4886   return mips_output_conditional_branch (insn,
4887                                          operands,
4888                                          /*two_operands_p=*/0,
4889                                          /*float_p=*/0,
4890                                          /*inverted_p=*/0,
4891                                          get_attr_length (insn));
4893   [(set_attr "type" "branch")
4894    (set_attr "mode" "none")])
4896 (define_insn "*branch_zero<mode>_inverted"
4897   [(set (pc)
4898         (if_then_else
4899          (match_operator:GPR 0 "comparison_operator"
4900                              [(match_operand:GPR 2 "register_operand" "d")
4901                               (const_int 0)])
4902          (pc)
4903          (label_ref (match_operand 1 "" ""))))]
4904   "!TARGET_MIPS16"
4906   return mips_output_conditional_branch (insn,
4907                                          operands,
4908                                          /*two_operands_p=*/0,
4909                                          /*float_p=*/0,
4910                                          /*inverted_p=*/1,
4911                                          get_attr_length (insn));
4913   [(set_attr "type" "branch")
4914    (set_attr "mode" "none")])
4916 ;; Conditional branch on equality comparison.
4918 (define_insn "*branch_equality<mode>"
4919   [(set (pc)
4920         (if_then_else
4921          (match_operator:GPR 0 "equality_operator"
4922                              [(match_operand:GPR 2 "register_operand" "d")
4923                               (match_operand:GPR 3 "register_operand" "d")])
4924          (label_ref (match_operand 1 "" ""))
4925          (pc)))]
4926   "!TARGET_MIPS16"
4928   return mips_output_conditional_branch (insn,
4929                                          operands,
4930                                          /*two_operands_p=*/1,
4931                                          /*float_p=*/0,
4932                                          /*inverted_p=*/0,
4933                                          get_attr_length (insn));
4935   [(set_attr "type" "branch")
4936    (set_attr "mode" "none")])
4938 (define_insn "*branch_equality<mode>_inverted"
4939   [(set (pc)
4940         (if_then_else
4941          (match_operator:GPR 0 "equality_operator"
4942                              [(match_operand:GPR 2 "register_operand" "d")
4943                               (match_operand:GPR 3 "register_operand" "d")])
4944          (pc)
4945          (label_ref (match_operand 1 "" ""))))]
4946   "!TARGET_MIPS16"
4948   return mips_output_conditional_branch (insn,
4949                                          operands,
4950                                          /*two_operands_p=*/1,
4951                                          /*float_p=*/0,
4952                                          /*inverted_p=*/1,
4953                                          get_attr_length (insn));
4955   [(set_attr "type" "branch")
4956    (set_attr "mode" "none")])
4958 ;; MIPS16 branches
4960 (define_insn "*branch_equality<mode>_mips16"
4961   [(set (pc)
4962         (if_then_else
4963          (match_operator:GPR 0 "equality_operator"
4964                              [(match_operand:GPR 1 "register_operand" "d,t")
4965                               (const_int 0)])
4966          (match_operand 2 "pc_or_label_operand" "")
4967          (match_operand 3 "pc_or_label_operand" "")))]
4968   "TARGET_MIPS16"
4970   if (operands[2] != pc_rtx)
4971     {
4972       if (which_alternative == 0)
4973         return "b%C0z\t%1,%2";
4974       else
4975         return "bt%C0z\t%2";
4976     }
4977   else
4978     {
4979       if (which_alternative == 0)
4980         return "b%N0z\t%1,%3";
4981       else
4982         return "bt%N0z\t%3";
4983     }
4985   [(set_attr "type" "branch")
4986    (set_attr "mode" "none")
4987    (set_attr "length" "8")])
4989 (define_expand "b<code>"
4990   [(set (pc)
4991         (if_then_else (any_cond:CC (cc0)
4992                                    (const_int 0))
4993                       (label_ref (match_operand 0 ""))
4994                       (pc)))]
4995   ""
4997   gen_conditional_branch (operands, <CODE>);
4998   DONE;
5002 ;;  ....................
5004 ;;      SETTING A REGISTER FROM A COMPARISON
5006 ;;  ....................
5008 (define_expand "seq"
5009   [(set (match_operand:SI 0 "register_operand")
5010         (eq:SI (match_dup 1)
5011                (match_dup 2)))]
5012   ""
5013   { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
5015 (define_insn "*seq_<mode>"
5016   [(set (match_operand:GPR 0 "register_operand" "=d")
5017         (eq:GPR (match_operand:GPR 1 "register_operand" "d")
5018                 (const_int 0)))]
5019   "!TARGET_MIPS16"
5020   "sltu\t%0,%1,1"
5021   [(set_attr "type" "slt")
5022    (set_attr "mode" "<MODE>")])
5024 (define_insn "*seq_<mode>_mips16"
5025   [(set (match_operand:GPR 0 "register_operand" "=t")
5026         (eq:GPR (match_operand:GPR 1 "register_operand" "d")
5027                 (const_int 0)))]
5028   "TARGET_MIPS16"
5029   "sltu\t%1,1"
5030   [(set_attr "type" "slt")
5031    (set_attr "mode" "<MODE>")])
5033 ;; "sne" uses sltu instructions in which the first operand is $0.
5034 ;; This isn't possible in mips16 code.
5036 (define_expand "sne"
5037   [(set (match_operand:SI 0 "register_operand")
5038         (ne:SI (match_dup 1)
5039                (match_dup 2)))]
5040   "!TARGET_MIPS16"
5041   { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
5043 (define_insn "*sne_<mode>"
5044   [(set (match_operand:GPR 0 "register_operand" "=d")
5045         (ne:GPR (match_operand:GPR 1 "register_operand" "d")
5046                 (const_int 0)))]
5047   "!TARGET_MIPS16"
5048   "sltu\t%0,%.,%1"
5049   [(set_attr "type" "slt")
5050    (set_attr "mode" "<MODE>")])
5052 (define_expand "sgt"
5053   [(set (match_operand:SI 0 "register_operand")
5054         (gt:SI (match_dup 1)
5055                (match_dup 2)))]
5056   ""
5057   { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
5059 (define_insn "*sgt_<mode>"
5060   [(set (match_operand:GPR 0 "register_operand" "=d")
5061         (gt:GPR (match_operand:GPR 1 "register_operand" "d")
5062                 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
5063   "!TARGET_MIPS16"
5064   "slt\t%0,%z2,%1"
5065   [(set_attr "type" "slt")
5066    (set_attr "mode" "<MODE>")])
5068 (define_insn "*sgt_<mode>_mips16"
5069   [(set (match_operand:GPR 0 "register_operand" "=t")
5070         (gt:GPR (match_operand:GPR 1 "register_operand" "d")
5071                 (match_operand:GPR 2 "register_operand" "d")))]
5072   "TARGET_MIPS16"
5073   "slt\t%2,%1"
5074   [(set_attr "type" "slt")
5075    (set_attr "mode" "<MODE>")])
5077 (define_expand "sge"
5078   [(set (match_operand:SI 0 "register_operand")
5079         (ge:SI (match_dup 1)
5080                (match_dup 2)))]
5081   ""
5082   { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
5084 (define_insn "*sge_<mode>"
5085   [(set (match_operand:GPR 0 "register_operand" "=d")
5086         (ge:GPR (match_operand:GPR 1 "register_operand" "d")
5087                 (const_int 1)))]
5088   "!TARGET_MIPS16"
5089   "slt\t%0,%.,%1"
5090   [(set_attr "type" "slt")
5091    (set_attr "mode" "<MODE>")])
5093 (define_expand "slt"
5094   [(set (match_operand:SI 0 "register_operand")
5095         (lt:SI (match_dup 1)
5096                (match_dup 2)))]
5097   ""
5098   { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
5100 (define_insn "*slt_<mode>"
5101   [(set (match_operand:GPR 0 "register_operand" "=d")
5102         (lt:GPR (match_operand:GPR 1 "register_operand" "d")
5103                 (match_operand:GPR 2 "arith_operand" "dI")))]
5104   "!TARGET_MIPS16"
5105   "slt\t%0,%1,%2"
5106   [(set_attr "type" "slt")
5107    (set_attr "mode" "<MODE>")])
5109 (define_insn "*slt_<mode>_mips16"
5110   [(set (match_operand:GPR 0 "register_operand" "=t,t")
5111         (lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
5112                 (match_operand:GPR 2 "arith_operand" "d,I")))]
5113   "TARGET_MIPS16"
5114   "slt\t%1,%2"
5115   [(set_attr "type" "slt")
5116    (set_attr "mode" "<MODE>")
5117    (set_attr_alternative "length"
5118                 [(const_int 4)
5119                  (if_then_else (match_operand 2 "m16_uimm8_1")
5120                                (const_int 4)
5121                                (const_int 8))])])
5123 (define_expand "sle"
5124   [(set (match_operand:SI 0 "register_operand")
5125         (le:SI (match_dup 1)
5126                (match_dup 2)))]
5127   ""
5128   { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
5130 (define_insn "*sle_<mode>"
5131   [(set (match_operand:GPR 0 "register_operand" "=d")
5132         (le:GPR (match_operand:GPR 1 "register_operand" "d")
5133                 (match_operand:GPR 2 "sle_operand" "")))]
5134   "!TARGET_MIPS16"
5136   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5137   return "slt\t%0,%1,%2";
5139   [(set_attr "type" "slt")
5140    (set_attr "mode" "<MODE>")])
5142 (define_insn "*sle_<mode>_mips16"
5143   [(set (match_operand:GPR 0 "register_operand" "=t")
5144         (le:GPR (match_operand:GPR 1 "register_operand" "d")
5145                 (match_operand:GPR 2 "sle_operand" "")))]
5146   "TARGET_MIPS16"
5148   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5149   return "slt\t%1,%2";
5151   [(set_attr "type" "slt")
5152    (set_attr "mode" "<MODE>")
5153    (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
5154                                       (const_int 4)
5155                                       (const_int 8)))])
5157 (define_expand "sgtu"
5158   [(set (match_operand:SI 0 "register_operand")
5159         (gtu:SI (match_dup 1)
5160                 (match_dup 2)))]
5161   ""
5162   { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
5164 (define_insn "*sgtu_<mode>"
5165   [(set (match_operand:GPR 0 "register_operand" "=d")
5166         (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
5167                  (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
5168   "!TARGET_MIPS16"
5169   "sltu\t%0,%z2,%1"
5170   [(set_attr "type" "slt")
5171    (set_attr "mode" "<MODE>")])
5173 (define_insn "*sgtu_<mode>_mips16"
5174   [(set (match_operand:GPR 0 "register_operand" "=t")
5175         (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
5176                  (match_operand:GPR 2 "register_operand" "d")))]
5177   "TARGET_MIPS16"
5178   "sltu\t%2,%1"
5179   [(set_attr "type" "slt")
5180    (set_attr "mode" "<MODE>")])
5182 (define_expand "sgeu"
5183   [(set (match_operand:SI 0 "register_operand")
5184         (geu:SI (match_dup 1)
5185                 (match_dup 2)))]
5186   ""
5187   { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
5189 (define_insn "*sge_<mode>"
5190   [(set (match_operand:GPR 0 "register_operand" "=d")
5191         (geu:GPR (match_operand:GPR 1 "register_operand" "d")
5192                  (const_int 1)))]
5193   "!TARGET_MIPS16"
5194   "sltu\t%0,%.,%1"
5195   [(set_attr "type" "slt")
5196    (set_attr "mode" "<MODE>")])
5198 (define_expand "sltu"
5199   [(set (match_operand:SI 0 "register_operand")
5200         (ltu:SI (match_dup 1)
5201                 (match_dup 2)))]
5202   ""
5203   { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
5205 (define_insn "*sltu_<mode>"
5206   [(set (match_operand:GPR 0 "register_operand" "=d")
5207         (ltu:GPR (match_operand:GPR 1 "register_operand" "d")
5208                  (match_operand:GPR 2 "arith_operand" "dI")))]
5209   "!TARGET_MIPS16"
5210   "sltu\t%0,%1,%2"
5211   [(set_attr "type" "slt")
5212    (set_attr "mode" "<MODE>")])
5214 (define_insn "*sltu_<mode>_mips16"
5215   [(set (match_operand:GPR 0 "register_operand" "=t,t")
5216         (ltu:GPR (match_operand:GPR 1 "register_operand" "d,d")
5217                  (match_operand:GPR 2 "arith_operand" "d,I")))]
5218   "TARGET_MIPS16"
5219   "sltu\t%1,%2"
5220   [(set_attr "type" "slt")
5221    (set_attr "mode" "<MODE>")
5222    (set_attr_alternative "length"
5223                 [(const_int 4)
5224                  (if_then_else (match_operand 2 "m16_uimm8_1")
5225                                (const_int 4)
5226                                (const_int 8))])])
5228 (define_expand "sleu"
5229   [(set (match_operand:SI 0 "register_operand")
5230         (leu:SI (match_dup 1)
5231                 (match_dup 2)))]
5232   ""
5233   { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
5235 (define_insn "*sleu_<mode>"
5236   [(set (match_operand:GPR 0 "register_operand" "=d")
5237         (leu:GPR (match_operand:GPR 1 "register_operand" "d")
5238                  (match_operand:GPR 2 "sleu_operand" "")))]
5239   "!TARGET_MIPS16"
5241   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5242   return "sltu\t%0,%1,%2";
5244   [(set_attr "type" "slt")
5245    (set_attr "mode" "<MODE>")])
5247 (define_insn "*sleu_<mode>_mips16"
5248   [(set (match_operand:GPR 0 "register_operand" "=t")
5249         (leu:GPR (match_operand:GPR 1 "register_operand" "d")
5250                  (match_operand:GPR 2 "sleu_operand" "")))]
5251   "TARGET_MIPS16"
5253   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5254   return "sltu\t%1,%2";
5256   [(set_attr "type" "slt")
5257    (set_attr "mode" "<MODE>")
5258    (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
5259                                       (const_int 4)
5260                                       (const_int 8)))])
5263 ;;  ....................
5265 ;;      FLOATING POINT COMPARISONS
5267 ;;  ....................
5269 (define_insn "sunordered_df"
5270   [(set (match_operand:CC 0 "register_operand" "=z")
5271         (unordered:CC (match_operand:DF 1 "register_operand" "f")
5272                       (match_operand:DF 2 "register_operand" "f")))]
5273   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5274   "c.un.d\t%Z0%1,%2"
5275   [(set_attr "type" "fcmp")
5276    (set_attr "mode" "FPSW")])
5278 (define_insn "sunlt_df"
5279   [(set (match_operand:CC 0 "register_operand" "=z")
5280         (unlt:CC (match_operand:DF 1 "register_operand" "f")
5281                  (match_operand:DF 2 "register_operand" "f")))]
5282   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5283   "c.ult.d\t%Z0%1,%2"
5284   [(set_attr "type" "fcmp")
5285    (set_attr "mode" "FPSW")])
5287 (define_insn "suneq_df"
5288   [(set (match_operand:CC 0 "register_operand" "=z")
5289         (uneq:CC (match_operand:DF 1 "register_operand" "f")
5290                  (match_operand:DF 2 "register_operand" "f")))]
5291   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5292   "c.ueq.d\t%Z0%1,%2"
5293   [(set_attr "type" "fcmp")
5294    (set_attr "mode" "FPSW")])
5296 (define_insn "sunle_df"
5297   [(set (match_operand:CC 0 "register_operand" "=z")
5298         (unle:CC (match_operand:DF 1 "register_operand" "f")
5299                  (match_operand:DF 2 "register_operand" "f")))]
5300   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5301   "c.ule.d\t%Z0%1,%2"
5302   [(set_attr "type" "fcmp")
5303    (set_attr "mode" "FPSW")])
5305 (define_insn "seq_df"
5306   [(set (match_operand:CC 0 "register_operand" "=z")
5307         (eq:CC (match_operand:DF 1 "register_operand" "f")
5308                (match_operand:DF 2 "register_operand" "f")))]
5309   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5310   "c.eq.d\t%Z0%1,%2"
5311   [(set_attr "type" "fcmp")
5312    (set_attr "mode" "FPSW")])
5314 (define_insn "slt_df"
5315   [(set (match_operand:CC 0 "register_operand" "=z")
5316         (lt:CC (match_operand:DF 1 "register_operand" "f")
5317                (match_operand:DF 2 "register_operand" "f")))]
5318   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5319   "c.lt.d\t%Z0%1,%2"
5320   [(set_attr "type" "fcmp")
5321    (set_attr "mode" "FPSW")])
5323 (define_insn "sle_df"
5324   [(set (match_operand:CC 0 "register_operand" "=z")
5325         (le:CC (match_operand:DF 1 "register_operand" "f")
5326                (match_operand:DF 2 "register_operand" "f")))]
5327   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5328   "c.le.d\t%Z0%1,%2"
5329   [(set_attr "type" "fcmp")
5330    (set_attr "mode" "FPSW")])
5332 (define_insn "sgt_df"
5333   [(set (match_operand:CC 0 "register_operand" "=z")
5334         (gt:CC (match_operand:DF 1 "register_operand" "f")
5335                (match_operand:DF 2 "register_operand" "f")))]
5336   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5337   "c.lt.d\t%Z0%2,%1"
5338   [(set_attr "type" "fcmp")
5339    (set_attr "mode" "FPSW")])
5341 (define_insn "sge_df"
5342   [(set (match_operand:CC 0 "register_operand" "=z")
5343         (ge:CC (match_operand:DF 1 "register_operand" "f")
5344                (match_operand:DF 2 "register_operand" "f")))]
5345   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5346   "c.le.d\t%Z0%2,%1"
5347   [(set_attr "type" "fcmp")
5348    (set_attr "mode" "FPSW")])
5350 (define_insn "sunordered_sf"
5351   [(set (match_operand:CC 0 "register_operand" "=z")
5352         (unordered:CC (match_operand:SF 1 "register_operand" "f")
5353                       (match_operand:SF 2 "register_operand" "f")))]
5354   "TARGET_HARD_FLOAT"
5355   "c.un.s\t%Z0%1,%2"
5356   [(set_attr "type" "fcmp")
5357    (set_attr "mode" "FPSW")])
5359 (define_insn "sunlt_sf"
5360   [(set (match_operand:CC 0 "register_operand" "=z")
5361         (unlt:CC (match_operand:SF 1 "register_operand" "f")
5362                  (match_operand:SF 2 "register_operand" "f")))]
5363   "TARGET_HARD_FLOAT"
5364   "c.ult.s\t%Z0%1,%2"
5365   [(set_attr "type" "fcmp")
5366    (set_attr "mode" "FPSW")])
5368 (define_insn "suneq_sf"
5369   [(set (match_operand:CC 0 "register_operand" "=z")
5370         (uneq:CC (match_operand:SF 1 "register_operand" "f")
5371                  (match_operand:SF 2 "register_operand" "f")))]
5372   "TARGET_HARD_FLOAT"
5373   "c.ueq.s\t%Z0%1,%2"
5374   [(set_attr "type" "fcmp")
5375    (set_attr "mode" "FPSW")])
5377 (define_insn "sunle_sf"
5378   [(set (match_operand:CC 0 "register_operand" "=z")
5379         (unle:CC (match_operand:SF 1 "register_operand" "f")
5380                  (match_operand:SF 2 "register_operand" "f")))]
5381   "TARGET_HARD_FLOAT"
5382   "c.ule.s\t%Z0%1,%2"
5383   [(set_attr "type" "fcmp")
5384    (set_attr "mode" "FPSW")])
5386 (define_insn "seq_sf"
5387   [(set (match_operand:CC 0 "register_operand" "=z")
5388         (eq:CC (match_operand:SF 1 "register_operand" "f")
5389                (match_operand:SF 2 "register_operand" "f")))]
5390   "TARGET_HARD_FLOAT"
5391   "c.eq.s\t%Z0%1,%2"
5392   [(set_attr "type" "fcmp")
5393    (set_attr "mode" "FPSW")])
5395 (define_insn "slt_sf"
5396   [(set (match_operand:CC 0 "register_operand" "=z")
5397         (lt:CC (match_operand:SF 1 "register_operand" "f")
5398                (match_operand:SF 2 "register_operand" "f")))]
5399   "TARGET_HARD_FLOAT"
5400   "c.lt.s\t%Z0%1,%2"
5401   [(set_attr "type" "fcmp")
5402    (set_attr "mode" "FPSW")])
5404 (define_insn "sle_sf"
5405   [(set (match_operand:CC 0 "register_operand" "=z")
5406         (le:CC (match_operand:SF 1 "register_operand" "f")
5407                (match_operand:SF 2 "register_operand" "f")))]
5408   "TARGET_HARD_FLOAT"
5409   "c.le.s\t%Z0%1,%2"
5410   [(set_attr "type" "fcmp")
5411    (set_attr "mode" "FPSW")])
5413 (define_insn "sgt_sf"
5414   [(set (match_operand:CC 0 "register_operand" "=z")
5415         (gt:CC (match_operand:SF 1 "register_operand" "f")
5416                (match_operand:SF 2 "register_operand" "f")))]
5417   "TARGET_HARD_FLOAT"
5418   "c.lt.s\t%Z0%2,%1"
5419   [(set_attr "type" "fcmp")
5420    (set_attr "mode" "FPSW")])
5422 (define_insn "sge_sf"
5423   [(set (match_operand:CC 0 "register_operand" "=z")
5424         (ge:CC (match_operand:SF 1 "register_operand" "f")
5425                (match_operand:SF 2 "register_operand" "f")))]
5426   "TARGET_HARD_FLOAT"
5427   "c.le.s\t%Z0%2,%1"
5428   [(set_attr "type" "fcmp")
5429    (set_attr "mode" "FPSW")])
5432 ;;  ....................
5434 ;;      UNCONDITIONAL BRANCHES
5436 ;;  ....................
5438 ;; Unconditional branches.
5440 (define_insn "jump"
5441   [(set (pc)
5442         (label_ref (match_operand 0 "" "")))]
5443   "!TARGET_MIPS16"
5445   if (flag_pic)
5446     {
5447       if (get_attr_length (insn) <= 8)
5448         return "%*b\t%l0%/";
5449       else
5450         {
5451           output_asm_insn (mips_output_load_label (), operands);
5452           return "%*jr\t%@%/%]";
5453         }
5454     }
5455   else
5456     return "%*j\t%l0%/";
5458   [(set_attr "type"     "jump")
5459    (set_attr "mode"     "none")
5460    (set (attr "length")
5461         ;; We can't use `j' when emitting PIC.  Emit a branch if it's
5462         ;; in range, otherwise load the address of the branch target into
5463         ;; $at and then jump to it.
5464         (if_then_else
5465          (ior (eq (symbol_ref "flag_pic") (const_int 0))
5466               (lt (abs (minus (match_dup 0)
5467                               (plus (pc) (const_int 4))))
5468                   (const_int 131072)))
5469          (const_int 4) (const_int 16)))])
5471 ;; We need a different insn for the mips16, because a mips16 branch
5472 ;; does not have a delay slot.
5474 (define_insn ""
5475   [(set (pc)
5476         (label_ref (match_operand 0 "" "")))]
5477   "TARGET_MIPS16"
5478   "b\t%l0"
5479   [(set_attr "type"     "branch")
5480    (set_attr "mode"     "none")
5481    (set_attr "length"   "8")])
5483 (define_expand "indirect_jump"
5484   [(set (pc) (match_operand 0 "register_operand"))]
5485   ""
5487   operands[0] = force_reg (Pmode, operands[0]);
5488   if (Pmode == SImode)
5489     emit_jump_insn (gen_indirect_jumpsi (operands[0]));
5490   else
5491     emit_jump_insn (gen_indirect_jumpdi (operands[0]));
5492   DONE;
5495 (define_insn "indirect_jump<mode>"
5496   [(set (pc) (match_operand:P 0 "register_operand" "d"))]
5497   ""
5498   "%*j\t%0%/"
5499   [(set_attr "type" "jump")
5500    (set_attr "mode" "none")])
5502 (define_expand "tablejump"
5503   [(set (pc)
5504         (match_operand 0 "register_operand"))
5505    (use (label_ref (match_operand 1 "")))]
5506   ""
5508   if (TARGET_MIPS16)
5509     operands[0] = expand_binop (Pmode, add_optab,
5510                                 convert_to_mode (Pmode, operands[0], false),
5511                                 gen_rtx_LABEL_REF (Pmode, operands[1]),
5512                                 0, 0, OPTAB_WIDEN);
5513   else if (TARGET_GPWORD)
5514     operands[0] = expand_binop (Pmode, add_optab, operands[0],
5515                                 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
5517   if (Pmode == SImode)
5518     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
5519   else
5520     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
5521   DONE;
5524 (define_insn "tablejump<mode>"
5525   [(set (pc)
5526         (match_operand:P 0 "register_operand" "d"))
5527    (use (label_ref (match_operand 1 "" "")))]
5528   ""
5529   "%*j\t%0%/"
5530   [(set_attr "type" "jump")
5531    (set_attr "mode" "none")])
5533 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
5534 ;; While it is possible to either pull it off the stack (in the
5535 ;; o32 case) or recalculate it given t9 and our target label,
5536 ;; it takes 3 or 4 insns to do so.
5538 (define_expand "builtin_setjmp_setup"
5539   [(use (match_operand 0 "register_operand"))]
5540   "TARGET_ABICALLS"
5542   rtx addr;
5544   addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
5545   emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
5546   DONE;
5549 ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
5550 ;; that older code did recalculate the gp from $25.  Continue to jump through
5551 ;; $25 for compatibility (we lose nothing by doing so).
5553 (define_expand "builtin_longjmp"
5554   [(use (match_operand 0 "register_operand"))]
5555   "TARGET_ABICALLS"
5557   /* The elements of the buffer are, in order:  */
5558   int W = GET_MODE_SIZE (Pmode);
5559   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5560   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
5561   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
5562   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
5563   rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5564   /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
5565      The target is bound to be using $28 as the global pointer
5566      but the current function might not be.  */
5567   rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
5569   /* This bit is similar to expand_builtin_longjmp except that it
5570      restores $gp as well.  */
5571   emit_move_insn (hard_frame_pointer_rtx, fp);
5572   emit_move_insn (pv, lab);
5573   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5574   emit_move_insn (gp, gpv);
5575   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5576   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5577   emit_insn (gen_rtx_USE (VOIDmode, gp));
5578   emit_indirect_jump (pv);
5579   DONE;
5583 ;;  ....................
5585 ;;      Function prologue/epilogue
5587 ;;  ....................
5590 (define_expand "prologue"
5591   [(const_int 1)]
5592   ""
5594   mips_expand_prologue ();
5595   DONE;
5598 ;; Block any insns from being moved before this point, since the
5599 ;; profiling call to mcount can use various registers that aren't
5600 ;; saved or used to pass arguments.
5602 (define_insn "blockage"
5603   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
5604   ""
5605   ""
5606   [(set_attr "type"     "unknown")
5607    (set_attr "mode"     "none")
5608    (set_attr "length"   "0")])
5610 (define_expand "epilogue"
5611   [(const_int 2)]
5612   ""
5614   mips_expand_epilogue (false);
5615   DONE;
5618 (define_expand "sibcall_epilogue"
5619   [(const_int 2)]
5620   ""
5622   mips_expand_epilogue (true);
5623   DONE;
5626 ;; Trivial return.  Make it look like a normal return insn as that
5627 ;; allows jump optimizations to work better.
5629 (define_insn "return"
5630   [(return)]
5631   "mips_can_use_return_insn ()"
5632   "%*j\t$31%/"
5633   [(set_attr "type"     "jump")
5634    (set_attr "mode"     "none")])
5636 ;; Normal return.
5638 (define_insn "return_internal"
5639   [(return)
5640    (use (match_operand 0 "pmode_register_operand" ""))]
5641   ""
5642   "%*j\t%0%/"
5643   [(set_attr "type"     "jump")
5644    (set_attr "mode"     "none")])
5646 ;; This is used in compiling the unwind routines.
5647 (define_expand "eh_return"
5648   [(use (match_operand 0 "general_operand"))]
5649   ""
5651   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
5653   if (GET_MODE (operands[0]) != gpr_mode)
5654     operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
5655   if (TARGET_64BIT)
5656     emit_insn (gen_eh_set_lr_di (operands[0]));
5657   else
5658     emit_insn (gen_eh_set_lr_si (operands[0]));
5660   DONE;
5663 ;; Clobber the return address on the stack.  We can't expand this
5664 ;; until we know where it will be put in the stack frame.
5666 (define_insn "eh_set_lr_si"
5667   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5668    (clobber (match_scratch:SI 1 "=&d"))]
5669   "! TARGET_64BIT"
5670   "#")
5672 (define_insn "eh_set_lr_di"
5673   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5674    (clobber (match_scratch:DI 1 "=&d"))]
5675   "TARGET_64BIT"
5676   "#")
5678 (define_split
5679   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
5680    (clobber (match_scratch 1))]
5681   "reload_completed && !TARGET_DEBUG_D_MODE"
5682   [(const_int 0)]
5684   mips_set_return_address (operands[0], operands[1]);
5685   DONE;
5688 (define_insn_and_split "exception_receiver"
5689   [(set (reg:SI 28)
5690         (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
5691   "TARGET_ABICALLS && TARGET_OLDABI"
5692   "#"
5693   "&& reload_completed"
5694   [(const_int 0)]
5696   mips_restore_gp ();
5697   DONE;
5699   [(set_attr "type"   "load")
5700    (set_attr "length" "12")])
5703 ;;  ....................
5705 ;;      FUNCTION CALLS
5707 ;;  ....................
5709 ;; Instructions to load a call address from the GOT.  The address might
5710 ;; point to a function or to a lazy binding stub.  In the latter case,
5711 ;; the stub will use the dynamic linker to resolve the function, which
5712 ;; in turn will change the GOT entry to point to the function's real
5713 ;; address.
5715 ;; This means that every call, even pure and constant ones, can
5716 ;; potentially modify the GOT entry.  And once a stub has been called,
5717 ;; we must not call it again.
5719 ;; We represent this restriction using an imaginary fixed register that
5720 ;; acts like a GOT version number.  By making the register call-clobbered,
5721 ;; we tell the target-independent code that the address could be changed
5722 ;; by any call insn.
5723 (define_insn "load_call<mode>"
5724   [(set (match_operand:P 0 "register_operand" "=c")
5725         (unspec:P [(match_operand:P 1 "register_operand" "r")
5726                    (match_operand:P 2 "immediate_operand" "")
5727                    (reg:P FAKE_CALL_REGNO)]
5728                   UNSPEC_LOAD_CALL))]
5729   "TARGET_ABICALLS"
5730   "<load>\t%0,%R2(%1)"
5731   [(set_attr "type" "load")
5732    (set_attr "mode" "<MODE>")
5733    (set_attr "length" "4")])
5735 ;; Sibling calls.  All these patterns use jump instructions.
5737 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
5738 ;; addresses if a direct jump is acceptable.  Since the 'S' constraint
5739 ;; is defined in terms of call_insn_operand, the same is true of the
5740 ;; constraints.
5742 ;; When we use an indirect jump, we need a register that will be
5743 ;; preserved by the epilogue.  Since TARGET_ABICALLS forces us to
5744 ;; use $25 for this purpose -- and $25 is never clobbered by the
5745 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
5747 (define_expand "sibcall"
5748   [(parallel [(call (match_operand 0 "")
5749                     (match_operand 1 ""))
5750               (use (match_operand 2 ""))        ;; next_arg_reg
5751               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
5752   "TARGET_SIBCALLS"
5754   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
5755   DONE;
5758 (define_insn "sibcall_internal"
5759   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
5760          (match_operand 1 "" ""))]
5761   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5762   "@
5763     %*jr\t%0%/
5764     %*j\t%0%/"
5765   [(set_attr "type" "call")])
5767 (define_expand "sibcall_value"
5768   [(parallel [(set (match_operand 0 "")
5769                    (call (match_operand 1 "")
5770                          (match_operand 2 "")))
5771               (use (match_operand 3 ""))])]             ;; next_arg_reg
5772   "TARGET_SIBCALLS"
5774   mips_expand_call (operands[0], XEXP (operands[1], 0),
5775                     operands[2], operands[3], true);
5776   DONE;
5779 (define_insn "sibcall_value_internal"
5780   [(set (match_operand 0 "register_operand" "=df,df")
5781         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5782               (match_operand 2 "" "")))]
5783   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5784   "@
5785     %*jr\t%1%/
5786     %*j\t%1%/"
5787   [(set_attr "type" "call")])
5789 (define_insn "sibcall_value_multiple_internal"
5790   [(set (match_operand 0 "register_operand" "=df,df")
5791         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5792               (match_operand 2 "" "")))
5793    (set (match_operand 3 "register_operand" "=df,df")
5794         (call (mem:SI (match_dup 1))
5795               (match_dup 2)))]
5796   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5797   "@
5798     %*jr\t%1%/
5799     %*j\t%1%/"
5800   [(set_attr "type" "call")])
5802 (define_expand "call"
5803   [(parallel [(call (match_operand 0 "")
5804                     (match_operand 1 ""))
5805               (use (match_operand 2 ""))        ;; next_arg_reg
5806               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
5807   ""
5809   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
5810   DONE;
5813 ;; This instruction directly corresponds to an assembly-language "jal".
5814 ;; There are four cases:
5816 ;;    - -mno-abicalls:
5817 ;;        Both symbolic and register destinations are OK.  The pattern
5818 ;;        always expands to a single mips instruction.
5820 ;;    - -mabicalls/-mno-explicit-relocs:
5821 ;;        Again, both symbolic and register destinations are OK.
5822 ;;        The call is treated as a multi-instruction black box.
5824 ;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
5825 ;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
5826 ;;        instruction.
5828 ;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
5829 ;;        Only "jal $25" is allowed.  The call is actually two instructions:
5830 ;;        "jalr $25" followed by an insn to reload $gp.
5832 ;; In the last case, we can generate the individual instructions with
5833 ;; a define_split.  There are several things to be wary of:
5835 ;;   - We can't expose the load of $gp before reload.  If we did,
5836 ;;     it might get removed as dead, but reload can introduce new
5837 ;;     uses of $gp by rematerializing constants.
5839 ;;   - We shouldn't restore $gp after calls that never return.
5840 ;;     It isn't valid to insert instructions between a noreturn
5841 ;;     call and the following barrier.
5843 ;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
5844 ;;     instruction preserves $gp and so have no effect on its liveness.
5845 ;;     But once we generate the separate insns, it becomes obvious that
5846 ;;     $gp is not live on entry to the call.
5848 ;; ??? The operands[2] = insn check is a hack to make the original insn
5849 ;; available to the splitter.
5850 (define_insn_and_split "call_internal"
5851   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
5852          (match_operand 1 "" ""))
5853    (clobber (reg:SI 31))]
5854   ""
5855   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
5856   "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
5857   [(const_int 0)]
5859   emit_call_insn (gen_call_split (operands[0], operands[1]));
5860   if (!find_reg_note (operands[2], REG_NORETURN, 0))
5861     mips_restore_gp ();
5862   DONE;
5864   [(set_attr "jal" "indirect,direct")
5865    (set_attr "extended_mips16" "no,yes")])
5867 (define_insn "call_split"
5868   [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
5869          (match_operand 1 "" ""))
5870    (clobber (reg:SI 31))
5871    (clobber (reg:SI 28))]
5872   "TARGET_SPLIT_CALLS"
5873   "%*jalr\t%0%/"
5874   [(set_attr "type" "call")])
5876 (define_expand "call_value"
5877   [(parallel [(set (match_operand 0 "")
5878                    (call (match_operand 1 "")
5879                          (match_operand 2 "")))
5880               (use (match_operand 3 ""))])]             ;; next_arg_reg
5881   ""
5883   mips_expand_call (operands[0], XEXP (operands[1], 0),
5884                     operands[2], operands[3], false);
5885   DONE;
5888 ;; See comment for call_internal.
5889 (define_insn_and_split "call_value_internal"
5890   [(set (match_operand 0 "register_operand" "=df,df")
5891         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5892               (match_operand 2 "" "")))
5893    (clobber (reg:SI 31))]
5894   ""
5895   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
5896   "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
5897   [(const_int 0)]
5899   emit_call_insn (gen_call_value_split (operands[0], operands[1],
5900                                         operands[2]));
5901   if (!find_reg_note (operands[3], REG_NORETURN, 0))
5902     mips_restore_gp ();
5903   DONE;
5905   [(set_attr "jal" "indirect,direct")
5906    (set_attr "extended_mips16" "no,yes")])
5908 (define_insn "call_value_split"
5909   [(set (match_operand 0 "register_operand" "=df")
5910         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
5911               (match_operand 2 "" "")))
5912    (clobber (reg:SI 31))
5913    (clobber (reg:SI 28))]
5914   "TARGET_SPLIT_CALLS"
5915   "%*jalr\t%1%/"
5916   [(set_attr "type" "call")])
5918 ;; See comment for call_internal.
5919 (define_insn_and_split "call_value_multiple_internal"
5920   [(set (match_operand 0 "register_operand" "=df,df")
5921         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5922               (match_operand 2 "" "")))
5923    (set (match_operand 3 "register_operand" "=df,df")
5924         (call (mem:SI (match_dup 1))
5925               (match_dup 2)))
5926    (clobber (reg:SI 31))]
5927   ""
5928   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
5929   "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
5930   [(const_int 0)]
5932   emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
5933                                                  operands[2], operands[3]));
5934   if (!find_reg_note (operands[4], REG_NORETURN, 0))
5935     mips_restore_gp ();
5936   DONE;
5938   [(set_attr "jal" "indirect,direct")
5939    (set_attr "extended_mips16" "no,yes")])
5941 (define_insn "call_value_multiple_split"
5942   [(set (match_operand 0 "register_operand" "=df")
5943         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
5944               (match_operand 2 "" "")))
5945    (set (match_operand 3 "register_operand" "=df")
5946         (call (mem:SI (match_dup 1))
5947               (match_dup 2)))
5948    (clobber (reg:SI 31))
5949    (clobber (reg:SI 28))]
5950   "TARGET_SPLIT_CALLS"
5951   "%*jalr\t%1%/"
5952   [(set_attr "type" "call")])
5954 ;; Call subroutine returning any type.
5956 (define_expand "untyped_call"
5957   [(parallel [(call (match_operand 0 "")
5958                     (const_int 0))
5959               (match_operand 1 "")
5960               (match_operand 2 "")])]
5961   ""
5963   int i;
5965   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
5967   for (i = 0; i < XVECLEN (operands[2], 0); i++)
5968     {
5969       rtx set = XVECEXP (operands[2], 0, i);
5970       emit_move_insn (SET_DEST (set), SET_SRC (set));
5971     }
5973   emit_insn (gen_blockage ());
5974   DONE;
5978 ;;  ....................
5980 ;;      MISC.
5982 ;;  ....................
5986 (define_insn "prefetch"
5987   [(prefetch (match_operand:QI 0 "address_operand" "p")
5988              (match_operand 1 "const_int_operand" "n")
5989              (match_operand 2 "const_int_operand" "n"))]
5990   "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
5992   operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
5993   return "pref\t%1,%a0";
5995   [(set_attr "type" "prefetch")])
5997 (define_insn "*prefetch_indexed_<mode>"
5998   [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
5999                      (match_operand:P 1 "register_operand" "d"))
6000              (match_operand 2 "const_int_operand" "n")
6001              (match_operand 3 "const_int_operand" "n"))]
6002   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6004   operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
6005   return "prefx\t%2,%1(%0)";
6007   [(set_attr "type" "prefetchx")])
6009 (define_insn "nop"
6010   [(const_int 0)]
6011   ""
6012   "%(nop%)"
6013   [(set_attr "type"     "nop")
6014    (set_attr "mode"     "none")])
6016 ;; Like nop, but commented out when outside a .set noreorder block.
6017 (define_insn "hazard_nop"
6018   [(const_int 1)]
6019   ""
6020   {
6021     if (set_noreorder)
6022       return "nop";
6023     else
6024       return "#nop";
6025   }
6026   [(set_attr "type"     "nop")])
6028 ;; MIPS4 Conditional move instructions.
6030 (define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
6031   [(set (match_operand:GPR 0 "register_operand" "=d,d")
6032         (if_then_else:GPR
6033          (match_operator:MOVECC 4 "equality_operator"
6034                 [(match_operand:MOVECC 1 "register_operand" "<ccreg>,<ccreg>")
6035                  (const_int 0)])
6036          (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
6037          (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
6038   "ISA_HAS_CONDMOVE"
6039   "@
6040     mov%T4\t%0,%z2,%1
6041     mov%t4\t%0,%z3,%1"
6042   [(set_attr "type" "condmove")
6043    (set_attr "mode" "<GPR:MODE>")])
6045 (define_insn "*movsf_on_<MOVECC:mode>"
6046   [(set (match_operand:SF 0 "register_operand" "=f,f")
6047         (if_then_else:SF
6048          (match_operator:MOVECC 4 "equality_operator"
6049                 [(match_operand:MOVECC 1 "register_operand" "<ccreg>,<ccreg>")
6050                  (const_int 0)])
6051          (match_operand:SF 2 "register_operand" "f,0")
6052          (match_operand:SF 3 "register_operand" "0,f")))]
6053   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6054   "@
6055     mov%T4.s\t%0,%2,%1
6056     mov%t4.s\t%0,%3,%1"
6057   [(set_attr "type" "condmove")
6058    (set_attr "mode" "SF")])
6060 (define_insn "*movdf_on_<MOVECC:mode>"
6061   [(set (match_operand:DF 0 "register_operand" "=f,f")
6062         (if_then_else:DF
6063          (match_operator:MOVECC 4 "equality_operator"
6064                 [(match_operand:MOVECC 1 "register_operand" "<ccreg>,<ccreg>")
6065                  (const_int 0)])
6066          (match_operand:DF 2 "register_operand" "f,0")
6067          (match_operand:DF 3 "register_operand" "0,f")))]
6068   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6069   "@
6070     mov%T4.d\t%0,%2,%1
6071     mov%t4.d\t%0,%3,%1"
6072   [(set_attr "type" "condmove")
6073    (set_attr "mode" "DF")])
6075 ;; These are the main define_expand's used to make conditional moves.
6077 (define_expand "mov<mode>cc"
6078   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6079    (set (match_operand:GPR 0 "register_operand")
6080         (if_then_else:GPR (match_dup 5)
6081                           (match_operand:GPR 2 "reg_or_0_operand")
6082                           (match_operand:GPR 3 "reg_or_0_operand")))]
6083   "ISA_HAS_CONDMOVE"
6085   gen_conditional_move (operands);
6086   DONE;
6089 (define_expand "movsfcc"
6090   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6091    (set (match_operand:SF 0 "register_operand")
6092         (if_then_else:SF (match_dup 5)
6093                          (match_operand:SF 2 "register_operand")
6094                          (match_operand:SF 3 "register_operand")))]
6095   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6097   gen_conditional_move (operands);
6098   DONE;
6101 (define_expand "movdfcc"
6102   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6103    (set (match_operand:DF 0 "register_operand")
6104         (if_then_else:DF (match_dup 5)
6105                          (match_operand:DF 2 "register_operand")
6106                          (match_operand:DF 3 "register_operand")))]
6107   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6109   gen_conditional_move (operands);
6110   DONE;
6114 ;;  ....................
6116 ;;      mips16 inline constant tables
6118 ;;  ....................
6121 (define_insn "consttable_int"
6122   [(unspec_volatile [(match_operand 0 "consttable_operand" "")
6123                      (match_operand 1 "const_int_operand" "")]
6124                     UNSPEC_CONSTTABLE_INT)]
6125   "TARGET_MIPS16"
6127   assemble_integer (operands[0], INTVAL (operands[1]),
6128                     BITS_PER_UNIT * INTVAL (operands[1]), 1);
6129   return "";
6131   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6133 (define_insn "consttable_float"
6134   [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
6135                     UNSPEC_CONSTTABLE_FLOAT)]
6136   "TARGET_MIPS16"
6138   REAL_VALUE_TYPE d;
6140   if (GET_CODE (operands[0]) != CONST_DOUBLE)
6141     abort ();
6142   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
6143   assemble_real (d, GET_MODE (operands[0]),
6144                  GET_MODE_BITSIZE (GET_MODE (operands[0])));
6145   return "";
6147   [(set (attr "length")
6148         (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
6150 (define_insn "align"
6151   [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
6152   ""
6153   ".align\t%0"
6154   [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
6156 (define_split
6157   [(match_operand 0 "small_data_pattern")]
6158   "reload_completed"
6159   [(match_dup 0)]
6160   { operands[0] = mips_rewrite_small_data (operands[0]); })